diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index f1844da86cf..7f218e99da4 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -2,7 +2,13 @@ name: "Code scanning - action" on: push: + branches: + - main + - 'rc/*' pull_request: + branches: + - main + - 'rc/*' schedule: - cron: '0 9 * * 1' @@ -14,16 +20,7 @@ jobs: steps: - name: Checkout repository uses: actions/checkout@v2 - with: - # We must fetch at least the immediate parents so that if this is - # a pull request then we can checkout the head. - fetch-depth: 2 - # If this run was triggered by a pull request event, then checkout - # the head of the pull request instead of the merge commit. - - run: git checkout HEAD^2 - if: ${{ github.event_name == 'pull_request' }} - # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL uses: github/codeql-action/init@v1 diff --git a/.github/workflows/generate-query-help-docs.yml b/.github/workflows/generate-query-help-docs.yml new file mode 100644 index 00000000000..e3af19c6dea --- /dev/null +++ b/.github/workflows/generate-query-help-docs.yml @@ -0,0 +1,60 @@ +name: Generate CodeQL query help documentation using Sphinx + +on: + workflow_dispatch: + inputs: + description: + description: A description of the purpose of this job. For human consumption. + required: false + push: + branches: + - 'lgtm.com' + pull_request: + paths: + - '.github/workflows/generate-query-help-docs.yml' + - 'docs/codeql/query-help/**' + +jobs: + build: + runs-on: ubuntu-latest + steps: + - name: Clone github/codeql + uses: actions/checkout@v2 + with: + path: codeql + - name: Clone github/codeql-go + uses: actions/checkout@v2 + with: + repository: 'github/codeql-go' + path: codeql-go + - name: Set up Python 3.8 + uses: actions/setup-python@v2 + with: + python-version: 3.8 + - name: Download CodeQL CLI + uses: dsaltares/fetch-gh-release-asset@aa37ae5c44d3c9820bc12fe675e8670ecd93bd1c + with: + repo: "github/codeql-cli-binaries" + version: "latest" + file: "codeql-linux64.zip" + token: ${{ secrets.GITHUB_TOKEN }} + - name: Unzip CodeQL CLI + run: unzip -d codeql-cli codeql-linux64.zip + - name: Set up query help docs folder + run: | + cp -r codeql/docs/codeql/** . + - name: Query help to markdown + run: | + PATH="$PATH:codeql-cli/codeql" python codeql/docs/codeql/query-help-markdown.py + - name: Run Sphinx for query help + uses: ammaraskar/sphinx-action@8b4f60114d7fd1faeba1a712269168508d4750d2 # v0.4 + with: + docs-folder: "query-help/" + pre-build-command: "python -m pip install --upgrade recommonmark && python -m pip install --upgrade sphinx-markdown-tables" + build-command: "sphinx-build -b dirhtml . _build" + - name: Upload HTML artifacts + uses: actions/upload-artifact@v2 + with: + name: query-help-html + path: query-help/_build + diff --git a/.gitignore b/.gitignore index b14dab0a6b1..0951496d45c 100644 --- a/.gitignore +++ b/.gitignore @@ -17,6 +17,9 @@ # Byte-compiled python files *.pyc +# python virtual environment folder +.venv/ + # It's useful (though not required) to be able to unpack codeql in the ql checkout itself /codeql/ diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index fa88395e5d0..39552ad0bd9 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -38,6 +38,8 @@ If you have an idea for a query that you would like to share with other CodeQL u - The queries and libraries must be autoformatted, for example using the "Format Document" command in [CodeQL for Visual Studio Code](https://help.semmle.com/codeql/codeql-for-vscode/procedures/about-codeql-for-vscode.html). + If you prefer, you can use this [pre-commit hook](misc/scripts/pre-commit) that automatically checks whether your files are correctly formatted. See the [pre-commit hook installation guide](docs/install-pre-commit-hook.md) for instructions on how to install the hook. + 4. **Compilation** - Compilation of the query and any associated libraries and tests must be resilient to future development of the [supported](docs/supported-queries.md) libraries. This means that the functionality cannot use internal libraries, cannot depend on the output of `getAQlClass`, and cannot make use of regexp matching on `toString`. diff --git a/change-notes/1.26/analysis-python.md b/change-notes/1.26/analysis-python.md index f60eb6b4354..0c6cbeaacfa 100644 --- a/change-notes/1.26/analysis-python.md +++ b/change-notes/1.26/analysis-python.md @@ -4,19 +4,34 @@ The following changes in version 1.26 affect Python analysis in all applications ## General improvements - -## New queries - -| **Query** | **Tags** | **Purpose** | -|-----------------------------|-----------|--------------------------------------------------------------------| - - ## Changes to existing queries | **Query** | **Expected impact** | **Change** | |----------------------------|------------------------|------------------------------------------------------------------| - - +|`py/unsafe-deserialization` | Different results. | The underlying data flow library has been changed. See below for more details. | +|`py/path-injection` | Different results. | The underlying data flow library has been changed. See below for more details. | +|`py/command-line-injection` | Different results. | The underlying data flow library has been changed. See below for more details. | +|`py/reflective-xss` | Different results. | The underlying data flow library has been changed. See below for more details. | +|`py/sql-injection` | Different results. | The underlying data flow library has been changed. See below for more details. | +|`py/code-injection` | Different results. | The underlying data flow library has been changed. See below for more details. | ## Changes to libraries - +* Some of the security queries now use the shared data flow library for data flow and taint tracking. This has resulted in an overall more robust and accurate analysis. The libraries mentioned below have been modelled in this new framework. Other libraries (e.g. the web framework `CherryPy`) have not been modelled yet, and this may lead to a temporary loss of results for these frameworks. +* Improved modelling of the following serialization libraries: + - `PyYAML` + - `dill` + - `pickle` + - `marshal` +* Improved modelling of the following web frameworks: + - `Django` (Note that modelling of class-based response handlers is currently incomplete.) + - `Flask` +* Support for Werkzeug `MultiDict`. +* Support for the [Python Database API Specification v2.0 (PEP-249)](https://www.python.org/dev/peps/pep-0249/), including the following libraries: + - `MySQLdb` + - `mysql-connector-python` + - `django.db` +* Improved modelling of the following command execution libraries: + - `Fabric` + - `Invoke` +* Improved modelling of security-related standard library modules, such as `os`, `popen2`, `platform`, and `base64`. +* The original versions of the updated queries have been preserved [here](https://github.com/github/codeql/tree/main/python/ql/src/experimental/Security-old-dataflow). * Added taint tracking support for string formatting through f-strings. diff --git a/cpp/change-notes/2020-02-04-unsigned-difference-expression-compared-zero.md b/cpp/change-notes/2020-02-04-unsigned-difference-expression-compared-zero.md new file mode 100644 index 00000000000..d4a6ebafa0c --- /dev/null +++ b/cpp/change-notes/2020-02-04-unsigned-difference-expression-compared-zero.md @@ -0,0 +1,2 @@ +lgtm +* A new query (`cpp/unsigned-difference-expression-compared-zero`) is run but not yet displayed on LGTM. The query finds unsigned subtractions used in relational comparisons with the value 0. This query was originally submitted as an experimental query by @ihsinme in https://github.com/github/codeql/pull/4745. diff --git a/cpp/config/suites/cpp/correctness b/cpp/config/suites/cpp/correctness index bcdf94c94ce..55678a1dd37 100644 --- a/cpp/config/suites/cpp/correctness +++ b/cpp/config/suites/cpp/correctness @@ -10,6 +10,7 @@ + semmlecode-cpp-queries/Likely Bugs/Underspecified Functions/MistypedFunctionArguments.ql: /Correctness/Dangerous Conversions + semmlecode-cpp-queries/Security/CWE/CWE-253/HResultBooleanConversion.ql: /Correctness/Dangerous Conversions + semmlecode-cpp-queries/Likely Bugs/OO/UnsafeUseOfThis.ql: /Correctness/Dangerous Conversions ++ semmlecode-cpp-queries/Security/CWE/CWE-191/UnsignedDifferenceExpressionComparedZero.ql: /Correctness/Dangerous Conversions # Consistent Use + semmlecode-cpp-queries/Critical/ReturnValueIgnored.ql: /Correctness/Consistent Use + semmlecode-cpp-queries/Likely Bugs/InconsistentCheckReturnNull.ql: /Correctness/Consistent Use diff --git a/cpp/ql/src/Architecture/General Class-Level Information/ClassHierarchies.ql b/cpp/ql/src/Architecture/General Class-Level Information/ClassHierarchies.ql index 9e399982fec..4d17618f1bc 100644 --- a/cpp/ql/src/Architecture/General Class-Level Information/ClassHierarchies.ql +++ b/cpp/ql/src/Architecture/General Class-Level Information/ClassHierarchies.ql @@ -4,9 +4,6 @@ * @kind graph * @id cpp/architecture/class-hierarchies * @graph.layout organic - * @workingset jhotdraw - * @result succeed 48 - * @result_ondemand succeed 48 * @tags maintainability */ diff --git a/cpp/ql/src/Architecture/General Class-Level Information/InheritanceDepthDistribution.ql b/cpp/ql/src/Architecture/General Class-Level Information/InheritanceDepthDistribution.ql index 72605be0540..0fc6f0ba2a7 100644 --- a/cpp/ql/src/Architecture/General Class-Level Information/InheritanceDepthDistribution.ql +++ b/cpp/ql/src/Architecture/General Class-Level Information/InheritanceDepthDistribution.ql @@ -4,9 +4,6 @@ * @kind chart * @id cpp/architecture/inheritance-depth-distribution * @chart.type line - * @workingset jhotdraw - * @result succeed 48 - * @result_ondemand succeed 48 * @tags maintainability */ diff --git a/cpp/ql/src/Architecture/General Namespace-Level Information/GlobalNamespaceClasses.ql b/cpp/ql/src/Architecture/General Namespace-Level Information/GlobalNamespaceClasses.ql index 77f1be32aa0..eec387e2957 100644 --- a/cpp/ql/src/Architecture/General Namespace-Level Information/GlobalNamespaceClasses.ql +++ b/cpp/ql/src/Architecture/General Namespace-Level Information/GlobalNamespaceClasses.ql @@ -1,7 +1,8 @@ /** * @name Global namespace classes * @description Finds classes that belong to no namespace. - * @kind table + * @kind problem + * @problem.severity recommendation * @id cpp/architecture/global-namespace-classes * @tags maintainability * modularity diff --git a/cpp/ql/src/Architecture/Refactoring Opportunities/ClassesWithManyDependencies.ql b/cpp/ql/src/Architecture/Refactoring Opportunities/ClassesWithManyDependencies.ql index 33db264a549..384af9ebef8 100644 --- a/cpp/ql/src/Architecture/Refactoring Opportunities/ClassesWithManyDependencies.ql +++ b/cpp/ql/src/Architecture/Refactoring Opportunities/ClassesWithManyDependencies.ql @@ -4,9 +4,6 @@ * @kind problem * @id cpp/architecture/classes-with-many-dependencies * @problem.severity recommendation - * @workingset jhotdraw - * @result succeed 20 - * @result_ondemand succeed 20 * @tags maintainability * statistical * non-attributable diff --git a/cpp/ql/src/Best Practices/Magic Constants/MagicConstants.qll b/cpp/ql/src/Best Practices/Magic Constants/MagicConstants.qll index d5bf4f71292..587b64b60b3 100644 --- a/cpp/ql/src/Best Practices/Magic Constants/MagicConstants.qll +++ b/cpp/ql/src/Best Practices/Magic Constants/MagicConstants.qll @@ -8,168 +8,41 @@ import semmle.code.cpp.AutogeneratedFile predicate trivialPositiveIntValue(string s) { // Small numbers s = [0 .. 20].toString() or - // Popular powers of two (decimal) - s = "16" or - s = "24" or - s = "32" or - s = "64" or - s = "128" or - s = "256" or - s = "512" or - s = "1024" or - s = "2048" or - s = "4096" or - s = "16384" or - s = "32768" or - s = "65536" or - s = "1048576" or - s = "2147483648" or - s = "4294967296" or - // Popular powers of two, minus one (decimal) - s = "15" or - s = "31" or - s = "63" or - s = "127" or - s = "255" or - s = "511" or - s = "1023" or - s = "2047" or - s = "4095" or - s = "16383" or - s = "32767" or - s = "65535" or - s = "1048577" or - s = "2147483647" or - s = "4294967295" or - // Popular powers of two (32-bit hex) - s = "0x00000001" or - s = "0x00000002" or - s = "0x00000004" or - s = "0x00000008" or - s = "0x00000010" or - s = "0x00000020" or - s = "0x00000040" or - s = "0x00000080" or - s = "0x00000100" or - s = "0x00000200" or - s = "0x00000400" or - s = "0x00000800" or - s = "0x00001000" or - s = "0x00002000" or - s = "0x00004000" or - s = "0x00008000" or - s = "0x00010000" or - s = "0x00020000" or - s = "0x00040000" or - s = "0x00080000" or - s = "0x00100000" or - s = "0x00200000" or - s = "0x00400000" or - s = "0x00800000" or - s = "0x01000000" or - s = "0x02000000" or - s = "0x04000000" or - s = "0x08000000" or - s = "0x10000000" or - s = "0x20000000" or - s = "0x40000000" or - s = "0x80000000" or - // Popular powers of two, minus one (32-bit hex) - s = "0x00000001" or - s = "0x00000003" or - s = "0x00000007" or - s = "0x0000000f" or - s = "0x0000001f" or - s = "0x0000003f" or - s = "0x0000007f" or - s = "0x000000ff" or - s = "0x000001ff" or - s = "0x000003ff" or - s = "0x000007ff" or - s = "0x00000fff" or - s = "0x00001fff" or - s = "0x00003fff" or - s = "0x00007fff" or - s = "0x0000ffff" or - s = "0x0001ffff" or - s = "0x0003ffff" or - s = "0x0007ffff" or - s = "0x000fffff" or - s = "0x001fffff" or - s = "0x003fffff" or - s = "0x007fffff" or - s = "0x00ffffff" or - s = "0x01ffffff" or - s = "0x03ffffff" or - s = "0x07ffffff" or - s = "0x0fffffff" or - s = "0x1fffffff" or - s = "0x3fffffff" or - s = "0x7fffffff" or - s = "0xffffffff" or - // Popular powers of two (16-bit hex) - s = "0x0001" or - s = "0x0002" or - s = "0x0004" or - s = "0x0008" or - s = "0x0010" or - s = "0x0020" or - s = "0x0040" or - s = "0x0080" or - s = "0x0100" or - s = "0x0200" or - s = "0x0400" or - s = "0x0800" or - s = "0x1000" or - s = "0x2000" or - s = "0x4000" or - s = "0x8000" or - // Popular powers of two, minus one (16-bit hex) - s = "0x0001" or - s = "0x0003" or - s = "0x0007" or - s = "0x000f" or - s = "0x001f" or - s = "0x003f" or - s = "0x007f" or - s = "0x00ff" or - s = "0x01ff" or - s = "0x03ff" or - s = "0x07ff" or - s = "0x0fff" or - s = "0x1fff" or - s = "0x3fff" or - s = "0x7fff" or - s = "0xffff" or - // Popular powers of two (8-bit hex) - s = "0x01" or - s = "0x02" or - s = "0x04" or - s = "0x08" or - s = "0x10" or - s = "0x20" or - s = "0x40" or - s = "0x80" or - // Popular powers of two, minus one (8-bit hex) - s = "0x01" or - s = "0x03" or - s = "0x07" or - s = "0x0f" or - s = "0x1f" or - s = "0x3f" or - s = "0x7f" or - s = "0xff" or - s = "0x00" or - // Powers of ten - s = "10" or - s = "100" or - s = "1000" or - s = "10000" or - s = "100000" or - s = "1000000" or - s = "10000000" or - s = "100000000" or - s = "1000000000" + s = + [ + // Popular powers of two (decimal) + "16", "24", "32", "64", "128", "256", "512", "1024", "2048", "4096", "16384", "32768", + "65536", "1048576", "2147483648", "4294967296", + // Popular powers of two, minus one (decimal) + "15", "31", "63", "127", "255", "511", "1023", "2047", "4095", "16383", "32767", "65535", + "1048577", "2147483647", "4294967295", + // Popular powers of two (32-bit hex) + "0x00000001", "0x00000002", "0x00000004", "0x00000008", "0x00000010", "0x00000020", + "0x00000040", "0x00000080", "0x00000100", "0x00000200", "0x00000400", "0x00000800", + "0x00001000", "0x00002000", "0x00004000", "0x00008000", "0x00010000", "0x00020000", + "0x00040000", "0x00080000", "0x00100000", "0x00200000", "0x00400000", "0x00800000", + "0x01000000", "0x02000000", "0x04000000", "0x08000000", "0x10000000", "0x20000000", + "0x40000000", "0x80000000", + // Popular powers of two, minus one (32-bit hex) + "0x00000001", "0x00000003", "0x00000007", "0x0000000f", "0x0000001f", "0x0000003f", + "0x0000007f", "0x000000ff", "0x000001ff", "0x000003ff", "0x000007ff", "0x00000fff", + "0x00001fff", "0x00003fff", "0x00007fff", "0x0000ffff", "0x0001ffff", "0x0003ffff", + "0x0007ffff", "0x000fffff", "0x001fffff", "0x003fffff", "0x007fffff", "0x00ffffff", + "0x01ffffff", "0x03ffffff", "0x07ffffff", "0x0fffffff", "0x1fffffff", "0x3fffffff", + "0x7fffffff", "0xffffffff", + // Popular powers of two (16-bit hex) + "0x0001", "0x0002", "0x0004", "0x0008", "0x0010", "0x0020", "0x0040", "0x0080", "0x0100", + "0x0200", "0x0400", "0x0800", "0x1000", "0x2000", "0x4000", "0x8000", + // Popular powers of two, minus one (16-bit hex) + "0x0001", "0x0003", "0x0007", "0x000f", "0x001f", "0x003f", "0x007f", "0x00ff", "0x01ff", + "0x03ff", "0x07ff", "0x0fff", "0x1fff", "0x3fff", "0x7fff", "0xffff", + // Popular powers of two (8-bit hex) + "0x01", "0x02", "0x04", "0x08", "0x10", "0x20", "0x40", "0x80", + // Popular powers of two, minus one (8-bit hex) + "0x01", "0x03", "0x07", "0x0f", "0x1f", "0x3f", "0x7f", "0xff", "0x00", + // Powers of ten + "10", "100", "1000", "10000", "100000", "1000000", "10000000", "100000000", "1000000000" + ] } predicate trivialIntValue(string s) { @@ -235,10 +108,7 @@ predicate joiningStringTrivial(Literal lit) { // understand (which is against the spirit of these queries). stringLiteral(lit) and exists(FunctionCall fc | - ( - fc.getTarget().getName() = "operator+" or - fc.getTarget().getName() = "operator<<" - ) and + fc.getTarget().getName() = ["operator+", "operator<<"] and fc.getAnArgument().getAChild*() = lit ) and lit.getValue().length() < 16 diff --git a/cpp/ql/src/DefaultOptions.qll b/cpp/ql/src/DefaultOptions.qll index 3e03ec9ee65..9ed99054098 100644 --- a/cpp/ql/src/DefaultOptions.qll +++ b/cpp/ql/src/DefaultOptions.qll @@ -59,14 +59,9 @@ class Options extends string { predicate exits(Function f) { f.getAnAttribute().hasName("noreturn") or - exists(string name | f.hasGlobalOrStdName(name) | - name = "exit" or - name = "_exit" or - name = "abort" or - name = "__assert_fail" or - name = "longjmp" or - name = "__builtin_unreachable" - ) + f.hasGlobalOrStdName([ + "exit", "_exit", "abort", "__assert_fail", "longjmp", "__builtin_unreachable" + ]) or CustomOptions::exits(f) // old Options.qll } diff --git a/cpp/ql/src/JPL_C/LOC-2/Rule 05/HeapMemory.ql b/cpp/ql/src/JPL_C/LOC-2/Rule 05/HeapMemory.ql index e170c48f4f6..30324d8840d 100644 --- a/cpp/ql/src/JPL_C/LOC-2/Rule 05/HeapMemory.ql +++ b/cpp/ql/src/JPL_C/LOC-2/Rule 05/HeapMemory.ql @@ -21,15 +21,7 @@ class Initialization extends Function { } class Allocation extends FunctionCall { - Allocation() { - exists(string name | name = this.getTarget().getName() | - name = "malloc" or - name = "calloc" or - name = "alloca" or - name = "sbrk" or - name = "valloc" - ) - } + Allocation() { this.getTarget().getName() = ["malloc", "calloc", "alloca", "sbrk", "valloc"] } } from Function f, Allocation a diff --git a/cpp/ql/src/JPL_C/LOC-2/Rule 07/ThreadSafety.ql b/cpp/ql/src/JPL_C/LOC-2/Rule 07/ThreadSafety.ql index 5b9f9cf79d1..4eacedc3339 100644 --- a/cpp/ql/src/JPL_C/LOC-2/Rule 07/ThreadSafety.ql +++ b/cpp/ql/src/JPL_C/LOC-2/Rule 07/ThreadSafety.ql @@ -13,13 +13,8 @@ import cpp class ForbiddenCall extends FunctionCall { ForbiddenCall() { - exists(string name | name = this.getTarget().getName() | - name = "task_delay" or - name = "taskDelay" or - name = "sleep" or - name = "nanosleep" or - name = "clock_nanosleep" - ) + this.getTarget().getName() = + ["task_delay", "taskDelay", "sleep", "nanosleep", "clock_nanosleep"] } } diff --git a/cpp/ql/src/JPL_C/LOC-2/Rule 09/Semaphores.qll b/cpp/ql/src/JPL_C/LOC-2/Rule 09/Semaphores.qll index d662aa85033..0b60a3b9877 100644 --- a/cpp/ql/src/JPL_C/LOC-2/Rule 09/Semaphores.qll +++ b/cpp/ql/src/JPL_C/LOC-2/Rule 09/Semaphores.qll @@ -6,12 +6,7 @@ import cpp class SemaphoreCreation extends FunctionCall { SemaphoreCreation() { - exists(string name | name = this.getTarget().getName() | - name = "semBCreate" or - name = "semMCreate" or - name = "semCCreate" or - name = "semRWCreate" - ) + this.getTarget().getName() = ["semBCreate", "semMCreate", "semCCreate", "semRWCreate"] } Variable getSemaphore() { result.getAnAccess() = this.getParent().(Assignment).getLValue() } @@ -72,11 +67,7 @@ class SemaphoreGive extends UnlockOperation { } class LockingPrimitive extends FunctionCall, LockOperation { - LockingPrimitive() { - exists(string name | name = this.getTarget().getName() | - name = "taskLock" or name = "intLock" or name = "taskRtpLock" - ) - } + LockingPrimitive() { this.getTarget().getName() = ["taskLock", "intLock", "taskRtpLock"] } override Function getLocked() { result = this.getTarget() } @@ -89,11 +80,7 @@ class LockingPrimitive extends FunctionCall, LockOperation { } class UnlockingPrimitive extends FunctionCall, UnlockOperation { - UnlockingPrimitive() { - exists(string name | name = this.getTarget().getName() | - name = "taskUnlock" or name = "intUnlock" or name = "taskRtpUnlock" - ) - } + UnlockingPrimitive() { this.getTarget().getName() = ["taskUnlock", "intUnlock", "taskRtpUnlock"] } Function getLocked() { result = getMatchingLock().getLocked() } diff --git a/cpp/ql/src/JPL_C/LOC-3/Rule 17/BasicIntTypes.ql b/cpp/ql/src/JPL_C/LOC-3/Rule 17/BasicIntTypes.ql index 965bb8440b0..82b7f146554 100644 --- a/cpp/ql/src/JPL_C/LOC-3/Rule 17/BasicIntTypes.ql +++ b/cpp/ql/src/JPL_C/LOC-3/Rule 17/BasicIntTypes.ql @@ -12,18 +12,7 @@ import cpp predicate allowedTypedefs(TypedefType t) { - exists(string name | name = t.getName() | - name = "I64" or - name = "U64" or - name = "I32" or - name = "U32" or - name = "I16" or - name = "U16" or - name = "I8" or - name = "U8" or - name = "F64" or - name = "F32" - ) + t.getName() = ["I64", "U64", "I32", "U32", "I16", "U16", "I8", "U8", "F64", "F32"] } /** diff --git a/cpp/ql/src/JPL_C/Tasks.qll b/cpp/ql/src/JPL_C/Tasks.qll index 51eb0477c03..19f4b5a9840 100644 --- a/cpp/ql/src/JPL_C/Tasks.qll +++ b/cpp/ql/src/JPL_C/Tasks.qll @@ -5,8 +5,8 @@ import cpp */ class Task extends Function { Task() { - exists(FunctionCall taskCreate, string name | name = "taskCreate" or name = "taskSpawn" | - name = taskCreate.getTarget().getName() and + exists(FunctionCall taskCreate | + taskCreate.getTarget().getName() = ["taskCreate", "taskSpawn"] and this = taskCreate.getArgument(4).(AddressOfExpr).getAddressable() ) } diff --git a/cpp/ql/src/Likely Bugs/Conversion/LossyFunctionResultCast.ql b/cpp/ql/src/Likely Bugs/Conversion/LossyFunctionResultCast.ql index 27f2000692c..2a8aba6a961 100644 --- a/cpp/ql/src/Likely Bugs/Conversion/LossyFunctionResultCast.ql +++ b/cpp/ql/src/Likely Bugs/Conversion/LossyFunctionResultCast.ql @@ -13,38 +13,17 @@ import cpp import semmle.code.cpp.dataflow.DataFlow predicate whitelist(Function f) { - exists(string fName | - fName = f.getName() and - ( - fName = "ceil" or - fName = "ceilf" or - fName = "ceill" or - fName = "floor" or - fName = "floorf" or - fName = "floorl" or - fName = "nearbyint" or - fName = "nearbyintf" or - fName = "nearbyintl" or - fName = "rint" or - fName = "rintf" or - fName = "rintl" or - fName = "round" or - fName = "roundf" or - fName = "roundl" or - fName = "trunc" or - fName = "truncf" or - fName = "truncl" or - fName.matches("__builtin_%") - ) - ) + f.getName() = + [ + "ceil", "ceilf", "ceill", "floor", "floorf", "floorl", "nearbyint", "nearbyintf", + "nearbyintl", "rint", "rintf", "rintl", "round", "roundf", "roundl", "trunc", "truncf", + "truncl" + ] or + f.getName().matches("__builtin_%") } predicate whitelistPow(FunctionCall fc) { - ( - fc.getTarget().getName() = "pow" or - fc.getTarget().getName() = "powf" or - fc.getTarget().getName() = "powl" - ) and + fc.getTarget().getName() = ["pow", "powf", "powl"] and exists(float value | value = fc.getArgument(0).getValue().toFloat() and (value.floor() - value).abs() < 0.001 diff --git a/cpp/ql/src/Security/CWE/CWE-020/ExternalAPIsSpecific.qll b/cpp/ql/src/Security/CWE/CWE-020/ExternalAPIsSpecific.qll index 788baeddbff..9ca598f86d6 100644 --- a/cpp/ql/src/Security/CWE/CWE-020/ExternalAPIsSpecific.qll +++ b/cpp/ql/src/Security/CWE/CWE-020/ExternalAPIsSpecific.qll @@ -46,7 +46,7 @@ class UntrustedDataToExternalAPIConfig extends TaintTracking::Configuration { UntrustedDataToExternalAPIConfig() { this = "UntrustedDataToExternalAPIConfig" } override predicate isSource(DataFlow::Node source) { - exists(RemoteFlowFunction remoteFlow | + exists(RemoteFlowSourceFunction remoteFlow | remoteFlow = source.asExpr().(Call).getTarget() and remoteFlow.hasRemoteFlowSource(_, _) ) diff --git a/cpp/ql/src/Security/CWE/CWE-079/CgiXss.ql b/cpp/ql/src/Security/CWE/CWE-079/CgiXss.ql index 0e0c4add7f6..24484a9dcaf 100644 --- a/cpp/ql/src/Security/CWE/CWE-079/CgiXss.ql +++ b/cpp/ql/src/Security/CWE/CWE-079/CgiXss.ql @@ -29,6 +29,8 @@ class QueryString extends EnvironmentRead { } class Configuration extends TaintTrackingConfiguration { + override predicate isSource(Expr source) { source instanceof QueryString } + override predicate isSink(Element tainted) { exists(PrintStdoutCall call | call.getAnArgument() = tainted) } diff --git a/cpp/ql/src/Security/CWE/CWE-089/SqlTainted.ql b/cpp/ql/src/Security/CWE/CWE-089/SqlTainted.ql index de786d22f30..5ed84f45250 100644 --- a/cpp/ql/src/Security/CWE/CWE-089/SqlTainted.ql +++ b/cpp/ql/src/Security/CWE/CWE-089/SqlTainted.ql @@ -27,6 +27,10 @@ class Configuration extends TaintTrackingConfiguration { override predicate isSink(Element tainted) { exists(SQLLikeFunction runSql | runSql.outermostWrapperFunctionCall(tainted, _)) } + + override predicate isBarrier(Expr e) { + super.isBarrier(e) or e.getUnspecifiedType() instanceof IntegralType + } } from diff --git a/cpp/ql/src/Security/CWE/CWE-191/UnsignedDifferenceExpressionComparedZero.c b/cpp/ql/src/Security/CWE/CWE-191/UnsignedDifferenceExpressionComparedZero.c new file mode 100644 index 00000000000..d2f2b76fddc --- /dev/null +++ b/cpp/ql/src/Security/CWE/CWE-191/UnsignedDifferenceExpressionComparedZero.c @@ -0,0 +1,5 @@ +unsigned limit = get_limit(); +unsigned total = 0; +while (limit - total > 0) { // wrong: if `total` is greater than `limit` this will underflow and continue executing the loop. + total += get_data(); +} \ No newline at end of file diff --git a/cpp/ql/src/Security/CWE/CWE-191/UnsignedDifferenceExpressionComparedZero.qhelp b/cpp/ql/src/Security/CWE/CWE-191/UnsignedDifferenceExpressionComparedZero.qhelp new file mode 100644 index 00000000000..965429bda8a --- /dev/null +++ b/cpp/ql/src/Security/CWE/CWE-191/UnsignedDifferenceExpressionComparedZero.qhelp @@ -0,0 +1,31 @@ + + + +

+This rule finds relational comparisons between the result of an unsigned subtraction and the value 0. +Such comparisons are likely to be wrong as the value of an unsigned subtraction can never be negative. So the +relational comparison ends up checking whether the result of the subtraction is equal to 0. +This is probably not what the programmer intended. +

+
+ + +

If a relational comparison is intended, consider casting the result of the subtraction to a signed type. + If the intention was to test for equality, consider replacing the relational comparison with an equality test. +

+ +
+ + + + + + +
  • SEI CERT C Coding Standard: +INT02-C. Understand integer conversion rules. +
  • + +
    +
    diff --git a/cpp/ql/src/Security/CWE/CWE-191/UnsignedDifferenceExpressionComparedZero.ql b/cpp/ql/src/Security/CWE/CWE-191/UnsignedDifferenceExpressionComparedZero.ql new file mode 100644 index 00000000000..007a4fd746d --- /dev/null +++ b/cpp/ql/src/Security/CWE/CWE-191/UnsignedDifferenceExpressionComparedZero.ql @@ -0,0 +1,49 @@ +/** + * @name Unsigned difference expression compared to zero + * @description A subtraction with an unsigned result can never be negative. Using such an expression in a relational comparison with `0` is likely to be wrong. + * @kind problem + * @id cpp/unsigned-difference-expression-compared-zero + * @problem.severity warning + * @precision medium + * @tags security + * correctness + * external/cwe/cwe-191 + */ + +import cpp +import semmle.code.cpp.commons.Exclusions +import semmle.code.cpp.valuenumbering.GlobalValueNumbering +import semmle.code.cpp.rangeanalysis.SimpleRangeAnalysis +import semmle.code.cpp.controlflow.Guards + +/** Holds if `sub` is guarded by a condition which ensures that `left >= right`. */ +pragma[noinline] +predicate isGuarded(SubExpr sub, Expr left, Expr right) { + exists(GuardCondition guard | + guard.controls(sub.getBasicBlock(), true) and + guard.ensuresLt(left, right, 0, sub.getBasicBlock(), false) + ) +} + +/** Holds if `sub` will never be negative. */ +predicate nonNegative(SubExpr sub) { + not exprMightOverflowNegatively(sub.getFullyConverted()) + or + // The subtraction is guarded by a check of the form `left >= right`. + exists(GVN left, GVN right | + // This is basically a poor man's version of a directional unbind operator. + strictcount([left, globalValueNumber(sub.getLeftOperand())]) = 1 and + strictcount([right, globalValueNumber(sub.getRightOperand())]) = 1 and + isGuarded(sub, left.getAnExpr(), right.getAnExpr()) + ) +} + +from RelationalOperation ro, SubExpr sub +where + not isFromMacroDefinition(ro) and + not isFromMacroDefinition(sub) and + ro.getLesserOperand().getValue().toInt() = 0 and + ro.getGreaterOperand() = sub and + sub.getFullyConverted().getUnspecifiedType().(IntegralType).isUnsigned() and + not nonNegative(sub) +select ro, "Unsigned subtraction can never be negative." diff --git a/cpp/ql/src/Security/CWE/CWE-313/CleartextSqliteDatabase.ql b/cpp/ql/src/Security/CWE/CWE-313/CleartextSqliteDatabase.ql index 000833cbb58..fb5454d523e 100644 --- a/cpp/ql/src/Security/CWE/CWE-313/CleartextSqliteDatabase.ql +++ b/cpp/ql/src/Security/CWE/CWE-313/CleartextSqliteDatabase.ql @@ -34,6 +34,10 @@ predicate sqlite_encryption_used() { } class Configuration extends TaintTrackingConfiguration { + override predicate isSource(Expr source) { + super.isSource(source) and source instanceof SensitiveExpr + } + override predicate isSink(Element taintedArg) { exists(SqliteFunctionCall sqliteCall | taintedArg = sqliteCall.getASource() and diff --git a/cpp/ql/src/Security/CWE/CWE-457/InitializationFunctions.qll b/cpp/ql/src/Security/CWE/CWE-457/InitializationFunctions.qll index b77ff068150..4739c7ad5cf 100644 --- a/cpp/ql/src/Security/CWE/CWE-457/InitializationFunctions.qll +++ b/cpp/ql/src/Security/CWE/CWE-457/InitializationFunctions.qll @@ -326,52 +326,37 @@ class InitializationFunction extends Function { // Return value is not a success code but the output functions never fail. name.matches("_Interlocked%") or - // Functions that never fail, according to MSDN. - name = "QueryPerformanceCounter" - or - name = "QueryPerformanceFrequency" - or - // Functions that never fail post-Vista, according to MSDN. - name = "InitializeCriticalSectionAndSpinCount" - or - // `rand_s` writes 0 to a non-null argument if it fails, according to MSDN. - name = "rand_s" - or - // IntersectRect initializes the argument regardless of whether the input intersects - name = "IntersectRect" - or - name = "SetRect" - or - name = "UnionRect" - or - // These functions appears to have an incorrect CFG, which leads to false positives - name = "PhysicalToLogicalDPIPoint" - or - name = "LogicalToPhysicalDPIPoint" - or - // Sets NtProductType to default on error - name = "RtlGetNtProductType" - or - // Our CFG is not sophisticated enough to detect that the argument is always initialized - name = "StringCchLengthA" - or - // All paths init the argument, and always returns SUCCESS. - name = "RtlUnicodeToMultiByteSize" - or - // All paths init the argument, and always returns SUCCESS. - name = "RtlMultiByteToUnicodeSize" - or - // All paths init the argument, and always returns SUCCESS. - name = "RtlUnicodeToMultiByteN" - or - // Always initializes argument - name = "RtlGetFirstRange" - or - // Destination range is zeroed out on failure, assuming first two parameters are valid - name = "memcpy_s" - or - // This zeroes the memory unconditionally - name = "SeCreateAccessState" + name = + [ + // Functions that never fail, according to MSDN. + "QueryPerformanceCounter", "QueryPerformanceFrequency", + // Functions that never fail post-Vista, according to MSDN. + "InitializeCriticalSectionAndSpinCount", + // `rand_s` writes 0 to a non-null argument if it fails, according to MSDN. + "rand_s", + // IntersectRect initializes the argument regardless of whether the input intersects + "IntersectRect", "SetRect", "UnionRect", + // These functions appears to have an incorrect CFG, which leads to false positives + "PhysicalToLogicalDPIPoint", "LogicalToPhysicalDPIPoint", + // Sets NtProductType to default on error + "RtlGetNtProductType", + // Our CFG is not sophisticated enough to detect that the argument is always initialized + "StringCchLengthA", + // All paths init the argument, and always returns SUCCESS. + "RtlUnicodeToMultiByteSize", + // All paths init the argument, and always returns SUCCESS. + "RtlMultiByteToUnicodeSize", + // All paths init the argument, and always returns SUCCESS. + "RtlUnicodeToMultiByteN", + // Always initializes argument + "RtlGetFirstRange", + // Destination range is zeroed out on failure, assuming first two parameters are valid + "memcpy_s", + // This zeroes the memory unconditionally + "SeCreateAccessState", + // Argument initialization is optional, but always succeeds + "KeGetCurrentProcessorNumberEx" + ] ) } } diff --git a/cpp/ql/src/Security/CWE/CWE-732/FilePermissions.qll b/cpp/ql/src/Security/CWE/CWE-732/FilePermissions.qll index d62f3e6a6da..ad5ed29098c 100644 --- a/cpp/ql/src/Security/CWE/CWE-732/FilePermissions.qll +++ b/cpp/ql/src/Security/CWE/CWE-732/FilePermissions.qll @@ -140,12 +140,9 @@ class FopenCreationExpr extends FileCreationExpr { class FopensCreationExpr extends FileCreationExpr { FopensCreationExpr() { - exists(string name | name = this.getTarget().getName() | - name = "fopen_s" or - name = "_wfopen_s" - ) and + this.getTarget().getName() = ["fopen_s", "_wfopen_s"] and exists(string mode | - (mode = "w" or mode = "a") and + mode = ["w", "a"] and this.getArgument(2).getValue().matches(mode + "%") ) } diff --git a/cpp/ql/src/experimental/Security/CWE/CWE-120/MemoryUnsafeFunctionScan.cpp b/cpp/ql/src/experimental/Security/CWE/CWE-120/MemoryUnsafeFunctionScan.cpp index 001f4da6028..e7394ffefc7 100644 --- a/cpp/ql/src/experimental/Security/CWE/CWE-120/MemoryUnsafeFunctionScan.cpp +++ b/cpp/ql/src/experimental/Security/CWE/CWE-120/MemoryUnsafeFunctionScan.cpp @@ -13,9 +13,10 @@ int main(int argc, char **argv) char buf1[10]; scanf("%s", buf1); - // GOOD, length is specified. The length should be one less than the size of the buffer, since the last character is the NULL terminator. - char buf2[10]; - sscanf(buf2, "%9s"); + // GOOD, length is specified. The length should be one less than the size of the destination buffer, since the last character is the NULL terminator. + char buf2[20]; + char buf3[10]; + sscanf(buf2, "%9s", buf3); // BAD, do not use scanf without specifying a length first char file[10]; diff --git a/cpp/ql/src/experimental/Security/CWE/CWE-14/CompilerRemovalOfCodeToClearBuffers.c b/cpp/ql/src/experimental/Security/CWE/CWE-14/CompilerRemovalOfCodeToClearBuffers.c new file mode 100644 index 00000000000..14dd07a573e --- /dev/null +++ b/cpp/ql/src/experimental/Security/CWE/CWE-14/CompilerRemovalOfCodeToClearBuffers.c @@ -0,0 +1,35 @@ +// BAD: the memset call will probably be removed. +void getPassword(void) { + char pwd[64]; + if (GetPassword(pwd, sizeof(pwd))) { + /* Checking of password, secure operations, etc. */ + } + memset(pwd, 0, sizeof(pwd)); +} +// GOOD: in this case the memset will not be removed. +void getPassword(void) { + char pwd[64]; + + if (retrievePassword(pwd, sizeof(pwd))) { + /* Checking of password, secure operations, etc. */ + } + memset_s(pwd, 0, sizeof(pwd)); +} +// GOOD: in this case the memset will not be removed. +void getPassword(void) { + char pwd[64]; + if (retrievePassword(pwd, sizeof(pwd))) { + /* Checking of password, secure operations, etc. */ + } + SecureZeroMemory(pwd, sizeof(pwd)); +} +// GOOD: in this case the memset will not be removed. +void getPassword(void) { + char pwd[64]; + if (retrievePassword(pwd, sizeof(pwd))) { + /* Checking of password, secure operations, etc. */ + } +#pragma optimize("", off) + memset(pwd, 0, sizeof(pwd)); +#pragma optimize("", on) +} diff --git a/cpp/ql/src/experimental/Security/CWE/CWE-14/CompilerRemovalOfCodeToClearBuffers.qhelp b/cpp/ql/src/experimental/Security/CWE/CWE-14/CompilerRemovalOfCodeToClearBuffers.qhelp new file mode 100644 index 00000000000..df0ed151d8f --- /dev/null +++ b/cpp/ql/src/experimental/Security/CWE/CWE-14/CompilerRemovalOfCodeToClearBuffers.qhelp @@ -0,0 +1,31 @@ + + + +

    Compiler optimization will exclude the cleaning of private information. +Using the memset function to clear private data in a variable that has no subsequent use is potentially dangerous, since the compiler can remove the call. +For some compilers, optimization is also possible when using calls to free memory after the memset function.

    + +

    It is possible to miss detection of vulnerabilities if used to clear fields of structures or parts of a buffer.

    + +
    + + +

    We recommend to use the RtlSecureZeroMemory or memset_s functions, or compilation flags that exclude optimization of memset calls (e.g. -fno-builtin-memset).

    + +
    + +

    The following example demonstrates an erroneous and corrected use of the memset function.

    + + +
    + + +
  • + CERT C Coding Standard: + MSC06-C. Beware of compiler optimizations. +
  • + +
    +
    diff --git a/cpp/ql/src/experimental/Security/CWE/CWE-14/CompilerRemovalOfCodeToClearBuffers.ql b/cpp/ql/src/experimental/Security/CWE/CWE-14/CompilerRemovalOfCodeToClearBuffers.ql new file mode 100644 index 00000000000..db09de9430d --- /dev/null +++ b/cpp/ql/src/experimental/Security/CWE/CWE-14/CompilerRemovalOfCodeToClearBuffers.ql @@ -0,0 +1,127 @@ +/** + * @name Compiler Removal Of Code To Clear Buffers + * @description Using memset the function to clear private data in a variable that has no subsequent use + * is potentially dangerous because the compiler can remove the call. + * @kind problem + * @id cpp/compiler-removal-of-code-to-clear-buffers + * @problem.severity warning + * @precision medium + * @tags security + * external/cwe/cwe-14 + */ + +import cpp +import semmle.code.cpp.dataflow.DataFlow +import semmle.code.cpp.dataflow.StackAddress + +/** + * A call to `memset` of the form `memset(ptr, value, num)`, for some local variable `ptr`. + */ +class CompilerRemovaMemset extends FunctionCall { + CompilerRemovaMemset() { + this.getTarget().hasGlobalOrStdName("memset") and + exists(DataFlow::Node source, DataFlow::Node sink, LocalVariable isv, Expr exp | + DataFlow::localFlow(source, sink) and + this.getArgument(0) = isv.getAnAccess() and + ( + source.asExpr() = exp + or + // handle the case where exp is defined by an address being passed into some function. + source.asDefiningArgument() = exp + ) and + exp.getLocation().getEndLine() < this.getArgument(0).getLocation().getStartLine() and + sink.asExpr() = this.getArgument(0) + ) + } + + predicate isExistsAllocForThisVariable() { + exists(AllocationExpr alloc, Variable v | + alloc = v.getAnAssignedValue() and + this.getArgument(0) = v.getAnAccess() and + alloc.getASuccessor+() = this + ) + or + not stackPointerFlowsToUse(this.getArgument(0), _, _, _) + } + + predicate isExistsFreeForThisVariable() { + exists(DeallocationExpr free, Variable v | + this.getArgument(0) = v.getAnAccess() and + free.getFreedExpr() = v.getAnAccess() and + this.getASuccessor+() = free + ) + } + + predicate isExistsCallWithThisVariableExcludingDeallocationCalls() { + exists(FunctionCall fc, Variable v | + not fc instanceof DeallocationExpr and + this.getArgument(0) = v.getAnAccess() and + fc.getAnArgument() = v.getAnAccess() and + this.getASuccessor+() = fc + ) + } + + predicate isVariableUseAfterMemsetExcludingCalls() { + exists(DataFlow::Node source, DataFlow::Node sink, LocalVariable isv, Expr exp | + DataFlow::localFlow(source, sink) and + this.getArgument(0) = isv.getAnAccess() and + source.asExpr() = isv.getAnAccess() and + exp.getLocation().getStartLine() > this.getArgument(2).getLocation().getEndLine() and + not exp.getParent() instanceof FunctionCall and + sink.asExpr() = exp + ) + } + + predicate isVariableUseBoundWithArgumentFunction() { + exists(DataFlow::Node source, DataFlow::Node sink, LocalVariable isv, Parameter p, Expr exp | + DataFlow::localFlow(source, sink) and + this.getArgument(0) = isv.getAnAccess() and + this.getEnclosingFunction().getAParameter() = p and + exp.getAChild*() = p.getAnAccess() and + source.asExpr() = exp and + sink.asExpr() = isv.getAnAccess() + ) + } + + predicate isVariableUseBoundWithGlobalVariable() { + exists( + DataFlow::Node source, DataFlow::Node sink, LocalVariable isv, GlobalVariable gv, Expr exp + | + DataFlow::localFlow(source, sink) and + this.getArgument(0) = isv.getAnAccess() and + exp.getAChild*() = gv.getAnAccess() and + source.asExpr() = exp and + sink.asExpr() = isv.getAnAccess() + ) + } + + predicate isExistsCompilationFlagsBlockingRemoval() { + exists(Compilation c | + c.getAFileCompiled() = this.getFile() and + c.getAnArgument() = "-fno-builtin-memset" + ) + } + + predicate isUseVCCompilation() { + exists(Compilation c | + c.getAFileCompiled() = this.getFile() and + ( + c.getArgument(2).matches("%gcc%") or + c.getArgument(2).matches("%g++%") or + c.getArgument(2).matches("%clang%") or + c.getArgument(2) = "--force-recompute" + ) + ) + } +} + +from CompilerRemovaMemset fc +where + not (fc.isExistsAllocForThisVariable() and not fc.isExistsFreeForThisVariable()) and + not (fc.isExistsFreeForThisVariable() and not fc.isUseVCCompilation()) and + not fc.isVariableUseAfterMemsetExcludingCalls() and + not fc.isExistsCallWithThisVariableExcludingDeallocationCalls() and + not fc.isVariableUseBoundWithArgumentFunction() and + not fc.isVariableUseBoundWithGlobalVariable() and + not fc.isExistsCompilationFlagsBlockingRemoval() +select fc.getArgument(0), "This variable will not be cleared." diff --git a/cpp/ql/src/experimental/Security/CWE/CWE-190/AllocMultiplicationOverflow.cpp b/cpp/ql/src/experimental/Security/CWE/CWE-190/AllocMultiplicationOverflow.cpp new file mode 100644 index 00000000000..bde49c946ea --- /dev/null +++ b/cpp/ql/src/experimental/Security/CWE/CWE-190/AllocMultiplicationOverflow.cpp @@ -0,0 +1,19 @@ + +image::image(int width, int height) +{ + int x, y; + + // allocate width * height pixels + pixels = new uint32_t[width * height]; + + // fill width * height pixels + for (y = 0; y < height; y++) + { + for (x = 0; x < width; x++) + { + pixels[(y * width) + height] = 0; + } + } + + // ... +} diff --git a/cpp/ql/src/experimental/Security/CWE/CWE-190/AllocMultiplicationOverflow.qhelp b/cpp/ql/src/experimental/Security/CWE/CWE-190/AllocMultiplicationOverflow.qhelp new file mode 100644 index 00000000000..97bd393d5a0 --- /dev/null +++ b/cpp/ql/src/experimental/Security/CWE/CWE-190/AllocMultiplicationOverflow.qhelp @@ -0,0 +1,25 @@ + + + + +

    The result of a multiplication is used in the size of an allocation. If the multiplication can be made to overflow, a much smaller amount of memory may be allocated than the rest of the code expects. This may lead to overflowing writes when the buffer is accessed later.

    +
    + + +

    To fix this issue, ensure that the arithmetic used in the size of an allocation cannot overflow before memory is allocated.

    +
    + + +

    In the following example, an array of size width * height is allocated and stored as pixels. If width and height are set such that the multiplication overflows and wraps to a small value (say, 4) then the initialization code that follows the allocation will write beyond the end of the array.

    + +
    + + +
  • + Cplusplus.com: Integer overflow. +
  • +
    + +
    diff --git a/cpp/ql/src/experimental/Security/CWE/CWE-190/AllocMultiplicationOverflow.ql b/cpp/ql/src/experimental/Security/CWE/CWE-190/AllocMultiplicationOverflow.ql new file mode 100644 index 00000000000..3a253854679 --- /dev/null +++ b/cpp/ql/src/experimental/Security/CWE/CWE-190/AllocMultiplicationOverflow.ql @@ -0,0 +1,40 @@ +/** + * @name Multiplication result may overflow and be used in allocation + * @description Using a multiplication result that may overflow in the size of an allocation may lead to buffer overflows when the allocated memory is used. + * @kind path-problem + * @problem.severity warning + * @precision low + * @tags security + * correctness + * external/cwe/cwe-190 + * external/cwe/cwe-128 + * @id cpp/multiplication-overflow-in-alloc + */ + +import cpp +import semmle.code.cpp.models.interfaces.Allocation +import semmle.code.cpp.dataflow.DataFlow +import DataFlow::PathGraph + +class MultToAllocConfig extends DataFlow::Configuration { + MultToAllocConfig() { this = "MultToAllocConfig" } + + override predicate isSource(DataFlow::Node node) { + // a multiplication of two non-constant expressions + exists(MulExpr me | + me = node.asExpr() and + forall(Expr e | e = me.getAnOperand() | not exists(e.getValue())) + ) + } + + override predicate isSink(DataFlow::Node node) { + // something that affects an allocation size + node.asExpr() = any(AllocationExpr ae).getSizeExpr().getAChild*() + } +} + +from MultToAllocConfig config, DataFlow::PathNode source, DataFlow::PathNode sink +where config.hasFlowPath(source, sink) +select sink, source, sink, + "Potentially overflowing value from $@ is used in the size of this allocation.", source, + "multiplication" diff --git a/cpp/ql/src/experimental/Security/CWE/CWE-191/UnsignedDifferenceExpressionComparedZero.c b/cpp/ql/src/experimental/Security/CWE/CWE-191/UnsignedDifferenceExpressionComparedZero.c deleted file mode 100644 index f6054226848..00000000000 --- a/cpp/ql/src/experimental/Security/CWE/CWE-191/UnsignedDifferenceExpressionComparedZero.c +++ /dev/null @@ -1,11 +0,0 @@ -unsigned long sizeArray; - -// BAD: let's consider several values, taking ULONG_MAX =18446744073709551615 -// sizeArray = 60; (sizeArray - 10) = 50; true -// sizeArray = 10; (sizeArray - 10) = 0; false -// sizeArray = 1; (sizeArray - 10) = 18446744073709551607; true -// sizeArray = 0; (sizeArray - 10) = 18446744073709551606; true -if (sizeArray - 10 > 0) - -// GOOD: Prevent overflow by checking the input -if (sizeArray > 10) diff --git a/cpp/ql/src/experimental/Security/CWE/CWE-191/UnsignedDifferenceExpressionComparedZero.qhelp b/cpp/ql/src/experimental/Security/CWE/CWE-191/UnsignedDifferenceExpressionComparedZero.qhelp deleted file mode 100644 index 3bf28d13df4..00000000000 --- a/cpp/ql/src/experimental/Security/CWE/CWE-191/UnsignedDifferenceExpressionComparedZero.qhelp +++ /dev/null @@ -1,33 +0,0 @@ - - - -

    The code compares the unsigned difference with zero. -It is highly probable that the condition is wrong if the difference expression has the unsigned type. -The condition holds in all the cases when difference is not equal to zero. -It means that we may use condition not equal. But the programmer probably wanted to compare the difference of elements.

    - -

    False positives include code in which the first difference element is always greater than or equal to the second. -For comparison, ">" such conditions are equivalent to "! =", And are recommended for replacement. -For comparison "> =", the conditions are always true and are recommended to be excluded.

    - -
    - - -

    Use a simple comparison of two elements, instead of comparing their difference to zero.

    - -
    - -

    The following example demonstrates an erroneous and corrected use of comparison.

    - - -
    - - -
  • CERT C Coding Standard: -INT02-C. Understand integer conversion rules. -
  • - -
    -
    diff --git a/cpp/ql/src/experimental/Security/CWE/CWE-191/UnsignedDifferenceExpressionComparedZero.ql b/cpp/ql/src/experimental/Security/CWE/CWE-191/UnsignedDifferenceExpressionComparedZero.ql deleted file mode 100644 index 300b2f944b5..00000000000 --- a/cpp/ql/src/experimental/Security/CWE/CWE-191/UnsignedDifferenceExpressionComparedZero.ql +++ /dev/null @@ -1,23 +0,0 @@ -/** - * @name Unsigned difference expression compared to zero - * @description It is highly probable that the condition is wrong if the difference expression has the unsigned type. - * The condition holds in all the cases when difference is not equal to zero. It means that we may use condition not equal. - * But the programmer probably wanted to compare the difference of elements. - * @kind problem - * @id cpp/unsigned-difference-expression-compared-zero - * @problem.severity warning - * @precision medium - * @tags security - * external/cwe/cwe-191 - */ - -import cpp -import semmle.code.cpp.commons.Exclusions - -from RelationalOperation ro, SubExpr sub -where - not isFromMacroDefinition(ro) and - ro.getLesserOperand().getValue().toInt() = 0 and - ro.getGreaterOperand() = sub and - sub.getFullyConverted().getUnspecifiedType().(IntegralType).isUnsigned() -select ro, "Difference in condition is always greater than or equal to zero" diff --git a/cpp/ql/src/experimental/Security/CWE/CWE-359/PrivateCleartextWrite.ql b/cpp/ql/src/experimental/Security/CWE/CWE-359/PrivateCleartextWrite.ql index 60b13525aff..205f17c06c9 100644 --- a/cpp/ql/src/experimental/Security/CWE/CWE-359/PrivateCleartextWrite.ql +++ b/cpp/ql/src/experimental/Security/CWE/CWE-359/PrivateCleartextWrite.ql @@ -16,6 +16,6 @@ import DataFlow::PathGraph from WriteConfig b, DataFlow::PathNode source, DataFlow::PathNode sink where b.hasFlowPath(source, sink) -select sink.getNode(), - "This write into the external location '" + sink + "' may contain unencrypted data from $@", - source, "this source." +select sink.getNode(), source, sink, + "This write into the external location '" + sink.getNode() + + "' may contain unencrypted data from $@", source, "this source." diff --git a/cpp/ql/src/experimental/Security/CWE/CWE-401/MemoryLeakOnFailedCallToRealloc.c b/cpp/ql/src/experimental/Security/CWE/CWE-401/MemoryLeakOnFailedCallToRealloc.c new file mode 100644 index 00000000000..dc5565f3471 --- /dev/null +++ b/cpp/ql/src/experimental/Security/CWE/CWE-401/MemoryLeakOnFailedCallToRealloc.c @@ -0,0 +1,20 @@ +// BAD: on unsuccessful call to realloc, we will lose a pointer to a valid memory block +if (currentSize < newSize) +{ + buffer = (unsigned char *)realloc(buffer, newSize); +} + + + +// GOOD: this way we will exclude possible memory leak +unsigned char * tmp; +if (currentSize < newSize) +{ + tmp = (unsigned char *)realloc(buffer, newSize); +} +if (tmp == NULL) +{ + free(buffer); +} +else + buffer = tmp; diff --git a/cpp/ql/src/experimental/Security/CWE/CWE-401/MemoryLeakOnFailedCallToRealloc.qhelp b/cpp/ql/src/experimental/Security/CWE/CWE-401/MemoryLeakOnFailedCallToRealloc.qhelp new file mode 100644 index 00000000000..14dcff74a25 --- /dev/null +++ b/cpp/ql/src/experimental/Security/CWE/CWE-401/MemoryLeakOnFailedCallToRealloc.qhelp @@ -0,0 +1,38 @@ + + + +

    Memory leak on failed call to realloc. +The expression mem = realloc (mem, size) is potentially dangerous, if the call fails, we will lose the pointer to the memory block. +An unsuccessful call is possible not only when trying to allocate a large amount of memory, but also when the process memory is strongly segmented.

    + +

    False positives include code in which immediately after calling the realloc function, the pointer is manipulated without first checking for validity. +In this case, an exception will occur in the program and it will terminate. +But from the point of view of safe coding, these places require the attention of developers. +At this stage, false positives are also possible in situations where the exception handling is quite complicated and occurs outside the base block in which memory is redistributed.

    + +
    + + +

    We recommend storing the result in a temporary variable and eliminating memory leak.

    + +
    + +

    The following example demonstrates an erroneous and corrected use of the realloc function.

    + + +
    + + +
  • + CERT C++ Coding Standard: +MEM51-CPP. Properly deallocate dynamically allocated resources. +
  • +
  • + CERT C Coding Standard: + WIN30-C. Properly pair allocation and deallocation functions. +
  • + +
    +
    diff --git a/cpp/ql/src/experimental/Security/CWE/CWE-401/MemoryLeakOnFailedCallToRealloc.ql b/cpp/ql/src/experimental/Security/CWE/CWE-401/MemoryLeakOnFailedCallToRealloc.ql new file mode 100644 index 00000000000..cf0afc64013 --- /dev/null +++ b/cpp/ql/src/experimental/Security/CWE/CWE-401/MemoryLeakOnFailedCallToRealloc.ql @@ -0,0 +1,61 @@ +/** + * @name Memory leak on failed call to realloc + * @description The expression mem = realloc (mem, size) is potentially dangerous, if the call fails, we will lose the pointer to the memory block. + * We recommend storing the result in a temporary variable and eliminating memory leak. + * @kind problem + * @id cpp/memory-leak-on-failed-call-to-realloc + * @problem.severity warning + * @precision medium + * @tags correctness + * security + * external/cwe/cwe-401 + */ + +import cpp +import semmle.code.cpp.controlflow.Guards +import semmle.code.cpp.valuenumbering.HashCons + +/** + * A function call that potentially does not return (such as `exit`). + */ +class CallMayNotReturn extends FunctionCall { + CallMayNotReturn() { + // call that is known to not return + not exists(this.(ControlFlowNode).getASuccessor()) + or + // call to another function that may not return + exists(CallMayNotReturn exit | getTarget() = exit.getEnclosingFunction()) + } +} + +/** + * A call to `realloc` of the form `v = realloc(v, size)`, for some variable `v`. + */ +class ReallocCallLeak extends FunctionCall { + Variable v; + + ReallocCallLeak() { + exists(AssignExpr ex | + this.getTarget().hasGlobalOrStdName("realloc") and + this = ex.getRValue() and + hashCons(ex.getLValue()) = hashCons(this.getArgument(0)) and + v.getAnAccess() = this.getArgument(0) + ) + } + + /** + * Holds if failure of this allocation may be handled by termination, for + * example a call to `exit()`. + */ + predicate mayHandleByTermination() { + exists(GuardCondition guard, CallMayNotReturn exit | + this.(ControlFlowNode).getASuccessor*() = guard and + guard.getAChild*() = v.getAnAccess() and + guard.controls(exit.getBasicBlock(), _) + ) + } +} + +from ReallocCallLeak rcl +where not rcl.mayHandleByTermination() +select rcl, "possible loss of original pointer on unsuccessful call realloc" diff --git a/cpp/ql/src/experimental/Security/CWE/CWE-570/WrongInDetectingAndHandlingMemoryAllocationErrors.cpp b/cpp/ql/src/experimental/Security/CWE/CWE-570/WrongInDetectingAndHandlingMemoryAllocationErrors.cpp new file mode 100644 index 00000000000..df69886e97b --- /dev/null +++ b/cpp/ql/src/experimental/Security/CWE/CWE-570/WrongInDetectingAndHandlingMemoryAllocationErrors.cpp @@ -0,0 +1,35 @@ +// BAD: on memory allocation error, the program terminates. +void badFunction(const int *source, std::size_t length) noexcept { + int * dest = new int[length]; + std::memset(dest, 0, length); +// .. +} +// GOOD: memory allocation error will be handled. +void goodFunction(const int *source, std::size_t length) noexcept { + try { + int * dest = new int[length]; + } catch(std::bad_alloc) { + // ... + } + std::memset(dest, 0, length); +// .. +} +// BAD: memory allocation error will not be handled. +void badFunction(const int *source, std::size_t length) noexcept { + try { + int * dest = new (std::nothrow) int[length]; + } catch(std::bad_alloc) { + // ... + } + std::memset(dest, 0, length); +// .. +} +// GOOD: memory allocation error will be handled. +void goodFunction(const int *source, std::size_t length) noexcept { + int * dest = new (std::nothrow) int[length]; + if (!dest) { + return; + } + std::memset(dest, 0, length); +// .. +} diff --git a/cpp/ql/src/experimental/Security/CWE/CWE-570/WrongInDetectingAndHandlingMemoryAllocationErrors.qhelp b/cpp/ql/src/experimental/Security/CWE/CWE-570/WrongInDetectingAndHandlingMemoryAllocationErrors.qhelp new file mode 100644 index 00000000000..9e6cb2d89ce --- /dev/null +++ b/cpp/ql/src/experimental/Security/CWE/CWE-570/WrongInDetectingAndHandlingMemoryAllocationErrors.qhelp @@ -0,0 +1,27 @@ + + + +

    When using the new operator to allocate memory, you need to pay attention to the different ways of detecting errors. ::operator new(std::size_t) throws an exception on error, whereas ::operator new(std::size_t, const std::nothrow_t &) returns zero on error. The programmer can get confused and check the error that occurs when allocating memory incorrectly. That can lead to an unhandled program termination or to a violation of the program logic.

    + +
    + + +

    Use the correct error detection method corresponding with the memory allocation.

    + +
    + +

    The following example demonstrates various approaches to detecting memory allocation errors using the new operator.

    + + +
    + + +
  • + CERT C++ Coding Standard: +MEM52-CPP. Detect and handle memory allocation errors. +
  • + +
    +
    diff --git a/cpp/ql/src/experimental/Security/CWE/CWE-570/WrongInDetectingAndHandlingMemoryAllocationErrors.ql b/cpp/ql/src/experimental/Security/CWE/CWE-570/WrongInDetectingAndHandlingMemoryAllocationErrors.ql new file mode 100644 index 00000000000..dd9c16fac11 --- /dev/null +++ b/cpp/ql/src/experimental/Security/CWE/CWE-570/WrongInDetectingAndHandlingMemoryAllocationErrors.ql @@ -0,0 +1,87 @@ +/** + * @name Detect And Handle Memory Allocation Errors + * @description --::operator new(std::size_t) throws an exception on error, and ::operator new(std::size_t, const std::nothrow_t &) returns zero on error. + * --the programmer can get confused when check the error that occurs when allocating memory incorrectly. + * @kind problem + * @id cpp/detect-and-handle-memory-allocation-errors + * @problem.severity warning + * @precision medium + * @tags correctness + * security + * external/cwe/cwe-570 + */ + +import cpp + +/** + * Lookup if condition compare with 0 + */ +class IfCompareWithZero extends IfStmt { + IfCompareWithZero() { + this.getCondition().(EQExpr).getAChild().getValue() = "0" + or + this.getCondition().(NEExpr).getAChild().getValue() = "0" and + this.hasElse() + or + this.getCondition().(NEExpr).getAChild().getValue() = "0" and + this.getThen().getAChild*() instanceof ReturnStmt + } +} + +/** + * lookup for calls to `operator new`, with incorrect error handling. + */ +class WrongCheckErrorOperatorNew extends FunctionCall { + Expr exp; + + WrongCheckErrorOperatorNew() { + this = exp.(NewOrNewArrayExpr).getAChild().(FunctionCall) and + ( + this.getTarget().hasGlobalOrStdName("operator new") + or + this.getTarget().hasGlobalOrStdName("operator new[]") + ) + } + + /** + * Holds if handler `try ... catch` exists. + */ + predicate isExistsTryCatchBlock() { + exists(TryStmt ts | this.getEnclosingStmt() = ts.getStmt().getAChild*()) + } + + /** + * Holds if results call `operator new` check in `operator if`. + */ + predicate isExistsIfCondition() { + exists(IfCompareWithZero ifc, AssignExpr aex, Initializer it | + // call `operator new` directly from the condition of `operator if`. + this = ifc.getCondition().getAChild*() + or + // check results call `operator new` with variable appropriation + postDominates(ifc, this) and + aex.getAChild() = exp and + ifc.getCondition().getAChild().(VariableAccess).getTarget() = + aex.getLValue().(VariableAccess).getTarget() + or + // check results call `operator new` with declaration variable + postDominates(ifc, this) and + exp = it.getExpr() and + it.getDeclaration() = ifc.getCondition().getAChild().(VariableAccess).getTarget() + ) + } + + /** + * Holds if `(std::nothrow)` exists in call `operator new`. + */ + predicate isExistsNothrow() { this.getAChild().toString() = "nothrow" } +} + +from WrongCheckErrorOperatorNew op +where + // use call `operator new` with `(std::nothrow)` and checking error using `try ... catch` block and not `operator if` + op.isExistsNothrow() and not op.isExistsIfCondition() and op.isExistsTryCatchBlock() + or + // use call `operator new` without `(std::nothrow)` and checking error using `operator if` and not `try ... catch` block + not op.isExistsNothrow() and not op.isExistsTryCatchBlock() and op.isExistsIfCondition() +select op, "memory allocation error check is incorrect or missing" diff --git a/cpp/ql/src/experimental/Security/CWE/CWE-788/AccessOfMemoryLocationAfterEndOfBufferUsingStrlen.c b/cpp/ql/src/experimental/Security/CWE/CWE-788/AccessOfMemoryLocationAfterEndOfBufferUsingStrlen.c new file mode 100644 index 00000000000..ba78d4b97d1 --- /dev/null +++ b/cpp/ql/src/experimental/Security/CWE/CWE-788/AccessOfMemoryLocationAfterEndOfBufferUsingStrlen.c @@ -0,0 +1,9 @@ +// BAD: if buffer does not have a terminal zero, then access outside the allocated memory is possible. + +buffer[strlen(buffer)] = 0; + + +// GOOD: we will eliminate dangerous behavior if we use a different method of calculating the length. +size_t len; +... +buffer[len] = 0 diff --git a/cpp/ql/src/experimental/Security/CWE/CWE-788/AccessOfMemoryLocationAfterEndOfBufferUsingStrlen.qhelp b/cpp/ql/src/experimental/Security/CWE/CWE-788/AccessOfMemoryLocationAfterEndOfBufferUsingStrlen.qhelp new file mode 100644 index 00000000000..51424ce7619 --- /dev/null +++ b/cpp/ql/src/experimental/Security/CWE/CWE-788/AccessOfMemoryLocationAfterEndOfBufferUsingStrlen.qhelp @@ -0,0 +1,31 @@ + + + +

    Potentially dangerous use of the strlen function to calculate the length of a string. +The expression buffer[strlen(buffer)] = 0 is potentially dangerous, if the variable buffer does not have a terminal zero, then access beyond the bounds of the allocated memory is possible, which will lead to undefined behavior. +If terminal zero is present, then the specified expression is meaningless.

    + +

    False positives include heavily nested strlen. This situation is unlikely.

    + +
    + + +

    We recommend using another method for calculating the string length

    + +
    + +

    The following example demonstrates an erroneous and corrected use of the strlen function.

    + + +
    + + +
  • + CERT C Coding Standard: + STR32-C. Do not pass a non-null-terminated character sequence to a library function that expects a string. +
  • + +
    +
    diff --git a/cpp/ql/src/experimental/Security/CWE/CWE-788/AccessOfMemoryLocationAfterEndOfBufferUsingStrlen.ql b/cpp/ql/src/experimental/Security/CWE/CWE-788/AccessOfMemoryLocationAfterEndOfBufferUsingStrlen.ql new file mode 100644 index 00000000000..012109074e9 --- /dev/null +++ b/cpp/ql/src/experimental/Security/CWE/CWE-788/AccessOfMemoryLocationAfterEndOfBufferUsingStrlen.ql @@ -0,0 +1,34 @@ +/** + * @name Access Of Memory Location After End Of Buffer + * @description The expression `buffer [strlen (buffer)] = 0` is potentially dangerous, if the variable `buffer` does not have a terminal zero, then access beyond the bounds of the allocated memory is possible, which will lead to undefined behavior. + * If terminal zero is present, then the specified expression is meaningless. + * @kind problem + * @id cpp/access-memory-location-after-end-buffer + * @problem.severity warning + * @precision medium + * @tags correctness + * security + * external/cwe/cwe-788 + */ + +import cpp +import semmle.code.cpp.valuenumbering.GlobalValueNumbering +import semmle.code.cpp.dataflow.DataFlow + +from StrlenCall fc, AssignExpr expr, ArrayExpr exprarr +where + exprarr = expr.getLValue() and + expr.getRValue().getValue().toInt() = 0 and + globalValueNumber(exprarr.getArrayOffset()) = globalValueNumber(fc) and + not exists(Expr exptmp | + ( + DataFlow::localExprFlow(fc, exptmp) or + exptmp.getAChild*() = fc.getArgument(0).(VariableAccess).getTarget().getAnAccess() + ) and + dominates(exptmp, expr) and + postDominates(exptmp, fc) and + not exptmp.getEnclosingStmt() = fc.getEnclosingStmt() and + not exptmp.getEnclosingStmt() = expr.getEnclosingStmt() + ) and + globalValueNumber(fc.getArgument(0)) = globalValueNumber(exprarr.getArrayBase()) +select expr, "potential unsafe or redundant assignment." diff --git a/cpp/ql/src/experimental/Security/CWE/CWE-788/AccessOfMemoryLocationAfterEndOfBufferUsingStrncat.c b/cpp/ql/src/experimental/Security/CWE/CWE-788/AccessOfMemoryLocationAfterEndOfBufferUsingStrncat.c new file mode 100644 index 00000000000..060a22b5c18 --- /dev/null +++ b/cpp/ql/src/experimental/Security/CWE/CWE-788/AccessOfMemoryLocationAfterEndOfBufferUsingStrncat.c @@ -0,0 +1,4 @@ + +strncat(dest, source, sizeof(dest) - strlen(dest)); // BAD: writes a zero byte past the `dest` buffer. + +strncat(dest, source, sizeof(dest) - strlen(dest) -1); // GOOD: Reserves space for the zero byte. diff --git a/cpp/ql/src/experimental/Security/CWE/CWE-788/AccessOfMemoryLocationAfterEndOfBufferUsingStrncat.qhelp b/cpp/ql/src/experimental/Security/CWE/CWE-788/AccessOfMemoryLocationAfterEndOfBufferUsingStrncat.qhelp new file mode 100644 index 00000000000..5c2154097ec --- /dev/null +++ b/cpp/ql/src/experimental/Security/CWE/CWE-788/AccessOfMemoryLocationAfterEndOfBufferUsingStrncat.qhelp @@ -0,0 +1,32 @@ + + + +

    The standard library function strncat(dest, source, count) appends the source string to the dest string. count specifies the maximum number of characters to append and must be less than the remaining space in the target buffer. Calls of the form strncat (dest, source, sizeof (dest) - strlen (dest)) set the third argument to one more than possible. So when the dest is full, the expression sizeof (dest) - strlen (dest) will be equal to one, and not zero as the programmer might think. Making a call of this type may result in a zero byte being written just outside the dest buffer.

    + + +
    + + +

    We recommend subtracting one from the third argument. For example, replace strncat(dest, source, sizeof(dest)-strlen(dest)) with strncat(dest, source, sizeof(dest)-strlen(dest)-1).

    + +
    + +

    The following example demonstrates an erroneous and corrected use of the strncat function.

    + + +
    + + +
  • + CERT C Coding Standard: +STR31-C. Guarantee that storage for strings has sufficient space for character data and the null terminator. +
  • +
  • + CERT C Coding Standard: + ARR30-C. Do not form or use out-of-bounds pointers or array subscripts. +
  • + +
    +
    diff --git a/cpp/ql/src/experimental/Security/CWE/CWE-788/AccessOfMemoryLocationAfterEndOfBufferUsingStrncat.ql b/cpp/ql/src/experimental/Security/CWE/CWE-788/AccessOfMemoryLocationAfterEndOfBufferUsingStrncat.ql new file mode 100644 index 00000000000..5311ffe2708 --- /dev/null +++ b/cpp/ql/src/experimental/Security/CWE/CWE-788/AccessOfMemoryLocationAfterEndOfBufferUsingStrncat.ql @@ -0,0 +1,64 @@ +/** + * @name Access Of Memory Location After The End Of A Buffer Using Strncat + * @description Calls of the form `strncat(dest, source, sizeof (dest) - strlen (dest))` set the third argument to one more than possible. So when `dest` is full, the expression `sizeof(dest) - strlen (dest)` will be equal to one, and not zero as the programmer might think. Making a call of this type may result in a zero byte being written just outside the `dest` buffer. + * @kind problem + * @id cpp/access-memory-location-after-end-buffer + * @problem.severity warning + * @precision medium + * @tags correctness + * security + * external/cwe/cwe-788 + */ + +import cpp +import semmle.code.cpp.valuenumbering.GlobalValueNumbering + +/** + * A call to `strncat` of the form `strncat(buff, str, someExpr - strlen(buf))`, for some expression `someExpr` equal to `sizeof(buff)`. + */ +class WrongCallStrncat extends FunctionCall { + Expr leftsomeExpr; + + WrongCallStrncat() { + this.getTarget().hasGlobalOrStdName("strncat") and + // the expression of the first argument in `strncat` and `strnlen` is identical + globalValueNumber(this.getArgument(0)) = + globalValueNumber(this.getArgument(2).(SubExpr).getRightOperand().(StrlenCall).getStringExpr()) and + // using a string constant often speaks of manually calculating the length of the required buffer. + ( + not this.getArgument(1) instanceof StringLiteral and + not this.getArgument(1) instanceof CharLiteral + ) and + // for use in predicates + leftsomeExpr = this.getArgument(2).(SubExpr).getLeftOperand() + } + + /** + * Holds if the left side of the expression `someExpr` equal to `sizeof(buf)`. + */ + predicate isExpressionEqualSizeof() { + // the left side of the expression `someExpr` is `sizeof(buf)`. + globalValueNumber(this.getArgument(0)) = + globalValueNumber(leftsomeExpr.(SizeofExprOperator).getExprOperand()) + or + // value of the left side of the expression `someExpr` equal `sizeof(buf)` value, and `buf` is array. + leftsomeExpr.getValue().toInt() = this.getArgument(0).getType().getSize() + } + + /** + * Holds if the left side of the expression `someExpr` equal to variable containing the length of the memory allocated for the buffer. + */ + predicate isVariableEqualValueSizegBuffer() { + // the left side of expression `someExpr` is the variable that was used in the function of allocating memory for the buffer`. + exists(AllocationExpr alc | + leftsomeExpr.(VariableAccess).getTarget() = + alc.(FunctionCall).getArgument(0).(VariableAccess).getTarget() + ) + } +} + +from WrongCallStrncat sc +where + sc.isExpressionEqualSizeof() or + sc.isVariableEqualValueSizegBuffer() +select sc, "if the used buffer is full, writing out of the buffer is possible" diff --git a/cpp/ql/src/semmle/code/cpp/Comments.qll b/cpp/ql/src/semmle/code/cpp/Comments.qll index 65e2af5fd22..7574f0ff32c 100644 --- a/cpp/ql/src/semmle/code/cpp/Comments.qll +++ b/cpp/ql/src/semmle/code/cpp/Comments.qll @@ -50,5 +50,5 @@ class CStyleComment extends Comment { * ``` */ class CppStyleComment extends Comment { - CppStyleComment() { this.getContents().prefix(2) = "//" } + CppStyleComment() { this.getContents().matches("//%") } } diff --git a/cpp/ql/src/semmle/code/cpp/Declaration.qll b/cpp/ql/src/semmle/code/cpp/Declaration.qll index 35ae092780d..7ac79fd99c1 100644 --- a/cpp/ql/src/semmle/code/cpp/Declaration.qll +++ b/cpp/ql/src/semmle/code/cpp/Declaration.qll @@ -139,6 +139,19 @@ class Declaration extends Locatable, @declaration { this.hasQualifiedName("std", "", name) } + /** + * Holds if this declaration has the given name in the global namespace, + * the `std` namespace or the `bsl` namespace. + * We treat `std` and `bsl` as the same in some of our models. + */ + predicate hasGlobalOrStdOrBslName(string name) { + this.hasGlobalName(name) + or + this.hasQualifiedName("std", "", name) + or + this.hasQualifiedName("bsl", "", name) + } + /** Gets a specifier of this declaration. */ Specifier getASpecifier() { none() } // overridden in subclasses diff --git a/cpp/ql/src/semmle/code/cpp/Element.qll b/cpp/ql/src/semmle/code/cpp/Element.qll index f4c1bd972c6..66f23ea110f 100644 --- a/cpp/ql/src/semmle/code/cpp/Element.qll +++ b/cpp/ql/src/semmle/code/cpp/Element.qll @@ -270,7 +270,12 @@ private predicate isFromUninstantiatedTemplateRec(Element e, Element template) { } /** - * A C++11 `static_assert` or C11 `_Static_assert` construct. + * A C++11 `static_assert` or C11 `_Static_assert` construct. For example each + * line in the following example contains a static assert: + * ``` + * static_assert(sizeof(MyStruct) <= 4096); + * static_assert(sizeof(MyStruct) <= 4096, "MyStruct is too big!"); + * ``` */ class StaticAssert extends Locatable, @static_assert { override string toString() { result = "static_assert(..., \"" + getMessage() + "\")" } diff --git a/cpp/ql/src/semmle/code/cpp/File.qll b/cpp/ql/src/semmle/code/cpp/File.qll index 1887f43b70c..c7486f4d75d 100644 --- a/cpp/ql/src/semmle/code/cpp/File.qll +++ b/cpp/ql/src/semmle/code/cpp/File.qll @@ -363,20 +363,8 @@ class File extends Container, @file { */ class HeaderFile extends File { HeaderFile() { - exists(string ext | ext = this.getExtension().toLowerCase() | - ext = "h" or - ext = "r" or - /* --- */ ext = "hpp" or - ext = "hxx" or - ext = "h++" or - ext = "hh" or - ext = "hp" or - ext = "tcc" or - ext = "tpp" or - ext = "txx" or - ext = "t++" - /* --- --- */ - ) + this.getExtension().toLowerCase() = + ["h", "r", "hpp", "hxx", "h++", "hh", "hp", "tcc", "tpp", "txx", "t++"] or not exists(this.getExtension()) and exists(Include i | i.getIncludedFile() = this) @@ -406,7 +394,7 @@ class HeaderFile extends File { * `File.compiledAsC`. */ class CFile extends File { - CFile() { exists(string ext | ext = this.getExtension().toLowerCase() | ext = "c" or ext = "i") } + CFile() { this.getExtension().toLowerCase() = ["c", "i"] } override string getAPrimaryQlClass() { result = "CFile" } } @@ -419,21 +407,10 @@ class CFile extends File { */ class CppFile extends File { CppFile() { - exists(string ext | ext = this.getExtension().toLowerCase() | - /* --- */ ext = "cpp" or - ext = "cxx" or - ext = "c++" or - ext = "cc" or - ext = "cp" or - ext = "icc" or - ext = "ipp" or - ext = "ixx" or - ext = "i++" or - ext = "ii" - /* --- */ - // Note: .C files are indistinguishable from .c files on some - // file systems, so we just treat them as CFile's. - ) + this.getExtension().toLowerCase() = + ["cpp", "cxx", "c++", "cc", "cp", "icc", "ipp", "ixx", "i++", "ii"] + // Note: .C files are indistinguishable from .c files on some + // file systems, so we just treat them as CFile's. } override string getAPrimaryQlClass() { result = "CppFile" } diff --git a/cpp/ql/src/semmle/code/cpp/Function.qll b/cpp/ql/src/semmle/code/cpp/Function.qll index 2c45fa184cf..ac345e8a29a 100644 --- a/cpp/ql/src/semmle/code/cpp/Function.qll +++ b/cpp/ql/src/semmle/code/cpp/Function.qll @@ -334,6 +334,18 @@ class Function extends Declaration, ControlFlowNode, AccessHolder, @function { ) } + /** + * Gets the class of which this function, called `memberName`, is a member. + * + * Prefer to use `getDeclaringType()` or `getName()` directly if you do not + * need to reason about both. + */ + pragma[nomagic] + Class getClassAndName(string memberName) { + this.hasName(memberName) and + this.getDeclaringType() = result + } + /** * Implements `ControlFlowNode.getControlFlowScope`. The `Function` is * used to represent the exit node of the control flow graph, so it is @@ -391,20 +403,30 @@ class Function extends Declaration, ControlFlowNode, AccessHolder, @function { /** Holds if this function has a `noexcept` exception specification. */ predicate isNoExcept() { getADeclarationEntry().isNoExcept() } - /** Gets a function that overloads this one. */ + /** + * Gets a function that overloads this one. + * + * Note: if _overrides_ are wanted rather than _overloads_ then + * `MemberFunction::getAnOverridingFunction` should be used instead. + */ Function getAnOverload() { - result.getName() = getName() and - result.getNamespace() = getNamespace() and - result != this and - // If this function is declared in a class, only consider other - // functions from the same class. Conversely, if this function is not - // declared in a class, only consider other functions not declared in a - // class. ( - if exists(getDeclaringType()) - then result.getDeclaringType() = getDeclaringType() - else not exists(result.getDeclaringType()) + // If this function is declared in a class, only consider other + // functions from the same class. + exists(string name, Class declaringType | + candGetAnOverloadMember(name, declaringType, this) and + candGetAnOverloadMember(name, declaringType, result) + ) + or + // Conversely, if this function is not + // declared in a class, only consider other functions not declared in a + // class. + exists(string name, Namespace namespace | + candGetAnOverloadNonMember(name, namespace, this) and + candGetAnOverloadNonMember(name, namespace, result) + ) ) and + result != this and // Instantiations and specializations don't participate in overload // resolution. not ( @@ -445,50 +467,15 @@ class Function extends Declaration, ControlFlowNode, AccessHolder, @function { // ... and likewise for destructors. this.(Destructor).getADestruction().mayBeGloballyImpure() else - not exists(string name | this.hasGlobalOrStdName(name) | - // Unless it's a function that we know is side-effect-free, it may - // have side-effects. - name = "strcmp" or - name = "wcscmp" or - name = "_mbscmp" or - name = "strlen" or - name = "wcslen" or - name = "_mbslen" or - name = "_mbslen_l" or - name = "_mbstrlen" or - name = "_mbstrlen_l" or - name = "strnlen" or - name = "strnlen_s" or - name = "wcsnlen" or - name = "wcsnlen_s" or - name = "_mbsnlen" or - name = "_mbsnlen_l" or - name = "_mbstrnlen" or - name = "_mbstrnlen_l" or - name = "strncmp" or - name = "wcsncmp" or - name = "_mbsncmp" or - name = "_mbsncmp_l" or - name = "strchr" or - name = "memchr" or - name = "wmemchr" or - name = "memcmp" or - name = "wmemcmp" or - name = "_memicmp" or - name = "_memicmp_l" or - name = "feof" or - name = "isdigit" or - name = "isxdigit" or - name = "abs" or - name = "fabs" or - name = "labs" or - name = "floor" or - name = "ceil" or - name = "atoi" or - name = "atol" or - name = "atoll" or - name = "atof" - ) + // Unless it's a function that we know is side-effect-free, it may + // have side-effects. + not this.hasGlobalOrStdName([ + "strcmp", "wcscmp", "_mbscmp", "strlen", "wcslen", "_mbslen", "_mbslen_l", "_mbstrlen", + "_mbstrlen_l", "strnlen", "strnlen_s", "wcsnlen", "wcsnlen_s", "_mbsnlen", "_mbsnlen_l", + "_mbstrnlen", "_mbstrnlen_l", "strncmp", "wcsncmp", "_mbsncmp", "_mbsncmp_l", "strchr", + "memchr", "wmemchr", "memcmp", "wmemcmp", "_memicmp", "_memicmp_l", "feof", "isdigit", + "isxdigit", "abs", "fabs", "labs", "floor", "ceil", "atoi", "atol", "atoll", "atof" + ]) } /** @@ -497,6 +484,19 @@ class Function extends Declaration, ControlFlowNode, AccessHolder, @function { override AccessHolder getEnclosingAccessHolder() { result = this.getDeclaringType() } } +pragma[noinline] +private predicate candGetAnOverloadMember(string name, Class declaringType, Function f) { + f.getName() = name and + f.getDeclaringType() = declaringType +} + +pragma[noinline] +private predicate candGetAnOverloadNonMember(string name, Namespace namespace, Function f) { + f.getName() = name and + f.getNamespace() = namespace and + not exists(f.getDeclaringType()) +} + /** * A particular declaration or definition of a C/C++ function. For example the * declaration and definition of `MyFunction` in the following code are each a @@ -680,7 +680,7 @@ class FunctionDeclarationEntry extends DeclarationEntry, @fun_decl { /** * A C/C++ non-member function (a function that is not a member of any - * class). For example the in the following code, `MyFunction` is a + * class). For example, in the following code, `MyFunction` is a * `TopLevelFunction` but `MyMemberFunction` is not: * ``` * void MyFunction() { diff --git a/cpp/ql/src/semmle/code/cpp/Namespace.qll b/cpp/ql/src/semmle/code/cpp/Namespace.qll index 6172c3af50c..d46abc6b4db 100644 --- a/cpp/ql/src/semmle/code/cpp/Namespace.qll +++ b/cpp/ql/src/semmle/code/cpp/Namespace.qll @@ -7,8 +7,21 @@ import semmle.code.cpp.Type import semmle.code.cpp.metrics.MetricNamespace /** - * A C++ namespace. + * A C++ namespace. For example the (single) namespace `A` in the following + * code: + * ``` + * namespace A + * { + * // ... + * } * + * // ... + * + * namespace A + * { + * // ... + * } + * ``` * Note that namespaces are somewhat nebulous entities, as they do not in * general have a single well-defined location in the source code. The * related notion of a `NamespaceDeclarationEntry` is rather more concrete, @@ -96,10 +109,22 @@ class Namespace extends NameQualifyingElement, @namespace { } /** - * A declaration of (part of) a C++ namespace. + * A declaration of (part of) a C++ namespace. This corresponds to a single + * `namespace N { ... }` occurrence in the source code. For example the two + * mentions of `A` in the following code: + * ``` + * namespace A + * { + * // ... + * } * - * This corresponds to a single `namespace N { ... }` occurrence in the - * source code. + * // ... + * + * namespace A + * { + * // ... + * } + * ``` */ class NamespaceDeclarationEntry extends Locatable, @namespace_decl { /** @@ -143,8 +168,9 @@ class UsingEntry extends Locatable, @using { /** * A C++ `using` declaration. For example: - * - * `using std::string;` + * ``` + * using std::string; + * ``` */ class UsingDeclarationEntry extends UsingEntry { UsingDeclarationEntry() { @@ -162,8 +188,9 @@ class UsingDeclarationEntry extends UsingEntry { /** * A C++ `using` directive. For example: - * - * `using namespace std;` + * ``` + * using namespace std; + * ``` */ class UsingDirectiveEntry extends UsingEntry { UsingDirectiveEntry() { diff --git a/cpp/ql/src/semmle/code/cpp/Preprocessor.qll b/cpp/ql/src/semmle/code/cpp/Preprocessor.qll index a9609922b74..2389db07f2a 100644 --- a/cpp/ql/src/semmle/code/cpp/Preprocessor.qll +++ b/cpp/ql/src/semmle/code/cpp/Preprocessor.qll @@ -2,9 +2,14 @@ import semmle.code.cpp.Location import semmle.code.cpp.Element /** - * A C/C++ preprocessor directive. - * - * For example: `#ifdef`, `#line`, or `#pragma`. + * A C/C++ preprocessor directive. For example each of the following lines of + * code contains a `PreprocessorDirective`: + * ``` + * #pragma once + * #ifdef MYDEFINE + * #include "myfile.h" + * #line 1 "source.c" + * ``` */ class PreprocessorDirective extends Locatable, @preprocdirect { override string toString() { result = "Preprocessor directive" } @@ -98,9 +103,9 @@ class PreprocessorBranchDirective extends PreprocessorDirective, TPreprocessorBr * A C/C++ preprocessor branching directive: `#if`, `#ifdef`, `#ifndef`, or * `#elif`. * - * A branching directive can have its condition evaluated at compile-time, - * and as a result, the preprocessor will either take the branch, or not - * take the branch. + * A branching directive has a condition and that condition may be evaluated + * at compile-time. As a result, the preprocessor will either take the + * branch, or not take the branch. * * However, there are also situations in which a branch's condition isn't * evaluated. The obvious case of this is when the directive is contained @@ -136,8 +141,13 @@ class PreprocessorBranch extends PreprocessorBranchDirective, @ppd_branch { } /** - * A C/C++ preprocessor `#if` directive. - * + * A C/C++ preprocessor `#if` directive. For example there is a + * `PreprocessorIf` on the first line of the following code: + * ``` + * #if defined(MYDEFINE) + * // ... + * #endif + * ``` * For the related notion of a directive which causes branching (which * includes `#if`, plus also `#ifdef`, `#ifndef`, and `#elif`), see * `PreprocessorBranch`. @@ -147,8 +157,13 @@ class PreprocessorIf extends PreprocessorBranch, @ppd_if { } /** - * A C/C++ preprocessor `#ifdef` directive. - * + * A C/C++ preprocessor `#ifdef` directive. For example there is a + * `PreprocessorIfdef` on the first line of the following code: + * ``` + * #ifdef MYDEFINE + * // ... + * #endif + * ``` * The syntax `#ifdef X` is shorthand for `#if defined(X)`. */ class PreprocessorIfdef extends PreprocessorBranch, @ppd_ifdef { @@ -158,8 +173,13 @@ class PreprocessorIfdef extends PreprocessorBranch, @ppd_ifdef { } /** - * A C/C++ preprocessor `#ifndef` directive. - * + * A C/C++ preprocessor `#ifndef` directive. For example there is a + * `PreprocessorIfndef` on the first line of the following code: + * ``` + * #ifndef MYDEFINE + * // ... + * #endif + * ``` * The syntax `#ifndef X` is shorthand for `#if !defined(X)`. */ class PreprocessorIfndef extends PreprocessorBranch, @ppd_ifndef { @@ -167,42 +187,80 @@ class PreprocessorIfndef extends PreprocessorBranch, @ppd_ifndef { } /** - * A C/C++ preprocessor `#else` directive. + * A C/C++ preprocessor `#else` directive. For example there is a + * `PreprocessorElse` on the fifth line of the following code: + * ``` + * #ifdef MYDEFINE1 + * // ... + * #elif MYDEFINE2 + * // ... + * #else + * // ... + * #endif + * ``` */ class PreprocessorElse extends PreprocessorBranchDirective, @ppd_else { override string toString() { result = "#else" } } /** - * A C/C++ preprocessor `#elif` directive. + * A C/C++ preprocessor `#elif` directive. For example there is a + * `PreprocessorElif` on the third line of the following code: + * ``` + * #ifdef MYDEFINE1 + * // ... + * #elif MYDEFINE2 + * // ... + * #else + * // ... + * #endif + * ``` */ class PreprocessorElif extends PreprocessorBranch, @ppd_elif { override string toString() { result = "#elif " + this.getHead() } } /** - * A C/C++ preprocessor `#endif` directive. + * A C/C++ preprocessor `#endif` directive. For example there is a + * `PreprocessorEndif` on the third line of the following code: + * ``` + * #ifdef MYDEFINE + * // ... + * #endif + * ``` */ class PreprocessorEndif extends PreprocessorBranchDirective, @ppd_endif { override string toString() { result = "#endif" } } /** - * A C/C++ preprocessor `#warning` directive. + * A C/C++ preprocessor `#warning` directive. For example: + * ``` + * #warning "This configuration is not supported." + * ``` */ class PreprocessorWarning extends PreprocessorDirective, @ppd_warning { override string toString() { result = "#warning " + this.getHead() } } /** - * A C/C++ preprocessor `#error` directive. + * A C/C++ preprocessor `#error` directive. For example: + * ``` + * #error "This configuration is not implemented." + * ``` */ class PreprocessorError extends PreprocessorDirective, @ppd_error { override string toString() { result = "#error " + this.getHead() } } /** - * A C/C++ preprocessor `#undef` directive. + * A C/C++ preprocessor `#undef` directive. For example there is a + * `PreprocessorUndef` on the second line of the following code: + * ``` + * #ifdef MYMACRO + * #undef MYMACRO + * #endif + * ``` */ class PreprocessorUndef extends PreprocessorDirective, @ppd_undef { override string toString() { result = "#undef " + this.getHead() } @@ -214,7 +272,10 @@ class PreprocessorUndef extends PreprocessorDirective, @ppd_undef { } /** - * A C/C++ preprocessor `#pragma` directive. + * A C/C++ preprocessor `#pragma` directive. For example: + * ``` + * #pragma once + * ``` */ class PreprocessorPragma extends PreprocessorDirective, @ppd_pragma { override string toString() { @@ -223,7 +284,10 @@ class PreprocessorPragma extends PreprocessorDirective, @ppd_pragma { } /** - * A C/C++ preprocessor `#line` directive. + * A C/C++ preprocessor `#line` directive. For example: + * ``` + * #line 1 "source.c" + * ``` */ class PreprocessorLine extends PreprocessorDirective, @ppd_line { override string toString() { result = "#line " + this.getHead() } diff --git a/cpp/ql/src/semmle/code/cpp/Print.qll b/cpp/ql/src/semmle/code/cpp/Print.qll index 4c9cc4edf27..f8d30f55a88 100644 --- a/cpp/ql/src/semmle/code/cpp/Print.qll +++ b/cpp/ql/src/semmle/code/cpp/Print.qll @@ -385,7 +385,7 @@ private class DumpFunction extends DumpDeclaration, Function { private string getACVQualifier() { result = getASpecifier().getName() and - (result = "const" or result = "volatile") + result = ["const", "volatile"] } private string getDeclaratorSuffix() { diff --git a/cpp/ql/src/semmle/code/cpp/Specifier.qll b/cpp/ql/src/semmle/code/cpp/Specifier.qll index 3d68fb374f1..1c1eb0c090a 100644 --- a/cpp/ql/src/semmle/code/cpp/Specifier.qll +++ b/cpp/ql/src/semmle/code/cpp/Specifier.qll @@ -171,8 +171,11 @@ class StdAttribute extends Attribute, @stdattribute { } /** - * An attribute introduced by Microsoft's `__declspec(name)` syntax, for - * example: `__declspec(dllimport)`. + * An attribute introduced by Microsoft's `__declspec(name)` syntax. For + * example the attribute on the following declaration: + * ``` + * __declspec(dllimport) void myFunction(); + * ``` */ class Declspec extends Attribute, @declspec { } @@ -186,8 +189,13 @@ class MicrosoftAttribute extends Attribute, @msattribute { } /** - * A C++11 `alignas` construct. - * + * A C++11 `alignas` construct. For example the attribute in the following + * code: + * ``` + * struct alignas(16) MyStruct { + * int x; + * }; + * ``` * Though it doesn't use the attribute syntax, `alignas(...)` is presented * as an `Attribute` for consistency with the `[[align(...)]]` attribute. */ @@ -197,7 +205,11 @@ class AlignAs extends Attribute, @alignas { /** * A GNU `format` attribute of the form `__attribute__((format(archetype, format-index, first-arg)))` - * that declares a function to accept a `printf` style format string. + * that declares a function to accept a `printf` style format string. For example the attribute + * on the following declaration: + * ``` + * int myPrintf(const char *format, ...) __attribute__((format(printf, 1, 2))); + * ``` */ class FormatAttribute extends GnuAttribute { FormatAttribute() { getName() = "format" } @@ -242,7 +254,11 @@ class FormatAttribute extends GnuAttribute { } /** - * An argument to an `Attribute`. + * An argument to an `Attribute`. For example the argument "dllimport" on the + * attribute in the following code: + * ``` + * __declspec(dllimport) void myFunction(); + * ``` */ class AttributeArgument extends Element, @attribute_arg { /** diff --git a/cpp/ql/src/semmle/code/cpp/Type.qll b/cpp/ql/src/semmle/code/cpp/Type.qll index 81b28cca4c9..a0d8c42df32 100644 --- a/cpp/ql/src/semmle/code/cpp/Type.qll +++ b/cpp/ql/src/semmle/code/cpp/Type.qll @@ -274,7 +274,7 @@ class Type extends Locatable, @type { /** * Gets this type with any typedefs resolved. For example, given - * `typedef C T`, this would resolve `const T&` to `const C&`. + * `typedef C T`, this would resolve `const T&` to `const C&`. * Note that this will only work if the resolved type actually appears * on its own elsewhere in the program. */ @@ -1544,9 +1544,9 @@ class FunctionPointerIshType extends DerivedType { /** * A C++ pointer to data member. See 15.5. * ``` - * class C { int m; }; + * class C { public: int m; }; * int C::* p = &C::m; // pointer to data member m of class C - * class C *; + * class C c; * int val = c.*p; // access data member * ``` */ diff --git a/cpp/ql/src/semmle/code/cpp/commons/DateTime.qll b/cpp/ql/src/semmle/code/cpp/commons/DateTime.qll index abbb1193021..c67bf7cf96e 100644 --- a/cpp/ql/src/semmle/code/cpp/commons/DateTime.qll +++ b/cpp/ql/src/semmle/code/cpp/commons/DateTime.qll @@ -14,11 +14,7 @@ class PackedTimeType extends Type { } } -private predicate timeType(string typeName) { - typeName = "_SYSTEMTIME" or - typeName = "SYSTEMTIME" or - typeName = "tm" -} +private predicate timeType(string typeName) { typeName = ["_SYSTEMTIME", "SYSTEMTIME", "tm"] } /** * A type that is used to represent times and dates in an 'unpacked' form, that is, diff --git a/cpp/ql/src/semmle/code/cpp/commons/Printf.qll b/cpp/ql/src/semmle/code/cpp/commons/Printf.qll index 4785c2b4aa4..8d9ad5c77e4 100644 --- a/cpp/ql/src/semmle/code/cpp/commons/Printf.qll +++ b/cpp/ql/src/semmle/code/cpp/commons/Printf.qll @@ -50,7 +50,15 @@ predicate primitiveVariadicFormatter( then formatParamIndex = f.getNumberOfParameters() - 3 else formatParamIndex = f.getNumberOfParameters() - 2 ) and - if type = "" then outputParamIndex = -1 else outputParamIndex = 0 // Conveniently, these buffer parameters are all at index 0. + ( + if type = "" then outputParamIndex = -1 else outputParamIndex = 0 // Conveniently, these buffer parameters are all at index 0. + ) and + not ( + // exclude functions with an implementation in the snapshot source + // directory, as they may not be standard implementations. + exists(f.getBlock()) and + exists(f.getFile().getRelativePath()) + ) } private predicate callsVariadicFormatter( @@ -900,6 +908,7 @@ class FormatLiteral extends Literal { */ int getNumArgNeeded(int n) { exists(this.getConvSpecOffset(n)) and + exists(this.getConversionChar(n)) and result = count(int mode | hasFormatArgumentIndexFor(n, mode)) } diff --git a/cpp/ql/src/semmle/code/cpp/commons/Scanf.qll b/cpp/ql/src/semmle/code/cpp/commons/Scanf.qll index 53fee14cd2a..461030f389d 100644 --- a/cpp/ql/src/semmle/code/cpp/commons/Scanf.qll +++ b/cpp/ql/src/semmle/code/cpp/commons/Scanf.qll @@ -34,10 +34,10 @@ class Scanf extends ScanfFunction { Scanf() { this instanceof TopLevelFunction and ( - hasName("scanf") or // scanf(format, args...) - hasName("wscanf") or // wscanf(format, args...) - hasName("_scanf_l") or // _scanf_l(format, locale, args...) - hasName("_wscanf_l") // _wscanf_l(format, locale, args...) + hasGlobalOrStdOrBslName("scanf") or // scanf(format, args...) + hasGlobalOrStdOrBslName("wscanf") or // wscanf(format, args...) + hasGlobalName("_scanf_l") or // _scanf_l(format, locale, args...) + hasGlobalName("_wscanf_l") // _wscanf_l(format, locale, args...) ) } @@ -53,10 +53,10 @@ class Fscanf extends ScanfFunction { Fscanf() { this instanceof TopLevelFunction and ( - hasName("fscanf") or // fscanf(src_stream, format, args...) - hasName("fwscanf") or // fwscanf(src_stream, format, args...) - hasName("_fscanf_l") or // _fscanf_l(src_stream, format, locale, args...) - hasName("_fwscanf_l") // _fwscanf_l(src_stream, format, locale, args...) + hasGlobalOrStdOrBslName("fscanf") or // fscanf(src_stream, format, args...) + hasGlobalOrStdOrBslName("fwscanf") or // fwscanf(src_stream, format, args...) + hasGlobalName("_fscanf_l") or // _fscanf_l(src_stream, format, locale, args...) + hasGlobalName("_fwscanf_l") // _fwscanf_l(src_stream, format, locale, args...) ) } @@ -72,10 +72,10 @@ class Sscanf extends ScanfFunction { Sscanf() { this instanceof TopLevelFunction and ( - hasName("sscanf") or // sscanf(src_stream, format, args...) - hasName("swscanf") or // swscanf(src, format, args...) - hasName("_sscanf_l") or // _sscanf_l(src, format, locale, args...) - hasName("_swscanf_l") // _swscanf_l(src, format, locale, args...) + hasGlobalOrStdOrBslName("sscanf") or // sscanf(src_stream, format, args...) + hasGlobalOrStdOrBslName("swscanf") or // swscanf(src, format, args...) + hasGlobalName("_sscanf_l") or // _sscanf_l(src, format, locale, args...) + hasGlobalName("_swscanf_l") // _swscanf_l(src, format, locale, args...) ) } @@ -91,8 +91,10 @@ class Snscanf extends ScanfFunction { Snscanf() { this instanceof TopLevelFunction and ( - hasName("_snscanf") or // _snscanf(src, max_amount, format, args...) - hasName("_snwscanf") // _snwscanf(src, max_amount, format, args...) + hasGlobalName("_snscanf") or // _snscanf(src, max_amount, format, args...) + hasGlobalName("_snwscanf") or // _snwscanf(src, max_amount, format, args...) + hasGlobalName("_snscanf_l") or // _snscanf_l(src, max_amount, format, locale, args...) + hasGlobalName("_snwscanf_l") // _snwscanf_l(src, max_amount, format, locale, args...) // note that the max_amount is not a limit on the output length, it's an input length // limit used with non null-terminated strings. ) @@ -101,6 +103,12 @@ class Snscanf extends ScanfFunction { override int getInputParameterIndex() { result = 0 } override int getFormatParameterIndex() { result = 2 } + + /** + * Gets the position at which the maximum number of characters in the + * input string is specified. + */ + int getInputLengthParameterIndex() { result = 1 } } /** diff --git a/cpp/ql/src/semmle/code/cpp/commons/Synchronization.qll b/cpp/ql/src/semmle/code/cpp/commons/Synchronization.qll index c7641385393..92955ae3580 100644 --- a/cpp/ql/src/semmle/code/cpp/commons/Synchronization.qll +++ b/cpp/ql/src/semmle/code/cpp/commons/Synchronization.qll @@ -87,7 +87,7 @@ abstract class MutexType extends Type { private Function mustlockCandidate() { exists(string name | name = result.getName() | name = "lock" or - name.suffix(name.length() - 10) = "mutex_lock" + name.matches("%mutex\\_lock") ) } @@ -97,7 +97,7 @@ private Function mustlockCandidate() { private Function trylockCandidate() { exists(string name | name = result.getName() | name = "try_lock" or - name.suffix(name.length() - 13) = "mutex_trylock" + name.matches("%mutex\\_trylock") ) } @@ -107,7 +107,7 @@ private Function trylockCandidate() { private Function unlockCandidate() { exists(string name | name = result.getName() | name = "unlock" or - name.suffix(name.length() - 12) = "mutex_unlock" + name.matches("%mutex\\_unlock") ) } diff --git a/cpp/ql/src/semmle/code/cpp/controlflow/Dataflow.qll b/cpp/ql/src/semmle/code/cpp/controlflow/Dataflow.qll index 1a5d81ee9f3..32eb4ecc2e0 100644 --- a/cpp/ql/src/semmle/code/cpp/controlflow/Dataflow.qll +++ b/cpp/ql/src/semmle/code/cpp/controlflow/Dataflow.qll @@ -13,7 +13,7 @@ import Dereferenced * predicates that implement this analysis. */ abstract class DataflowAnnotation extends string { - DataflowAnnotation() { this = "pointer-null" or this = "pointer-valid" } + DataflowAnnotation() { this = ["pointer-null", "pointer-valid"] } /** Holds if this annotation is the default annotation. */ abstract predicate isDefault(); @@ -98,7 +98,7 @@ abstract class DataflowAnnotation extends string { * respectively. */ class NullnessAnnotation extends DataflowAnnotation { - NullnessAnnotation() { this = "pointer-null" or this = "pointer-valid" } + NullnessAnnotation() { this = ["pointer-null", "pointer-valid"] } override predicate isDefault() { this = "pointer-valid" } diff --git a/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl.qll b/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl.qll index d9f5acdd279..59cc8d529a7 100644 --- a/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl.qll +++ b/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl.qll @@ -3598,6 +3598,7 @@ private module FlowExploration { or exists(PartialPathNodeRev mid | revPartialPathStep(mid, node, sc1, sc2, ap, config) and + not clearsContent(node, ap.getHead()) and not fullBarrier(node, config) and distSink(node.getEnclosingCallable(), config) <= config.explorationLimit() ) @@ -3611,6 +3612,7 @@ private module FlowExploration { exists(PartialPathNodeFwd mid | partialPathStep(mid, node, cc, sc1, sc2, ap, config) and not fullBarrier(node, config) and + not clearsContent(node, ap.getHead().getContent()) and if node instanceof CastingNode then compatibleTypes(getNodeType(node), ap.getType()) else any() diff --git a/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl2.qll b/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl2.qll index d9f5acdd279..59cc8d529a7 100644 --- a/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl2.qll +++ b/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl2.qll @@ -3598,6 +3598,7 @@ private module FlowExploration { or exists(PartialPathNodeRev mid | revPartialPathStep(mid, node, sc1, sc2, ap, config) and + not clearsContent(node, ap.getHead()) and not fullBarrier(node, config) and distSink(node.getEnclosingCallable(), config) <= config.explorationLimit() ) @@ -3611,6 +3612,7 @@ private module FlowExploration { exists(PartialPathNodeFwd mid | partialPathStep(mid, node, cc, sc1, sc2, ap, config) and not fullBarrier(node, config) and + not clearsContent(node, ap.getHead().getContent()) and if node instanceof CastingNode then compatibleTypes(getNodeType(node), ap.getType()) else any() diff --git a/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl3.qll b/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl3.qll index d9f5acdd279..59cc8d529a7 100644 --- a/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl3.qll +++ b/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl3.qll @@ -3598,6 +3598,7 @@ private module FlowExploration { or exists(PartialPathNodeRev mid | revPartialPathStep(mid, node, sc1, sc2, ap, config) and + not clearsContent(node, ap.getHead()) and not fullBarrier(node, config) and distSink(node.getEnclosingCallable(), config) <= config.explorationLimit() ) @@ -3611,6 +3612,7 @@ private module FlowExploration { exists(PartialPathNodeFwd mid | partialPathStep(mid, node, cc, sc1, sc2, ap, config) and not fullBarrier(node, config) and + not clearsContent(node, ap.getHead().getContent()) and if node instanceof CastingNode then compatibleTypes(getNodeType(node), ap.getType()) else any() diff --git a/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl4.qll b/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl4.qll index d9f5acdd279..59cc8d529a7 100644 --- a/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl4.qll +++ b/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl4.qll @@ -3598,6 +3598,7 @@ private module FlowExploration { or exists(PartialPathNodeRev mid | revPartialPathStep(mid, node, sc1, sc2, ap, config) and + not clearsContent(node, ap.getHead()) and not fullBarrier(node, config) and distSink(node.getEnclosingCallable(), config) <= config.explorationLimit() ) @@ -3611,6 +3612,7 @@ private module FlowExploration { exists(PartialPathNodeFwd mid | partialPathStep(mid, node, cc, sc1, sc2, ap, config) and not fullBarrier(node, config) and + not clearsContent(node, ap.getHead().getContent()) and if node instanceof CastingNode then compatibleTypes(getNodeType(node), ap.getType()) else any() diff --git a/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImplLocal.qll b/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImplLocal.qll index d9f5acdd279..59cc8d529a7 100644 --- a/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImplLocal.qll +++ b/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImplLocal.qll @@ -3598,6 +3598,7 @@ private module FlowExploration { or exists(PartialPathNodeRev mid | revPartialPathStep(mid, node, sc1, sc2, ap, config) and + not clearsContent(node, ap.getHead()) and not fullBarrier(node, config) and distSink(node.getEnclosingCallable(), config) <= config.explorationLimit() ) @@ -3611,6 +3612,7 @@ private module FlowExploration { exists(PartialPathNodeFwd mid | partialPathStep(mid, node, cc, sc1, sc2, ap, config) and not fullBarrier(node, config) and + not clearsContent(node, ap.getHead().getContent()) and if node instanceof CastingNode then compatibleTypes(getNodeType(node), ap.getType()) else any() diff --git a/cpp/ql/src/semmle/code/cpp/dataflow/internal/FlowVar.qll b/cpp/ql/src/semmle/code/cpp/dataflow/internal/FlowVar.qll index 33a74c96718..f3aa94a7992 100644 --- a/cpp/ql/src/semmle/code/cpp/dataflow/internal/FlowVar.qll +++ b/cpp/ql/src/semmle/code/cpp/dataflow/internal/FlowVar.qll @@ -620,7 +620,8 @@ module FlowVar_internal { private predicate largeVariable(Variable v, int liveBlocks, int defs) { liveBlocks = strictcount(SubBasicBlock sbb | variableLiveInSBB(sbb, v)) and defs = strictcount(SubBasicBlock sbb | exists(TBlockVar(sbb, v))) and - liveBlocks * defs > 1000000 + // Convert to float to avoid int overflow (32-bit two's complement) + liveBlocks.(float) * defs.(float) > 100000.0 } /** diff --git a/cpp/ql/src/semmle/code/cpp/ir/dataflow/DefaultTaintTracking.qll b/cpp/ql/src/semmle/code/cpp/ir/dataflow/DefaultTaintTracking.qll index 7ca5020422d..7ca03067d0a 100644 --- a/cpp/ql/src/semmle/code/cpp/ir/dataflow/DefaultTaintTracking.qll +++ b/cpp/ql/src/semmle/code/cpp/ir/dataflow/DefaultTaintTracking.qll @@ -36,43 +36,33 @@ private predicate predictableInstruction(Instruction instr) { * library's `returnArgument` predicate. */ predicate predictableOnlyFlow(string name) { - name = "strcasestr" or - name = "strchnul" or - name = "strchr" or - name = "strchrnul" or - name = "strcmp" or - name = "strcspn" or - name = "strncmp" or - name = "strndup" or - name = "strnlen" or - name = "strrchr" or - name = "strspn" or - name = "strstr" or - name = "strtod" or - name = "strtof" or - name = "strtol" or - name = "strtoll" or - name = "strtoq" or - name = "strtoul" + name = + [ + "strcasestr", "strchnul", "strchr", "strchrnul", "strcmp", "strcspn", "strncmp", "strndup", + "strnlen", "strrchr", "strspn", "strstr", "strtod", "strtof", "strtol", "strtoll", "strtoq", + "strtoul" + ] } private DataFlow::Node getNodeForSource(Expr source) { isUserInput(source, _) and - ( - result = DataFlow::exprNode(source) - or - // Some of the sources in `isUserInput` are intended to match the value of - // an expression, while others (those modeled below) are intended to match - // the taint that propagates out of an argument, like the `char *` argument - // to `gets`. It's impossible here to tell which is which, but the "access - // to argv" source is definitely not intended to match an output argument, - // and it causes false positives if we let it. - // - // This case goes together with the similar (but not identical) rule in - // `nodeIsBarrierIn`. - result = DataFlow::definitionByReferenceNodeFromArgument(source) and - not argv(source.(VariableAccess).getTarget()) - ) + result = getNodeForExpr(source) +} + +private DataFlow::Node getNodeForExpr(Expr node) { + result = DataFlow::exprNode(node) + or + // Some of the sources in `isUserInput` are intended to match the value of + // an expression, while others (those modeled below) are intended to match + // the taint that propagates out of an argument, like the `char *` argument + // to `gets`. It's impossible here to tell which is which, but the "access + // to argv" source is definitely not intended to match an output argument, + // and it causes false positives if we let it. + // + // This case goes together with the similar (but not identical) rule in + // `nodeIsBarrierIn`. + result = DataFlow::definitionByReferenceNodeFromArgument(node) and + not argv(node.(VariableAccess).getTarget()) } private class DefaultTaintTrackingCfg extends DataFlow::Configuration { @@ -216,16 +206,27 @@ private predicate nodeIsBarrierIn(DataFlow::Node node) { cached private predicate commonTaintStep(DataFlow::Node fromNode, DataFlow::Node toNode) { - instructionToInstructionTaintStep(fromNode.asInstruction(), toNode.asInstruction()) - or operandToInstructionTaintStep(fromNode.asOperand(), toNode.asInstruction()) or - operandToOperandTaintStep(fromNode.asOperand(), toNode.asOperand()) + instructionToOperandTaintStep(fromNode.asInstruction(), toNode.asOperand()) } -private predicate operandToOperandTaintStep(Operand fromOperand, Operand toOperand) { +private predicate instructionToOperandTaintStep(Instruction fromInstr, Operand toOperand) { + // Propagate flow from the definition of an operand to the operand, even when the overlap is inexact. + // We only do this in certain cases: + // 1. The instruction's result must not be conflated, and + // 2. The instruction's result type is one the types where we expect element-to-object flow. Currently + // this is array types and union types. This matches the other two cases of element-to-object flow in + // `DefaultTaintTracking`. + toOperand.getAnyDef() = fromInstr and + not fromInstr.isResultConflated() and + ( + fromInstr.getResultType() instanceof ArrayType or + fromInstr.getResultType() instanceof Union + ) + or exists(ReadSideEffectInstruction readInstr | - fromOperand = readInstr.getArgumentOperand() and + fromInstr = readInstr.getArgumentDef() and toOperand = readInstr.getSideEffectOperand() ) } @@ -268,18 +269,18 @@ private predicate operandToInstructionTaintStep(Operand fromOperand, Instruction outInstr.getPrimaryInstruction() = call ) ) -} - -private predicate instructionToInstructionTaintStep(Instruction i1, Instruction i2) { + or // Flow through pointer dereference - i2.(LoadInstruction).getSourceAddress() = i1 + toInstr.(LoadInstruction).getSourceAddressOperand() = fromOperand or // Flow through partial reads of arrays and unions - i2.(LoadInstruction).getSourceValueOperand().getAnyDef() = i1 and - not i1.isResultConflated() and - ( - i1.getResultType() instanceof ArrayType or - i1.getResultType() instanceof Union + toInstr.(LoadInstruction).getSourceValueOperand() = fromOperand and + exists(Instruction fromInstr | fromInstr = fromOperand.getAnyDef() | + not fromInstr.isResultConflated() and + ( + fromInstr.getResultType() instanceof ArrayType or + fromInstr.getResultType() instanceof Union + ) ) or // Unary instructions tend to preserve enough information in practice that we @@ -289,63 +290,54 @@ private predicate instructionToInstructionTaintStep(Instruction i1, Instruction // `FieldAddressInstruction` could cause flow into one field to come out an // unrelated field. This would happen across function boundaries, where the IR // would not be able to match loads to stores. - i2.(UnaryInstruction).getUnary() = i1 and + toInstr.(UnaryInstruction).getUnaryOperand() = fromOperand and ( - not i2 instanceof FieldAddressInstruction + not toInstr instanceof FieldAddressInstruction or - i2.(FieldAddressInstruction).getField().getDeclaringType() instanceof Union + toInstr.(FieldAddressInstruction).getField().getDeclaringType() instanceof Union ) or - // Flow out of definition-by-reference - i2.(ChiInstruction).getPartial() = i1.(WriteSideEffectInstruction) and - not i2.isResultConflated() - or // Flow from an element to an array or union that contains it. - i2.(ChiInstruction).getPartial() = i1 and - not i2.isResultConflated() and - exists(Type t | i2.getResultLanguageType().hasType(t, false) | + toInstr.(ChiInstruction).getPartialOperand() = fromOperand and + not toInstr.isResultConflated() and + exists(Type t | toInstr.getResultLanguageType().hasType(t, false) | t instanceof Union or t instanceof ArrayType ) or exists(BinaryInstruction bin | - bin = i2 and - predictableInstruction(i2.getAnOperand().getDef()) and - i1 = i2.getAnOperand().getDef() + bin = toInstr and + predictableInstruction(toInstr.getAnOperand().getDef()) and + fromOperand = toInstr.getAnOperand() ) or // This is part of the translation of `a[i]`, where we want taint to flow // from `a`. - i2.(PointerAddInstruction).getLeft() = i1 - or - // Until we have from through indirections across calls, we'll take flow out - // of the parameter and into its indirection. - exists(IRFunction f, Parameter parameter | - i1 = getInitializeParameter(f, parameter) and - i2 = getInitializeIndirection(f, parameter) - ) + toInstr.(PointerAddInstruction).getLeftOperand() = fromOperand or // Until we have flow through indirections across calls, we'll take flow out // of the indirection and into the argument. // When we get proper flow through indirections across calls, this code can be // moved to `adjusedSink` or possibly into the `DataFlow::ExprNode` class. exists(ReadSideEffectInstruction read | - read.getAnOperand().(SideEffectOperand).getAnyDef() = i1 and - read.getArgumentDef() = i2 + read.getSideEffectOperand() = fromOperand and + read.getArgumentDef() = toInstr ) -} - -pragma[noinline] -private InitializeIndirectionInstruction getInitializeIndirection(IRFunction f, Parameter p) { - result.getParameter() = p and - result.getEnclosingIRFunction() = f -} - -pragma[noinline] -private InitializeParameterInstruction getInitializeParameter(IRFunction f, Parameter p) { - result.getParameter() = p and - result.getEnclosingIRFunction() = f + or + // Until we have from through indirections across calls, we'll take flow out + // of the parameter and into its indirection. + // `InitializeIndirectionInstruction` only has a single operand: the address of the + // value whose indirection we are initializing. When initializing an indirection of a parameter `p`, + // the IR looks like this: + // ``` + // m1 = InitializeParameter[p] : &r1 + // r2 = Load[p] : r2, m1 + // m3 = InitializeIndirection[p] : &r2 + // ``` + // So by having flow from `r2` to `m3` we're enabling flow from `m1` to `m3`. This relies on the + // `LoadOperand`'s overlap being exact. + toInstr.(InitializeIndirectionInstruction).getAnOperand() = fromOperand } /** @@ -547,9 +539,15 @@ module TaintedWithPath { * a characteristic predicate. */ class TaintTrackingConfiguration extends TSingleton { + /** Override this to specify which elements are sources in this configuration. */ + predicate isSource(Expr source) { exists(getNodeForSource(source)) } + /** Override this to specify which elements are sinks in this configuration. */ abstract predicate isSink(Element e); + /** Override this to specify which expressions are barriers in this configuration. */ + predicate isBarrier(Expr e) { nodeIsBarrier(getNodeForExpr(e)) } + /** * Override this predicate to `any()` to allow taint to flow through global * variables. @@ -563,7 +561,11 @@ module TaintedWithPath { private class AdjustedConfiguration extends DataFlow3::Configuration { AdjustedConfiguration() { this = "AdjustedConfiguration" } - override predicate isSource(DataFlow::Node source) { source = getNodeForSource(_) } + override predicate isSource(DataFlow::Node source) { + exists(TaintTrackingConfiguration cfg, Expr e | + cfg.isSource(e) and source = getNodeForExpr(e) + ) + } override predicate isSink(DataFlow::Node sink) { exists(TaintTrackingConfiguration cfg | cfg.isSink(adjustedSink(sink))) @@ -579,7 +581,9 @@ module TaintedWithPath { ) } - override predicate isBarrier(DataFlow::Node node) { nodeIsBarrier(node) } + override predicate isBarrier(DataFlow::Node node) { + exists(TaintTrackingConfiguration cfg, Expr e | cfg.isBarrier(e) and node = getNodeForExpr(e)) + } override predicate isBarrierIn(DataFlow::Node node) { nodeIsBarrierIn(node) } } @@ -606,7 +610,8 @@ module TaintedWithPath { exists(AdjustedConfiguration cfg, DataFlow3::Node sourceNode, DataFlow3::Node sinkNode | cfg.hasFlow(sourceNode, sinkNode) | - sourceNode = getNodeForSource(e) + sourceNode = getNodeForExpr(e) and + exists(TaintTrackingConfiguration ttCfg | ttCfg.isSource(e)) or e = adjustedSink(sinkNode) and exists(TaintTrackingConfiguration ttCfg | ttCfg.isSink(e)) @@ -660,7 +665,7 @@ module TaintedWithPath { /** A PathNode whose `Element` is a source. It may also be a sink. */ private class InitialPathNode extends EndpointPathNode { - InitialPathNode() { exists(getNodeForSource(this.inner())) } + InitialPathNode() { exists(TaintTrackingConfiguration cfg | cfg.isSource(this.inner())) } } /** A PathNode whose `Element` is a sink. It may also be a source. */ @@ -682,14 +687,14 @@ module TaintedWithPath { // Same for the first node exists(WrapPathNode sourceNode | DataFlow3::PathGraph::edges(sourceNode.inner(), b.(WrapPathNode).inner()) and - sourceNode.inner().getNode() = getNodeForSource(a.(InitialPathNode).inner()) + sourceNode.inner().getNode() = getNodeForExpr(a.(InitialPathNode).inner()) ) or // Finally, handle the case where the path goes directly from a source to a // sink, meaning that they both need to be translated. exists(WrapPathNode sinkNode, WrapPathNode sourceNode | DataFlow3::PathGraph::edges(sourceNode.inner(), sinkNode.inner()) and - sourceNode.inner().getNode() = getNodeForSource(a.(InitialPathNode).inner()) and + sourceNode.inner().getNode() = getNodeForExpr(a.(InitialPathNode).inner()) and b.(FinalPathNode).inner() = adjustedSink(sinkNode.inner().getNode()) ) } @@ -712,7 +717,7 @@ module TaintedWithPath { predicate taintedWithPath(Expr source, Element tainted, PathNode sourceNode, PathNode sinkNode) { exists(AdjustedConfiguration cfg, DataFlow3::Node flowSource, DataFlow3::Node flowSink | source = sourceNode.(InitialPathNode).inner() and - flowSource = getNodeForSource(source) and + flowSource = getNodeForExpr(source) and cfg.hasFlow(flowSource, flowSink) and tainted = adjustedSink(flowSink) and tainted = sinkNode.(FinalPathNode).inner() @@ -734,8 +739,8 @@ module TaintedWithPath { * through a global variable. */ predicate taintedWithoutGlobals(Element tainted) { - exists(PathNode sourceNode, FinalPathNode sinkNode | - sourceNode.(WrapPathNode).inner().getNode() = getNodeForSource(_) and + exists(AdjustedConfiguration cfg, PathNode sourceNode, FinalPathNode sinkNode | + cfg.isSource(sourceNode.(WrapPathNode).inner().getNode()) and edgesWithoutGlobals+(sourceNode, sinkNode) and tainted = sinkNode.inner() ) diff --git a/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl.qll b/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl.qll index d9f5acdd279..59cc8d529a7 100644 --- a/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl.qll +++ b/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl.qll @@ -3598,6 +3598,7 @@ private module FlowExploration { or exists(PartialPathNodeRev mid | revPartialPathStep(mid, node, sc1, sc2, ap, config) and + not clearsContent(node, ap.getHead()) and not fullBarrier(node, config) and distSink(node.getEnclosingCallable(), config) <= config.explorationLimit() ) @@ -3611,6 +3612,7 @@ private module FlowExploration { exists(PartialPathNodeFwd mid | partialPathStep(mid, node, cc, sc1, sc2, ap, config) and not fullBarrier(node, config) and + not clearsContent(node, ap.getHead().getContent()) and if node instanceof CastingNode then compatibleTypes(getNodeType(node), ap.getType()) else any() diff --git a/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl2.qll b/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl2.qll index d9f5acdd279..59cc8d529a7 100644 --- a/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl2.qll +++ b/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl2.qll @@ -3598,6 +3598,7 @@ private module FlowExploration { or exists(PartialPathNodeRev mid | revPartialPathStep(mid, node, sc1, sc2, ap, config) and + not clearsContent(node, ap.getHead()) and not fullBarrier(node, config) and distSink(node.getEnclosingCallable(), config) <= config.explorationLimit() ) @@ -3611,6 +3612,7 @@ private module FlowExploration { exists(PartialPathNodeFwd mid | partialPathStep(mid, node, cc, sc1, sc2, ap, config) and not fullBarrier(node, config) and + not clearsContent(node, ap.getHead().getContent()) and if node instanceof CastingNode then compatibleTypes(getNodeType(node), ap.getType()) else any() diff --git a/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl3.qll b/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl3.qll index d9f5acdd279..59cc8d529a7 100644 --- a/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl3.qll +++ b/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl3.qll @@ -3598,6 +3598,7 @@ private module FlowExploration { or exists(PartialPathNodeRev mid | revPartialPathStep(mid, node, sc1, sc2, ap, config) and + not clearsContent(node, ap.getHead()) and not fullBarrier(node, config) and distSink(node.getEnclosingCallable(), config) <= config.explorationLimit() ) @@ -3611,6 +3612,7 @@ private module FlowExploration { exists(PartialPathNodeFwd mid | partialPathStep(mid, node, cc, sc1, sc2, ap, config) and not fullBarrier(node, config) and + not clearsContent(node, ap.getHead().getContent()) and if node instanceof CastingNode then compatibleTypes(getNodeType(node), ap.getType()) else any() diff --git a/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl4.qll b/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl4.qll index d9f5acdd279..59cc8d529a7 100644 --- a/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl4.qll +++ b/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl4.qll @@ -3598,6 +3598,7 @@ private module FlowExploration { or exists(PartialPathNodeRev mid | revPartialPathStep(mid, node, sc1, sc2, ap, config) and + not clearsContent(node, ap.getHead()) and not fullBarrier(node, config) and distSink(node.getEnclosingCallable(), config) <= config.explorationLimit() ) @@ -3611,6 +3612,7 @@ private module FlowExploration { exists(PartialPathNodeFwd mid | partialPathStep(mid, node, cc, sc1, sc2, ap, config) and not fullBarrier(node, config) and + not clearsContent(node, ap.getHead().getContent()) and if node instanceof CastingNode then compatibleTypes(getNodeType(node), ap.getType()) else any() diff --git a/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowUtil.qll b/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowUtil.qll index 15fc2fa1d9a..cbc44ac920d 100644 --- a/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowUtil.qll +++ b/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowUtil.qll @@ -716,21 +716,15 @@ private predicate modelFlow(Operand opFrom, Instruction iTo) { iTo = call or exists(int index, WriteSideEffectInstruction outNode | - modelOut.isParameterDeref(index) and + modelOut.isParameterDerefOrQualifierObject(index) and iTo = outNode and outNode = getSideEffectFor(call, index) ) - or - exists(WriteSideEffectInstruction outNode | - modelOut.isQualifierObject() and - iTo = outNode and - outNode = getSideEffectFor(call, -1) - ) ) and ( exists(int index | - modelIn.isParameter(index) and - opFrom = call.getPositionalArgumentOperand(index) + modelIn.isParameterOrQualifierAddress(index) and + opFrom = call.getArgumentOperand(index) ) or exists(int index, ReadSideEffectInstruction read | @@ -739,9 +733,6 @@ private predicate modelFlow(Operand opFrom, Instruction iTo) { opFrom = read.getSideEffectOperand() ) or - modelIn.isQualifierAddress() and - opFrom = call.getThisArgumentOperand() - or exists(ReadSideEffectInstruction read | modelIn.isQualifierObject() and read = getSideEffectFor(call, -1) and diff --git a/cpp/ql/src/semmle/code/cpp/ir/implementation/IRType.qll b/cpp/ql/src/semmle/code/cpp/ir/implementation/IRType.qll index 3bf3bf2e276..e0bccafae6b 100644 --- a/cpp/ql/src/semmle/code/cpp/ir/implementation/IRType.qll +++ b/cpp/ql/src/semmle/code/cpp/ir/implementation/IRType.qll @@ -341,7 +341,7 @@ module IRTypeConsistency { query predicate multipleIRTypes(Language::LanguageType type, string message) { strictcount(type.getIRType()) > 1 and message = - "`LanguageType` " + type.getAQlClass() + " has multiple `IRType`s: " + + "`LanguageType` " + type + " has multiple `IRType`s: " + concat(type.getIRType().toString(), ", ") } diff --git a/cpp/ql/src/semmle/code/cpp/models/Models.qll b/cpp/ql/src/semmle/code/cpp/models/Models.qll index f2612d69b84..c36c1da9bcd 100644 --- a/cpp/ql/src/semmle/code/cpp/models/Models.qll +++ b/cpp/ql/src/semmle/code/cpp/models/Models.qll @@ -15,6 +15,10 @@ private import implementations.Strcat private import implementations.Strcpy private import implementations.Strdup private import implementations.Strftime +private import implementations.Strtok +private import implementations.Strset +private import implementations.Strcrement +private import implementations.Strnextc private import implementations.StdContainer private import implementations.StdPair private import implementations.StdMap @@ -23,3 +27,6 @@ private import implementations.StdString private import implementations.Swap private import implementations.GetDelim private import implementations.SmartPointer +private import implementations.Sscanf +private import implementations.Send +private import implementations.Recv diff --git a/cpp/ql/src/semmle/code/cpp/models/implementations/Allocation.qll b/cpp/ql/src/semmle/code/cpp/models/implementations/Allocation.qll index 709d3c3db00..91ec1525834 100644 --- a/cpp/ql/src/semmle/code/cpp/models/implementations/Allocation.qll +++ b/cpp/ql/src/semmle/code/cpp/models/implementations/Allocation.qll @@ -14,95 +14,58 @@ private class MallocAllocationFunction extends AllocationFunction { int sizeArg; MallocAllocationFunction() { - exists(string name | - hasGlobalOrStdName(name) and - // malloc(size) - (name = "malloc" and sizeArg = 0) - or - hasGlobalName(name) and - ( - // ExAllocatePool(type, size) - name = "ExAllocatePool" and sizeArg = 1 - or - // ExAllocatePool(type, size, tag) - name = "ExAllocatePoolWithTag" and sizeArg = 1 - or - // ExAllocatePoolWithTagPriority(type, size, tag, priority) - name = "ExAllocatePoolWithTagPriority" and sizeArg = 1 - or - // ExAllocatePoolWithQuota(type, size) - name = "ExAllocatePoolWithQuota" and sizeArg = 1 - or - // ExAllocatePoolWithQuotaTag(type, size, tag) - name = "ExAllocatePoolWithQuotaTag" and sizeArg = 1 - or - // IoAllocateMdl(address, size, flag, flag, irp) - name = "IoAllocateMdl" and sizeArg = 1 - or - // IoAllocateErrorLogEntry(object, size) - name = "IoAllocateErrorLogEntry" and sizeArg = 1 - or - // MmAllocateContiguousMemory(size, maxaddress) - name = "MmAllocateContiguousMemory" and sizeArg = 0 - or - // MmAllocateContiguousNodeMemory(size, minaddress, maxaddress, bound, flag, prefer) - name = "MmAllocateContiguousNodeMemory" and sizeArg = 0 - or - // MmAllocateContiguousMemorySpecifyCache(size, minaddress, maxaddress, bound, type) - name = "MmAllocateContiguousMemorySpecifyCache" and sizeArg = 0 - or - // MmAllocateContiguousMemorySpecifyCacheNode(size, minaddress, maxaddress, bound, type, prefer) - name = "MmAllocateContiguousMemorySpecifyCacheNode" and sizeArg = 0 - or - // MmAllocateNonCachedMemory(size) - name = "MmAllocateNonCachedMemory" and sizeArg = 0 - or - // MmAllocateMappingAddress(size, tag) - name = "MmAllocateMappingAddress" and sizeArg = 0 - or - // MmAllocatePagesForMdl(minaddress, maxaddress, skip, size) - name = "MmAllocatePagesForMdl" and sizeArg = 3 - or - // MmAllocatePagesForMdlEx(minaddress, maxaddress, skip, size, type, flags) - name = "MmAllocatePagesForMdlEx" and sizeArg = 3 - or - // MmAllocateNodePagesForMdlEx(minaddress, maxaddress, skip, size, type, prefer, flags) - name = "MmAllocateNodePagesForMdlEx" and sizeArg = 3 - or - // LocalAlloc(flags, size) - name = "LocalAlloc" and sizeArg = 1 - or - // GlobalAlloc(flags, size) - name = "GlobalAlloc" and sizeArg = 1 - or - // HeapAlloc(heap, flags, size) - name = "HeapAlloc" and sizeArg = 2 - or - // VirtualAlloc(address, size, type, flag) - name = "VirtualAlloc" and sizeArg = 1 - or - // CoTaskMemAlloc(size) - name = "CoTaskMemAlloc" and sizeArg = 0 - or - // kmem_alloc(size, flags) - name = "kmem_alloc" and sizeArg = 0 - or - // kmem_zalloc(size, flags) - name = "kmem_zalloc" and sizeArg = 0 - or - // CRYPTO_malloc(size_t num, const char *file, int line) - name = "CRYPTO_malloc" and sizeArg = 0 - or - // CRYPTO_zalloc(size_t num, const char *file, int line) - name = "CRYPTO_zalloc" and sizeArg = 0 - or - // CRYPTO_secure_malloc(size_t num, const char *file, int line) - name = "CRYPTO_secure_malloc" and sizeArg = 0 - or - // CRYPTO_secure_zalloc(size_t num, const char *file, int line) - name = "CRYPTO_secure_zalloc" and sizeArg = 0 - ) - ) + // --- C library allocation + hasGlobalOrStdName("malloc") and // malloc(size) + sizeArg = 0 + or + hasGlobalName([ + // --- Windows Memory Management for Windows Drivers + "MmAllocateContiguousMemory", // MmAllocateContiguousMemory(size, maxaddress) + "MmAllocateContiguousNodeMemory", // MmAllocateContiguousNodeMemory(size, minaddress, maxaddress, bound, flag, prefer) + "MmAllocateContiguousMemorySpecifyCache", // MmAllocateContiguousMemorySpecifyCache(size, minaddress, maxaddress, bound, type) + "MmAllocateContiguousMemorySpecifyCacheNode", // MmAllocateContiguousMemorySpecifyCacheNode(size, minaddress, maxaddress, bound, type, prefer) + "MmAllocateNonCachedMemory", // MmAllocateNonCachedMemory(size) + "MmAllocateMappingAddress", // MmAllocateMappingAddress(size, tag) + // --- Windows COM allocation + "CoTaskMemAlloc", // CoTaskMemAlloc(size) + // --- Solaris/BSD kernel memory allocator + "kmem_alloc", // kmem_alloc(size, flags) + "kmem_zalloc", // kmem_zalloc(size, flags) + // --- OpenSSL memory allocation + "CRYPTO_malloc", // CRYPTO_malloc(size_t num, const char *file, int line) + "CRYPTO_zalloc", // CRYPTO_zalloc(size_t num, const char *file, int line) + "CRYPTO_secure_malloc", // CRYPTO_secure_malloc(size_t num, const char *file, int line) + "CRYPTO_secure_zalloc" // CRYPTO_secure_zalloc(size_t num, const char *file, int line) + ]) and + sizeArg = 0 + or + hasGlobalName([ + // --- Windows Memory Management for Windows Drivers + "ExAllocatePool", // ExAllocatePool(type, size) + "ExAllocatePoolWithTag", // ExAllocatePool(type, size, tag) + "ExAllocatePoolWithTagPriority", // ExAllocatePoolWithTagPriority(type, size, tag, priority) + "ExAllocatePoolWithQuota", // ExAllocatePoolWithQuota(type, size) + "ExAllocatePoolWithQuotaTag", // ExAllocatePoolWithQuotaTag(type, size, tag) + "IoAllocateMdl", // IoAllocateMdl(address, size, flag, flag, irp) + "IoAllocateErrorLogEntry", // IoAllocateErrorLogEntry(object, size) + // --- Windows Global / Local legacy allocation + "LocalAlloc", // LocalAlloc(flags, size) + "GlobalAlloc", // GlobalAlloc(flags, size) + // --- Windows System Services allocation + "VirtualAlloc" // VirtualAlloc(address, size, type, flag) + ]) and + sizeArg = 1 + or + hasGlobalName(["HeapAlloc"]) and // HeapAlloc(heap, flags, size) + sizeArg = 2 + or + hasGlobalName([ + // --- Windows Memory Management for Windows Drivers + "MmAllocatePagesForMdl", // MmAllocatePagesForMdl(minaddress, maxaddress, skip, size) + "MmAllocatePagesForMdlEx", // MmAllocatePagesForMdlEx(minaddress, maxaddress, skip, size, type, flags) + "MmAllocateNodePagesForMdlEx" // MmAllocateNodePagesForMdlEx(minaddress, maxaddress, skip, size, type, prefer, flags) + ]) and + sizeArg = 3 } override int getSizeArg() { result = sizeArg } @@ -116,16 +79,14 @@ private class AllocaAllocationFunction extends AllocationFunction { int sizeArg; AllocaAllocationFunction() { - exists(string name | - hasGlobalName(name) and - ( - // alloca(size) - name = "alloca" and sizeArg = 0 - or - // __builtin_alloca(size) - name = "__builtin_alloca" and sizeArg = 0 - ) - ) + hasGlobalName([ + // --- stack allocation + "alloca", // // alloca(size) + "__builtin_alloca", // __builtin_alloca(size) + "_alloca", // _alloca(size) + "_malloca" // _malloca(size) + ]) and + sizeArg = 0 } override int getSizeArg() { result = sizeArg } @@ -142,11 +103,10 @@ private class CallocAllocationFunction extends AllocationFunction { int multArg; CallocAllocationFunction() { - exists(string name | - hasGlobalOrStdName(name) and - // calloc(num, size) - (name = "calloc" and sizeArg = 1 and multArg = 0) - ) + // --- C library allocation + hasGlobalOrStdName("calloc") and // calloc(num, size) + sizeArg = 1 and + multArg = 0 } override int getSizeArg() { result = sizeArg } @@ -163,29 +123,26 @@ private class ReallocAllocationFunction extends AllocationFunction { int reallocArg; ReallocAllocationFunction() { - exists(string name | - hasGlobalOrStdName(name) and - // realloc(ptr, size) - (name = "realloc" and sizeArg = 1 and reallocArg = 0) - or - hasGlobalName(name) and - ( - // LocalReAlloc(ptr, size, flags) - name = "LocalReAlloc" and sizeArg = 1 and reallocArg = 0 - or - // GlobalReAlloc(ptr, size, flags) - name = "GlobalReAlloc" and sizeArg = 1 and reallocArg = 0 - or - // HeapReAlloc(heap, flags, ptr, size) - name = "HeapReAlloc" and sizeArg = 3 and reallocArg = 2 - or - // CoTaskMemRealloc(ptr, size) - name = "CoTaskMemRealloc" and sizeArg = 1 and reallocArg = 0 - or - // CRYPTO_realloc(void *addr, size_t num, const char *file, int line); - name = "CRYPTO_realloc" and sizeArg = 1 and reallocArg = 0 - ) - ) + // --- C library allocation + hasGlobalOrStdName("realloc") and // realloc(ptr, size) + sizeArg = 1 and + reallocArg = 0 + or + hasGlobalName([ + // --- Windows Global / Local legacy allocation + "LocalReAlloc", // LocalReAlloc(ptr, size, flags) + "GlobalReAlloc", // GlobalReAlloc(ptr, size, flags) + // --- Windows COM allocation + "CoTaskMemRealloc", // CoTaskMemRealloc(ptr, size) + // --- OpenSSL memory allocation + "CRYPTO_realloc" // CRYPTO_realloc(void *addr, size_t num, const char *file, int line) + ]) and + sizeArg = 1 and + reallocArg = 0 + or + hasGlobalName("HeapReAlloc") and // HeapReAlloc(heap, flags, ptr, size) + sizeArg = 3 and + reallocArg = 2 } override int getSizeArg() { result = sizeArg } @@ -199,40 +156,20 @@ private class ReallocAllocationFunction extends AllocationFunction { */ private class SizelessAllocationFunction extends AllocationFunction { SizelessAllocationFunction() { - exists(string name | - hasGlobalName(name) and - ( - // ExAllocateFromLookasideListEx(list) - name = "ExAllocateFromLookasideListEx" - or - // ExAllocateFromPagedLookasideList(list) - name = "ExAllocateFromPagedLookasideList" - or - // ExAllocateFromNPagedLookasideList(list) - name = "ExAllocateFromNPagedLookasideList" - or - // ExAllocateTimer(callback, context, attributes) - name = "ExAllocateTimer" - or - // IoAllocateWorkItem(object) - name = "IoAllocateWorkItem" - or - // MmMapLockedPagesWithReservedMapping(address, tag, list, type) - name = "MmMapLockedPagesWithReservedMapping" - or - // MmMapLockedPages(list, mode) - name = "MmMapLockedPages" - or - // MmMapLockedPagesSpecifyCache(list, mode, type, address, flag, flag) - name = "MmMapLockedPagesSpecifyCache" - or - // pool_get(pool, flags) - name = "pool_get" - or - // pool_cache_get(pool, flags) - name = "pool_cache_get" - ) - ) + hasGlobalName([ + // --- Windows Memory Management for Windows Drivers + "ExAllocateFromLookasideListEx", // ExAllocateFromLookasideListEx(list) + "ExAllocateFromPagedLookasideList", // ExAllocateFromPagedLookasideList(list) + "ExAllocateFromNPagedLookasideList", // ExAllocateFromNPagedLookasideList(list) + "ExAllocateTimer", // ExAllocateTimer(callback, context, attributes) + "IoAllocateWorkItem", // IoAllocateWorkItem(object) + "MmMapLockedPagesWithReservedMapping", // MmMapLockedPagesWithReservedMapping(address, tag, list, type) + "MmMapLockedPages", // MmMapLockedPages(list, mode) + "MmMapLockedPagesSpecifyCache", // MmMapLockedPagesSpecifyCache(list, mode, type, address, flag, flag) + // --- NetBSD pool manager + "pool_get", // pool_get(pool, flags) + "pool_cache_get" // pool_cache_get(pool, flags) + ]) } } diff --git a/cpp/ql/src/semmle/code/cpp/models/implementations/Deallocation.qll b/cpp/ql/src/semmle/code/cpp/models/implementations/Deallocation.qll index 3c65aa699be..b56c8c21949 100644 --- a/cpp/ql/src/semmle/code/cpp/models/implementations/Deallocation.qll +++ b/cpp/ql/src/semmle/code/cpp/models/implementations/Deallocation.qll @@ -13,77 +13,43 @@ private class StandardDeallocationFunction extends DeallocationFunction { int freedArg; StandardDeallocationFunction() { - exists(string name | - hasGlobalName(name) and - ( - name = "free" and freedArg = 0 - or - name = "realloc" and freedArg = 0 - or - name = "CRYPTO_free" and freedArg = 0 - or - name = "CRYPTO_secure_free" and freedArg = 0 - ) - or - hasGlobalOrStdName(name) and - ( - name = "ExFreePoolWithTag" and freedArg = 0 - or - name = "ExFreeToLookasideListEx" and freedArg = 1 - or - name = "ExFreeToPagedLookasideList" and freedArg = 1 - or - name = "ExFreeToNPagedLookasideList" and freedArg = 1 - or - name = "ExDeleteTimer" and freedArg = 0 - or - name = "IoFreeMdl" and freedArg = 0 - or - name = "IoFreeWorkItem" and freedArg = 0 - or - name = "IoFreeErrorLogEntry" and freedArg = 0 - or - name = "MmFreeContiguousMemory" and freedArg = 0 - or - name = "MmFreeContiguousMemorySpecifyCache" and freedArg = 0 - or - name = "MmFreeNonCachedMemory" and freedArg = 0 - or - name = "MmFreeMappingAddress" and freedArg = 0 - or - name = "MmFreePagesFromMdl" and freedArg = 0 - or - name = "MmUnmapReservedMapping" and freedArg = 0 - or - name = "MmUnmapLockedPages" and freedArg = 0 - or - name = "LocalFree" and freedArg = 0 - or - name = "GlobalFree" and freedArg = 0 - or - name = "HeapFree" and freedArg = 2 - or - name = "VirtualFree" and freedArg = 0 - or - name = "CoTaskMemFree" and freedArg = 0 - or - name = "SysFreeString" and freedArg = 0 - or - name = "LocalReAlloc" and freedArg = 0 - or - name = "GlobalReAlloc" and freedArg = 0 - or - name = "HeapReAlloc" and freedArg = 2 - or - name = "CoTaskMemRealloc" and freedArg = 0 - or - name = "kmem_free" and freedArg = 0 - or - name = "pool_put" and freedArg = 1 - or - name = "pool_cache_put" and freedArg = 1 - ) - ) + hasGlobalName([ + // --- C library allocation + "free", "realloc", + // --- OpenSSL memory allocation + "CRYPTO_free", "CRYPTO_secure_free" + ]) and + freedArg = 0 + or + hasGlobalOrStdName([ + // --- Windows Memory Management for Windows Drivers + "ExFreePoolWithTag", "ExDeleteTimer", "IoFreeMdl", "IoFreeWorkItem", "IoFreeErrorLogEntry", + "MmFreeContiguousMemory", "MmFreeContiguousMemorySpecifyCache", "MmFreeNonCachedMemory", + "MmFreeMappingAddress", "MmFreePagesFromMdl", "MmUnmapReservedMapping", + "MmUnmapLockedPages", + // --- Windows Global / Local legacy allocation + "LocalFree", "GlobalFree", "LocalReAlloc", "GlobalReAlloc", + // --- Windows System Services allocation + "VirtualFree", + // --- Windows COM allocation + "CoTaskMemFree", "CoTaskMemRealloc", + // --- Windows Automation + "SysFreeString", + // --- Solaris/BSD kernel memory allocator + "kmem_free" + ]) and + freedArg = 0 + or + hasGlobalOrStdName([ + // --- Windows Memory Management for Windows Drivers + "ExFreeToLookasideListEx", "ExFreeToPagedLookasideList", "ExFreeToNPagedLookasideList", + // --- NetBSD pool manager + "pool_put", "pool_cache_put" + ]) and + freedArg = 1 + or + hasGlobalOrStdName(["HeapFree", "HeapReAlloc"]) and + freedArg = 2 } override int getFreedArg() { result = freedArg } diff --git a/cpp/ql/src/semmle/code/cpp/models/implementations/Fread.qll b/cpp/ql/src/semmle/code/cpp/models/implementations/Fread.qll index 11568c8a974..9524b18b0a2 100644 --- a/cpp/ql/src/semmle/code/cpp/models/implementations/Fread.qll +++ b/cpp/ql/src/semmle/code/cpp/models/implementations/Fread.qll @@ -1,7 +1,7 @@ import semmle.code.cpp.models.interfaces.Alias import semmle.code.cpp.models.interfaces.FlowSource -private class Fread extends AliasFunction, RemoteFlowFunction { +private class Fread extends AliasFunction, RemoteFlowSourceFunction { Fread() { this.hasGlobalName("fread") } override predicate parameterNeverEscapes(int n) { diff --git a/cpp/ql/src/semmle/code/cpp/models/implementations/GetDelim.qll b/cpp/ql/src/semmle/code/cpp/models/implementations/GetDelim.qll index 3561caee7fb..e2015406346 100644 --- a/cpp/ql/src/semmle/code/cpp/models/implementations/GetDelim.qll +++ b/cpp/ql/src/semmle/code/cpp/models/implementations/GetDelim.qll @@ -7,7 +7,7 @@ import semmle.code.cpp.models.interfaces.FlowSource * The standard functions `getdelim`, `getwdelim` and the glibc variant `__getdelim`. */ private class GetDelimFunction extends TaintFunction, AliasFunction, SideEffectFunction, - RemoteFlowFunction { + RemoteFlowSourceFunction { GetDelimFunction() { hasGlobalName(["getdelim", "getwdelim", "__getdelim"]) } override predicate hasTaintFlow(FunctionInput i, FunctionOutput o) { diff --git a/cpp/ql/src/semmle/code/cpp/models/implementations/Getenv.qll b/cpp/ql/src/semmle/code/cpp/models/implementations/Getenv.qll index 9761a4293a8..93b601de752 100644 --- a/cpp/ql/src/semmle/code/cpp/models/implementations/Getenv.qll +++ b/cpp/ql/src/semmle/code/cpp/models/implementations/Getenv.qll @@ -8,7 +8,7 @@ import semmle.code.cpp.models.interfaces.FlowSource /** * The POSIX function `getenv`. */ -class Getenv extends LocalFlowFunction { +class Getenv extends LocalFlowSourceFunction { Getenv() { this.hasGlobalName("getenv") } override predicate hasLocalFlowSource(FunctionOutput output, string description) { diff --git a/cpp/ql/src/semmle/code/cpp/models/implementations/Gets.qll b/cpp/ql/src/semmle/code/cpp/models/implementations/Gets.qll index 91653cd6b37..f698a1209f4 100644 --- a/cpp/ql/src/semmle/code/cpp/models/implementations/Gets.qll +++ b/cpp/ql/src/semmle/code/cpp/models/implementations/Gets.qll @@ -14,7 +14,7 @@ import semmle.code.cpp.models.interfaces.FlowSource * The standard functions `gets` and `fgets`. */ private class GetsFunction extends DataFlowFunction, TaintFunction, ArrayFunction, AliasFunction, - SideEffectFunction, RemoteFlowFunction { + SideEffectFunction, RemoteFlowSourceFunction { GetsFunction() { // gets(str) // fgets(str, num, stream) diff --git a/cpp/ql/src/semmle/code/cpp/models/implementations/IdentityFunction.qll b/cpp/ql/src/semmle/code/cpp/models/implementations/IdentityFunction.qll index 0178cd0f7ec..60afd2b25ef 100644 --- a/cpp/ql/src/semmle/code/cpp/models/implementations/IdentityFunction.qll +++ b/cpp/ql/src/semmle/code/cpp/models/implementations/IdentityFunction.qll @@ -6,12 +6,9 @@ import semmle.code.cpp.models.interfaces.SideEffect /** * The standard function templates `std::move` and `std::forward`. */ -private class IdentityFunction extends DataFlowFunction, SideEffectFunction, AliasFunction { - IdentityFunction() { - this.getNamespace().getParentNamespace() instanceof GlobalNamespace and - this.getNamespace().getName() = "std" and - this.getName() = ["move", "forward"] - } +private class IdentityFunction extends DataFlowFunction, SideEffectFunction, AliasFunction, + FunctionTemplateInstantiation { + IdentityFunction() { this.hasQualifiedName("std", ["move", "forward"]) } override predicate hasOnlySpecificReadSideEffects() { any() } @@ -32,5 +29,7 @@ private class IdentityFunction extends DataFlowFunction, SideEffectFunction, Ali override predicate hasDataFlow(FunctionInput input, FunctionOutput output) { // These functions simply return the argument value. input.isParameter(0) and output.isReturnValue() + or + input.isParameterDeref(0) and output.isReturnValueDeref() } } diff --git a/cpp/ql/src/semmle/code/cpp/models/implementations/Iterator.qll b/cpp/ql/src/semmle/code/cpp/models/implementations/Iterator.qll index 3a789a6aa25..a5b1c0e83ec 100644 --- a/cpp/ql/src/semmle/code/cpp/models/implementations/Iterator.qll +++ b/cpp/ql/src/semmle/code/cpp/models/implementations/Iterator.qll @@ -109,6 +109,8 @@ private class IteratorCrementOperator extends Operator, DataFlowFunction { override predicate hasDataFlow(FunctionInput input, FunctionOutput output) { input = iteratorInput and output.isReturnValue() + or + input.isParameterDeref(0) and output.isReturnValueDeref() } } @@ -159,6 +161,8 @@ private class IteratorAssignArithmeticOperator extends Operator, DataFlowFunctio override predicate hasDataFlow(FunctionInput input, FunctionOutput output) { input.isParameter(0) and output.isReturnValue() + or + input.isParameterDeref(0) and output.isReturnValueDeref() } override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { @@ -201,6 +205,9 @@ private class IteratorCrementMemberOperator extends MemberFunction, DataFlowFunc or input.isReturnValueDeref() and output.isQualifierObject() + or + input.isQualifierObject() and + output.isReturnValueDeref() } override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { diff --git a/cpp/ql/src/semmle/code/cpp/models/implementations/Memcpy.qll b/cpp/ql/src/semmle/code/cpp/models/implementations/Memcpy.qll index 813c2834586..b7d8aed60fa 100644 --- a/cpp/ql/src/semmle/code/cpp/models/implementations/Memcpy.qll +++ b/cpp/ql/src/semmle/code/cpp/models/implementations/Memcpy.qll @@ -6,6 +6,7 @@ import semmle.code.cpp.Function import semmle.code.cpp.models.interfaces.ArrayFunction import semmle.code.cpp.models.interfaces.DataFlow +import semmle.code.cpp.models.interfaces.Alias import semmle.code.cpp.models.interfaces.SideEffect import semmle.code.cpp.models.interfaces.Taint @@ -13,32 +14,35 @@ import semmle.code.cpp.models.interfaces.Taint * The standard functions `memcpy`, `memmove` and `bcopy`; and the gcc variant * `__builtin___memcpy_chk`. */ -private class MemcpyFunction extends ArrayFunction, DataFlowFunction, SideEffectFunction { +private class MemcpyFunction extends ArrayFunction, DataFlowFunction, SideEffectFunction, + AliasFunction { MemcpyFunction() { // memcpy(dest, src, num) // memmove(dest, src, num) // memmove(dest, src, num, remaining) - this.hasName(["memcpy", "memmove", "__builtin___memcpy_chk"]) + this.hasGlobalOrStdOrBslName(["memcpy", "memmove"]) or // bcopy(src, dest, num) - this.hasGlobalOrStdName("bcopy") + // mempcpy(dest, src, num) + // memccpy(dest, src, c, n) + this.hasGlobalName(["bcopy", mempcpy(), "memccpy", "__builtin___memcpy_chk"]) } /** * Gets the index of the parameter that is the source buffer for the copy. */ - int getParamSrc() { if this.hasGlobalOrStdName("bcopy") then result = 0 else result = 1 } + int getParamSrc() { if this.hasGlobalName("bcopy") then result = 0 else result = 1 } /** * Gets the index of the parameter that is the destination buffer for the * copy. */ - int getParamDest() { if this.hasGlobalOrStdName("bcopy") then result = 1 else result = 0 } + int getParamDest() { if this.hasGlobalName("bcopy") then result = 1 else result = 0 } /** * Gets the index of the parameter that is the size of the copy (in bytes). */ - int getParamSize() { result = 2 } + int getParamSize() { if this.hasGlobalName("memccpy") then result = 3 else result = 2 } override predicate hasArrayInput(int bufParam) { bufParam = getParamSrc() } @@ -68,7 +72,10 @@ private class MemcpyFunction extends ArrayFunction, DataFlowFunction, SideEffect override predicate hasOnlySpecificWriteSideEffects() { any() } override predicate hasSpecificWriteSideEffect(ParameterIndex i, boolean buffer, boolean mustWrite) { - i = getParamDest() and buffer = true and mustWrite = true + i = getParamDest() and + buffer = true and + // memccpy only writes until a given character `c` is found + (if this.hasGlobalName("memccpy") then mustWrite = false else mustWrite = true) } override predicate hasSpecificReadSideEffect(ParameterIndex i, boolean buffer) { @@ -82,4 +89,21 @@ private class MemcpyFunction extends ArrayFunction, DataFlowFunction, SideEffect i = getParamSrc() ) } + + override predicate parameterNeverEscapes(int index) { + index = getParamSrc() + or + this.hasGlobalName("bcopy") and index = getParamDest() + } + + override predicate parameterEscapesOnlyViaReturn(int index) { + not this.hasGlobalName("bcopy") and index = getParamDest() + } + + override predicate parameterIsAlwaysReturned(int index) { + not this.hasGlobalName(["bcopy", mempcpy(), "memccpy"]) and + index = getParamDest() + } } + +private string mempcpy() { result = ["mempcpy", "wmempcpy"] } diff --git a/cpp/ql/src/semmle/code/cpp/models/implementations/Memset.qll b/cpp/ql/src/semmle/code/cpp/models/implementations/Memset.qll index 0436fbeead9..d646be0363d 100644 --- a/cpp/ql/src/semmle/code/cpp/models/implementations/Memset.qll +++ b/cpp/ql/src/semmle/code/cpp/models/implementations/Memset.qll @@ -15,13 +15,11 @@ import semmle.code.cpp.models.interfaces.SideEffect private class MemsetFunction extends ArrayFunction, DataFlowFunction, AliasFunction, SideEffectFunction { MemsetFunction() { - hasGlobalName("memset") or - hasGlobalName("wmemset") or - hasGlobalName("bzero") or - hasGlobalName("__builtin_memset") or - hasGlobalName("__builtin_memset_chk") or - hasQualifiedName("std", "memset") or - hasQualifiedName("std", "wmemset") + this.hasGlobalOrStdOrBslName("memset") + or + this.hasGlobalOrStdName("wmemset") + or + this.hasGlobalName([bzero(), "__builtin_memset", "__builtin_memset_chk"]) } override predicate hasArrayOutput(int bufParam) { bufParam = 0 } @@ -33,17 +31,17 @@ private class MemsetFunction extends ArrayFunction, DataFlowFunction, AliasFunct override predicate hasArrayWithVariableSize(int bufParam, int countParam) { bufParam = 0 and - (if hasGlobalName("bzero") then countParam = 1 else countParam = 2) + (if hasGlobalName(bzero()) then countParam = 1 else countParam = 2) } - override predicate parameterNeverEscapes(int index) { hasGlobalName("bzero") and index = 0 } + override predicate parameterNeverEscapes(int index) { hasGlobalName(bzero()) and index = 0 } override predicate parameterEscapesOnlyViaReturn(int index) { - not hasGlobalName("bzero") and index = 0 + not hasGlobalName(bzero()) and index = 0 } override predicate parameterIsAlwaysReturned(int index) { - not hasGlobalName("bzero") and index = 0 + not hasGlobalName(bzero()) and index = 0 } override predicate hasOnlySpecificReadSideEffects() { any() } @@ -56,6 +54,8 @@ private class MemsetFunction extends ArrayFunction, DataFlowFunction, AliasFunct override ParameterIndex getParameterSizeIndex(ParameterIndex i) { i = 0 and - if hasGlobalName("bzero") then result = 1 else result = 2 + if hasGlobalName(bzero()) then result = 1 else result = 2 } } + +private string bzero() { result = ["bzero", "explicit_bzero"] } diff --git a/cpp/ql/src/semmle/code/cpp/models/implementations/Printf.qll b/cpp/ql/src/semmle/code/cpp/models/implementations/Printf.qll index efa39849b14..ed201a14587 100644 --- a/cpp/ql/src/semmle/code/cpp/models/implementations/Printf.qll +++ b/cpp/ql/src/semmle/code/cpp/models/implementations/Printf.qll @@ -15,21 +15,15 @@ private class Printf extends FormattingFunction, AliasFunction { Printf() { this instanceof TopLevelFunction and ( - hasGlobalOrStdName("printf") or - hasGlobalName("printf_s") or - hasGlobalOrStdName("wprintf") or - hasGlobalName("wprintf_s") or - hasGlobalName("g_printf") + hasGlobalOrStdOrBslName(["printf", "wprintf"]) or + hasGlobalName(["printf_s", "wprintf_s", "g_printf"]) ) and not exists(getDefinition().getFile().getRelativePath()) } override int getFormatParameterIndex() { result = 0 } - deprecated override predicate isWideCharDefault() { - hasGlobalOrStdName("wprintf") or - hasGlobalName("wprintf_s") - } + deprecated override predicate isWideCharDefault() { hasName(["wprintf", "wprintf_s"]) } override predicate isOutputGlobal() { any() } @@ -47,8 +41,7 @@ private class Fprintf extends FormattingFunction { Fprintf() { this instanceof TopLevelFunction and ( - hasGlobalOrStdName("fprintf") or - hasGlobalOrStdName("fwprintf") or + hasGlobalOrStdOrBslName(["fprintf", "fwprintf"]) or hasGlobalName("g_fprintf") ) and not exists(getDefinition().getFile().getRelativePath()) @@ -56,7 +49,7 @@ private class Fprintf extends FormattingFunction { override int getFormatParameterIndex() { result = 1 } - deprecated override predicate isWideCharDefault() { hasGlobalOrStdName("fwprintf") } + deprecated override predicate isWideCharDefault() { hasName("fwprintf") } override int getOutputParameterIndex(boolean isStream) { result = 0 and isStream = true } } @@ -68,26 +61,18 @@ private class Sprintf extends FormattingFunction { Sprintf() { this instanceof TopLevelFunction and ( - // sprintf(dst, format, args...) - hasGlobalOrStdName("sprintf") + hasGlobalOrStdOrBslName([ + "sprintf", // sprintf(dst, format, args...) + "wsprintf" // wsprintf(dst, format, args...) + ]) or - // _sprintf_l(dst, format, locale, args...) - hasGlobalName("_sprintf_l") - or - // __swprintf_l(dst, format, locale, args...) - hasGlobalName("__swprintf_l") - or - // wsprintf(dst, format, args...) - hasGlobalOrStdName("wsprintf") - or - // g_strdup_printf(format, ...) - hasGlobalName("g_strdup_printf") - or - // g_sprintf(dst, format, ...) - hasGlobalName("g_sprintf") - or - // __builtin___sprintf_chk(dst, flag, os, format, ...) - hasGlobalName("__builtin___sprintf_chk") + hasGlobalName([ + "_sprintf_l", // _sprintf_l(dst, format, locale, args...) + "__swprintf_l", // __swprintf_l(dst, format, locale, args...) + "g_strdup_printf", // g_strdup_printf(format, ...) + "g_sprintf", // g_sprintf(dst, format, ...) + "__builtin___sprintf_chk" // __builtin___sprintf_chk(dst, flag, os, format, ...) + ]) ) and not exists(getDefinition().getFile().getRelativePath()) } @@ -102,23 +87,20 @@ private class Sprintf extends FormattingFunction { } override int getFormatParameterIndex() { - hasGlobalName("g_strdup_printf") and result = 0 + hasName("g_strdup_printf") and result = 0 or - hasGlobalName("__builtin___sprintf_chk") and result = 3 + hasName("__builtin___sprintf_chk") and result = 3 or - getName() != "g_strdup_printf" and - getName() != "__builtin___sprintf_chk" and + not getName() = ["g_strdup_printf", "__builtin___sprintf_chk"] and result = 1 } override int getOutputParameterIndex(boolean isStream) { - not hasGlobalName("g_strdup_printf") and result = 0 and isStream = false + not hasName("g_strdup_printf") and result = 0 and isStream = false } override int getFirstFormatArgumentIndex() { - if hasGlobalName("__builtin___sprintf_chk") - then result = 4 - else result = getNumberOfParameters() + if hasName("__builtin___sprintf_chk") then result = 4 else result = getNumberOfParameters() } } @@ -129,26 +111,18 @@ private class SnprintfImpl extends Snprintf { SnprintfImpl() { this instanceof TopLevelFunction and ( - hasGlobalOrStdName("snprintf") or // C99 defines snprintf - hasGlobalOrStdName("swprintf") or // The s version of wide-char printf is also always the n version + hasGlobalOrStdOrBslName([ + "snprintf", // C99 defines snprintf + "swprintf" // The s version of wide-char printf is also always the n version + ]) + or // Microsoft has _snprintf as well as several other variations - hasGlobalName("sprintf_s") or - hasGlobalName("snprintf_s") or - hasGlobalName("swprintf_s") or - hasGlobalName("_snprintf") or - hasGlobalName("_snprintf_s") or - hasGlobalName("_snprintf_l") or - hasGlobalName("_snprintf_s_l") or - hasGlobalName("_snwprintf") or - hasGlobalName("_snwprintf_s") or - hasGlobalName("_snwprintf_l") or - hasGlobalName("_snwprintf_s_l") or - hasGlobalName("_sprintf_s_l") or - hasGlobalName("_swprintf_l") or - hasGlobalName("_swprintf_s_l") or - hasGlobalName("g_snprintf") or - hasGlobalName("wnsprintf") or - hasGlobalName("__builtin___snprintf_chk") + hasGlobalName([ + "sprintf_s", "snprintf_s", "swprintf_s", "_snprintf", "_snprintf_s", "_snprintf_l", + "_snprintf_s_l", "_snwprintf", "_snwprintf_s", "_snwprintf_l", "_snwprintf_s_l", + "_sprintf_s_l", "_swprintf_l", "_swprintf_s_l", "g_snprintf", "wnsprintf", + "__builtin___snprintf_chk" + ]) ) and not exists(getDefinition().getFile().getRelativePath()) } @@ -184,12 +158,7 @@ private class SnprintfImpl extends Snprintf { } override predicate returnsFullFormatLength() { - ( - hasGlobalOrStdName("snprintf") or - hasGlobalName("g_snprintf") or - hasGlobalName("__builtin___snprintf_chk") or - hasGlobalName("snprintf_s") - ) and + hasName(["snprintf", "g_snprintf", "__builtin___snprintf_chk", "snprintf_s"]) and not exists(getDefinition().getFile().getRelativePath()) } @@ -202,16 +171,10 @@ private class SnprintfImpl extends Snprintf { private class StringCchPrintf extends FormattingFunction { StringCchPrintf() { this instanceof TopLevelFunction and - ( - hasGlobalName("StringCchPrintf") or - hasGlobalName("StringCchPrintfEx") or - hasGlobalName("StringCchPrintf_l") or - hasGlobalName("StringCchPrintf_lEx") or - hasGlobalName("StringCbPrintf") or - hasGlobalName("StringCbPrintfEx") or - hasGlobalName("StringCbPrintf_l") or - hasGlobalName("StringCbPrintf_lEx") - ) and + hasGlobalName([ + "StringCchPrintf", "StringCchPrintfEx", "StringCchPrintf_l", "StringCchPrintf_lEx", + "StringCbPrintf", "StringCbPrintfEx", "StringCbPrintf_l", "StringCbPrintf_lEx" + ]) and not exists(getDefinition().getFile().getRelativePath()) } diff --git a/cpp/ql/src/semmle/code/cpp/models/implementations/Pure.qll b/cpp/ql/src/semmle/code/cpp/models/implementations/Pure.qll index 42021c48953..d81ac80deb8 100644 --- a/cpp/ql/src/semmle/code/cpp/models/implementations/Pure.qll +++ b/cpp/ql/src/semmle/code/cpp/models/implementations/Pure.qll @@ -7,10 +7,9 @@ import semmle.code.cpp.models.interfaces.SideEffect private class PureStrFunction extends AliasFunction, ArrayFunction, TaintFunction, SideEffectFunction { PureStrFunction() { - hasGlobalOrStdName([ - "atof", "atoi", "atol", "atoll", "strcasestr", "strchnul", "strchr", "strchrnul", "strstr", - "strpbrk", "strcmp", "strcspn", "strncmp", "strrchr", "strspn", "strtod", "strtof", - "strtol", "strtoll", "strtoq", "strtoul" + hasGlobalOrStdOrBslName([ + atoi(), "strcasestr", "strchnul", "strchr", "strchrnul", "strstr", "strpbrk", "strrchr", + "strspn", strtol(), strrev(), strcmp(), strlwr(), strupr() ]) } @@ -24,11 +23,16 @@ private class PureStrFunction extends AliasFunction, ArrayFunction, TaintFunctio override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { exists(ParameterIndex i | - input.isParameter(i) and - exists(getParameter(i)) - or - input.isParameterDeref(i) and - getParameter(i).getUnspecifiedType() instanceof PointerType + ( + input.isParameter(i) and + exists(getParameter(i)) + or + input.isParameterDeref(i) and + getParameter(i).getUnspecifiedType() instanceof PointerType + ) and + // Functions that end with _l also take a locale argument (always as the last argument), + // and we don't want taint from those arguments. + (not this.getName().matches("%\\_l") or exists(getParameter(i + 1))) ) and ( output.isReturnValueDeref() and @@ -60,10 +64,35 @@ private class PureStrFunction extends AliasFunction, ArrayFunction, TaintFunctio } } +private string atoi() { result = ["atof", "atoi", "atol", "atoll"] } + +private string strtol() { result = ["strtod", "strtof", "strtol", "strtoll", "strtoq", "strtoul"] } + +private string strlwr() { + result = ["_strlwr", "_wcslwr", "_mbslwr", "_strlwr_l", "_wcslwr_l", "_mbslwr_l"] +} + +private string strupr() { + result = ["_strupr", "_wcsupr", "_mbsupr", "_strupr_l", "_wcsupr_l", "_mbsupr_l"] +} + +private string strrev() { result = ["_strrev", "_wcsrev", "_mbsrev", "_mbsrev_l"] } + +private string strcmp() { + // NOTE: `strcoll` doesn't satisfy _all_ the definitions of purity: its behavior depends on + // `LC_COLLATE` (which is set by `setlocale`). Not sure this behavior worth including in the model, so + // for now we interpret the function as being pure. + result = + [ + "strcmp", "strcspn", "strncmp", "strcoll", "strverscmp", "_mbsnbcmp", "_mbsnbcmp_l", + "_stricmp" + ] +} + /** String standard `strlen` function, and related functions for computing string lengths. */ private class StrLenFunction extends AliasFunction, ArrayFunction, SideEffectFunction { StrLenFunction() { - hasGlobalOrStdName(["strlen", "strnlen", "wcslen"]) + hasGlobalOrStdOrBslName(["strlen", "strnlen", "wcslen"]) or hasGlobalName(["_mbslen", "_mbslen_l", "_mbstrlen", "_mbstrlen_l"]) } @@ -96,7 +125,7 @@ private class StrLenFunction extends AliasFunction, ArrayFunction, SideEffectFun /** Pure functions. */ private class PureFunction extends TaintFunction, SideEffectFunction { - PureFunction() { hasGlobalOrStdName(["abs", "labs"]) } + PureFunction() { hasGlobalOrStdOrBslName(["abs", "labs"]) } override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { exists(ParameterIndex i | @@ -114,7 +143,12 @@ private class PureFunction extends TaintFunction, SideEffectFunction { /** Pure raw-memory functions. */ private class PureMemFunction extends AliasFunction, ArrayFunction, TaintFunction, SideEffectFunction { - PureMemFunction() { hasGlobalOrStdName(["memchr", "memrchr", "rawmemchr", "memcmp", "memmem"]) } + PureMemFunction() { + hasGlobalOrStdOrBslName([ + "memchr", "__builtin_memchr", "memrchr", "rawmemchr", "memcmp", "__builtin_memcmp", "memmem" + ]) or + this.hasGlobalName("memfrob") + } override predicate hasArrayInput(int bufParam) { getParameter(bufParam).getUnspecifiedType() instanceof PointerType @@ -122,11 +156,15 @@ private class PureMemFunction extends AliasFunction, ArrayFunction, TaintFunctio override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { exists(ParameterIndex i | - input.isParameter(i) and - exists(getParameter(i)) - or - input.isParameterDeref(i) and - getParameter(i).getUnspecifiedType() instanceof PointerType + ( + input.isParameter(i) and + exists(getParameter(i)) + or + input.isParameterDeref(i) and + getParameter(i).getUnspecifiedType() instanceof PointerType + ) and + // `memfrob` should not have taint from the size argument. + (not this.hasGlobalName("memfrob") or i = 0) ) and ( output.isReturnValueDeref() and diff --git a/cpp/ql/src/semmle/code/cpp/models/implementations/Recv.qll b/cpp/ql/src/semmle/code/cpp/models/implementations/Recv.qll new file mode 100644 index 00000000000..691ba528f42 --- /dev/null +++ b/cpp/ql/src/semmle/code/cpp/models/implementations/Recv.qll @@ -0,0 +1,88 @@ +/** + * Provides implementation classes modeling `recv` and various similar + * functions. See `semmle.code.cpp.models.Models` for usage information. + */ + +import semmle.code.cpp.models.interfaces.Taint +import semmle.code.cpp.models.interfaces.ArrayFunction +import semmle.code.cpp.models.interfaces.Alias +import semmle.code.cpp.models.interfaces.FlowSource +import semmle.code.cpp.models.interfaces.SideEffect + +/** The function `recv` and its assorted variants */ +private class Recv extends AliasFunction, ArrayFunction, SideEffectFunction, + RemoteFlowSourceFunction { + Recv() { + this.hasGlobalName([ + "recv", // recv(socket, dest, len, flags) + "recvfrom", // recvfrom(socket, dest, len, flags, from, fromlen) + "recvmsg", // recvmsg(socket, msg, flags) + "read", // read(socket, dest, len) + "pread", // pread(socket, dest, len, offset) + "readv", // readv(socket, dest, len) + "preadv", // readv(socket, dest, len, offset) + "preadv2" // readv2(socket, dest, len, offset, flags) + ]) + } + + override predicate parameterNeverEscapes(int index) { + this.getParameter(index).getUnspecifiedType() instanceof PointerType + } + + override predicate parameterEscapesOnlyViaReturn(int index) { none() } + + override predicate parameterIsAlwaysReturned(int index) { none() } + + override predicate hasArrayWithVariableSize(int bufParam, int countParam) { + not this.hasGlobalName("recvmsg") and + bufParam = 1 and + countParam = 2 + } + + override predicate hasArrayInput(int bufParam) { this.hasGlobalName("recvfrom") and bufParam = 4 } + + override predicate hasArrayOutput(int bufParam) { + bufParam = 1 + or + this.hasGlobalName("recvfrom") and bufParam = 4 + } + + override predicate hasSpecificReadSideEffect(ParameterIndex i, boolean buffer) { + this.hasGlobalName("recvfrom") and + ( + i = 4 and buffer = true + or + i = 5 and buffer = false + ) + or + this.hasGlobalName("recvmsg") and + i = 1 and + buffer = true + } + + override ParameterIndex getParameterSizeIndex(ParameterIndex i) { i = 1 and result = 2 } + + override predicate hasSpecificWriteSideEffect(ParameterIndex i, boolean buffer, boolean mustWrite) { + i = 1 and buffer = true and mustWrite = false + or + this.hasGlobalName("recvfrom") and + ( + i = 4 and buffer = true and mustWrite = false + or + i = 5 and buffer = false and mustWrite = false + ) + } + + override predicate hasOnlySpecificReadSideEffects() { any() } + + override predicate hasOnlySpecificWriteSideEffects() { any() } + + override predicate hasRemoteFlowSource(FunctionOutput output, string description) { + ( + output.isParameterDeref(1) + or + this.hasGlobalName("recvfrom") and output.isParameterDeref([4, 5]) + ) and + description = "Buffer read by " + this.getName() + } +} diff --git a/cpp/ql/src/semmle/code/cpp/models/implementations/Send.qll b/cpp/ql/src/semmle/code/cpp/models/implementations/Send.qll new file mode 100644 index 00000000000..6086bc7748f --- /dev/null +++ b/cpp/ql/src/semmle/code/cpp/models/implementations/Send.qll @@ -0,0 +1,63 @@ +/** + * Provides implementation classes modeling `send` and various similar + * functions. See `semmle.code.cpp.models.Models` for usage information. + */ + +import semmle.code.cpp.models.interfaces.Taint +import semmle.code.cpp.models.interfaces.ArrayFunction +import semmle.code.cpp.models.interfaces.Alias +import semmle.code.cpp.models.interfaces.FlowSource +import semmle.code.cpp.models.interfaces.SideEffect + +/** The function `send` and its assorted variants */ +private class Send extends AliasFunction, ArrayFunction, SideEffectFunction, RemoteFlowSinkFunction { + Send() { + this.hasGlobalName([ + "send", // send(socket, buf, len, flags) + "sendto", // sendto(socket, buf, len, flags, to, tolen) + "sendmsg", // sendmsg(socket, msg, flags) + "write", // write(socket, buf, len) + "writev", // writev(socket, buf, len) + "pwritev", // pwritev(socket, buf, len, offset) + "pwritev2" // pwritev2(socket, buf, len, offset, flags) + ]) + } + + override predicate parameterNeverEscapes(int index) { + this.getParameter(index).getUnspecifiedType() instanceof PointerType + } + + override predicate parameterEscapesOnlyViaReturn(int index) { none() } + + override predicate parameterIsAlwaysReturned(int index) { none() } + + override predicate hasArrayWithVariableSize(int bufParam, int countParam) { + not this.hasGlobalName("sendmsg") and + bufParam = 1 and + countParam = 2 + } + + override predicate hasArrayInput(int bufParam) { bufParam = 1 } + + override predicate hasOnlySpecificReadSideEffects() { any() } + + override predicate hasOnlySpecificWriteSideEffects() { any() } + + override predicate hasSpecificWriteSideEffect(ParameterIndex i, boolean buffer, boolean mustWrite) { + none() + } + + override predicate hasSpecificReadSideEffect(ParameterIndex i, boolean buffer) { + i = 1 and buffer = true + or + this.hasGlobalName("sendto") and i = 4 and buffer = false + or + this.hasGlobalName("sendmsg") and i = 1 and buffer = true + } + + override ParameterIndex getParameterSizeIndex(ParameterIndex i) { i = 1 and result = 2 } + + override predicate hasRemoteFlowSink(FunctionInput input, string description) { + input.isParameterDeref(1) and description = "Buffer sent by " + this.getName() + } +} diff --git a/cpp/ql/src/semmle/code/cpp/models/implementations/SmartPointer.qll b/cpp/ql/src/semmle/code/cpp/models/implementations/SmartPointer.qll index b13b4a8801d..c6152624792 100644 --- a/cpp/ql/src/semmle/code/cpp/models/implementations/SmartPointer.qll +++ b/cpp/ql/src/semmle/code/cpp/models/implementations/SmartPointer.qll @@ -4,14 +4,14 @@ import semmle.code.cpp.models.interfaces.Taint * The `std::shared_ptr` and `std::unique_ptr` template classes. */ private class UniqueOrSharedPtr extends Class { - UniqueOrSharedPtr() { this.hasQualifiedName("std", ["shared_ptr", "unique_ptr"]) } + UniqueOrSharedPtr() { this.hasQualifiedName(["std", "bsl"], ["shared_ptr", "unique_ptr"]) } } /** * The `std::make_shared` and `std::make_unique` template functions. */ private class MakeUniqueOrShared extends TaintFunction { - MakeUniqueOrShared() { this.hasQualifiedName("std", ["make_shared", "make_unique"]) } + MakeUniqueOrShared() { this.hasQualifiedName(["bsl", "std"], ["make_shared", "make_unique"]) } override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { // Exclude the specializations of `std::make_shared` and `std::make_unique` that allocate arrays diff --git a/cpp/ql/src/semmle/code/cpp/models/implementations/Sscanf.qll b/cpp/ql/src/semmle/code/cpp/models/implementations/Sscanf.qll new file mode 100644 index 00000000000..b6120abf05a --- /dev/null +++ b/cpp/ql/src/semmle/code/cpp/models/implementations/Sscanf.qll @@ -0,0 +1,72 @@ +/** + * Provides implementation classes modeling `sscanf`, `fscanf` and various similar + * functions. See `semmle.code.cpp.models.Models` for usage information. + */ + +import semmle.code.cpp.Function +import semmle.code.cpp.commons.Scanf +import semmle.code.cpp.models.interfaces.ArrayFunction +import semmle.code.cpp.models.interfaces.Taint +import semmle.code.cpp.models.interfaces.Alias +import semmle.code.cpp.models.interfaces.SideEffect + +/** + * The standard function `sscanf`, `fscanf` and its assorted variants + */ +private class SscanfModel extends ArrayFunction, TaintFunction, AliasFunction, SideEffectFunction { + SscanfModel() { this instanceof Sscanf or this instanceof Fscanf or this instanceof Snscanf } + + override predicate hasArrayWithNullTerminator(int bufParam) { + bufParam = this.(ScanfFunction).getFormatParameterIndex() + or + not this instanceof Fscanf and + bufParam = this.(ScanfFunction).getInputParameterIndex() + } + + override predicate hasArrayInput(int bufParam) { hasArrayWithNullTerminator(bufParam) } + + private int getLengthParameterIndex() { result = this.(Snscanf).getInputLengthParameterIndex() } + + private int getLocaleParameterIndex() { + this.getName().matches("%\\_l") and + ( + if exists(getLengthParameterIndex()) + then result = getLengthParameterIndex() + 2 + else result = 2 + ) + } + + private int getArgsStartPosition() { result = this.getNumberOfParameters() } + + override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { + input.isParameterDeref(this.(ScanfFunction).getInputParameterIndex()) and + output.isParameterDeref(any(int i | i >= getArgsStartPosition())) + } + + override predicate parameterNeverEscapes(int index) { + index = [0 .. max(getACallToThisFunction().getNumberOfArguments())] + } + + override predicate parameterEscapesOnlyViaReturn(int index) { none() } + + override predicate parameterIsAlwaysReturned(int index) { none() } + + override predicate hasOnlySpecificReadSideEffects() { any() } + + override predicate hasOnlySpecificWriteSideEffects() { any() } + + override predicate hasSpecificWriteSideEffect(ParameterIndex i, boolean buffer, boolean mustWrite) { + i >= getArgsStartPosition() and + buffer = true and + mustWrite = true + } + + override predicate hasSpecificReadSideEffect(ParameterIndex i, boolean buffer) { + buffer = true and + i = + [ + this.(ScanfFunction).getInputParameterIndex(), + this.(ScanfFunction).getFormatParameterIndex(), getLocaleParameterIndex() + ] + } +} diff --git a/cpp/ql/src/semmle/code/cpp/models/implementations/StdContainer.qll b/cpp/ql/src/semmle/code/cpp/models/implementations/StdContainer.qll index e7abae4161f..367db1613fc 100644 --- a/cpp/ql/src/semmle/code/cpp/models/implementations/StdContainer.qll +++ b/cpp/ql/src/semmle/code/cpp/models/implementations/StdContainer.qll @@ -5,6 +5,41 @@ import semmle.code.cpp.models.interfaces.Taint import semmle.code.cpp.models.interfaces.Iterator +/** + * The `std::array` template class. + */ +private class Array extends Class { + Array() { this.hasQualifiedName(["std", "bsl"], "array") } +} + +/** + * The `std::deque` template class. + */ +private class Deque extends Class { + Deque() { this.hasQualifiedName(["std", "bsl"], "deque") } +} + +/** + * The `std::forward_list` template class. + */ +private class ForwardList extends Class { + ForwardList() { this.hasQualifiedName(["std", "bsl"], "forward_list") } +} + +/** + * The `std::list` template class. + */ +private class List extends Class { + List() { this.hasQualifiedName(["std", "bsl"], "list") } +} + +/** + * The `std::vector` template class. + */ +private class Vector extends Class { + Vector() { this.hasQualifiedName(["std", "bsl"], "vector") } +} + /** * Additional model for standard container constructors that reference the * value type of the container (that is, the `T` in `std::vector`). For @@ -15,7 +50,10 @@ import semmle.code.cpp.models.interfaces.Iterator */ private class StdSequenceContainerConstructor extends Constructor, TaintFunction { StdSequenceContainerConstructor() { - this.getDeclaringType().hasQualifiedName("std", ["vector", "deque", "list", "forward_list"]) + this.getDeclaringType() instanceof Vector or + this.getDeclaringType() instanceof Deque or + this.getDeclaringType() instanceof List or + this.getDeclaringType() instanceof ForwardList } /** @@ -50,7 +88,10 @@ private class StdSequenceContainerConstructor extends Constructor, TaintFunction * The standard container function `data`. */ private class StdSequenceContainerData extends TaintFunction { - StdSequenceContainerData() { this.hasQualifiedName("std", ["array", "vector"], "data") } + StdSequenceContainerData() { + this.getClassAndName("data") instanceof Array or + this.getClassAndName("data") instanceof Vector + } override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { // flow from container itself (qualifier) to return value @@ -69,10 +110,10 @@ private class StdSequenceContainerData extends TaintFunction { */ private class StdSequenceContainerPush extends TaintFunction { StdSequenceContainerPush() { - this.hasQualifiedName("std", "vector", "push_back") or - this.hasQualifiedName("std", "deque", ["push_back", "push_front"]) or - this.hasQualifiedName("std", "list", ["push_back", "push_front"]) or - this.hasQualifiedName("std", "forward_list", "push_front") + this.getClassAndName("push_back") instanceof Vector or + this.getClassAndName(["push_back", "push_front"]) instanceof Deque or + this.getClassAndName("push_front") instanceof ForwardList or + this.getClassAndName(["push_back", "push_front"]) instanceof List } override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { @@ -87,11 +128,11 @@ private class StdSequenceContainerPush extends TaintFunction { */ private class StdSequenceContainerFrontBack extends TaintFunction { StdSequenceContainerFrontBack() { - this.hasQualifiedName("std", "array", ["front", "back"]) or - this.hasQualifiedName("std", "vector", ["front", "back"]) or - this.hasQualifiedName("std", "deque", ["front", "back"]) or - this.hasQualifiedName("std", "list", ["front", "back"]) or - this.hasQualifiedName("std", "forward_list", "front") + this.getClassAndName(["front", "back"]) instanceof Array or + this.getClassAndName(["front", "back"]) instanceof Deque or + this.getClassAndName("front") instanceof ForwardList or + this.getClassAndName(["front", "back"]) instanceof List or + this.getClassAndName(["front", "back"]) instanceof Vector } override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { @@ -106,8 +147,10 @@ private class StdSequenceContainerFrontBack extends TaintFunction { */ private class StdSequenceContainerInsert extends TaintFunction { StdSequenceContainerInsert() { - this.hasQualifiedName("std", ["vector", "deque", "list"], "insert") or - this.hasQualifiedName("std", ["forward_list"], "insert_after") + this.getClassAndName("insert") instanceof Deque or + this.getClassAndName("insert") instanceof List or + this.getClassAndName("insert") instanceof Vector or + this.getClassAndName("insert_after") instanceof ForwardList } /** @@ -143,7 +186,10 @@ private class StdSequenceContainerInsert extends TaintFunction { */ private class StdSequenceContainerAssign extends TaintFunction { StdSequenceContainerAssign() { - this.hasQualifiedName("std", ["vector", "deque", "list", "forward_list"], "assign") + this.getClassAndName("assign") instanceof Deque or + this.getClassAndName("assign") instanceof ForwardList or + this.getClassAndName("assign") instanceof List or + this.getClassAndName("assign") instanceof Vector } /** @@ -170,30 +216,14 @@ private class StdSequenceContainerAssign extends TaintFunction { } } -/** - * The standard container `swap` functions. - */ -private class StdSequenceContainerSwap extends TaintFunction { - StdSequenceContainerSwap() { - this.hasQualifiedName("std", ["array", "vector", "deque", "list", "forward_list"], "swap") - } - - override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { - // container1.swap(container2) - input.isQualifierObject() and - output.isParameterDeref(0) - or - input.isParameterDeref(0) and - output.isQualifierObject() - } -} - /** * The standard container functions `at` and `operator[]`. */ private class StdSequenceContainerAt extends TaintFunction { StdSequenceContainerAt() { - this.hasQualifiedName("std", ["vector", "array", "deque"], ["at", "operator[]"]) + this.getClassAndName(["at", "operator[]"]) instanceof Array or + this.getClassAndName(["at", "operator[]"]) instanceof Deque or + this.getClassAndName(["at", "operator[]"]) instanceof Vector } override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { @@ -211,12 +241,12 @@ private class StdSequenceContainerAt extends TaintFunction { * The standard vector `emplace` function. */ class StdVectorEmplace extends TaintFunction { - StdVectorEmplace() { this.hasQualifiedName("std", "vector", "emplace") } + StdVectorEmplace() { this.getClassAndName("emplace") instanceof Vector } override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { // flow from any parameter except the position iterator to qualifier and return value // (here we assume taint flow from any constructor parameter to the constructed object) - input.isParameter([1 .. getNumberOfParameters() - 1]) and + input.isParameterDeref([1 .. getNumberOfParameters() - 1]) and ( output.isQualifierObject() or output.isReturnValue() @@ -228,12 +258,12 @@ class StdVectorEmplace extends TaintFunction { * The standard vector `emplace_back` function. */ class StdVectorEmplaceBack extends TaintFunction { - StdVectorEmplaceBack() { this.hasQualifiedName("std", "vector", "emplace_back") } + StdVectorEmplaceBack() { this.getClassAndName("emplace_back") instanceof Vector } override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { // flow from any parameter to qualifier // (here we assume taint flow from any constructor parameter to the constructed object) - input.isParameter([0 .. getNumberOfParameters() - 1]) and + input.isParameterDeref([0 .. getNumberOfParameters() - 1]) and output.isQualifierObject() } } diff --git a/cpp/ql/src/semmle/code/cpp/models/implementations/StdMap.qll b/cpp/ql/src/semmle/code/cpp/models/implementations/StdMap.qll index dc7f7f8dd11..aecd98981e8 100644 --- a/cpp/ql/src/semmle/code/cpp/models/implementations/StdMap.qll +++ b/cpp/ql/src/semmle/code/cpp/models/implementations/StdMap.qll @@ -5,14 +5,18 @@ import semmle.code.cpp.models.interfaces.Taint import semmle.code.cpp.models.interfaces.Iterator +/** + * The `std::map` and `std::unordered_map` template classes. + */ +private class MapOrUnorderedMap extends Class { + MapOrUnorderedMap() { this.hasQualifiedName(["std", "bsl"], ["map", "unordered_map"]) } +} + /** * Additional model for map constructors using iterator inputs. */ private class StdMapConstructor extends Constructor, TaintFunction { - StdMapConstructor() { - this.hasQualifiedName("std", "map", "map") or - this.hasQualifiedName("std", "unordered_map", "unordered_map") - } + StdMapConstructor() { this.getDeclaringType() instanceof MapOrUnorderedMap } /** * Gets the index of a parameter to this function that is an iterator. @@ -37,7 +41,7 @@ private class StdMapConstructor extends Constructor, TaintFunction { */ private class StdMapInsert extends TaintFunction { StdMapInsert() { - this.hasQualifiedName("std", ["map", "unordered_map"], ["insert", "insert_or_assign"]) + this.getClassAndName(["insert", "insert_or_assign"]) instanceof MapOrUnorderedMap } override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { @@ -55,9 +59,7 @@ private class StdMapInsert extends TaintFunction { * The standard map `emplace` and `emplace_hint` functions. */ private class StdMapEmplace extends TaintFunction { - StdMapEmplace() { - this.hasQualifiedName("std", ["map", "unordered_map"], ["emplace", "emplace_hint"]) - } + StdMapEmplace() { this.getClassAndName(["emplace", "emplace_hint"]) instanceof MapOrUnorderedMap } override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { // flow from the last parameter (which may be the value part used to @@ -79,7 +81,7 @@ private class StdMapEmplace extends TaintFunction { * The standard map `try_emplace` function. */ private class StdMapTryEmplace extends TaintFunction { - StdMapTryEmplace() { this.hasQualifiedName("std", ["map", "unordered_map"], "try_emplace") } + StdMapTryEmplace() { this.getClassAndName("try_emplace") instanceof MapOrUnorderedMap } override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { // flow from any parameter apart from the key to qualifier and return value @@ -102,27 +104,11 @@ private class StdMapTryEmplace extends TaintFunction { } } -/** - * The standard map `swap` function. - */ -private class StdMapSwap extends TaintFunction { - StdMapSwap() { this.hasQualifiedName("std", ["map", "unordered_map"], "swap") } - - override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { - // container1.swap(container2) - input.isQualifierObject() and - output.isParameterDeref(0) - or - input.isParameterDeref(0) and - output.isQualifierObject() - } -} - /** * The standard map `merge` function. */ private class StdMapMerge extends TaintFunction { - StdMapMerge() { this.hasQualifiedName("std", ["map", "unordered_map"], "merge") } + StdMapMerge() { this.getClassAndName("merge") instanceof MapOrUnorderedMap } override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { // container1.merge(container2) @@ -135,7 +121,7 @@ private class StdMapMerge extends TaintFunction { * The standard map functions `at` and `operator[]`. */ private class StdMapAt extends TaintFunction { - StdMapAt() { this.hasQualifiedName("std", ["map", "unordered_map"], ["at", "operator[]"]) } + StdMapAt() { this.getClassAndName(["at", "operator[]"]) instanceof MapOrUnorderedMap } override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { // flow from qualifier to referenced return value @@ -152,7 +138,7 @@ private class StdMapAt extends TaintFunction { * The standard map `find` function. */ private class StdMapFind extends TaintFunction { - StdMapFind() { this.hasQualifiedName("std", ["map", "unordered_map"], "find") } + StdMapFind() { this.getClassAndName("find") instanceof MapOrUnorderedMap } override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { input.isQualifierObject() and @@ -164,7 +150,7 @@ private class StdMapFind extends TaintFunction { * The standard map `erase` function. */ private class StdMapErase extends TaintFunction { - StdMapErase() { this.hasQualifiedName("std", ["map", "unordered_map"], "erase") } + StdMapErase() { this.getClassAndName("erase") instanceof MapOrUnorderedMap } override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { // flow from qualifier to iterator return value @@ -179,8 +165,7 @@ private class StdMapErase extends TaintFunction { */ private class StdMapEqualRange extends TaintFunction { StdMapEqualRange() { - this.hasQualifiedName("std", ["map", "unordered_map"], - ["lower_bound", "upper_bound", "equal_range"]) + this.getClassAndName(["lower_bound", "upper_bound", "equal_range"]) instanceof MapOrUnorderedMap } override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { diff --git a/cpp/ql/src/semmle/code/cpp/models/implementations/StdPair.qll b/cpp/ql/src/semmle/code/cpp/models/implementations/StdPair.qll index fbc8515b5ca..755f6a48520 100644 --- a/cpp/ql/src/semmle/code/cpp/models/implementations/StdPair.qll +++ b/cpp/ql/src/semmle/code/cpp/models/implementations/StdPair.qll @@ -7,10 +7,16 @@ import semmle.code.cpp.models.interfaces.Taint /** * An instantiation of `std::pair`. */ -class StdPairClass extends ClassTemplateInstantiation { - StdPairClass() { getTemplate().hasQualifiedName("std", "pair") } +private class StdPair extends ClassTemplateInstantiation { + StdPair() { this.hasQualifiedName(["std", "bsl"], "pair") } } +/** + * DEPRECATED: This is now called `StdPair` and is a private part of the + * library implementation. + */ +deprecated class StdPairClass = StdPair; + /** * Any of the single-parameter constructors of `std::pair` that takes a reference to an * instantiation of `std::pair`. These constructors allow conversion between pair types when the @@ -18,9 +24,9 @@ class StdPairClass extends ClassTemplateInstantiation { */ class StdPairCopyishConstructor extends Constructor, TaintFunction { StdPairCopyishConstructor() { - this.getDeclaringType() instanceof StdPairClass and + this.getDeclaringType() instanceof StdPair and this.getNumberOfParameters() = 1 and - this.getParameter(0).getUnspecifiedType().(ReferenceType).getBaseType() instanceof StdPairClass + this.getParameter(0).getUnspecifiedType().(ReferenceType).getBaseType() instanceof StdPair } override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { @@ -38,7 +44,7 @@ class StdPairCopyishConstructor extends Constructor, TaintFunction { * Additional model for `std::pair` constructors. */ private class StdPairConstructor extends Constructor, TaintFunction { - StdPairConstructor() { this.hasQualifiedName("std", "pair", "pair") } + StdPairConstructor() { this.getDeclaringType() instanceof StdPair } /** * Gets the index of a parameter to this function that is a reference to @@ -60,19 +66,3 @@ private class StdPairConstructor extends Constructor, TaintFunction { ) } } - -/** - * The standard pair `swap` function. - */ -private class StdPairSwap extends TaintFunction { - StdPairSwap() { this.hasQualifiedName("std", "pair", "swap") } - - override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { - // container1.swap(container2) - input.isQualifierObject() and - output.isParameterDeref(0) - or - input.isParameterDeref(0) and - output.isQualifierObject() - } -} diff --git a/cpp/ql/src/semmle/code/cpp/models/implementations/StdSet.qll b/cpp/ql/src/semmle/code/cpp/models/implementations/StdSet.qll index 846fce0fe8c..d2e9892abcb 100644 --- a/cpp/ql/src/semmle/code/cpp/models/implementations/StdSet.qll +++ b/cpp/ql/src/semmle/code/cpp/models/implementations/StdSet.qll @@ -5,14 +5,18 @@ import semmle.code.cpp.models.interfaces.Taint import semmle.code.cpp.models.interfaces.Iterator +/** + * An instantiation of `std::set` or `std::unordered_set`. + */ +private class StdSet extends ClassTemplateInstantiation { + StdSet() { this.hasQualifiedName(["std", "bsl"], ["set", "unordered_set"]) } +} + /** * Additional model for set constructors using iterator inputs. */ private class StdSetConstructor extends Constructor, TaintFunction { - StdSetConstructor() { - this.hasQualifiedName("std", "set", "set") or - this.hasQualifiedName("std", "unordered_set", "unordered_set") - } + StdSetConstructor() { this.getDeclaringType() instanceof StdSet } /** * Gets the index of a parameter to this function that is an iterator. @@ -36,7 +40,7 @@ private class StdSetConstructor extends Constructor, TaintFunction { * The standard set `insert` and `insert_or_assign` functions. */ private class StdSetInsert extends TaintFunction { - StdSetInsert() { this.hasQualifiedName("std", ["set", "unordered_set"], "insert") } + StdSetInsert() { this.getClassAndName("insert") instanceof StdSet } override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { // flow from last parameter to qualifier and return value @@ -53,9 +57,7 @@ private class StdSetInsert extends TaintFunction { * The standard set `emplace` and `emplace_hint` functions. */ private class StdSetEmplace extends TaintFunction { - StdSetEmplace() { - this.hasQualifiedName("std", ["set", "unordered_set"], ["emplace", "emplace_hint"]) - } + StdSetEmplace() { this.getClassAndName(["emplace", "emplace_hint"]) instanceof StdSet } override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { // flow from any parameter to qualifier and return value @@ -72,27 +74,11 @@ private class StdSetEmplace extends TaintFunction { } } -/** - * The standard set `swap` functions. - */ -private class StdSetSwap extends TaintFunction { - StdSetSwap() { this.hasQualifiedName("std", ["set", "unordered_set"], "swap") } - - override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { - // container1.swap(container2) - input.isQualifierObject() and - output.isParameterDeref(0) - or - input.isParameterDeref(0) and - output.isQualifierObject() - } -} - /** * The standard set `merge` function. */ private class StdSetMerge extends TaintFunction { - StdSetMerge() { this.hasQualifiedName("std", ["set", "unordered_set"], "merge") } + StdSetMerge() { this.getClassAndName("merge") instanceof StdSet } override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { // container1.merge(container2) @@ -105,7 +91,7 @@ private class StdSetMerge extends TaintFunction { * The standard set `find` function. */ private class StdSetFind extends TaintFunction { - StdSetFind() { this.hasQualifiedName("std", ["set", "unordered_set"], "find") } + StdSetFind() { this.getClassAndName("find") instanceof StdSet } override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { input.isQualifierObject() and @@ -117,7 +103,7 @@ private class StdSetFind extends TaintFunction { * The standard set `erase` function. */ private class StdSetErase extends TaintFunction { - StdSetErase() { this.hasQualifiedName("std", ["set", "unordered_set"], "erase") } + StdSetErase() { this.getClassAndName("erase") instanceof StdSet } override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { // flow from qualifier to iterator return value @@ -132,8 +118,7 @@ private class StdSetErase extends TaintFunction { */ private class StdSetEqualRange extends TaintFunction { StdSetEqualRange() { - this.hasQualifiedName("std", ["set", "unordered_set"], - ["lower_bound", "upper_bound", "equal_range"]) + this.getClassAndName(["lower_bound", "upper_bound", "equal_range"]) instanceof StdSet } override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { diff --git a/cpp/ql/src/semmle/code/cpp/models/implementations/StdString.qll b/cpp/ql/src/semmle/code/cpp/models/implementations/StdString.qll index 1e52a5ea6bd..73a0f6edf26 100644 --- a/cpp/ql/src/semmle/code/cpp/models/implementations/StdString.qll +++ b/cpp/ql/src/semmle/code/cpp/models/implementations/StdString.qll @@ -9,10 +9,10 @@ import semmle.code.cpp.models.interfaces.Iterator import semmle.code.cpp.models.interfaces.DataFlow /** - * The `std::basic_string` template class. + * The `std::basic_string` template class instantiations. */ -private class StdBasicString extends TemplateClass { - StdBasicString() { this.hasQualifiedName("std", "basic_string") } +private class StdBasicString extends ClassTemplateInstantiation { + StdBasicString() { this.hasQualifiedName(["std", "bsl"], "basic_string") } } /** @@ -24,7 +24,7 @@ private class StdBasicString extends TemplateClass { * ``` */ private class StdStringConstructor extends Constructor, TaintFunction { - StdStringConstructor() { this.getDeclaringType().hasQualifiedName("std", "basic_string") } + StdStringConstructor() { this.getDeclaringType() instanceof StdBasicString } /** * Gets the index of a parameter to this function that is a string (or @@ -69,7 +69,7 @@ private class StdStringConstructor extends Constructor, TaintFunction { * The `std::string` function `c_str`. */ private class StdStringCStr extends TaintFunction { - StdStringCStr() { this.hasQualifiedName("std", "basic_string", "c_str") } + StdStringCStr() { this.getClassAndName("c_str") instanceof StdBasicString } override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { // flow from string itself (qualifier) to return value @@ -82,7 +82,7 @@ private class StdStringCStr extends TaintFunction { * The `std::string` function `data`. */ private class StdStringData extends TaintFunction { - StdStringData() { this.hasQualifiedName("std", "basic_string", "data") } + StdStringData() { this.getClassAndName("data") instanceof StdBasicString } override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { // flow from string itself (qualifier) to return value @@ -100,7 +100,7 @@ private class StdStringData extends TaintFunction { * The `std::string` function `push_back`. */ private class StdStringPush extends TaintFunction { - StdStringPush() { this.hasQualifiedName("std", "basic_string", "push_back") } + StdStringPush() { this.getClassAndName("push_back") instanceof StdBasicString } override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { // flow from parameter to qualifier @@ -113,7 +113,7 @@ private class StdStringPush extends TaintFunction { * The `std::string` functions `front` and `back`. */ private class StdStringFrontBack extends TaintFunction { - StdStringFrontBack() { this.hasQualifiedName("std", "basic_string", ["front", "back"]) } + StdStringFrontBack() { this.getClassAndName(["front", "back"]) instanceof StdBasicString } override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { // flow from object to returned reference @@ -123,12 +123,12 @@ private class StdStringFrontBack extends TaintFunction { } /** - * The `std::string` function `operator+`. + * The (non-member) `std::string` function `operator+`. */ private class StdStringPlus extends TaintFunction { StdStringPlus() { - this.hasQualifiedName("std", "operator+") and - this.getUnspecifiedType() = any(StdBasicString s).getAnInstantiation() + this.hasQualifiedName(["std", "bsl"], "operator+") and + this.getUnspecifiedType() instanceof StdBasicString } override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { @@ -148,7 +148,7 @@ private class StdStringPlus extends TaintFunction { */ private class StdStringAppend extends TaintFunction { StdStringAppend() { - this.hasQualifiedName("std", "basic_string", ["operator+=", "append", "insert", "replace"]) + this.getClassAndName(["operator+=", "append", "insert", "replace"]) instanceof StdBasicString } /** @@ -190,7 +190,7 @@ private class StdStringAppend extends TaintFunction { * The standard function `std::string.assign`. */ private class StdStringAssign extends TaintFunction { - StdStringAssign() { this.hasQualifiedName("std", "basic_string", "assign") } + StdStringAssign() { this.getClassAndName("assign") instanceof StdBasicString } /** * Gets the index of a parameter to this function that is a string (or @@ -230,7 +230,7 @@ private class StdStringAssign extends TaintFunction { * The standard function `std::string.copy`. */ private class StdStringCopy extends TaintFunction { - StdStringCopy() { this.hasQualifiedName("std", "basic_string", "copy") } + StdStringCopy() { this.getClassAndName("copy") instanceof StdBasicString } override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { // copy(dest, num, pos) @@ -243,7 +243,7 @@ private class StdStringCopy extends TaintFunction { * The standard function `std::string.substr`. */ private class StdStringSubstr extends TaintFunction { - StdStringSubstr() { this.hasQualifiedName("std", "basic_string", "substr") } + StdStringSubstr() { this.getClassAndName("substr") instanceof StdBasicString } override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { // substr(pos, num) @@ -252,30 +252,11 @@ private class StdStringSubstr extends TaintFunction { } } -/** - * The standard functions `std::string.swap` and `std::stringstream::swap`. - */ -private class StdStringSwap extends TaintFunction { - StdStringSwap() { - this.hasQualifiedName("std", "basic_string", "swap") or - this.hasQualifiedName("std", "basic_stringstream", "swap") - } - - override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { - // str1.swap(str2) - input.isQualifierObject() and - output.isParameterDeref(0) - or - input.isParameterDeref(0) and - output.isQualifierObject() - } -} - /** * The `std::string` functions `at` and `operator[]`. */ private class StdStringAt extends TaintFunction { - StdStringAt() { this.hasQualifiedName("std", "basic_string", ["at", "operator[]"]) } + StdStringAt() { this.getClassAndName(["at", "operator[]"]) instanceof StdBasicString } override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { // flow from qualifier to referenced return value @@ -289,22 +270,25 @@ private class StdStringAt extends TaintFunction { } /** - * The `std::basic_istream` template class. + * The `std::basic_istream` template class instantiations. */ -private class StdBasicIStream extends TemplateClass { - StdBasicIStream() { this.hasQualifiedName("std", "basic_istream") } +private class StdBasicIStream extends ClassTemplateInstantiation { + StdBasicIStream() { this.hasQualifiedName(["std", "bsl"], "basic_istream") } } /** * The `std::istream` function `operator>>` (defined as a member function). */ private class StdIStreamIn extends DataFlowFunction, TaintFunction { - StdIStreamIn() { this.hasQualifiedName("std", "basic_istream", "operator>>") } + StdIStreamIn() { this.getClassAndName("operator>>") instanceof StdBasicIStream } override predicate hasDataFlow(FunctionInput input, FunctionOutput output) { // returns reference to `*this` input.isQualifierAddress() and output.isReturnValue() + or + input.isQualifierObject() and + output.isReturnValueDeref() } override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { @@ -323,15 +307,17 @@ private class StdIStreamIn extends DataFlowFunction, TaintFunction { */ private class StdIStreamInNonMember extends DataFlowFunction, TaintFunction { StdIStreamInNonMember() { - this.hasQualifiedName("std", "operator>>") and - this.getUnspecifiedType().(ReferenceType).getBaseType() = - any(StdBasicIStream s).getAnInstantiation() + this.hasQualifiedName(["std", "bsl"], "operator>>") and + this.getUnspecifiedType().(ReferenceType).getBaseType() instanceof StdBasicIStream } override predicate hasDataFlow(FunctionInput input, FunctionOutput output) { // flow from first parameter to return value input.isParameter(0) and output.isReturnValue() + or + input.isParameterDeref(0) and + output.isReturnValueDeref() } override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { @@ -350,7 +336,7 @@ private class StdIStreamInNonMember extends DataFlowFunction, TaintFunction { */ private class StdIStreamGet extends TaintFunction { StdIStreamGet() { - this.hasQualifiedName("std", "basic_istream", ["get", "peek"]) and + this.getClassAndName(["get", "peek"]) instanceof StdBasicIStream and this.getNumberOfParameters() = 0 } @@ -366,7 +352,7 @@ private class StdIStreamGet extends TaintFunction { */ private class StdIStreamRead extends DataFlowFunction, TaintFunction { StdIStreamRead() { - this.hasQualifiedName("std", "basic_istream", ["get", "read"]) and + this.getClassAndName(["get", "read"]) instanceof StdBasicIStream and this.getNumberOfParameters() > 0 } @@ -374,6 +360,9 @@ private class StdIStreamRead extends DataFlowFunction, TaintFunction { // returns reference to `*this` input.isQualifierAddress() and output.isReturnValue() + or + input.isQualifierObject() and + output.isReturnValueDeref() } override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { @@ -391,7 +380,7 @@ private class StdIStreamRead extends DataFlowFunction, TaintFunction { * The `std::istream` function `readsome`. */ private class StdIStreamReadSome extends TaintFunction { - StdIStreamReadSome() { this.hasQualifiedName("std", "basic_istream", "readsome") } + StdIStreamReadSome() { this.getClassAndName("readsome") instanceof StdBasicIStream } override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { // flow from qualifier to first parameter @@ -404,12 +393,15 @@ private class StdIStreamReadSome extends TaintFunction { * The `std::istream` function `putback`. */ private class StdIStreamPutBack extends DataFlowFunction, TaintFunction { - StdIStreamPutBack() { this.hasQualifiedName("std", "basic_istream", "putback") } + StdIStreamPutBack() { this.getClassAndName("putback") instanceof StdBasicIStream } override predicate hasDataFlow(FunctionInput input, FunctionOutput output) { // returns reference to `*this` input.isQualifierAddress() and output.isReturnValue() + or + input.isQualifierObject() and + output.isReturnValueDeref() } override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { @@ -437,12 +429,15 @@ private class StdIStreamPutBack extends DataFlowFunction, TaintFunction { * The `std::istream` function `getline`. */ private class StdIStreamGetLine extends DataFlowFunction, TaintFunction { - StdIStreamGetLine() { this.hasQualifiedName("std", "basic_istream", "getline") } + StdIStreamGetLine() { this.getClassAndName("getline") instanceof StdBasicIStream } override predicate hasDataFlow(FunctionInput input, FunctionOutput output) { // returns reference to `*this` input.isQualifierAddress() and output.isReturnValue() + or + input.isQualifierObject() and + output.isReturnValueDeref() } override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { @@ -460,12 +455,15 @@ private class StdIStreamGetLine extends DataFlowFunction, TaintFunction { * The (non-member) function `std::getline`. */ private class StdGetLine extends DataFlowFunction, TaintFunction { - StdGetLine() { this.hasQualifiedName("std", "getline") } + StdGetLine() { this.hasQualifiedName(["std", "bsl"], "getline") } override predicate hasDataFlow(FunctionInput input, FunctionOutput output) { // flow from first parameter to return value input.isParameter(0) and output.isReturnValue() + or + input.isParameterDeref(0) and + output.isReturnValueDeref() } override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { @@ -480,10 +478,10 @@ private class StdGetLine extends DataFlowFunction, TaintFunction { } /** - * The `std::basic_ostream` template class. + * The `std::basic_ostream` template class instantiations. */ -private class StdBasicOStream extends TemplateClass { - StdBasicOStream() { this.hasQualifiedName("std", "basic_ostream") } +private class StdBasicOStream extends ClassTemplateInstantiation { + StdBasicOStream() { this.hasQualifiedName(["std", "bsl"], "basic_ostream") } } /** @@ -491,12 +489,17 @@ private class StdBasicOStream extends TemplateClass { * `put` and `write`. */ private class StdOStreamOut extends DataFlowFunction, TaintFunction { - StdOStreamOut() { this.hasQualifiedName("std", "basic_ostream", ["operator<<", "put", "write"]) } + StdOStreamOut() { + this.getClassAndName(["operator<<", "put", "write"]) instanceof StdBasicOStream + } override predicate hasDataFlow(FunctionInput input, FunctionOutput output) { // returns reference to `*this` input.isQualifierAddress() and output.isReturnValue() + or + input.isQualifierObject() and + output.isReturnValueDeref() } override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { @@ -525,15 +528,17 @@ private class StdOStreamOut extends DataFlowFunction, TaintFunction { */ private class StdOStreamOutNonMember extends DataFlowFunction, TaintFunction { StdOStreamOutNonMember() { - this.hasQualifiedName("std", "operator<<") and - this.getUnspecifiedType().(ReferenceType).getBaseType() = - any(StdBasicOStream s).getAnInstantiation() + this.hasQualifiedName(["std", "bsl"], "operator<<") and + this.getUnspecifiedType().(ReferenceType).getBaseType() instanceof StdBasicOStream } override predicate hasDataFlow(FunctionInput input, FunctionOutput output) { // flow from first parameter to return value input.isParameter(0) and output.isReturnValue() + or + input.isParameterDeref(0) and + output.isReturnValueDeref() } override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { @@ -551,14 +556,19 @@ private class StdOStreamOutNonMember extends DataFlowFunction, TaintFunction { } } +/** + * The `std::basic_stringstream` template class instantiations. + */ +private class StdBasicStringStream extends ClassTemplateInstantiation { + StdBasicStringStream() { this.hasQualifiedName(["std", "bsl"], "basic_stringstream") } +} + /** * Additional model for `std::stringstream` constructors that take a string * input parameter. */ private class StdStringStreamConstructor extends Constructor, TaintFunction { - StdStringStreamConstructor() { - this.getDeclaringType().hasQualifiedName("std", "basic_stringstream") - } + StdStringStreamConstructor() { this.getDeclaringType() instanceof StdBasicStringStream } /** * Gets the index of a parameter to this function that is a string. @@ -582,7 +592,7 @@ private class StdStringStreamConstructor extends Constructor, TaintFunction { * The `std::stringstream` function `str`. */ private class StdStringStreamStr extends TaintFunction { - StdStringStreamStr() { this.hasQualifiedName("std", "basic_stringstream", "str") } + StdStringStreamStr() { this.getClassAndName("str") instanceof StdBasicStringStream } override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { // flow from qualifier to return value (if any) @@ -595,21 +605,33 @@ private class StdStringStreamStr extends TaintFunction { } } +/** + * The `std::basic_ios` template class instantiations. + */ +private class StdBasicIOS extends ClassTemplateInstantiation { + StdBasicIOS() { this.hasQualifiedName(["std", "bsl"], "basic_ios") } +} + /** * A `std::` stream function that does not require a model, except that it * returns a reference to `*this` and thus could be used in a chain. */ private class StdStreamFunction extends DataFlowFunction, TaintFunction { StdStreamFunction() { - this.hasQualifiedName("std", "basic_istream", ["ignore", "unget", "seekg"]) or - this.hasQualifiedName("std", "basic_ostream", ["seekp", "flush"]) or - this.hasQualifiedName("std", "basic_ios", "copyfmt") + this.getClassAndName(["ignore", "unget", "seekg"]) instanceof StdBasicIStream + or + this.getClassAndName(["seekp", "flush"]) instanceof StdBasicOStream + or + this.getClassAndName("copyfmt") instanceof StdBasicIOS } override predicate hasDataFlow(FunctionInput input, FunctionOutput output) { // returns reference to `*this` input.isQualifierAddress() and output.isReturnValue() + or + input.isQualifierObject() and + output.isReturnValueDeref() } override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { diff --git a/cpp/ql/src/semmle/code/cpp/models/implementations/Strcat.qll b/cpp/ql/src/semmle/code/cpp/models/implementations/Strcat.qll index 9acd5b32d4f..ee9af547582 100644 --- a/cpp/ql/src/semmle/code/cpp/models/implementations/Strcat.qll +++ b/cpp/ql/src/semmle/code/cpp/models/implementations/Strcat.qll @@ -13,15 +13,20 @@ import semmle.code.cpp.models.interfaces.SideEffect */ class StrcatFunction extends TaintFunction, DataFlowFunction, ArrayFunction, SideEffectFunction { StrcatFunction() { - exists(string name | name = getName() | - name = "strcat" or // strcat(dst, src) - name = "strncat" or // strncat(dst, src, max_amount) - name = "wcscat" or // wcscat(dst, src) - name = "_mbscat" or // _mbscat(dst, src) - name = "wcsncat" or // wcsncat(dst, src, max_amount) - name = "_mbsncat" or // _mbsncat(dst, src, max_amount) - name = "_mbsncat_l" // _mbsncat_l(dst, src, max_amount, locale) - ) + this.hasGlobalOrStdOrBslName([ + "strcat", // strcat(dst, src) + "strncat", // strncat(dst, src, max_amount) + "wcscat", // wcscat(dst, src) + "wcsncat" // wcsncat(dst, src, max_amount) + ]) + or + this.hasGlobalName([ + "_mbscat", // _mbscat(dst, src) + "_mbsncat", // _mbsncat(dst, src, max_amount) + "_mbsncat_l", // _mbsncat_l(dst, src, max_amount, locale) + "_mbsnbcat", // _mbsnbcat(dest, src, count) + "_mbsnbcat_l" // _mbsnbcat_l(dest, src, count, locale) + ]) } /** @@ -45,20 +50,13 @@ class StrcatFunction extends TaintFunction, DataFlowFunction, ArrayFunction, Sid } override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { - exists(string name | name = getName() | - ( - name = "strncat" or - name = "wcsncat" or - name = "_mbsncat" or - name = "_mbsncat_l" - ) and - input.isParameter(2) and - output.isParameterDeref(0) - or - name = "_mbsncat_l" and - input.isParameter(3) and - output.isParameterDeref(0) - ) + getName() = ["strncat", "wcsncat", "_mbsncat", "_mbsncat_l"] and + input.isParameter(2) and + output.isParameterDeref(0) + or + getName() = ["_mbsncat_l", "_mbsnbcat_l"] and + input.isParameter(3) and + output.isParameterDeref(0) or input.isParameterDeref(0) and output.isParameterDeref(0) diff --git a/cpp/ql/src/semmle/code/cpp/models/implementations/Strcpy.qll b/cpp/ql/src/semmle/code/cpp/models/implementations/Strcpy.qll index 061209d65b7..432fbf999ef 100644 --- a/cpp/ql/src/semmle/code/cpp/models/implementations/Strcpy.qll +++ b/cpp/ql/src/semmle/code/cpp/models/implementations/Strcpy.qll @@ -13,25 +13,36 @@ import semmle.code.cpp.models.interfaces.SideEffect */ class StrcpyFunction extends ArrayFunction, DataFlowFunction, TaintFunction, SideEffectFunction { StrcpyFunction() { - getName() = - [ + this.hasGlobalOrStdOrBslName([ "strcpy", // strcpy(dst, src) "wcscpy", // wcscpy(dst, src) - "_mbscpy", // _mbscpy(dst, src) "strncpy", // strncpy(dst, src, max_amount) - "_strncpy_l", // _strncpy_l(dst, src, max_amount, locale) "wcsncpy", // wcsncpy(dst, src, max_amount) + "strxfrm", // strxfrm(dest, src, max_amount) + "wcsxfrm" // wcsxfrm(dest, src, max_amount) + ]) + or + this.hasGlobalName([ + "_mbscpy", // _mbscpy(dst, src) + "_strncpy_l", // _strncpy_l(dst, src, max_amount, locale) "_wcsncpy_l", // _wcsncpy_l(dst, src, max_amount, locale) "_mbsncpy", // _mbsncpy(dst, src, max_amount) - "_mbsncpy_l" - ] // _mbsncpy_l(dst, src, max_amount, locale) + "_mbsncpy_l", // _mbsncpy_l(dst, src, max_amount, locale) + "_strxfrm_l", // _strxfrm_l(dest, src, max_amount, locale) + "wcsxfrm_l", // _strxfrm_l(dest, src, max_amount, locale) + "_mbsnbcpy", // _mbsnbcpy(dest, src, max_amount) + "stpcpy", // stpcpy(dest, src) + "stpncpy" // stpcpy(dest, src, max_amount) + ]) or - getName() = - [ - "strcpy_s", // strcpy_s(dst, max_amount, src) - "wcscpy_s", // wcscpy_s(dst, max_amount, src) - "_mbscpy_s" - ] and // _mbscpy_s(dst, max_amount, src) + ( + this.hasGlobalOrStdName([ + "strcpy_s", // strcpy_s(dst, max_amount, src) + "wcscpy_s" // wcscpy_s(dst, max_amount, src) + ]) + or + this.hasGlobalName("_mbscpy_s") // _mbscpy_s(dst, max_amount, src) + ) and // exclude the 2-parameter template versions // that find the size of a fixed size destination buffer. getNumberOfParameters() = 3 @@ -40,9 +51,7 @@ class StrcpyFunction extends ArrayFunction, DataFlowFunction, TaintFunction, Sid /** * Holds if this is one of the `strcpy_s` variants. */ - private predicate isSVariant() { - exists(string name | name = getName() | name.suffix(name.length() - 2) = "_s") - } + private predicate isSVariant() { getName().matches("%\\_s") } /** * Gets the index of the parameter that is the maximum size of the copy (in characters). @@ -50,10 +59,10 @@ class StrcpyFunction extends ArrayFunction, DataFlowFunction, TaintFunction, Sid int getParamSize() { if isSVariant() then result = 1 - else - if exists(getName().indexOf("ncpy")) - then result = 2 - else none() + else ( + getName().matches(["%ncpy%", "%nbcpy%", "%xfrm%"]) and + result = 2 + ) } /** diff --git a/cpp/ql/src/semmle/code/cpp/models/implementations/Strcrement.qll b/cpp/ql/src/semmle/code/cpp/models/implementations/Strcrement.qll new file mode 100644 index 00000000000..4c335c8581e --- /dev/null +++ b/cpp/ql/src/semmle/code/cpp/models/implementations/Strcrement.qll @@ -0,0 +1,49 @@ +/** + * Provides implementation classes modeling `_strinc`, `_strdec` and their variants. + * See `semmle.code.cpp.models.Models` for usage information. + */ + +import semmle.code.cpp.models.interfaces.ArrayFunction +import semmle.code.cpp.models.interfaces.Taint +import semmle.code.cpp.models.interfaces.SideEffect + +/** + * The function `_strinc`, `_strdec` and their variants. + */ +private class Strcrement extends ArrayFunction, TaintFunction, SideEffectFunction { + Strcrement() { + this.hasGlobalName([ + "_strinc", // _strinc(source, locale) + "_wcsinc", // _strinc(source, locale) + "_mbsinc", // _strinc(source) + "_mbsinc_l", // _strinc(source, locale) + "_strdec", // _strdec(start, source) + "_wcsdec", // _wcsdec(start, source) + "_mbsdec", // _mbsdec(start, source) + "_mbsdec_l" // _mbsdec_l(start, source, locale) + ]) + } + + override predicate hasArrayWithNullTerminator(int bufParam) { + // Match all parameters that are not locales. + this.getParameter(bufParam).getUnspecifiedType() instanceof PointerType + } + + override predicate hasArrayInput(int bufParam) { hasArrayWithNullTerminator(bufParam) } + + override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { + exists(int index | hasArrayInput(index) | + input.isParameter(index) and output.isReturnValue() + or + input.isParameterDeref(index) and output.isReturnValueDeref() + ) + } + + override predicate hasOnlySpecificReadSideEffects() { any() } + + override predicate hasOnlySpecificWriteSideEffects() { any() } + + override predicate hasSpecificReadSideEffect(ParameterIndex i, boolean buffer) { + hasArrayInput(i) and buffer = true + } +} diff --git a/cpp/ql/src/semmle/code/cpp/models/implementations/Strdup.qll b/cpp/ql/src/semmle/code/cpp/models/implementations/Strdup.qll index 7f71dfc0647..e2443b8151c 100644 --- a/cpp/ql/src/semmle/code/cpp/models/implementations/Strdup.qll +++ b/cpp/ql/src/semmle/code/cpp/models/implementations/Strdup.qll @@ -13,25 +13,14 @@ import semmle.code.cpp.models.interfaces.Taint */ private class StrdupFunction extends AllocationFunction, ArrayFunction, DataFlowFunction { StrdupFunction() { - exists(string name | - hasGlobalName(name) and - ( - // strdup(str) - name = "strdup" - or - // wcsdup(str) - name = "wcsdup" - or - // _strdup(str) - name = "_strdup" - or - // _wcsdup(str) - name = "_wcsdup" - or - // _mbsdup(str) - name = "_mbsdup" - ) - ) + hasGlobalName([ + // --- C library allocation + "strdup", // strdup(str) + "wcsdup", // wcsdup(str) + "_strdup", // _strdup(str) + "_wcsdup", // _wcsdup(str) + "_mbsdup" // _mbsdup(str) + ]) } override predicate hasArrayInput(int bufParam) { bufParam = 0 } @@ -51,8 +40,8 @@ private class StrndupFunction extends AllocationFunction, ArrayFunction, DataFlo StrndupFunction() { exists(string name | hasGlobalName(name) and - // strndup(str, maxlen) - name = "strndup" + // --- C library allocation + name = "strndup" // strndup(str, maxlen) ) } diff --git a/cpp/ql/src/semmle/code/cpp/models/implementations/Strnextc.qll b/cpp/ql/src/semmle/code/cpp/models/implementations/Strnextc.qll new file mode 100644 index 00000000000..fc8ac17b5f6 --- /dev/null +++ b/cpp/ql/src/semmle/code/cpp/models/implementations/Strnextc.qll @@ -0,0 +1,38 @@ +/** + * Provides implementation classes modeling `strnextc` and various similar functions. + * See `semmle.code.cpp.models.Models` for usage information. + */ + +import semmle.code.cpp.models.interfaces.ArrayFunction +import semmle.code.cpp.models.interfaces.Taint +import semmle.code.cpp.models.interfaces.Alias +import semmle.code.cpp.models.interfaces.SideEffect + +/** + * The function `strnextc` and its variants. + */ +private class Strnextc extends TaintFunction, ArrayFunction, AliasFunction, SideEffectFunction { + Strnextc() { this.hasGlobalName(["_strnextc", "_wcsnextc", "_mbsnextc", "_mbsnextc_l"]) } + + override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { + input.isParameterDeref(0) and output.isReturnValue() + } + + override predicate hasArrayWithNullTerminator(int bufParam) { bufParam = 0 } + + override predicate hasArrayInput(int bufParam) { bufParam = 0 } + + override predicate parameterNeverEscapes(int index) { index = 0 } + + override predicate parameterEscapesOnlyViaReturn(int index) { none() } + + override predicate parameterIsAlwaysReturned(int index) { none() } + + override predicate hasOnlySpecificReadSideEffects() { any() } + + override predicate hasOnlySpecificWriteSideEffects() { any() } + + override predicate hasSpecificReadSideEffect(ParameterIndex i, boolean buffer) { + i = 0 and buffer = true + } +} diff --git a/cpp/ql/src/semmle/code/cpp/models/implementations/Strset.qll b/cpp/ql/src/semmle/code/cpp/models/implementations/Strset.qll new file mode 100644 index 00000000000..f4a80cbabac --- /dev/null +++ b/cpp/ql/src/semmle/code/cpp/models/implementations/Strset.qll @@ -0,0 +1,62 @@ +/** + * Provides implementation classes modeling `strset` and various similar + * functions. See `semmle.code.cpp.models.Models` for usage information. + */ + +import semmle.code.cpp.Function +import semmle.code.cpp.models.interfaces.ArrayFunction +import semmle.code.cpp.models.interfaces.DataFlow +import semmle.code.cpp.models.interfaces.Alias +import semmle.code.cpp.models.interfaces.SideEffect + +/** + * The standard function `strset` and its assorted variants + */ +private class StrsetFunction extends ArrayFunction, DataFlowFunction, AliasFunction, + SideEffectFunction { + StrsetFunction() { + hasGlobalName([ + "strset", "_strset", "_strset_l", "_wcsset", "_wcsset_l", "_mbsset", "_mbsset_l", + "_mbsnbset", "_mbsnbset_l", "_strnset", "_strnset_l", "_wcsnset", "_wcsnset_l", "_mbsnset", + "_mbsnset_l" + ]) + } + + override predicate hasArrayWithNullTerminator(int bufParam) { bufParam = 0 } + + override predicate hasArrayInput(int bufParam) { bufParam = 0 } + + override predicate hasArrayOutput(int bufParam) { bufParam = 0 } + + override predicate hasDataFlow(FunctionInput input, FunctionOutput output) { + // flow from the character that overrides the string + input.isParameter(1) and + ( + output.isReturnValueDeref() + or + output.isParameterDeref(0) + ) + or + // flow from the input string to the output string + input.isParameter(0) and + output.isReturnValue() + } + + override predicate parameterNeverEscapes(int index) { none() } + + override predicate parameterEscapesOnlyViaReturn(int index) { index = 0 } + + override predicate parameterIsAlwaysReturned(int index) { index = 0 } + + override predicate hasOnlySpecificReadSideEffects() { any() } + + override predicate hasOnlySpecificWriteSideEffects() { any() } + + override predicate hasSpecificWriteSideEffect(ParameterIndex i, boolean buffer, boolean mustWrite) { + i = 0 and buffer = true and mustWrite = true + } + + override predicate hasSpecificReadSideEffect(ParameterIndex i, boolean buffer) { + i = 0 and buffer = true + } +} diff --git a/cpp/ql/src/semmle/code/cpp/models/implementations/Strtok.qll b/cpp/ql/src/semmle/code/cpp/models/implementations/Strtok.qll new file mode 100644 index 00000000000..f2cb6498819 --- /dev/null +++ b/cpp/ql/src/semmle/code/cpp/models/implementations/Strtok.qll @@ -0,0 +1,88 @@ +/** + * Provides implementation classes modeling `strtok` and various similar + * functions. See `semmle.code.cpp.models.Models` for usage information. + */ + +import semmle.code.cpp.Function +import semmle.code.cpp.models.interfaces.ArrayFunction +import semmle.code.cpp.models.interfaces.ArrayFunction +import semmle.code.cpp.models.interfaces.Alias +import semmle.code.cpp.models.interfaces.SideEffect +import semmle.code.cpp.models.interfaces.Taint + +/** + * The standard function `strtok` and its assorted variants + */ +private class Strtok extends ArrayFunction, AliasFunction, TaintFunction, SideEffectFunction { + Strtok() { + this.hasGlobalOrStdOrBslName("strtok") or + this.hasGlobalName(["strtok_r", "_strtok_l", "wcstok", "_wcstok_l", "_mbstok", "_mbstok_l"]) + } + + override predicate hasArrayWithNullTerminator(int bufParam) { bufParam = [0, 1] } + + override predicate hasArrayInput(int bufParam) { bufParam = [0, 1] } + + override predicate hasArrayOutput(int bufParam) { bufParam = 0 } + + override predicate parameterNeverEscapes(int index) { index = 1 } + + override predicate parameterEscapesOnlyViaReturn(int index) { index = 0 } + + override predicate parameterIsAlwaysReturned(int index) { none() } + + override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { + input.isParameter(0) and output.isReturnValue() + } + + override predicate hasOnlySpecificReadSideEffects() { none() } + + override predicate hasOnlySpecificWriteSideEffects() { none() } + + override predicate hasSpecificWriteSideEffect(ParameterIndex i, boolean buffer, boolean mustWrite) { + i = 0 and buffer = true and mustWrite = false + } + + override predicate hasSpecificReadSideEffect(ParameterIndex i, boolean buffer) { + i = [0, 1] and buffer = true + } +} + +/** + * The function `strtok` is a variant of `strtok` that takes a `char**` parameter instead of + * a `char*` as the first parameter. + */ +private class Strsep extends ArrayFunction, AliasFunction, TaintFunction, SideEffectFunction { + Strsep() { this.hasGlobalName("strsep") } + + override predicate hasArrayWithNullTerminator(int bufParam) { bufParam = 1 } + + override predicate hasArrayInput(int bufParam) { bufParam = 1 } + + override predicate parameterNeverEscapes(int index) { index = [0, 1] } + + override predicate parameterEscapesOnlyViaReturn(int index) { none() } + + override predicate parameterIsAlwaysReturned(int index) { none() } + + override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { + // NOTE: What we really want here is: (input.isParameterDerefDeref(0) or input.isParameterDeref(1)) + // as the first conjunct. + input.isParameterDeref([0, 1]) and + (output.isReturnValue() or output.isReturnValueDeref()) + } + + override predicate hasOnlySpecificReadSideEffects() { any() } + + override predicate hasOnlySpecificWriteSideEffects() { any() } + + override predicate hasSpecificWriteSideEffect(ParameterIndex i, boolean buffer, boolean mustWrite) { + i = 0 and buffer = false and mustWrite = false + } + + override predicate hasSpecificReadSideEffect(ParameterIndex i, boolean buffer) { + i = 0 and buffer = false + or + i = 1 and buffer = true + } +} diff --git a/cpp/ql/src/semmle/code/cpp/models/implementations/Swap.qll b/cpp/ql/src/semmle/code/cpp/models/implementations/Swap.qll index 9fb1f470022..b79f7afe5d9 100644 --- a/cpp/ql/src/semmle/code/cpp/models/implementations/Swap.qll +++ b/cpp/ql/src/semmle/code/cpp/models/implementations/Swap.qll @@ -1,11 +1,15 @@ import semmle.code.cpp.models.interfaces.DataFlow import semmle.code.cpp.models.interfaces.Taint +import semmle.code.cpp.models.interfaces.Alias /** - * The standard function `swap`. + * The standard function `swap`. A use of `swap` looks like this: + * ``` + * std::swap(obj1, obj2) + * ``` */ private class Swap extends DataFlowFunction { - Swap() { this.hasQualifiedName("std", "swap") } + Swap() { this.hasQualifiedName(["std", "bsl"], "swap") } override predicate hasDataFlow(FunctionInput input, FunctionOutput output) { input.isParameterDeref(0) and @@ -15,3 +19,32 @@ private class Swap extends DataFlowFunction { output.isParameterDeref(0) } } + +/** + * A `swap` member function that is used as follows: + * ``` + * obj1.swap(obj2) + * ``` + */ +private class MemberSwap extends TaintFunction, MemberFunction, AliasFunction { + MemberSwap() { + this.hasName("swap") and + this.getNumberOfParameters() = 1 and + this.getParameter(0).getType().(ReferenceType).getBaseType().getUnspecifiedType() = + getDeclaringType() + } + + override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { + input.isQualifierObject() and + output.isParameterDeref(0) + or + input.isParameterDeref(0) and + output.isQualifierObject() + } + + override predicate parameterNeverEscapes(int index) { none() } + + override predicate parameterEscapesOnlyViaReturn(int index) { index = 0 } + + override predicate parameterIsAlwaysReturned(int index) { index = 0 } +} diff --git a/cpp/ql/src/semmle/code/cpp/models/interfaces/Allocation.qll b/cpp/ql/src/semmle/code/cpp/models/interfaces/Allocation.qll index 65c677761cc..d309791f79a 100644 --- a/cpp/ql/src/semmle/code/cpp/models/interfaces/Allocation.qll +++ b/cpp/ql/src/semmle/code/cpp/models/interfaces/Allocation.qll @@ -93,16 +93,10 @@ abstract class AllocationExpr extends Expr { */ class OperatorNewAllocationFunction extends AllocationFunction { OperatorNewAllocationFunction() { - exists(string name | - hasGlobalName(name) and - ( - // operator new(bytes, ...) - name = "operator new" - or - // operator new[](bytes, ...) - name = "operator new[]" - ) - ) + hasGlobalName([ + "operator new", // operator new(bytes, ...) + "operator new[]" // operator new[](bytes, ...) + ]) } override int getSizeArg() { result = 0 } diff --git a/cpp/ql/src/semmle/code/cpp/models/interfaces/DataFlow.qll b/cpp/ql/src/semmle/code/cpp/models/interfaces/DataFlow.qll index c1b65d62706..b30861254dc 100644 --- a/cpp/ql/src/semmle/code/cpp/models/interfaces/DataFlow.qll +++ b/cpp/ql/src/semmle/code/cpp/models/interfaces/DataFlow.qll @@ -24,5 +24,6 @@ abstract class DataFlowFunction extends Function { * represented by `input` to the return value or buffer represented by * `output` */ + pragma[nomagic] abstract predicate hasDataFlow(FunctionInput input, FunctionOutput output); } diff --git a/cpp/ql/src/semmle/code/cpp/models/interfaces/Deallocation.qll b/cpp/ql/src/semmle/code/cpp/models/interfaces/Deallocation.qll index 501839de678..9c74102e99c 100644 --- a/cpp/ql/src/semmle/code/cpp/models/interfaces/Deallocation.qll +++ b/cpp/ql/src/semmle/code/cpp/models/interfaces/Deallocation.qll @@ -38,16 +38,10 @@ abstract class DeallocationExpr extends Expr { */ class OperatorDeleteDeallocationFunction extends DeallocationFunction { OperatorDeleteDeallocationFunction() { - exists(string name | - hasGlobalName(name) and - ( - // operator delete(pointer, ...) - name = "operator delete" - or - // operator delete[](pointer, ...) - name = "operator delete[]" - ) - ) + hasGlobalName([ + "operator delete", // operator delete(pointer, ...) + "operator delete[]" // operator delete[](pointer, ...) + ]) } override int getFreedArg() { result = 0 } diff --git a/cpp/ql/src/semmle/code/cpp/models/interfaces/FlowSource.qll b/cpp/ql/src/semmle/code/cpp/models/interfaces/FlowSource.qll index c0c95b38756..8c80377c8ec 100644 --- a/cpp/ql/src/semmle/code/cpp/models/interfaces/FlowSource.qll +++ b/cpp/ql/src/semmle/code/cpp/models/interfaces/FlowSource.qll @@ -1,9 +1,9 @@ /** - * Provides a class for modeling functions that return data from potentially untrusted sources. To use - * this QL library, create a QL class extending `DataFlowFunction` with a + * Provides classes for modeling functions that return data from (or send data to) potentially untrusted + * sources. To use this QL library, create a QL class extending `DataFlowFunction` with a * characteristic predicate that selects the function or set of functions you * are modeling. Within that class, override the predicates provided by - * `RemoteFlowFunction` to match the flow within that function. + * `RemoteFlowSourceFunction` or `RemoteFlowSinkFunction` to match the flow within that function. */ import cpp @@ -13,19 +13,42 @@ import semmle.code.cpp.models.Models /** * A library function that returns data that may be read from a network connection. */ -abstract class RemoteFlowFunction extends Function { +abstract class RemoteFlowSourceFunction extends Function { /** * Holds if remote data described by `description` flows from `output` of a call to this function. */ abstract predicate hasRemoteFlowSource(FunctionOutput output, string description); } +/** + * DEPRECATED: Use `RemoteFlowSourceFunction` instead. + * + * A library function that returns data that may be read from a network connection. + */ +deprecated class RemoteFlowFunction = RemoteFlowSourceFunction; + /** * A library function that returns data that is directly controlled by a user. */ -abstract class LocalFlowFunction extends Function { +abstract class LocalFlowSourceFunction extends Function { /** * Holds if data described by `description` flows from `output` of a call to this function. */ abstract predicate hasLocalFlowSource(FunctionOutput output, string description); } + +/** + * DEPRECATED: Use `LocalFlowSourceFunction` instead. + * + * A library function that returns data that is directly controlled by a user. + */ +deprecated class LocalFlowFunction = LocalFlowSourceFunction; + +/** A library function that sends data over a network connection. */ +abstract class RemoteFlowSinkFunction extends Function { + /** + * Holds if data described by `description` flows into `input` to a call to this function, and is then + * send over a network connection. + */ + abstract predicate hasRemoteFlowSink(FunctionInput input, string description); +} diff --git a/cpp/ql/src/semmle/code/cpp/models/interfaces/FunctionInputsAndOutputs.qll b/cpp/ql/src/semmle/code/cpp/models/interfaces/FunctionInputsAndOutputs.qll index 195cbcb63b5..4ab55ee5b3f 100644 --- a/cpp/ql/src/semmle/code/cpp/models/interfaces/FunctionInputsAndOutputs.qll +++ b/cpp/ql/src/semmle/code/cpp/models/interfaces/FunctionInputsAndOutputs.qll @@ -108,6 +108,16 @@ class FunctionInput extends TFunctionInput { */ predicate isQualifierAddress() { none() } + /** + * Holds if `i >= 0` and `isParameter(i)` holds for this value, or + * if `i = -1` and `isQualifierAddress()` holds for this value. + */ + final predicate isParameterOrQualifierAddress(ParameterIndex i) { + i >= 0 and this.isParameter(i) + or + i = -1 and this.isQualifierAddress() + } + /** * Holds if this is the input value pointed to by the return value of a * function, if the function returns a pointer, or the input value referred @@ -134,7 +144,7 @@ class FunctionInput extends TFunctionInput { predicate isReturnValueDeref() { none() } /** - * Holds if `i >= 0` and `isParameterDeref(i)` holds for this is value, or + * Holds if `i >= 0` and `isParameterDeref(i)` holds for this value, or * if `i = -1` and `isQualifierObject()` holds for this value. */ final predicate isParameterDerefOrQualifierObject(ParameterIndex i) { diff --git a/cpp/ql/src/semmle/code/cpp/models/interfaces/Taint.qll b/cpp/ql/src/semmle/code/cpp/models/interfaces/Taint.qll index fe617533f59..05a5d9f1c28 100644 --- a/cpp/ql/src/semmle/code/cpp/models/interfaces/Taint.qll +++ b/cpp/ql/src/semmle/code/cpp/models/interfaces/Taint.qll @@ -28,5 +28,6 @@ abstract class TaintFunction extends Function { * Holds if data passed into the argument, qualifier, or buffer represented by * `input` influences the return value or buffer represented by `output` */ + pragma[nomagic] abstract predicate hasTaintFlow(FunctionInput input, FunctionOutput output); } diff --git a/cpp/ql/src/semmle/code/cpp/security/BufferAccess.qll b/cpp/ql/src/semmle/code/cpp/security/BufferAccess.qll index 977e5fcb078..faeb859506d 100644 --- a/cpp/ql/src/semmle/code/cpp/security/BufferAccess.qll +++ b/cpp/ql/src/semmle/code/cpp/security/BufferAccess.qll @@ -42,13 +42,11 @@ abstract class BufferAccess extends Expr { */ class MemcpyBA extends BufferAccess { MemcpyBA() { - this.(FunctionCall).getTarget().getName() = "memcpy" or - this.(FunctionCall).getTarget().getName() = "wmemcpy" or - this.(FunctionCall).getTarget().getName() = "memmove" or - this.(FunctionCall).getTarget().getName() = "wmemmove" or - this.(FunctionCall).getTarget().getName() = "mempcpy" or - this.(FunctionCall).getTarget().getName() = "wmempcpy" or - this.(FunctionCall).getTarget().getName() = "RtlCopyMemoryNonTemporal" + this.(FunctionCall).getTarget().getName() = + [ + "memcpy", "wmemcpy", "memmove", "wmemmove", "mempcpy", "wmempcpy", + "RtlCopyMemoryNonTemporal" + ] } override string getName() { result = this.(FunctionCall).getTarget().getName() } @@ -157,10 +155,7 @@ class MemccpyBA extends BufferAccess { */ class MemcmpBA extends BufferAccess { MemcmpBA() { - this.(FunctionCall).getTarget().getName() = "memcmp" or - this.(FunctionCall).getTarget().getName() = "wmemcmp" or - this.(FunctionCall).getTarget().getName() = "_memicmp" or - this.(FunctionCall).getTarget().getName() = "_memicmp_l" + this.(FunctionCall).getTarget().getName() = ["memcmp", "wmemcmp", "_memicmp", "_memicmp_l"] } override string getName() { result = this.(FunctionCall).getTarget().getName() } @@ -188,10 +183,7 @@ class MemcmpBA extends BufferAccess { * _swab(src, dest, num) */ class SwabBA extends BufferAccess { - SwabBA() { - this.(FunctionCall).getTarget().getName() = "swab" or - this.(FunctionCall).getTarget().getName() = "_swab" - } + SwabBA() { this.(FunctionCall).getTarget().getName() = ["swab", "_swab"] } override string getName() { result = this.(FunctionCall).getTarget().getName() } @@ -218,10 +210,7 @@ class SwabBA extends BufferAccess { * wmemset(dest, value, num) */ class MemsetBA extends BufferAccess { - MemsetBA() { - this.(FunctionCall).getTarget().getName() = "memset" or - this.(FunctionCall).getTarget().getName() = "wmemset" - } + MemsetBA() { this.(FunctionCall).getTarget().getName() = ["memset", "wmemset"] } override string getName() { result = this.(FunctionCall).getTarget().getName() } @@ -262,10 +251,7 @@ class ZeroMemoryBA extends BufferAccess { * wmemchr(buffer, value, num) */ class MemchrBA extends BufferAccess { - MemchrBA() { - this.(FunctionCall).getTarget().getName() = "memchr" or - this.(FunctionCall).getTarget().getName() = "wmemchr" - } + MemchrBA() { this.(FunctionCall).getTarget().getName() = ["memchr", "wmemchr"] } override string getName() { result = this.(FunctionCall).getTarget().getName() } diff --git a/cpp/ql/src/semmle/code/cpp/security/CommandExecution.qll b/cpp/ql/src/semmle/code/cpp/security/CommandExecution.qll index 38187f2e0e6..d9bb701be58 100644 --- a/cpp/ql/src/semmle/code/cpp/security/CommandExecution.qll +++ b/cpp/ql/src/semmle/code/cpp/security/CommandExecution.qll @@ -168,17 +168,14 @@ class ArrayExecFunctionCall extends FunctionCall { * for testing purposes. */ predicate shellCommandPreface(string cmd, string flag) { - (cmd = "sh" or cmd = "/bin/sh" or cmd = "bash" or cmd = "/bin/bash") and + cmd = ["sh", "/bin/sh", "bash", "/bin/bash"] and flag = "-c" or - ( - cmd = "cmd" or - cmd = "cmd.exe" or - cmd = "CMD" or - cmd = "CMD.EXE" or - cmd = "%WINDIR%\\system32\\cmd.exe" // used in Juliet tests - ) and - (flag = "/c" or flag = "/C") + cmd = + [ + "cmd", "cmd.exe", "CMD", "CMD.EXE", "%WINDIR%\\system32\\cmd.exe" // used in Juliet tests + ] and + flag = ["/c", "/C"] } /** diff --git a/cpp/ql/src/semmle/code/cpp/security/Encryption.qll b/cpp/ql/src/semmle/code/cpp/security/Encryption.qll index d8b2d44c923..606242e833c 100644 --- a/cpp/ql/src/semmle/code/cpp/security/Encryption.qll +++ b/cpp/ql/src/semmle/code/cpp/security/Encryption.qll @@ -8,21 +8,17 @@ import cpp * Gets the name of an algorithm that is known to be insecure. */ string getAnInsecureAlgorithmName() { - result = "DES" or - result = "RC2" or - result = "RC4" or - result = "RC5" or - result = "ARCFOUR" // a variant of RC4 + result = + [ + "DES", "RC2", "RC4", "RC5", "ARCFOUR" // ARCFOUR is a variant of RC4 + ] } /** * Gets the name of a hash algorithm that is insecure if it is being used for * encryption (but it is hard to know when that is happening). */ -string getAnInsecureHashAlgorithmName() { - result = "SHA1" or - result = "MD5" -} +string getAnInsecureHashAlgorithmName() { result = ["SHA1", "MD5"] } /** * Gets the regular expression used for matching strings that look like they @@ -45,13 +41,7 @@ string getInsecureAlgorithmRegex() { * Gets the name of an algorithm that is known to be secure. */ string getASecureAlgorithmName() { - result = "RSA" or - result = "SHA256" or - result = "CCM" or - result = "GCM" or - result = "AES" or - result = "Blowfish" or - result = "ECIES" + result = ["RSA", "SHA256", "CCM", "GCM", "AES", "Blowfish", "ECIES"] } /** diff --git a/cpp/ql/src/semmle/code/cpp/security/FlowSources.qll b/cpp/ql/src/semmle/code/cpp/security/FlowSources.qll index c8bad67352b..b080651951f 100644 --- a/cpp/ql/src/semmle/code/cpp/security/FlowSources.qll +++ b/cpp/ql/src/semmle/code/cpp/security/FlowSources.qll @@ -23,7 +23,7 @@ private class RemoteReturnSource extends RemoteFlowSource { string sourceType; RemoteReturnSource() { - exists(RemoteFlowFunction func, CallInstruction instr, FunctionOutput output | + exists(RemoteFlowSourceFunction func, CallInstruction instr, FunctionOutput output | asInstruction() = instr and instr.getStaticCallTarget() = func and func.hasRemoteFlowSource(output, sourceType) and @@ -42,7 +42,7 @@ private class RemoteParameterSource extends RemoteFlowSource { string sourceType; RemoteParameterSource() { - exists(RemoteFlowFunction func, WriteSideEffectInstruction instr, FunctionOutput output | + exists(RemoteFlowSourceFunction func, WriteSideEffectInstruction instr, FunctionOutput output | asInstruction() = instr and instr.getPrimaryInstruction().(CallInstruction).getStaticCallTarget() = func and func.hasRemoteFlowSource(output, sourceType) and @@ -57,7 +57,7 @@ private class LocalReturnSource extends LocalFlowSource { string sourceType; LocalReturnSource() { - exists(LocalFlowFunction func, CallInstruction instr, FunctionOutput output | + exists(LocalFlowSourceFunction func, CallInstruction instr, FunctionOutput output | asInstruction() = instr and instr.getStaticCallTarget() = func and func.hasLocalFlowSource(output, sourceType) and @@ -76,7 +76,7 @@ private class LocalParameterSource extends LocalFlowSource { string sourceType; LocalParameterSource() { - exists(LocalFlowFunction func, WriteSideEffectInstruction instr, FunctionOutput output | + exists(LocalFlowSourceFunction func, WriteSideEffectInstruction instr, FunctionOutput output | asInstruction() = instr and instr.getPrimaryInstruction().(CallInstruction).getStaticCallTarget() = func and func.hasLocalFlowSource(output, sourceType) and @@ -98,3 +98,31 @@ private class ArgvSource extends LocalFlowSource { override string getSourceType() { result = "a command-line argument" } } + +/** A remote data flow sink. */ +abstract class RemoteFlowSink extends DataFlow::Node { + /** Gets a string that describes the type of this flow sink. */ + abstract string getSinkType(); +} + +private class RemoteParameterSink extends RemoteFlowSink { + string sourceType; + + RemoteParameterSink() { + exists(RemoteFlowSinkFunction func, FunctionInput input, CallInstruction call, int index | + func.hasRemoteFlowSink(input, sourceType) and call.getStaticCallTarget() = func + | + exists(ReadSideEffectInstruction read | + call = read.getPrimaryInstruction() and + read.getIndex() = index and + this.asOperand() = read.getSideEffectOperand() and + input.isParameterDerefOrQualifierObject(index) + ) + or + input.isParameterOrQualifierAddress(index) and + this.asOperand() = call.getArgumentOperand(index) + ) + } + + override string getSinkType() { result = sourceType } +} diff --git a/cpp/ql/src/semmle/code/cpp/security/Security.qll b/cpp/ql/src/semmle/code/cpp/security/Security.qll index c12a70b52c6..d39c13a25a0 100644 --- a/cpp/ql/src/semmle/code/cpp/security/Security.qll +++ b/cpp/ql/src/semmle/code/cpp/security/Security.qll @@ -6,6 +6,7 @@ import semmle.code.cpp.exprs.Expr import semmle.code.cpp.commons.Environment import semmle.code.cpp.security.SecurityOptions +import semmle.code.cpp.models.interfaces.FlowSource /** * Extend this class to customize the security queries for @@ -20,36 +21,13 @@ class SecurityOptions extends string { * name is a pure function of its arguments. */ predicate isPureFunction(string name) { - name = "abs" or - name = "atof" or - name = "atoi" or - name = "atol" or - name = "atoll" or - name = "labs" or - name = "strcasestr" or - name = "strcat" or - name = "strchnul" or - name = "strchr" or - name = "strchrnul" or - name = "strcmp" or - name = "strcpy" or - name = "strcspn" or - name = "strdup" or - name = "strlen" or - name = "strncat" or - name = "strncmp" or - name = "strncpy" or - name = "strndup" or - name = "strnlen" or - name = "strrchr" or - name = "strspn" or - name = "strstr" or - name = "strtod" or - name = "strtof" or - name = "strtol" or - name = "strtoll" or - name = "strtoq" or - name = "strtoul" + name = + [ + "abs", "atof", "atoi", "atol", "atoll", "labs", "strcasestr", "strcat", "strchnul", + "strchr", "strchrnul", "strcmp", "strcpy", "strcspn", "strdup", "strlen", "strncat", + "strncmp", "strncpy", "strndup", "strnlen", "strrchr", "strspn", "strstr", "strtod", + "strtof", "strtol", "strtoll", "strtoq", "strtoul" + ] } /** @@ -73,13 +51,7 @@ class SecurityOptions extends string { functionCall.getTarget().hasGlobalOrStdName(fname) and exists(functionCall.getArgument(arg)) and ( - fname = "fread" and arg = 0 - or - fname = "fgets" and arg = 0 - or - fname = "fgetws" and arg = 0 - or - fname = "gets" and arg = 0 + fname = ["fread", "fgets", "fgetws", "gets"] and arg = 0 or fname = "scanf" and arg >= 1 or @@ -88,18 +60,14 @@ class SecurityOptions extends string { or functionCall.getTarget().hasGlobalName(fname) and exists(functionCall.getArgument(arg)) and - ( - fname = "read" and arg = 1 - or - fname = "getaddrinfo" and arg = 3 - or - fname = "recv" and arg = 1 - or - fname = "recvfrom" and - (arg = 1 or arg = 4 or arg = 5) - or - fname = "recvmsg" and arg = 1 - ) + fname = "getaddrinfo" and + arg = 3 + ) + or + exists(RemoteFlowSourceFunction remote, FunctionOutput output | + functionCall.getTarget() = remote and + output.isParameterDerefOrQualifierObject(arg) and + remote.hasRemoteFlowSource(output, _) ) } @@ -110,11 +78,16 @@ class SecurityOptions extends string { exists(string fname | functionCall.getTarget().getName() = fname and ( - fname = "fgets" or - fname = "gets" or + fname = ["fgets", "gets"] or userInputReturn(fname) ) ) + or + exists(RemoteFlowSourceFunction remote, FunctionOutput output | + functionCall.getTarget() = remote and + (output.isReturnValue() or output.isReturnValueDeref()) and + remote.hasRemoteFlowSource(output, _) + ) } /** @@ -132,30 +105,12 @@ class SecurityOptions extends string { */ predicate isProcessOperationArgument(string function, int arg) { // POSIX - function = "system" and arg = 0 - or - function = "popen" and arg = 0 - or - function = "execl" and arg = 0 - or - function = "execlp" and arg = 0 - or - function = "execle" and arg = 0 - or - function = "execv" and arg = 0 - or - function = "execvp" and arg = 0 - or - function = "execvpe" and arg = 0 - or - function = "dlopen" and arg = 0 + function = + ["system", "popen", "execl", "execlp", "execle", "execv", "execvp", "execvpe", "dlopen"] and + arg = 0 or // Windows - function = "LoadLibrary" and arg = 0 - or - function = "LoadLibraryA" and arg = 0 - or - function = "LoadLibraryW" and arg = 0 + function = ["LoadLibrary", "LoadLibraryA", "LoadLibraryW"] and arg = 0 } /** diff --git a/cpp/ql/src/semmlecode.cpp.dbscheme b/cpp/ql/src/semmlecode.cpp.dbscheme index c82db4c596b..ddd31fd02e5 100644 --- a/cpp/ql/src/semmlecode.cpp.dbscheme +++ b/cpp/ql/src/semmlecode.cpp.dbscheme @@ -691,8 +691,28 @@ typedefbase( int type_id: @type ref ); +/** + * An instance of the C++11 `decltype` operator. For example: + * ``` + * int a; + * decltype(1+a) b; + * ``` + * Here `expr` is `1+a`. + * + * Sometimes an additional pair of parentheses around the expression + * would change the semantics of this decltype, e.g. + * ``` + * struct A { double x; }; + * const A* a = new A(); + * decltype( a->x ); // type is double + * decltype((a->x)); // type is const double& + * ``` + * (Please consult the C++11 standard for more details). + * `parentheses_would_change_meaning` is `true` iff that is the case. + */ +#keyset[id, expr] decltypes( - unique int id: @decltype, + int id: @decltype, int expr: @expr ref, int base_type: @type ref, boolean parentheses_would_change_meaning: boolean ref diff --git a/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-14/semmle/tests/CompilerRemovalOfCodeToClearBuffers.expected b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-14/semmle/tests/CompilerRemovalOfCodeToClearBuffers.expected new file mode 100644 index 00000000000..8d98d94ff46 --- /dev/null +++ b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-14/semmle/tests/CompilerRemovalOfCodeToClearBuffers.expected @@ -0,0 +1,3 @@ +| test.c:13:9:13:13 | buff1 | This variable will not be cleared. | +| test.c:35:9:35:13 | buff1 | This variable will not be cleared. | +| test.c:43:9:43:13 | buff1 | This variable will not be cleared. | diff --git a/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-14/semmle/tests/CompilerRemovalOfCodeToClearBuffers.qlref b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-14/semmle/tests/CompilerRemovalOfCodeToClearBuffers.qlref new file mode 100644 index 00000000000..61d2a29b126 --- /dev/null +++ b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-14/semmle/tests/CompilerRemovalOfCodeToClearBuffers.qlref @@ -0,0 +1 @@ +experimental/Security/CWE/CWE-14/CompilerRemovalOfCodeToClearBuffers.ql diff --git a/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-14/semmle/tests/test.c b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-14/semmle/tests/test.c new file mode 100644 index 00000000000..221072330c3 --- /dev/null +++ b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-14/semmle/tests/test.c @@ -0,0 +1,201 @@ +struct buffers +{ + unsigned char buff1[50]; + unsigned char *buff2; +} globalBuff1,*globalBuff2; + +unsigned char * globalBuff; +void badFunc0_0(){ + unsigned char buff1[12]; + int i; + for(i=0;i<12;i++) + buff1[i]=13; + memset(buff1,12,12); +} +void nobadFunc0_0(){ + unsigned char buff1[12]; + memset(buff1,12,12); +} +void nobadFunc0_1(){ + unsigned char buff1[12]; + int i; + memset(buff1,12,12); + for(i=0;i<12;i++) + buff1[i]=13; + free(buff1); +} +void nobadFunc1_0(){ + unsigned char * buff1; + buff1 = (unsigned char *) malloc(12); + memset(buff1,12,12); +} +void badFunc1_0(){ + unsigned char * buff1; + buff1 = (unsigned char *) malloc(12); + memset(buff1,12,12); + free(buff1); +} +void badFunc1_1(){ + unsigned char buff1[12]; + int i; + for(i=0;i<12;i++) + buff1[i]=13; + memset(buff1,12,12); + free(buff1); +} +void nobadFunc2_0_0(){ + unsigned char buff1[12]; + int i; + for(i=0;i<12;i++) + buff1[i]=13; + memset(buff1,12,12); + printf(buff1); +} + +void nobadFunc2_0_1(){ + unsigned char buff1[12]; + int i; + for(i=0;i<12;i++) + buff1[i]=13; + memset(buff1,12,12); + printf(buff1+3); +} + +void nobadFunc2_0_2(){ + unsigned char buff1[12]; + int i; + for(i=0;i<12;i++) + buff1[i]=13; + memset(buff1,12,12); + printf(*buff1); +} + +void nobadFunc2_0_3(){ + unsigned char buff1[12]; + int i; + for(i=0;i<12;i++) + buff1[i]=13; + memset(buff1,12,12); + printf(*(buff1+3)); +} +unsigned char * nobadFunc2_0_4(){ + unsigned char buff1[12]; + int i; + for(i=0;i<12;i++) + buff1[i]=13; + memset(buff1,12,12); + return buff1; +} + +unsigned char * nobadFunc2_0_5(){ + unsigned char buff1[12]; + int i; + for(i=0;i<12;i++) + buff1[i]=13; + memset(buff1,12,12); + return buff1+3; +} +unsigned char nobadFunc2_0_6(){ + unsigned char buff1[12]; + int i; + for(i=0;i<12;i++) + buff1[i]=13; + memset(buff1,12,12); + return *buff1; +} + +unsigned char nobadFunc2_0_7(){ + unsigned char buff1[12]; + int i; + for(i=0;i<12;i++) + buff1[i]=13; + memset(buff1,12,12); + return *(buff1+3); +} +void nobadFunc2_1_0(){ + unsigned char buff1[12]; + int i; + for(i=0;i<12;i++) + buff1[i]=13; + memset(buff1,12,12); + if(*buff1==0) + printf("123123"); +} +void nobadFunc2_1_1(){ + unsigned char buff1[12]; + int i; + for(i=0;i<12;i++) + buff1[i]=13; + memset(buff1,12,12); + if(*(buff1+3)==0) + printf("123123"); +} +void nobadFunc2_1_2(){ + unsigned char buff1[12]; + int i; + for(i=0;i<12;i++) + buff1[i]=13; + memset(buff1,12,12); + buff1[2]=5; +} +void nobadFunc3_0(unsigned char * buffAll){ + unsigned char * buff1 = buffAll; + memset(buff1,12,12); +} +void nobadFunc3_1(unsigned char * buffAll){ + unsigned char * buff1 = buffAll+3; + memset(buff1,12,12); +} +void nobadFunc3_2(struct buffers buffAll){ + unsigned char * buff1 = buffAll.buff1; + memset(buff1,12,12); +} +void nobadFunc3_3(struct buffers buffAll){ + unsigned char * buff1 = buffAll.buff2; + memset(buff1,12,12); +} +void nobadFunc3_4(struct buffers buffAll){ + unsigned char * buff1 = buffAll.buff2+3; + memset(buff1,12,12); +} +void nobadFunc3_5(struct buffers * buffAll){ + unsigned char * buff1 = buffAll->buff1; + memset(buff1,12,12); +} +void nobadFunc3_6(struct buffers *buffAll){ + unsigned char * buff1 = buffAll->buff2; + memset(buff1,12,12); +} +void nobadFunc4(){ + unsigned char * buff1 = globalBuff; + memset(buff1,12,12); +} +void nobadFunc4_0(){ + unsigned char * buff1 = globalBuff; + memset(buff1,12,12); +} +void nobadFunc4_1(){ + unsigned char * buff1 = globalBuff+3; + memset(buff1,12,12); +} +void nobadFunc4_2(){ + unsigned char * buff1 = globalBuff1.buff1; + memset(buff1,12,12); +} +void nobadFunc4_3(){ + unsigned char * buff1 = globalBuff1.buff2; + memset(buff1,12,12); +} +void nobadFunc4_4(){ + unsigned char * buff1 = globalBuff1.buff2+3; + memset(buff1,12,12); +} +void nobadFunc4_5(){ + unsigned char * buff1 = globalBuff2->buff1; + memset(buff1,12,12); +} +void nobadFunc4_6(){ + unsigned char * buff1 = globalBuff2->buff2; + memset(buff1,12,12); +} + diff --git a/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-190/AllocMultiplicationOverflow/AllocMultiplicationOverflow.expected b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-190/AllocMultiplicationOverflow/AllocMultiplicationOverflow.expected new file mode 100644 index 00000000000..b8428a43d11 --- /dev/null +++ b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-190/AllocMultiplicationOverflow/AllocMultiplicationOverflow.expected @@ -0,0 +1,17 @@ +edges +| test.cpp:22:17:22:21 | ... * ... | test.cpp:23:33:23:37 | size1 | +nodes +| test.cpp:13:33:13:37 | ... * ... | semmle.label | ... * ... | +| test.cpp:15:31:15:35 | ... * ... | semmle.label | ... * ... | +| test.cpp:19:34:19:38 | ... * ... | semmle.label | ... * ... | +| test.cpp:22:17:22:21 | ... * ... | semmle.label | ... * ... | +| test.cpp:23:33:23:37 | size1 | semmle.label | size1 | +| test.cpp:30:27:30:31 | ... * ... | semmle.label | ... * ... | +| test.cpp:31:27:31:31 | ... * ... | semmle.label | ... * ... | +#select +| test.cpp:13:33:13:37 | ... * ... | test.cpp:13:33:13:37 | ... * ... | test.cpp:13:33:13:37 | ... * ... | Potentially overflowing value from $@ is used in the size of this allocation. | test.cpp:13:33:13:37 | ... * ... | multiplication | +| test.cpp:15:31:15:35 | ... * ... | test.cpp:15:31:15:35 | ... * ... | test.cpp:15:31:15:35 | ... * ... | Potentially overflowing value from $@ is used in the size of this allocation. | test.cpp:15:31:15:35 | ... * ... | multiplication | +| test.cpp:19:34:19:38 | ... * ... | test.cpp:19:34:19:38 | ... * ... | test.cpp:19:34:19:38 | ... * ... | Potentially overflowing value from $@ is used in the size of this allocation. | test.cpp:19:34:19:38 | ... * ... | multiplication | +| test.cpp:23:33:23:37 | size1 | test.cpp:22:17:22:21 | ... * ... | test.cpp:23:33:23:37 | size1 | Potentially overflowing value from $@ is used in the size of this allocation. | test.cpp:22:17:22:21 | ... * ... | multiplication | +| test.cpp:30:27:30:31 | ... * ... | test.cpp:30:27:30:31 | ... * ... | test.cpp:30:27:30:31 | ... * ... | Potentially overflowing value from $@ is used in the size of this allocation. | test.cpp:30:27:30:31 | ... * ... | multiplication | +| test.cpp:31:27:31:31 | ... * ... | test.cpp:31:27:31:31 | ... * ... | test.cpp:31:27:31:31 | ... * ... | Potentially overflowing value from $@ is used in the size of this allocation. | test.cpp:31:27:31:31 | ... * ... | multiplication | diff --git a/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-190/AllocMultiplicationOverflow/AllocMultiplicationOverflow.qlref b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-190/AllocMultiplicationOverflow/AllocMultiplicationOverflow.qlref new file mode 100644 index 00000000000..7bb108b6628 --- /dev/null +++ b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-190/AllocMultiplicationOverflow/AllocMultiplicationOverflow.qlref @@ -0,0 +1 @@ +experimental/Security/CWE/CWE-190/AllocMultiplicationOverflow.ql diff --git a/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-190/AllocMultiplicationOverflow/test.cpp b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-190/AllocMultiplicationOverflow/test.cpp new file mode 100644 index 00000000000..ab26fef3ed0 --- /dev/null +++ b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-190/AllocMultiplicationOverflow/test.cpp @@ -0,0 +1,32 @@ + +typedef unsigned long size_t; +void *malloc(size_t size); + +int getAnInt(); + +void test() +{ + int x = getAnInt(); + int y = getAnInt(); + + char *buffer1 = (char *)malloc(x + y); // GOOD + char *buffer2 = (char *)malloc(x * y); // BAD + int *buffer3 = (int *)malloc(x * sizeof(int)); // GOOD + int *buffer4 = (int *)malloc(x * y * sizeof(int)); // BAD + + if ((x <= 1000) && (y <= 1000)) + { + char *buffer5 = (char *)malloc(x * y); // GOOD [FALSE POSITIVE] + } + + size_t size1 = x * y; + char *buffer5 = (char *)malloc(size1); // BAD + + size_t size2 = x; + size2 *= y; + char *buffer6 = (char *)malloc(size2); // BAD [NOT DETECTED] + + char *buffer7 = new char[x * 10]; // GOOD + char *buffer8 = new char[x * y]; // BAD + char *buffer9 = new char[x * x]; // BAD +} diff --git a/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-359/semmle/tests/PrivateCleartextWrite.expected b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-359/semmle/tests/PrivateCleartextWrite.expected index c263d7e6dfd..887547f2c2e 100644 --- a/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-359/semmle/tests/PrivateCleartextWrite.expected +++ b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-359/semmle/tests/PrivateCleartextWrite.expected @@ -13,9 +13,9 @@ nodes | test.cpp:96:37:96:46 | theZipcode | semmle.label | theZipcode | | test.cpp:99:42:99:51 | theZipcode | semmle.label | theZipcode | #select -| test.cpp:57:9:57:18 | theZipcode | This write into the external location 'theZipcode' may contain unencrypted data from $@ | test.cpp:57:9:57:18 | theZipcode | this source. | -| test.cpp:74:24:74:30 | medical | This write into the external location 'medical' may contain unencrypted data from $@ | test.cpp:74:24:74:30 | medical | this source. | -| test.cpp:78:24:78:27 | temp | This write into the external location 'temp' may contain unencrypted data from $@ | test.cpp:77:16:77:22 | medical | this source. | -| test.cpp:82:24:82:28 | buff5 | This write into the external location 'buff5' may contain unencrypted data from $@ | test.cpp:81:22:81:28 | medical | this source. | -| test.cpp:96:37:96:46 | theZipcode | This write into the external location 'theZipcode' may contain unencrypted data from $@ | test.cpp:96:37:96:46 | theZipcode | this source. | -| test.cpp:99:42:99:51 | theZipcode | This write into the external location 'theZipcode' may contain unencrypted data from $@ | test.cpp:99:42:99:51 | theZipcode | this source. | +| test.cpp:57:9:57:18 | theZipcode | test.cpp:57:9:57:18 | theZipcode | test.cpp:57:9:57:18 | theZipcode | This write into the external location 'theZipcode' may contain unencrypted data from $@ | test.cpp:57:9:57:18 | theZipcode | this source. | +| test.cpp:74:24:74:30 | medical | test.cpp:74:24:74:30 | medical | test.cpp:74:24:74:30 | medical | This write into the external location 'medical' may contain unencrypted data from $@ | test.cpp:74:24:74:30 | medical | this source. | +| test.cpp:78:24:78:27 | temp | test.cpp:77:16:77:22 | medical | test.cpp:78:24:78:27 | temp | This write into the external location 'temp' may contain unencrypted data from $@ | test.cpp:77:16:77:22 | medical | this source. | +| test.cpp:82:24:82:28 | buff5 | test.cpp:81:22:81:28 | medical | test.cpp:82:24:82:28 | buff5 | This write into the external location 'buff5' may contain unencrypted data from $@ | test.cpp:81:22:81:28 | medical | this source. | +| test.cpp:96:37:96:46 | theZipcode | test.cpp:96:37:96:46 | theZipcode | test.cpp:96:37:96:46 | theZipcode | This write into the external location 'theZipcode' may contain unencrypted data from $@ | test.cpp:96:37:96:46 | theZipcode | this source. | +| test.cpp:99:42:99:51 | theZipcode | test.cpp:99:42:99:51 | theZipcode | test.cpp:99:42:99:51 | theZipcode | This write into the external location 'theZipcode' may contain unencrypted data from $@ | test.cpp:99:42:99:51 | theZipcode | this source. | diff --git a/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-401/semmle/tests/MemoryLeakOnFailedCallToRealloc.expected b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-401/semmle/tests/MemoryLeakOnFailedCallToRealloc.expected new file mode 100644 index 00000000000..b40e19c7559 --- /dev/null +++ b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-401/semmle/tests/MemoryLeakOnFailedCallToRealloc.expected @@ -0,0 +1,8 @@ +| test.c:34:29:34:35 | call to realloc | possible loss of original pointer on unsuccessful call realloc | +| test.c:63:29:63:35 | call to realloc | possible loss of original pointer on unsuccessful call realloc | +| test.c:139:29:139:35 | call to realloc | possible loss of original pointer on unsuccessful call realloc | +| test.c:186:29:186:35 | call to realloc | possible loss of original pointer on unsuccessful call realloc | +| test.c:282:29:282:35 | call to realloc | possible loss of original pointer on unsuccessful call realloc | +| test.c:299:26:299:32 | call to realloc | possible loss of original pointer on unsuccessful call realloc | +| test.c:328:29:328:35 | call to realloc | possible loss of original pointer on unsuccessful call realloc | +| test.c:342:29:342:35 | call to realloc | possible loss of original pointer on unsuccessful call realloc | diff --git a/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-401/semmle/tests/MemoryLeakOnFailedCallToRealloc.qlref b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-401/semmle/tests/MemoryLeakOnFailedCallToRealloc.qlref new file mode 100644 index 00000000000..e80e86cbdcc --- /dev/null +++ b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-401/semmle/tests/MemoryLeakOnFailedCallToRealloc.qlref @@ -0,0 +1 @@ +experimental/Security/CWE/CWE-401/MemoryLeakOnFailedCallToRealloc.ql \ No newline at end of file diff --git a/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-401/semmle/tests/test.c b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-401/semmle/tests/test.c new file mode 100644 index 00000000000..df33fc19ef6 --- /dev/null +++ b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-401/semmle/tests/test.c @@ -0,0 +1,346 @@ +#define size_t int +#define NULL ((void*)0) + +#define assert(x) if (!(x)) __assert_fail(#x,__FILE__,__LINE__) +void __assert_fail(const char *assertion, const char *file, int line); + +void aFakeFailed_1(int file, int line) +{ +} +void aFailed_1(int file, int line) +{ + exit(0); +} +void aFailed_2(int file, int line, int ex) +{ + if(ex == 1) + exit(0); + else + return; +} +#define F_NUM 1 +#define myASSERT_1(expr) \ + if (!(expr)) \ + aFailed_1(F_NUM, __LINE__) +#define myASSERT_2(expr) \ + if (!(expr)) \ + aFailed_2(F_NUM, __LINE__, 1) + +unsigned char * badResize_0(unsigned char * buffer,size_t currentSize,size_t newSize) +{ + // BAD: on unsuccessful call to realloc, we will lose a pointer to a valid memory block + if (currentSize < newSize) + { + buffer = (unsigned char *)realloc(buffer, newSize); + } + return buffer; +} + +unsigned char * goodResize_0(unsigned char * buffer,size_t currentSize,size_t newSize) +{ + // GOOD: this way we will exclude possible memory leak + unsigned char * tmp; + if (currentSize < newSize) + { + tmp = (unsigned char *)realloc(buffer, newSize); + } + if (tmp == NULL) + { + free(buffer); + return NULL; + } + else + buffer = tmp; + return buffer; +} +unsigned char * badResize_1_0(unsigned char * buffer,size_t currentSize,size_t newSize) +{ + if(!buffer) + exit(0); + // BAD: on unsuccessful call to realloc, we will lose a pointer to a valid memory block + if (currentSize < newSize) + { + buffer = (unsigned char *)realloc(buffer, newSize); + } + return buffer; +} + +unsigned char * noBadResize_1_0(unsigned char * buffer,size_t currentSize,size_t newSize) +{ + // GOOD: program to end + if (currentSize < newSize) + { + buffer = (unsigned char *)realloc(buffer, newSize); + } + if(!buffer) + exit(0); + return buffer; +} +unsigned char * noBadResize_1_1(unsigned char * buffer,size_t currentSize,size_t newSize) +{ + // GOOD: program to end + if (currentSize < newSize) + { + buffer = (unsigned char *)realloc(buffer, newSize); + } + if(buffer) + return buffer; + else + exit(0); +} +unsigned char * noBadResize_1_2(unsigned char * buffer,size_t currentSize,size_t newSize) +{ + // GOOD: program to end + if (currentSize < newSize) + { + if(buffer = (unsigned char *)realloc(buffer, newSize)) + exit(0); + } + return buffer; +} +unsigned char * noBadResize_1_3(unsigned char * buffer,size_t currentSize,size_t newSize) +{ + // GOOD: program to end + if (currentSize < newSize) + { + buffer = (unsigned char *)realloc(buffer, newSize); + } + if(!buffer) + aFailed_1(1, 1); + return buffer; +} +unsigned char * noBadResize_1_4(unsigned char * buffer,size_t currentSize,size_t newSize) +{ + // GOOD: program to end + if (currentSize < newSize) + { + buffer = (unsigned char *)realloc(buffer, newSize); + } + if(buffer) + return buffer; + else + aFailed_1(1, 1); +} +unsigned char * noBadResize_1_5(unsigned char * buffer,size_t currentSize,size_t newSize) +{ + // GOOD: program to end + if (currentSize < newSize) + { + if(buffer = (unsigned char *)realloc(buffer, newSize)) + aFailed_1(1, 1); + } + return buffer; +} +unsigned char * badResize_1_1(unsigned char * buffer,size_t currentSize,size_t newSize) +{ + // BAD: on unsuccessful call to realloc, we will lose a pointer to a valid memory block + if (currentSize < newSize) + { + buffer = (unsigned char *)realloc(buffer, newSize); + } + if(!buffer) + aFakeFailed_1(1, 1); + return buffer; +} + +unsigned char * noBadResize_1_6(unsigned char * buffer,size_t currentSize,size_t newSize) +{ + // GOOD: program to end + if (currentSize < newSize) + { + buffer = (unsigned char *)realloc(buffer, newSize); + } + if(!buffer) + aFailed_2(1, 1, 1); + return buffer; +} +unsigned char * noBadResize_1_7(unsigned char * buffer,size_t currentSize,size_t newSize) +{ + // GOOD: program to end + if (currentSize < newSize) + { + buffer = (unsigned char *)realloc(buffer, newSize); + } + if(buffer) + return buffer; + else + aFailed_2(1, 1, 1); +} +unsigned char * noBadResize_1_8(unsigned char * buffer,size_t currentSize,size_t newSize) +{ + // GOOD: program to end + if (currentSize < newSize) + { + if(buffer = (unsigned char *)realloc(buffer, newSize)) + aFailed_2(1, 1, 1); + } + return buffer; +} + +unsigned char * badResize_2_0(unsigned char * buffer,size_t currentSize,size_t newSize) +{ + // BAD: on unsuccessful call to realloc, we will lose a pointer to a valid memory block + assert(buffer!=0); + if (currentSize < newSize) + { + buffer = (unsigned char *)realloc(buffer, newSize); + } + return buffer; +} + +unsigned char * noBadResize_2_0(unsigned char * buffer,size_t currentSize,size_t newSize) +{ + // GOOD: program to end + if (currentSize < newSize) + { + buffer = (unsigned char *)realloc(buffer, newSize); + assert(buffer!=0); + } + return buffer; +} + +unsigned char * noBadResize2e_2_1(unsigned char * buffer,size_t currentSize,size_t newSize) +{ + // GOOD: program to end + if (currentSize < newSize) + { + buffer = (unsigned char *)realloc(buffer, newSize); + } + assert(buffer!=0); + return buffer; +} +unsigned char * noBadResize_2_2(unsigned char * buffer,size_t currentSize,size_t newSize) +{ + // GOOD: program to end + if (currentSize < newSize) + { + buffer = (unsigned char *)realloc(buffer, newSize); + assert(buffer); + } + return buffer; +} + +unsigned char * noBadResize_2_3(unsigned char * buffer,size_t currentSize,size_t newSize) +{ + // GOOD: program to end + if (currentSize < newSize) + { + buffer = (unsigned char *)realloc(buffer, newSize); + } + assert(buffer); + return buffer; +} +unsigned char * noBadResize_2_4(unsigned char * buffer,size_t currentSize,size_t newSize) +{ + // GOOD: program to end + if (currentSize < newSize) + { + buffer = (unsigned char *)realloc(buffer, newSize); + myASSERT_1(buffer); + } + return buffer; +} + +unsigned char * noBadResize_2_5(unsigned char * buffer,size_t currentSize,size_t newSize) +{ + // GOOD: program to end + if (currentSize < newSize) + { + buffer = (unsigned char *)realloc(buffer, newSize); + } + myASSERT_1(buffer); + return buffer; +} +unsigned char * noBadResize_2_6(unsigned char * buffer,size_t currentSize,size_t newSize) +{ + // GOOD: program to end + if (currentSize < newSize) + { + buffer = (unsigned char *)realloc(buffer, newSize); + myASSERT_2(buffer); + } + return buffer; +} + +unsigned char * noBadResize_2_7(unsigned char * buffer,size_t currentSize,size_t newSize) +{ + // GOOD: program to end + if (currentSize < newSize) + { + buffer = (unsigned char *)realloc(buffer, newSize); + } + myASSERT_2(buffer); + return buffer; +} + +unsigned char *goodResize_3_1(unsigned char *buffer, size_t currentSize, size_t newSize) +{ + // GOOD: this way we will exclude possible memory leak [FALSE POSITIVE] + unsigned char *tmp = buffer; + if (currentSize < newSize) + { + buffer = (unsigned char *)realloc(buffer, newSize); + if (buffer == NULL) + { + free(tmp); + return NULL; + } + } + + return buffer; +} + +unsigned char *goodResize_3_2(unsigned char *buffer, size_t currentSize, size_t newSize) +{ + // GOOD: this way we will exclude possible memory leak [FALSE POSITIVE] + unsigned char *tmp = buffer; + if (currentSize < newSize) + { + tmp = (unsigned char *)realloc(tmp, newSize); + if (tmp != 0) + { + buffer = tmp; + } + } + + return buffer; +} + +void abort(void); + +unsigned char *noBadResize_4_1(unsigned char *buffer, size_t currentSize, size_t newSize) +{ + // GOOD: program to end + if (currentSize < newSize) + { + if (buffer = (unsigned char *)realloc(buffer, newSize)) + abort(); + } + + return buffer; +} + +unsigned char * badResize_5_2(unsigned char *buffer, size_t currentSize, size_t newSize, int cond) +{ + // BAD: on unsuccessful call to realloc, we will lose a pointer to a valid memory block + if (currentSize < newSize) + { + buffer = (unsigned char *)realloc(buffer, newSize); + } + if (cond) + { + abort(); // irrelevant + } + return buffer; +} + +unsigned char * badResize_5_1(unsigned char *buffer, size_t currentSize, size_t newSize, int cond) +{ + // BAD: on unsuccessful call to realloc, we will lose a pointer to a valid memory block + if (currentSize < newSize) + { + buffer = (unsigned char *)realloc(buffer, newSize); + assert(cond); // irrelevant + } + return buffer; +} diff --git a/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-570/semmle/tests/WrongInDetectingAndHandlingMemoryAllocationErrors.expected b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-570/semmle/tests/WrongInDetectingAndHandlingMemoryAllocationErrors.expected new file mode 100644 index 00000000000..80e82cff212 --- /dev/null +++ b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-570/semmle/tests/WrongInDetectingAndHandlingMemoryAllocationErrors.expected @@ -0,0 +1,5 @@ +| test.cpp:30:15:30:26 | call to operator new[] | memory allocation error check is incorrect or missing | +| test.cpp:38:9:38:20 | call to operator new[] | memory allocation error check is incorrect or missing | +| test.cpp:50:13:50:38 | call to operator new[] | memory allocation error check is incorrect or missing | +| test.cpp:51:22:51:47 | call to operator new[] | memory allocation error check is incorrect or missing | +| test.cpp:53:18:53:43 | call to operator new[] | memory allocation error check is incorrect or missing | diff --git a/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-570/semmle/tests/WrongInDetectingAndHandlingMemoryAllocationErrors.qlref b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-570/semmle/tests/WrongInDetectingAndHandlingMemoryAllocationErrors.qlref new file mode 100644 index 00000000000..fc3252ef122 --- /dev/null +++ b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-570/semmle/tests/WrongInDetectingAndHandlingMemoryAllocationErrors.qlref @@ -0,0 +1 @@ +experimental/Security/CWE/CWE-570/WrongInDetectingAndHandlingMemoryAllocationErrors.ql diff --git a/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-570/semmle/tests/test.cpp b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-570/semmle/tests/test.cpp new file mode 100644 index 00000000000..e4aa8cf2976 --- /dev/null +++ b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-570/semmle/tests/test.cpp @@ -0,0 +1,97 @@ +#define NULL ((void*)0) +class exception {}; + +namespace std{ + struct nothrow_t {}; + typedef unsigned long size_t; + class bad_alloc{ + const char* what() const throw(); + }; + extern const std::nothrow_t nothrow; +} + +using namespace std; + +void* operator new(std::size_t _Size); +void* operator new[](std::size_t _Size); +void* operator new( std::size_t count, const std::nothrow_t& tag ); +void* operator new[]( std::size_t count, const std::nothrow_t& tag ); + +void badNew_0_0() +{ + while (true) { + new int[100]; // BAD [NOT DETECTED] + if(!(new int[100])) // BAD [NOT DETECTED] + return; + } +} +void badNew_0_1() +{ + int * i = new int[100]; // BAD + if(i == 0) + return; + if(!i) + return; + if(i == NULL) + return; + int * j; + j = new int[100]; // BAD + if(j == 0) + return; + if(!j) + return; + if(j == NULL) + return; +} +void badNew_1_0() +{ + try { + while (true) { + new(std::nothrow) int[100]; // BAD + int* p = new(std::nothrow) int[100]; // BAD + int* p1; + p1 = new(std::nothrow) int[100]; // BAD + } + } catch (const exception &){//const std::bad_alloc& e) { +// std::cout << e.what() << '\n'; + } +} +void badNew_1_1() +{ + while (true) { + int* p = new(std::nothrow) int[100]; // BAD [NOT DETECTED] + new(std::nothrow) int[100]; // BAD [NOT DETECTED] + } +} + +void goodNew_0_0() +{ + try { + while (true) { + new int[100]; // GOOD + } + } catch (const exception &){//const std::bad_alloc& e) { +// std::cout << e.what() << '\n'; + } +} + +void goodNew_1_0() +{ + while (true) { + int* p = new(std::nothrow) int[100]; // GOOD + if (p == nullptr) { +// std::cout << "Allocation returned nullptr\n"; + break; + } + int* p1; + p1 = new(std::nothrow) int[100]; // GOOD + if (p1 == nullptr) { +// std::cout << "Allocation returned nullptr\n"; + break; + } + if (new(std::nothrow) int[100] == nullptr) { // GOOD +// std::cout << "Allocation returned nullptr\n"; + break; + } + } +} diff --git a/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-788/semmle/tests/AccessOfMemoryLocationAfterEndOfBufferUsingStrlen.expected b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-788/semmle/tests/AccessOfMemoryLocationAfterEndOfBufferUsingStrlen.expected new file mode 100644 index 00000000000..103afd8ffd9 --- /dev/null +++ b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-788/semmle/tests/AccessOfMemoryLocationAfterEndOfBufferUsingStrlen.expected @@ -0,0 +1,9 @@ +| test.c:42:3:42:24 | ... = ... | potential unsafe or redundant assignment. | +| test.c:43:3:43:40 | ... = ... | potential unsafe or redundant assignment. | +| test.c:44:3:44:40 | ... = ... | potential unsafe or redundant assignment. | +| test.c:45:3:45:44 | ... = ... | potential unsafe or redundant assignment. | +| test.c:46:3:46:44 | ... = ... | potential unsafe or redundant assignment. | +| test.c:47:3:47:48 | ... = ... | potential unsafe or redundant assignment. | +| test.c:48:3:48:48 | ... = ... | potential unsafe or redundant assignment. | +| test.c:49:3:49:50 | ... = ... | potential unsafe or redundant assignment. | +| test.c:50:3:50:50 | ... = ... | potential unsafe or redundant assignment. | diff --git a/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-788/semmle/tests/AccessOfMemoryLocationAfterEndOfBufferUsingStrlen.qlref b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-788/semmle/tests/AccessOfMemoryLocationAfterEndOfBufferUsingStrlen.qlref new file mode 100644 index 00000000000..6ba005d087a --- /dev/null +++ b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-788/semmle/tests/AccessOfMemoryLocationAfterEndOfBufferUsingStrlen.qlref @@ -0,0 +1 @@ +experimental/Security/CWE/CWE-788/AccessOfMemoryLocationAfterEndOfBufferUsingStrlen.ql diff --git a/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-788/semmle/tests/AccessOfMemoryLocationAfterEndOfBufferUsingStrncat.expected b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-788/semmle/tests/AccessOfMemoryLocationAfterEndOfBufferUsingStrncat.expected new file mode 100644 index 00000000000..af52dac0144 --- /dev/null +++ b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-788/semmle/tests/AccessOfMemoryLocationAfterEndOfBufferUsingStrncat.expected @@ -0,0 +1,3 @@ +| test.c:4:3:4:9 | call to strncat | if the used buffer is full, writing out of the buffer is possible | +| test.c:11:3:11:9 | call to strncat | if the used buffer is full, writing out of the buffer is possible | +| test.c:19:3:19:9 | call to strncat | if the used buffer is full, writing out of the buffer is possible | diff --git a/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-788/semmle/tests/AccessOfMemoryLocationAfterEndOfBufferUsingStrncat.qlref b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-788/semmle/tests/AccessOfMemoryLocationAfterEndOfBufferUsingStrncat.qlref new file mode 100644 index 00000000000..8fd8b1b3217 --- /dev/null +++ b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-788/semmle/tests/AccessOfMemoryLocationAfterEndOfBufferUsingStrncat.qlref @@ -0,0 +1 @@ +experimental/Security/CWE/CWE-788/AccessOfMemoryLocationAfterEndOfBufferUsingStrncat.ql diff --git a/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-788/semmle/tests/test.c b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-788/semmle/tests/test.c new file mode 100644 index 00000000000..d986bb3b13c --- /dev/null +++ b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-788/semmle/tests/test.c @@ -0,0 +1,73 @@ +void workFunction_0(char *s) { + char buf[80]; + strncat(buf, s, sizeof(buf)-strlen(buf)-1); // GOOD + strncat(buf, s, sizeof(buf)-strlen(buf)); // BAD + strncat(buf, "fix", sizeof(buf)-strlen(buf)); // BAD [NOT DETECTED] +} +void workFunction_1(char *s) { +#define MAX_SIZE 80 + char buf[MAX_SIZE]; + strncat(buf, s, MAX_SIZE-strlen(buf)-1); // GOOD + strncat(buf, s, MAX_SIZE-strlen(buf)); // BAD + strncat(buf, "fix", MAX_SIZE-strlen(buf)); // BAD [NOT DETECTED] +} +void workFunction_2_0(char *s) { + char * buf; + int len=80; + buf = (char *) malloc(len); + strncat(buf, s, len-strlen(buf)-1); // GOOD + strncat(buf, s, len-strlen(buf)); // BAD + strncat(buf, "fix", len-strlen(buf)); // BAD [NOT DETECTED] +} +void workFunction_2_1(char *s) { + char * buf; + int len=80; + buf = (char *) malloc(len+1); + strncat(buf, s, len-strlen(buf)-1); // GOOD + strncat(buf, s, len-strlen(buf)); // GOOD +} + +struct buffers +{ + unsigned char buff1[50]; + unsigned char *buff2; +} globalBuff1,*globalBuff2,globalBuff1_c,*globalBuff2_c; + + +void badFunc0(){ + unsigned char buff1[12]; + struct buffers buffAll; + struct buffers * buffAll1; + + buff1[strlen(buff1)]=0; // BAD + buffAll.buff1[strlen(buffAll.buff1)]=0; // BAD + buffAll.buff2[strlen(buffAll.buff2)]=0; // BAD + buffAll1->buff1[strlen(buffAll1->buff1)]=0; // BAD + buffAll1->buff2[strlen(buffAll1->buff2)]=0; // BAD + globalBuff1.buff1[strlen(globalBuff1.buff1)]=0; // BAD + globalBuff1.buff2[strlen(globalBuff1.buff2)]=0; // BAD + globalBuff2->buff1[strlen(globalBuff2->buff1)]=0; // BAD + globalBuff2->buff2[strlen(globalBuff2->buff2)]=0; // BAD +} +void noBadFunc0(){ + unsigned char buff1[12],buff1_c[12]; + struct buffers buffAll,buffAll_c; + struct buffers * buffAll1,*buffAll1_c; + + buff1[strlen(buff1_c)]=0; // GOOD + buffAll.buff1[strlen(buffAll_c.buff1)]=0; // GOOD + buffAll.buff2[strlen(buffAll.buff1)]=0; // GOOD + buffAll1->buff1[strlen(buffAll1_c->buff1)]=0; // GOOD + buffAll1->buff2[strlen(buffAll1->buff1)]=0; // GOOD + globalBuff1.buff1[strlen(globalBuff1_c.buff1)]=0; // GOOD + globalBuff1.buff2[strlen(globalBuff1.buff1)]=0; // GOOD + globalBuff2->buff1[strlen(globalBuff2_c->buff1)]=0; // GOOD + globalBuff2->buff2[strlen(globalBuff2->buff1)]=0; // GOOD +} +void goodFunc0(){ + unsigned char buffer[12]; + int i; + for(i = 0; i < 6; i++) + buffer[i] = 'A'; + buffer[i]=0; +} diff --git a/cpp/ql/test/experimental/query-tests/Security/CWE/semmle/tests/MemoryUnsafeFunctionScan.cpp b/cpp/ql/test/experimental/query-tests/Security/CWE/semmle/tests/MemoryUnsafeFunctionScan.cpp index f9ffc5e8687..09506cbc087 100644 --- a/cpp/ql/test/experimental/query-tests/Security/CWE/semmle/tests/MemoryUnsafeFunctionScan.cpp +++ b/cpp/ql/test/experimental/query-tests/Security/CWE/semmle/tests/MemoryUnsafeFunctionScan.cpp @@ -1,5 +1,10 @@ ///// Library routines ///// +typedef unsigned long size_t; +void *malloc(size_t size); + +size_t strlen(const char *s); + int scanf(const char *format, ...); int sscanf(const char *str, const char *format, ...); int fscanf(const char *str, const char *format, ...); @@ -13,13 +18,23 @@ int main(int argc, char **argv) char buf1[10]; scanf("%s", buf1); - // GOOD, length is specified - char buf2[10]; - sscanf(buf2, "%9s"); + // GOOD, length is specified. The length should be one less than the size of the destination buffer, since the last character is the NULL terminator. + char buf2[20]; + char buf3[10]; + sscanf(buf2, "%9s", buf3); // BAD, do not use scanf without specifying a length first char file[10]; fscanf(file, "%s", buf2); + // GOOD, with 'sscanf' the input can be checked first and enough room allocated [FALSE POSITIVE] + if (argc >= 1) + { + char *src = argv[0]; + char *dest = (char *)malloc(strlen(src) + 1); + + sscanf(src, "%s", dest); + } + return 0; } diff --git a/cpp/ql/test/experimental/query-tests/Security/CWE/semmle/tests/MemoryUnsafeFunctionScan.expected b/cpp/ql/test/experimental/query-tests/Security/CWE/semmle/tests/MemoryUnsafeFunctionScan.expected index 701fd4320b0..2739ed872e2 100644 --- a/cpp/ql/test/experimental/query-tests/Security/CWE/semmle/tests/MemoryUnsafeFunctionScan.expected +++ b/cpp/ql/test/experimental/query-tests/Security/CWE/semmle/tests/MemoryUnsafeFunctionScan.expected @@ -1,2 +1,3 @@ -| MemoryUnsafeFunctionScan.cpp:14:5:14:9 | call to scanf | Dangerous use of one of the scanf functions | -| MemoryUnsafeFunctionScan.cpp:22:5:22:10 | call to fscanf | Dangerous use of one of the scanf functions | +| MemoryUnsafeFunctionScan.cpp:19:5:19:9 | call to scanf | Dangerous use of one of the scanf functions | +| MemoryUnsafeFunctionScan.cpp:28:5:28:10 | call to fscanf | Dangerous use of one of the scanf functions | +| MemoryUnsafeFunctionScan.cpp:36:3:36:8 | call to sscanf | Dangerous use of one of the scanf functions | diff --git a/cpp/ql/test/library-tests/dataflow/DefaultTaintTracking/annotate_sinks_only/defaulttainttracking.cpp b/cpp/ql/test/library-tests/dataflow/DefaultTaintTracking/annotate_sinks_only/defaulttainttracking.cpp index b24efc1dc8e..020a2f90b9e 100644 --- a/cpp/ql/test/library-tests/dataflow/DefaultTaintTracking/annotate_sinks_only/defaulttainttracking.cpp +++ b/cpp/ql/test/library-tests/dataflow/DefaultTaintTracking/annotate_sinks_only/defaulttainttracking.cpp @@ -216,3 +216,46 @@ void test_pointers2() sink(ptr4); // clean sink(*ptr4); // $ MISSING: ast,ir } + +// --- recv --- + +int recv(int s, char* buf, int len, int flags); + +void test_recv() { + char buffer[1024]; + recv(0, buffer, sizeof(buffer), 0); + sink(buffer); // $ ast,ir + sink(*buffer); // $ ast,ir +} + +// --- send and related functions --- + +int send(int, const void*, int, int); + +void test_send(char* buffer, int length) { + send(0, buffer, length, 0); // $ remote +} + +struct iovec { + void *iov_base; + unsigned iov_len; +}; + +int readv(int, const struct iovec*, int); +int writev(int, const struct iovec*, int); + +void sink(const iovec* iovs); +void sink(iovec); + +int test_readv_and_writev(iovec* iovs) { + readv(0, iovs, 16); + sink(iovs); // $ast,ir + sink(iovs[0]); // $ast MISSING: ir + sink(*iovs); // $ast MISSING: ir + + char* p = (char*)iovs[1].iov_base; + sink(p); // $ MISSING: ast,ir + sink(*p); // $ MISSING: ast,ir + + writev(0, iovs, 16); // $ remote +} diff --git a/cpp/ql/test/library-tests/dataflow/DefaultTaintTracking/annotate_sinks_only/remote-flow-sink.expected b/cpp/ql/test/library-tests/dataflow/DefaultTaintTracking/annotate_sinks_only/remote-flow-sink.expected new file mode 100644 index 00000000000..e69de29bb2d diff --git a/cpp/ql/test/library-tests/dataflow/DefaultTaintTracking/annotate_sinks_only/remote-flow-sink.ql b/cpp/ql/test/library-tests/dataflow/DefaultTaintTracking/annotate_sinks_only/remote-flow-sink.ql new file mode 100644 index 00000000000..4fbbe8fa3bf --- /dev/null +++ b/cpp/ql/test/library-tests/dataflow/DefaultTaintTracking/annotate_sinks_only/remote-flow-sink.ql @@ -0,0 +1,20 @@ +/** This tests that we are able to detect remote flow sinks. */ + +import cpp +import TestUtilities.InlineExpectationsTest +import semmle.code.cpp.security.FlowSources + +class RemoteFlowSinkTest extends InlineExpectationsTest { + RemoteFlowSinkTest() { this = "RemoteFlowSinkTest" } + + override string getARelevantTag() { result = "remote" } + + override predicate hasActualResult(Location location, string element, string tag, string value) { + tag = "remote" and + value = "" and + exists(RemoteFlowSink node | + location = node.getLocation() and + element = node.toString() + ) + } +} diff --git a/cpp/ql/test/library-tests/dataflow/fields/conflated.cpp b/cpp/ql/test/library-tests/dataflow/fields/conflated.cpp new file mode 100644 index 00000000000..aa600a99a5e --- /dev/null +++ b/cpp/ql/test/library-tests/dataflow/fields/conflated.cpp @@ -0,0 +1,62 @@ +int user_input(); +void sink(int); + +struct A { + int* p; + int x; +}; + +void pointer_without_allocation(const A& ra) { + *ra.p = user_input(); + sink(*ra.p); // $ MISSING: ast,ir +} + +void argument_source(void*); +void sink(void*); + +void pointer_without_allocation_2() { + char *raw; + argument_source(raw); + sink(raw); // $ ast MISSING: ir +} + +A* makeA() { + return new A; +} + +void no_InitializeDynamicAllocation_instruction() { + A* pa = makeA(); + pa->x = user_input(); + sink(pa->x); // $ ast MISSING: ir +} + +void fresh_or_arg(A* arg, bool unknown) { + A* pa; + pa = unknown ? arg : new A; + pa->x = user_input(); + sink(pa->x); // $ ast MISSING: ir +} + +struct LinkedList { + LinkedList* next; + int y; + + LinkedList() = default; + LinkedList(LinkedList* next) : next(next) {} +}; + +// Note: This example also suffers from #113: there is no ChiInstruction that merges the result of the +// InitializeDynamicAllocation instruction into {AllAliasedMemory}. But even when that's fixed there's +// still no dataflow because `ll->next->y = user_input()` writes to {AllAliasedMemory}. +void too_many_indirections() { + LinkedList* ll = new LinkedList; + ll->next = new LinkedList; + ll->next->y = user_input(); + sink(ll->next->y); // $ ast MISSING: ir +} + +void too_many_indirections_2(LinkedList* next) { + LinkedList* ll = new LinkedList(next); + ll->next->y = user_input(); + sink(ll->next->y); // $ ast MISSING: ir +} diff --git a/cpp/ql/test/library-tests/dataflow/fields/dataflow-consistency.expected b/cpp/ql/test/library-tests/dataflow/fields/dataflow-consistency.expected index 49b12c14350..c6528723d22 100644 --- a/cpp/ql/test/library-tests/dataflow/fields/dataflow-consistency.expected +++ b/cpp/ql/test/library-tests/dataflow/fields/dataflow-consistency.expected @@ -121,6 +121,13 @@ postWithInFlow | by_reference.cpp:127:30:127:38 | inner_ptr [inner post update] | PostUpdateNode should not be the target of local flow. | | complex.cpp:11:22:11:23 | a_ [post update] | PostUpdateNode should not be the target of local flow. | | complex.cpp:12:22:12:23 | b_ [post update] | PostUpdateNode should not be the target of local flow. | +| conflated.cpp:10:3:10:7 | * ... [post update] | PostUpdateNode should not be the target of local flow. | +| conflated.cpp:10:7:10:7 | p [inner post update] | PostUpdateNode should not be the target of local flow. | +| conflated.cpp:29:7:29:7 | x [post update] | PostUpdateNode should not be the target of local flow. | +| conflated.cpp:36:7:36:7 | x [post update] | PostUpdateNode should not be the target of local flow. | +| conflated.cpp:53:7:53:10 | next [post update] | PostUpdateNode should not be the target of local flow. | +| conflated.cpp:54:13:54:13 | y [post update] | PostUpdateNode should not be the target of local flow. | +| conflated.cpp:60:13:60:13 | y [post update] | PostUpdateNode should not be the target of local flow. | | constructors.cpp:20:24:20:25 | a_ [post update] | PostUpdateNode should not be the target of local flow. | | constructors.cpp:21:24:21:25 | b_ [post update] | PostUpdateNode should not be the target of local flow. | | qualifiers.cpp:9:36:9:36 | a [post update] | PostUpdateNode should not be the target of local flow. | diff --git a/cpp/ql/test/library-tests/dataflow/fields/dataflow-ir-consistency.expected b/cpp/ql/test/library-tests/dataflow/fields/dataflow-ir-consistency.expected index b09317c2c1b..63d3b2c0f48 100644 --- a/cpp/ql/test/library-tests/dataflow/fields/dataflow-ir-consistency.expected +++ b/cpp/ql/test/library-tests/dataflow/fields/dataflow-ir-consistency.expected @@ -1,6 +1,10 @@ uniqueEnclosingCallable uniqueType uniqueNodeLocation +| E.cpp:15:31:15:33 | buf | Node should have one location but has 2. | +| aliasing.cpp:2:11:2:13 | (unnamed parameter 0) | Node should have one location but has 2. | +| conflated.cpp:2:11:2:13 | (unnamed parameter 0) | Node should have one location but has 2. | +| conflated.cpp:14:22:14:25 | buf | Node should have one location but has 2. | | file://:0:0:0:0 | (unnamed parameter 0) | Node should have one location but has 0. | | file://:0:0:0:0 | (unnamed parameter 0) | Node should have one location but has 0. | | file://:0:0:0:0 | (unnamed parameter 0) | Node should have one location but has 0. | @@ -129,6 +133,8 @@ postWithInFlow | complex.cpp:54:12:54:12 | Chi | PostUpdateNode should not be the target of local flow. | | complex.cpp:55:12:55:12 | Chi | PostUpdateNode should not be the target of local flow. | | complex.cpp:56:12:56:12 | Chi | PostUpdateNode should not be the target of local flow. | +| conflated.cpp:45:39:45:42 | Chi | PostUpdateNode should not be the target of local flow. | +| conflated.cpp:53:3:53:27 | Chi | PostUpdateNode should not be the target of local flow. | | constructors.cpp:20:24:20:29 | Chi | PostUpdateNode should not be the target of local flow. | | constructors.cpp:21:24:21:29 | Chi | PostUpdateNode should not be the target of local flow. | | constructors.cpp:23:28:23:28 | Chi | PostUpdateNode should not be the target of local flow. | diff --git a/cpp/ql/test/library-tests/dataflow/fields/partial-definition-diff.expected b/cpp/ql/test/library-tests/dataflow/fields/partial-definition-diff.expected index bba86417ca5..996836a65b4 100644 --- a/cpp/ql/test/library-tests/dataflow/fields/partial-definition-diff.expected +++ b/cpp/ql/test/library-tests/dataflow/fields/partial-definition-diff.expected @@ -309,6 +309,22 @@ | complex.cpp:62:7:62:8 | b2 | AST only | | complex.cpp:65:7:65:8 | b3 | AST only | | complex.cpp:68:7:68:8 | b4 | AST only | +| conflated.cpp:10:3:10:7 | * ... | AST only | +| conflated.cpp:10:4:10:5 | ra | AST only | +| conflated.cpp:19:19:19:21 | raw | AST only | +| conflated.cpp:20:8:20:10 | raw | AST only | +| conflated.cpp:29:3:29:4 | pa | AST only | +| conflated.cpp:29:7:29:7 | x | AST only | +| conflated.cpp:36:3:36:4 | pa | AST only | +| conflated.cpp:36:7:36:7 | x | AST only | +| conflated.cpp:53:7:53:10 | next | AST only | +| conflated.cpp:54:3:54:4 | ll | AST only | +| conflated.cpp:54:7:54:10 | next | AST only | +| conflated.cpp:54:13:54:13 | y | AST only | +| conflated.cpp:59:35:59:38 | next | AST only | +| conflated.cpp:60:3:60:4 | ll | AST only | +| conflated.cpp:60:7:60:10 | next | AST only | +| conflated.cpp:60:13:60:13 | y | AST only | | constructors.cpp:20:24:20:25 | a_ | AST only | | constructors.cpp:21:24:21:25 | b_ | AST only | | constructors.cpp:28:10:28:10 | f | AST only | diff --git a/cpp/ql/test/library-tests/dataflow/fields/partial-definition-ir.expected b/cpp/ql/test/library-tests/dataflow/fields/partial-definition-ir.expected index 8d12b2a7e05..294c46a5694 100644 --- a/cpp/ql/test/library-tests/dataflow/fields/partial-definition-ir.expected +++ b/cpp/ql/test/library-tests/dataflow/fields/partial-definition-ir.expected @@ -57,6 +57,7 @@ | complex.cpp:54:6:54:10 | inner | | complex.cpp:55:6:55:10 | inner | | complex.cpp:56:6:56:10 | inner | +| conflated.cpp:53:3:53:4 | ll | | constructors.cpp:20:24:20:25 | this | | constructors.cpp:21:24:21:25 | this | | qualifiers.cpp:9:30:9:33 | this | diff --git a/cpp/ql/test/library-tests/dataflow/fields/partial-definition.expected b/cpp/ql/test/library-tests/dataflow/fields/partial-definition.expected index 6c58d51ff74..9b03e4f8039 100644 --- a/cpp/ql/test/library-tests/dataflow/fields/partial-definition.expected +++ b/cpp/ql/test/library-tests/dataflow/fields/partial-definition.expected @@ -366,6 +366,23 @@ | complex.cpp:62:7:62:8 | b2 | | complex.cpp:65:7:65:8 | b3 | | complex.cpp:68:7:68:8 | b4 | +| conflated.cpp:10:3:10:7 | * ... | +| conflated.cpp:10:4:10:5 | ra | +| conflated.cpp:19:19:19:21 | raw | +| conflated.cpp:20:8:20:10 | raw | +| conflated.cpp:29:3:29:4 | pa | +| conflated.cpp:29:7:29:7 | x | +| conflated.cpp:36:3:36:4 | pa | +| conflated.cpp:36:7:36:7 | x | +| conflated.cpp:53:3:53:4 | ll | +| conflated.cpp:53:7:53:10 | next | +| conflated.cpp:54:3:54:4 | ll | +| conflated.cpp:54:7:54:10 | next | +| conflated.cpp:54:13:54:13 | y | +| conflated.cpp:59:35:59:38 | next | +| conflated.cpp:60:3:60:4 | ll | +| conflated.cpp:60:7:60:10 | next | +| conflated.cpp:60:13:60:13 | y | | constructors.cpp:20:24:20:25 | a_ | | constructors.cpp:20:24:20:25 | this | | constructors.cpp:21:24:21:25 | b_ | diff --git a/cpp/ql/test/library-tests/dataflow/fields/path-flow.expected b/cpp/ql/test/library-tests/dataflow/fields/path-flow.expected index b932e0395f4..6604dde87d4 100644 --- a/cpp/ql/test/library-tests/dataflow/fields/path-flow.expected +++ b/cpp/ql/test/library-tests/dataflow/fields/path-flow.expected @@ -336,6 +336,27 @@ edges | complex.cpp:62:7:62:8 | b2 [inner, f, b_] | complex.cpp:40:17:40:17 | b [inner, f, b_] | | complex.cpp:65:7:65:8 | b3 [inner, f, a_] | complex.cpp:40:17:40:17 | b [inner, f, a_] | | complex.cpp:65:7:65:8 | b3 [inner, f, b_] | complex.cpp:40:17:40:17 | b [inner, f, b_] | +| conflated.cpp:19:19:19:21 | ref arg raw | conflated.cpp:20:8:20:10 | raw | +| conflated.cpp:29:3:29:4 | pa [post update] [x] | conflated.cpp:30:8:30:9 | pa [x] | +| conflated.cpp:29:3:29:22 | ... = ... | conflated.cpp:29:3:29:4 | pa [post update] [x] | +| conflated.cpp:29:11:29:20 | call to user_input | conflated.cpp:29:3:29:22 | ... = ... | +| conflated.cpp:30:8:30:9 | pa [x] | conflated.cpp:30:12:30:12 | x | +| conflated.cpp:36:3:36:4 | pa [post update] [x] | conflated.cpp:37:8:37:9 | pa [x] | +| conflated.cpp:36:3:36:22 | ... = ... | conflated.cpp:36:3:36:4 | pa [post update] [x] | +| conflated.cpp:36:11:36:20 | call to user_input | conflated.cpp:36:3:36:22 | ... = ... | +| conflated.cpp:37:8:37:9 | pa [x] | conflated.cpp:37:12:37:12 | x | +| conflated.cpp:54:3:54:4 | ll [post update] [next, y] | conflated.cpp:55:8:55:9 | ll [next, y] | +| conflated.cpp:54:3:54:28 | ... = ... | conflated.cpp:54:7:54:10 | next [post update] [y] | +| conflated.cpp:54:7:54:10 | next [post update] [y] | conflated.cpp:54:3:54:4 | ll [post update] [next, y] | +| conflated.cpp:54:17:54:26 | call to user_input | conflated.cpp:54:3:54:28 | ... = ... | +| conflated.cpp:55:8:55:9 | ll [next, y] | conflated.cpp:55:12:55:15 | next [y] | +| conflated.cpp:55:12:55:15 | next [y] | conflated.cpp:55:18:55:18 | y | +| conflated.cpp:60:3:60:4 | ll [post update] [next, y] | conflated.cpp:61:8:61:9 | ll [next, y] | +| conflated.cpp:60:3:60:28 | ... = ... | conflated.cpp:60:7:60:10 | next [post update] [y] | +| conflated.cpp:60:7:60:10 | next [post update] [y] | conflated.cpp:60:3:60:4 | ll [post update] [next, y] | +| conflated.cpp:60:17:60:26 | call to user_input | conflated.cpp:60:3:60:28 | ... = ... | +| conflated.cpp:61:8:61:9 | ll [next, y] | conflated.cpp:61:12:61:15 | next [y] | +| conflated.cpp:61:12:61:15 | next [y] | conflated.cpp:61:18:61:18 | y | | constructors.cpp:26:15:26:15 | f [a_] | constructors.cpp:28:10:28:10 | f [a_] | | constructors.cpp:26:15:26:15 | f [b_] | constructors.cpp:29:10:29:10 | f [b_] | | constructors.cpp:28:10:28:10 | f [a_] | constructors.cpp:28:12:28:12 | call to a | @@ -827,6 +848,32 @@ nodes | complex.cpp:62:7:62:8 | b2 [inner, f, b_] | semmle.label | b2 [inner, f, b_] | | complex.cpp:65:7:65:8 | b3 [inner, f, a_] | semmle.label | b3 [inner, f, a_] | | complex.cpp:65:7:65:8 | b3 [inner, f, b_] | semmle.label | b3 [inner, f, b_] | +| conflated.cpp:19:19:19:21 | ref arg raw | semmle.label | ref arg raw | +| conflated.cpp:20:8:20:10 | raw | semmle.label | raw | +| conflated.cpp:29:3:29:4 | pa [post update] [x] | semmle.label | pa [post update] [x] | +| conflated.cpp:29:3:29:22 | ... = ... | semmle.label | ... = ... | +| conflated.cpp:29:11:29:20 | call to user_input | semmle.label | call to user_input | +| conflated.cpp:30:8:30:9 | pa [x] | semmle.label | pa [x] | +| conflated.cpp:30:12:30:12 | x | semmle.label | x | +| conflated.cpp:36:3:36:4 | pa [post update] [x] | semmle.label | pa [post update] [x] | +| conflated.cpp:36:3:36:22 | ... = ... | semmle.label | ... = ... | +| conflated.cpp:36:11:36:20 | call to user_input | semmle.label | call to user_input | +| conflated.cpp:37:8:37:9 | pa [x] | semmle.label | pa [x] | +| conflated.cpp:37:12:37:12 | x | semmle.label | x | +| conflated.cpp:54:3:54:4 | ll [post update] [next, y] | semmle.label | ll [post update] [next, y] | +| conflated.cpp:54:3:54:28 | ... = ... | semmle.label | ... = ... | +| conflated.cpp:54:7:54:10 | next [post update] [y] | semmle.label | next [post update] [y] | +| conflated.cpp:54:17:54:26 | call to user_input | semmle.label | call to user_input | +| conflated.cpp:55:8:55:9 | ll [next, y] | semmle.label | ll [next, y] | +| conflated.cpp:55:12:55:15 | next [y] | semmle.label | next [y] | +| conflated.cpp:55:18:55:18 | y | semmle.label | y | +| conflated.cpp:60:3:60:4 | ll [post update] [next, y] | semmle.label | ll [post update] [next, y] | +| conflated.cpp:60:3:60:28 | ... = ... | semmle.label | ... = ... | +| conflated.cpp:60:7:60:10 | next [post update] [y] | semmle.label | next [post update] [y] | +| conflated.cpp:60:17:60:26 | call to user_input | semmle.label | call to user_input | +| conflated.cpp:61:8:61:9 | ll [next, y] | semmle.label | ll [next, y] | +| conflated.cpp:61:12:61:15 | next [y] | semmle.label | next [y] | +| conflated.cpp:61:18:61:18 | y | semmle.label | y | | constructors.cpp:26:15:26:15 | f [a_] | semmle.label | f [a_] | | constructors.cpp:26:15:26:15 | f [b_] | semmle.label | f [b_] | | constructors.cpp:28:10:28:10 | f [a_] | semmle.label | f [a_] | @@ -1028,6 +1075,11 @@ nodes | complex.cpp:42:18:42:18 | call to a | complex.cpp:55:19:55:28 | call to user_input | complex.cpp:42:18:42:18 | call to a | call to a flows from $@ | complex.cpp:55:19:55:28 | call to user_input | call to user_input | | complex.cpp:43:18:43:18 | call to b | complex.cpp:54:19:54:28 | call to user_input | complex.cpp:43:18:43:18 | call to b | call to b flows from $@ | complex.cpp:54:19:54:28 | call to user_input | call to user_input | | complex.cpp:43:18:43:18 | call to b | complex.cpp:56:19:56:28 | call to user_input | complex.cpp:43:18:43:18 | call to b | call to b flows from $@ | complex.cpp:56:19:56:28 | call to user_input | call to user_input | +| conflated.cpp:20:8:20:10 | raw | conflated.cpp:19:19:19:21 | ref arg raw | conflated.cpp:20:8:20:10 | raw | raw flows from $@ | conflated.cpp:19:19:19:21 | ref arg raw | ref arg raw | +| conflated.cpp:30:12:30:12 | x | conflated.cpp:29:11:29:20 | call to user_input | conflated.cpp:30:12:30:12 | x | x flows from $@ | conflated.cpp:29:11:29:20 | call to user_input | call to user_input | +| conflated.cpp:37:12:37:12 | x | conflated.cpp:36:11:36:20 | call to user_input | conflated.cpp:37:12:37:12 | x | x flows from $@ | conflated.cpp:36:11:36:20 | call to user_input | call to user_input | +| conflated.cpp:55:18:55:18 | y | conflated.cpp:54:17:54:26 | call to user_input | conflated.cpp:55:18:55:18 | y | y flows from $@ | conflated.cpp:54:17:54:26 | call to user_input | call to user_input | +| conflated.cpp:61:18:61:18 | y | conflated.cpp:60:17:60:26 | call to user_input | conflated.cpp:61:18:61:18 | y | y flows from $@ | conflated.cpp:60:17:60:26 | call to user_input | call to user_input | | constructors.cpp:28:12:28:12 | call to a | constructors.cpp:34:11:34:20 | call to user_input | constructors.cpp:28:12:28:12 | call to a | call to a flows from $@ | constructors.cpp:34:11:34:20 | call to user_input | call to user_input | | constructors.cpp:28:12:28:12 | call to a | constructors.cpp:36:11:36:20 | call to user_input | constructors.cpp:28:12:28:12 | call to a | call to a flows from $@ | constructors.cpp:36:11:36:20 | call to user_input | call to user_input | | constructors.cpp:29:12:29:12 | call to b | constructors.cpp:35:14:35:23 | call to user_input | constructors.cpp:29:12:29:12 | call to b | call to b flows from $@ | constructors.cpp:35:14:35:23 | call to user_input | call to user_input | diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/constructor_delegation.cpp b/cpp/ql/test/library-tests/dataflow/taint-tests/constructor_delegation.cpp new file mode 100644 index 00000000000..d1acc67f81f --- /dev/null +++ b/cpp/ql/test/library-tests/dataflow/taint-tests/constructor_delegation.cpp @@ -0,0 +1,47 @@ + +int source(); +void sink(...); + +class MyValue +{ +public: + MyValue(int _x) : x(_x) {}; // taint flows from parameter `_x` to member variable `x` + MyValue(int _x, bool ex) : MyValue(_x) {}; // taint flows from parameter `_x` to member variable `x` + MyValue(int _x, int _y) : MyValue(_x + _y) {}; // taint flows from parameters `_x` and `_y` to member variable `x` + MyValue(int _x, bool ex1, bool ex2) : MyValue(0) {}; // taint doesn't flow from parameter `_x` + + int x; +}; + +class MyDerivedValue : public MyValue +{ +public: + MyDerivedValue(bool ex, int _x) : MyValue(_x) {}; // taint flows from parameter `_x` to member variable `x` +}; + +void test_inits() +{ + MyValue v1(0); + MyValue v2(source()); + MyValue v3(0, true); + MyValue v4(source(), true); + MyValue v5(0, 1); + MyValue v6(source(), 1); + MyValue v7(0, source()); + MyValue v8(0, true, true); + MyValue v9(source(), true, true); + MyDerivedValue v10(true, 0); + MyDerivedValue v11(true, source()); + + sink(v1.x); + sink(v2.x); // $ ast,ir + sink(v3.x); + sink(v4.x); // $ ir MISSING: ast + sink(v5.x); + sink(v6.x); // $ ir MISSING: ast + sink(v7.x); // $ ir MISSING: ast + sink(v8.x); + sink(v9.x); + sink(v10.x); + sink(v11.x); // $ ir MISSING: ast +} diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/format.cpp b/cpp/ql/test/library-tests/dataflow/taint-tests/format.cpp index 77c42570721..c6b877e9ca8 100644 --- a/cpp/ql/test/library-tests/dataflow/taint-tests/format.cpp +++ b/cpp/ql/test/library-tests/dataflow/taint-tests/format.cpp @@ -123,7 +123,7 @@ void test1() { int i = 0; sink(sscanf(string::source(), "%i", &i)); - sink(i); // $ MISSING: ast,ir + sink(i); // $ ast,ir } { char buffer[256] = {0}; @@ -133,7 +133,7 @@ void test1() { char buffer[256] = {0}; sink(sscanf(string::source(), "%s", &buffer)); - sink(buffer); // $ MISSING: ast,ir + sink(buffer); // $ ast,ir } } diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/localTaint.expected b/cpp/ql/test/library-tests/dataflow/taint-tests/localTaint.expected index 4407266a6e7..9f038101d67 100644 --- a/cpp/ql/test/library-tests/dataflow/taint-tests/localTaint.expected +++ b/cpp/ql/test/library-tests/dataflow/taint-tests/localTaint.expected @@ -135,6 +135,28 @@ | arrayassignment.cpp:145:12:145:12 | 5 | arrayassignment.cpp:145:7:145:13 | access to array | TAINT | | arrayassignment.cpp:146:7:146:10 | arr3 | arrayassignment.cpp:146:7:146:13 | access to array | | | arrayassignment.cpp:146:12:146:12 | 5 | arrayassignment.cpp:146:7:146:13 | access to array | TAINT | +| constructor_delegation.cpp:8:2:8:8 | this | constructor_delegation.cpp:8:20:8:24 | constructor init of field x [pre-this] | | +| constructor_delegation.cpp:8:14:8:15 | _x | constructor_delegation.cpp:8:22:8:23 | _x | | +| constructor_delegation.cpp:8:22:8:23 | _x | constructor_delegation.cpp:8:20:8:24 | constructor init of field x | TAINT | +| constructor_delegation.cpp:9:37:9:38 | _x | constructor_delegation.cpp:9:29:9:39 | call to MyValue | TAINT | +| constructor_delegation.cpp:10:36:10:37 | _x | constructor_delegation.cpp:10:36:10:42 | ... + ... | TAINT | +| constructor_delegation.cpp:10:36:10:42 | ... + ... | constructor_delegation.cpp:10:28:10:43 | call to MyValue | TAINT | +| constructor_delegation.cpp:10:41:10:42 | _y | constructor_delegation.cpp:10:36:10:42 | ... + ... | TAINT | +| constructor_delegation.cpp:11:48:11:48 | 0 | constructor_delegation.cpp:11:40:11:49 | call to MyValue | TAINT | +| constructor_delegation.cpp:19:44:19:45 | _x | constructor_delegation.cpp:19:36:19:46 | call to MyValue | TAINT | +| constructor_delegation.cpp:24:13:24:13 | 0 | constructor_delegation.cpp:24:13:24:14 | call to MyValue | TAINT | +| constructor_delegation.cpp:24:13:24:14 | call to MyValue | constructor_delegation.cpp:36:7:36:8 | v1 | | +| constructor_delegation.cpp:25:13:25:18 | call to source | constructor_delegation.cpp:25:13:25:21 | call to MyValue | TAINT | +| constructor_delegation.cpp:25:13:25:21 | call to MyValue | constructor_delegation.cpp:37:7:37:8 | v2 | | +| constructor_delegation.cpp:26:13:26:20 | call to MyValue | constructor_delegation.cpp:38:7:38:8 | v3 | | +| constructor_delegation.cpp:27:13:27:27 | call to MyValue | constructor_delegation.cpp:39:7:39:8 | v4 | | +| constructor_delegation.cpp:28:13:28:17 | call to MyValue | constructor_delegation.cpp:40:7:40:8 | v5 | | +| constructor_delegation.cpp:29:13:29:24 | call to MyValue | constructor_delegation.cpp:41:7:41:8 | v6 | | +| constructor_delegation.cpp:30:13:30:24 | call to MyValue | constructor_delegation.cpp:42:7:42:8 | v7 | | +| constructor_delegation.cpp:31:13:31:26 | call to MyValue | constructor_delegation.cpp:43:7:43:8 | v8 | | +| constructor_delegation.cpp:32:13:32:33 | call to MyValue | constructor_delegation.cpp:44:7:44:8 | v9 | | +| constructor_delegation.cpp:33:21:33:28 | call to MyDerivedValue | constructor_delegation.cpp:45:7:45:9 | v10 | | +| constructor_delegation.cpp:34:21:34:35 | call to MyDerivedValue | constructor_delegation.cpp:46:7:46:9 | v11 | | | copyableclass.cpp:8:2:8:16 | this | copyableclass.cpp:8:28:8:32 | constructor init of field v [pre-this] | | | copyableclass.cpp:8:22:8:23 | _v | copyableclass.cpp:8:30:8:31 | _v | | | copyableclass.cpp:8:30:8:31 | _v | copyableclass.cpp:8:28:8:32 | constructor init of field v | TAINT | @@ -356,23 +378,27 @@ | format.cpp:114:37:114:50 | call to source | format.cpp:114:18:114:23 | ref arg buffer | TAINT | | format.cpp:119:10:119:11 | 0 | format.cpp:120:29:120:29 | i | | | format.cpp:119:10:119:11 | 0 | format.cpp:121:8:121:8 | i | | +| format.cpp:120:15:120:19 | 123 | format.cpp:120:28:120:29 | ref arg & ... | TAINT | | format.cpp:120:28:120:29 | ref arg & ... | format.cpp:120:29:120:29 | i [inner post update] | | | format.cpp:120:28:120:29 | ref arg & ... | format.cpp:121:8:121:8 | i | | | format.cpp:120:29:120:29 | i | format.cpp:120:28:120:29 | & ... | | | format.cpp:124:10:124:11 | 0 | format.cpp:125:40:125:40 | i | | | format.cpp:124:10:124:11 | 0 | format.cpp:126:8:126:8 | i | | +| format.cpp:125:15:125:28 | call to source | format.cpp:125:39:125:40 | ref arg & ... | TAINT | | format.cpp:125:39:125:40 | ref arg & ... | format.cpp:125:40:125:40 | i [inner post update] | | | format.cpp:125:39:125:40 | ref arg & ... | format.cpp:126:8:126:8 | i | | | format.cpp:125:40:125:40 | i | format.cpp:125:39:125:40 | & ... | | | format.cpp:129:21:129:24 | {...} | format.cpp:130:32:130:37 | buffer | | | format.cpp:129:21:129:24 | {...} | format.cpp:131:8:131:13 | buffer | | | format.cpp:129:23:129:23 | 0 | format.cpp:129:21:129:24 | {...} | TAINT | +| format.cpp:130:15:130:22 | Hello. | format.cpp:130:31:130:37 | ref arg & ... | TAINT | | format.cpp:130:31:130:37 | ref arg & ... | format.cpp:130:32:130:37 | buffer [inner post update] | | | format.cpp:130:31:130:37 | ref arg & ... | format.cpp:131:8:131:13 | buffer | | | format.cpp:130:32:130:37 | buffer | format.cpp:130:31:130:37 | & ... | | | format.cpp:134:21:134:24 | {...} | format.cpp:135:40:135:45 | buffer | | | format.cpp:134:21:134:24 | {...} | format.cpp:136:8:136:13 | buffer | | | format.cpp:134:23:134:23 | 0 | format.cpp:134:21:134:24 | {...} | TAINT | +| format.cpp:135:15:135:28 | call to source | format.cpp:135:39:135:45 | ref arg & ... | TAINT | | format.cpp:135:39:135:45 | ref arg & ... | format.cpp:135:40:135:45 | buffer [inner post update] | | | format.cpp:135:39:135:45 | ref arg & ... | format.cpp:136:8:136:13 | buffer | | | format.cpp:135:40:135:45 | buffer | format.cpp:135:39:135:45 | & ... | | @@ -5004,7 +5030,9 @@ | swap1.cpp:24:9:24:13 | this | swap1.cpp:24:31:24:34 | this | | | swap1.cpp:24:23:24:26 | that | swap1.cpp:24:23:24:26 | that | | | swap1.cpp:24:23:24:26 | that | swap1.cpp:24:36:24:39 | that | | +| swap1.cpp:24:31:24:34 | this | swap1.cpp:24:36:24:39 | ref arg that | TAINT | | swap1.cpp:24:36:24:39 | ref arg that | swap1.cpp:24:23:24:26 | that | | +| swap1.cpp:24:36:24:39 | that | swap1.cpp:24:31:24:34 | ref arg this | TAINT | | swap1.cpp:25:9:25:13 | this | swap1.cpp:25:36:25:52 | constructor init of field data1 [pre-this] | | | swap1.cpp:25:28:25:31 | that | swap1.cpp:25:42:25:45 | that | | | swap1.cpp:25:47:25:51 | data1 | swap1.cpp:25:36:25:52 | constructor init of field data1 | TAINT | @@ -5014,28 +5042,36 @@ | swap1.cpp:29:23:29:27 | call to Class | swap1.cpp:30:18:30:20 | tmp | | | swap1.cpp:29:24:29:27 | that | swap1.cpp:29:23:29:27 | call to Class | | | swap1.cpp:30:13:30:16 | ref arg this | swap1.cpp:31:21:31:24 | this | | +| swap1.cpp:30:13:30:16 | this | swap1.cpp:30:18:30:20 | ref arg tmp | TAINT | | swap1.cpp:30:13:30:16 | this | swap1.cpp:31:21:31:24 | this | | +| swap1.cpp:30:18:30:20 | tmp | swap1.cpp:30:13:30:16 | ref arg this | TAINT | | swap1.cpp:31:21:31:24 | this | swap1.cpp:31:20:31:24 | * ... | TAINT | | swap1.cpp:34:16:34:24 | this | swap1.cpp:36:13:36:16 | this | | | swap1.cpp:34:34:34:37 | that | swap1.cpp:34:34:34:37 | that | | | swap1.cpp:34:34:34:37 | that | swap1.cpp:36:18:36:21 | that | | | swap1.cpp:36:13:36:16 | ref arg this | swap1.cpp:37:21:37:24 | this | | +| swap1.cpp:36:13:36:16 | this | swap1.cpp:36:18:36:21 | ref arg that | TAINT | | swap1.cpp:36:13:36:16 | this | swap1.cpp:37:21:37:24 | this | | | swap1.cpp:36:18:36:21 | ref arg that | swap1.cpp:34:34:34:37 | that | | +| swap1.cpp:36:18:36:21 | that | swap1.cpp:36:13:36:16 | ref arg this | TAINT | | swap1.cpp:37:21:37:24 | this | swap1.cpp:37:20:37:24 | * ... | TAINT | | swap1.cpp:40:16:40:26 | this | swap1.cpp:43:13:43:16 | this | | | swap1.cpp:40:41:40:44 | that | swap1.cpp:42:24:42:27 | that | | | swap1.cpp:42:23:42:27 | call to Class | swap1.cpp:43:18:43:20 | tmp | | | swap1.cpp:42:24:42:27 | that | swap1.cpp:42:23:42:27 | call to Class | | | swap1.cpp:43:13:43:16 | ref arg this | swap1.cpp:44:21:44:24 | this | | +| swap1.cpp:43:13:43:16 | this | swap1.cpp:43:18:43:20 | ref arg tmp | TAINT | | swap1.cpp:43:13:43:16 | this | swap1.cpp:44:21:44:24 | this | | +| swap1.cpp:43:18:43:20 | tmp | swap1.cpp:43:13:43:16 | ref arg this | TAINT | | swap1.cpp:44:21:44:24 | this | swap1.cpp:44:20:44:24 | * ... | TAINT | | swap1.cpp:47:16:47:26 | this | swap1.cpp:49:13:49:16 | this | | | swap1.cpp:47:36:47:39 | that | swap1.cpp:47:36:47:39 | that | | | swap1.cpp:47:36:47:39 | that | swap1.cpp:49:18:49:21 | that | | | swap1.cpp:49:13:49:16 | ref arg this | swap1.cpp:50:21:50:24 | this | | +| swap1.cpp:49:13:49:16 | this | swap1.cpp:49:18:49:21 | ref arg that | TAINT | | swap1.cpp:49:13:49:16 | this | swap1.cpp:50:21:50:24 | this | | | swap1.cpp:49:18:49:21 | ref arg that | swap1.cpp:47:36:47:39 | that | | +| swap1.cpp:49:18:49:21 | that | swap1.cpp:49:13:49:16 | ref arg this | TAINT | | swap1.cpp:50:21:50:24 | this | swap1.cpp:50:20:50:24 | * ... | TAINT | | swap1.cpp:53:14:53:17 | this | swap1.cpp:56:18:56:22 | this | | | swap1.cpp:53:26:53:29 | that | swap1.cpp:53:26:53:29 | that | | @@ -5049,7 +5085,9 @@ | swap1.cpp:61:32:61:32 | y | swap1.cpp:61:32:61:32 | y | | | swap1.cpp:61:32:61:32 | y | swap1.cpp:63:16:63:16 | y | | | swap1.cpp:63:9:63:9 | ref arg x | swap1.cpp:61:22:61:22 | x | | +| swap1.cpp:63:9:63:9 | x | swap1.cpp:63:16:63:16 | ref arg y | TAINT | | swap1.cpp:63:16:63:16 | ref arg y | swap1.cpp:61:32:61:32 | y | | +| swap1.cpp:63:16:63:16 | y | swap1.cpp:63:9:63:9 | ref arg x | TAINT | | swap1.cpp:69:23:69:23 | x | swap1.cpp:71:5:71:5 | x | | | swap1.cpp:69:23:69:23 | x | swap1.cpp:73:10:73:10 | x | | | swap1.cpp:69:23:69:23 | x | swap1.cpp:76:9:76:9 | x | | @@ -5158,7 +5196,9 @@ | swap2.cpp:24:9:24:13 | this | swap2.cpp:24:31:24:34 | this | | | swap2.cpp:24:23:24:26 | that | swap2.cpp:24:23:24:26 | that | | | swap2.cpp:24:23:24:26 | that | swap2.cpp:24:36:24:39 | that | | +| swap2.cpp:24:31:24:34 | this | swap2.cpp:24:36:24:39 | ref arg that | TAINT | | swap2.cpp:24:36:24:39 | ref arg that | swap2.cpp:24:23:24:26 | that | | +| swap2.cpp:24:36:24:39 | that | swap2.cpp:24:31:24:34 | ref arg this | TAINT | | swap2.cpp:25:9:25:13 | this | swap2.cpp:25:36:25:52 | constructor init of field data1 [pre-this] | | | swap2.cpp:25:28:25:31 | that | swap2.cpp:25:42:25:45 | that | | | swap2.cpp:25:28:25:31 | that | swap2.cpp:25:61:25:64 | that | | @@ -5173,28 +5213,36 @@ | swap2.cpp:29:23:29:27 | call to Class | swap2.cpp:30:18:30:20 | tmp | | | swap2.cpp:29:24:29:27 | that | swap2.cpp:29:23:29:27 | call to Class | | | swap2.cpp:30:13:30:16 | ref arg this | swap2.cpp:31:21:31:24 | this | | +| swap2.cpp:30:13:30:16 | this | swap2.cpp:30:18:30:20 | ref arg tmp | TAINT | | swap2.cpp:30:13:30:16 | this | swap2.cpp:31:21:31:24 | this | | +| swap2.cpp:30:18:30:20 | tmp | swap2.cpp:30:13:30:16 | ref arg this | TAINT | | swap2.cpp:31:21:31:24 | this | swap2.cpp:31:20:31:24 | * ... | TAINT | | swap2.cpp:34:16:34:24 | this | swap2.cpp:36:13:36:16 | this | | | swap2.cpp:34:34:34:37 | that | swap2.cpp:34:34:34:37 | that | | | swap2.cpp:34:34:34:37 | that | swap2.cpp:36:18:36:21 | that | | | swap2.cpp:36:13:36:16 | ref arg this | swap2.cpp:37:21:37:24 | this | | +| swap2.cpp:36:13:36:16 | this | swap2.cpp:36:18:36:21 | ref arg that | TAINT | | swap2.cpp:36:13:36:16 | this | swap2.cpp:37:21:37:24 | this | | | swap2.cpp:36:18:36:21 | ref arg that | swap2.cpp:34:34:34:37 | that | | +| swap2.cpp:36:18:36:21 | that | swap2.cpp:36:13:36:16 | ref arg this | TAINT | | swap2.cpp:37:21:37:24 | this | swap2.cpp:37:20:37:24 | * ... | TAINT | | swap2.cpp:40:16:40:26 | this | swap2.cpp:43:13:43:16 | this | | | swap2.cpp:40:41:40:44 | that | swap2.cpp:42:24:42:27 | that | | | swap2.cpp:42:23:42:27 | call to Class | swap2.cpp:43:18:43:20 | tmp | | | swap2.cpp:42:24:42:27 | that | swap2.cpp:42:23:42:27 | call to Class | | | swap2.cpp:43:13:43:16 | ref arg this | swap2.cpp:44:21:44:24 | this | | +| swap2.cpp:43:13:43:16 | this | swap2.cpp:43:18:43:20 | ref arg tmp | TAINT | | swap2.cpp:43:13:43:16 | this | swap2.cpp:44:21:44:24 | this | | +| swap2.cpp:43:18:43:20 | tmp | swap2.cpp:43:13:43:16 | ref arg this | TAINT | | swap2.cpp:44:21:44:24 | this | swap2.cpp:44:20:44:24 | * ... | TAINT | | swap2.cpp:47:16:47:26 | this | swap2.cpp:49:13:49:16 | this | | | swap2.cpp:47:36:47:39 | that | swap2.cpp:47:36:47:39 | that | | | swap2.cpp:47:36:47:39 | that | swap2.cpp:49:18:49:21 | that | | | swap2.cpp:49:13:49:16 | ref arg this | swap2.cpp:50:21:50:24 | this | | +| swap2.cpp:49:13:49:16 | this | swap2.cpp:49:18:49:21 | ref arg that | TAINT | | swap2.cpp:49:13:49:16 | this | swap2.cpp:50:21:50:24 | this | | | swap2.cpp:49:18:49:21 | ref arg that | swap2.cpp:47:36:47:39 | that | | +| swap2.cpp:49:18:49:21 | that | swap2.cpp:49:13:49:16 | ref arg this | TAINT | | swap2.cpp:50:21:50:24 | this | swap2.cpp:50:20:50:24 | * ... | TAINT | | swap2.cpp:53:14:53:17 | this | swap2.cpp:56:18:56:22 | this | | | swap2.cpp:53:26:53:29 | that | swap2.cpp:53:26:53:29 | that | | @@ -5216,7 +5264,9 @@ | swap2.cpp:61:32:61:32 | y | swap2.cpp:61:32:61:32 | y | | | swap2.cpp:61:32:61:32 | y | swap2.cpp:63:16:63:16 | y | | | swap2.cpp:63:9:63:9 | ref arg x | swap2.cpp:61:22:61:22 | x | | +| swap2.cpp:63:9:63:9 | x | swap2.cpp:63:16:63:16 | ref arg y | TAINT | | swap2.cpp:63:16:63:16 | ref arg y | swap2.cpp:61:32:61:32 | y | | +| swap2.cpp:63:16:63:16 | y | swap2.cpp:63:9:63:9 | ref arg x | TAINT | | swap2.cpp:69:23:69:23 | x | swap2.cpp:71:5:71:5 | x | | | swap2.cpp:69:23:69:23 | x | swap2.cpp:73:10:73:10 | x | | | swap2.cpp:69:23:69:23 | x | swap2.cpp:76:9:76:9 | x | | @@ -5815,6 +5865,183 @@ | taint.cpp:483:18:483:19 | ref arg & ... | taint.cpp:483:19:483:19 | n [inner post update] | | | taint.cpp:483:19:483:19 | n | taint.cpp:483:18:483:19 | & ... | | | taint.cpp:483:28:483:34 | source1 | taint.cpp:483:11:483:15 | ref arg & ... | TAINT | +| taint.cpp:492:24:492:29 | source | taint.cpp:494:27:494:32 | source | | +| taint.cpp:493:22:493:29 | ,.-;:_ | taint.cpp:494:35:494:39 | delim | | +| taint.cpp:493:22:493:29 | ,.-;:_ | taint.cpp:496:7:496:11 | delim | | +| taint.cpp:494:20:494:25 | call to strtok | taint.cpp:495:7:495:15 | tokenized | | +| taint.cpp:494:27:494:32 | source | taint.cpp:494:20:494:25 | call to strtok | TAINT | +| taint.cpp:503:26:503:28 | ptr | taint.cpp:504:10:504:12 | ptr | | +| taint.cpp:503:26:503:28 | ptr | taint.cpp:505:7:505:9 | ptr | | +| taint.cpp:503:26:503:28 | ptr | taint.cpp:506:8:506:10 | ptr | | +| taint.cpp:503:36:503:41 | source | taint.cpp:504:15:504:20 | source | | +| taint.cpp:504:10:504:12 | ptr | taint.cpp:504:2:504:8 | call to _strset | | +| taint.cpp:504:10:504:12 | ref arg ptr | taint.cpp:505:7:505:9 | ptr | | +| taint.cpp:504:10:504:12 | ref arg ptr | taint.cpp:506:8:506:10 | ptr | | +| taint.cpp:504:15:504:20 | source | taint.cpp:504:2:504:8 | call to _strset | TAINT | +| taint.cpp:504:15:504:20 | source | taint.cpp:504:10:504:12 | ref arg ptr | | +| taint.cpp:505:7:505:9 | ref arg ptr | taint.cpp:506:8:506:10 | ptr | | +| taint.cpp:506:8:506:10 | ptr | taint.cpp:506:7:506:10 | * ... | TAINT | +| taint.cpp:509:26:509:31 | source | taint.cpp:510:10:510:15 | source | | +| taint.cpp:509:26:509:31 | source | taint.cpp:511:7:511:12 | source | | +| taint.cpp:510:10:510:15 | ref arg source | taint.cpp:511:7:511:12 | source | | +| taint.cpp:510:10:510:15 | source | taint.cpp:510:2:510:8 | call to _strset | | +| taint.cpp:510:18:510:18 | 0 | taint.cpp:510:2:510:8 | call to _strset | TAINT | +| taint.cpp:510:18:510:18 | 0 | taint.cpp:510:10:510:15 | ref arg source | | +| taint.cpp:518:24:518:29 | source | taint.cpp:520:14:520:19 | source | | +| taint.cpp:519:6:519:6 | x | taint.cpp:520:11:520:11 | x | | +| taint.cpp:519:6:519:6 | x | taint.cpp:521:7:521:7 | x | | +| taint.cpp:520:10:520:11 | & ... | taint.cpp:520:2:520:8 | call to mempcpy | | +| taint.cpp:520:10:520:11 | ref arg & ... | taint.cpp:520:11:520:11 | x [inner post update] | | +| taint.cpp:520:10:520:11 | ref arg & ... | taint.cpp:521:7:521:7 | x | | +| taint.cpp:520:11:520:11 | x | taint.cpp:520:10:520:11 | & ... | | +| taint.cpp:520:14:520:19 | source | taint.cpp:520:2:520:8 | call to mempcpy | TAINT | +| taint.cpp:520:14:520:19 | source | taint.cpp:520:10:520:11 | ref arg & ... | TAINT | +| taint.cpp:528:24:528:29 | source | taint.cpp:530:16:530:21 | source | | +| taint.cpp:529:6:529:9 | dest | taint.cpp:530:10:530:13 | dest | | +| taint.cpp:529:6:529:9 | dest | taint.cpp:530:35:530:38 | dest | | +| taint.cpp:529:6:529:9 | dest | taint.cpp:531:7:531:10 | dest | | +| taint.cpp:530:10:530:13 | dest | taint.cpp:530:2:530:8 | call to memccpy | | +| taint.cpp:530:10:530:13 | ref arg dest | taint.cpp:531:7:531:10 | dest | | +| taint.cpp:530:16:530:21 | source | taint.cpp:530:2:530:8 | call to memccpy | TAINT | +| taint.cpp:530:16:530:21 | source | taint.cpp:530:10:530:13 | ref arg dest | TAINT | +| taint.cpp:538:24:538:28 | dest1 | taint.cpp:539:9:539:13 | dest1 | | +| taint.cpp:538:24:538:28 | dest1 | taint.cpp:540:7:540:11 | dest1 | | +| taint.cpp:538:37:538:41 | dest2 | taint.cpp:542:9:542:13 | dest2 | | +| taint.cpp:538:37:538:41 | dest2 | taint.cpp:543:7:543:11 | dest2 | | +| taint.cpp:538:50:538:54 | clean | taint.cpp:542:16:542:20 | clean | | +| taint.cpp:538:63:538:68 | source | taint.cpp:539:16:539:21 | source | | +| taint.cpp:539:9:539:13 | dest1 | taint.cpp:539:2:539:7 | call to strcat | | +| taint.cpp:539:9:539:13 | dest1 | taint.cpp:539:9:539:13 | ref arg dest1 | TAINT | +| taint.cpp:539:9:539:13 | ref arg dest1 | taint.cpp:540:7:540:11 | dest1 | | +| taint.cpp:539:16:539:21 | source | taint.cpp:539:9:539:13 | ref arg dest1 | TAINT | +| taint.cpp:542:9:542:13 | dest2 | taint.cpp:542:2:542:7 | call to strcat | | +| taint.cpp:542:9:542:13 | dest2 | taint.cpp:542:9:542:13 | ref arg dest2 | TAINT | +| taint.cpp:542:9:542:13 | ref arg dest2 | taint.cpp:543:7:543:11 | dest2 | | +| taint.cpp:542:16:542:20 | clean | taint.cpp:542:9:542:13 | ref arg dest2 | TAINT | +| taint.cpp:550:37:550:41 | dest1 | taint.cpp:552:36:552:40 | dest1 | | +| taint.cpp:550:37:550:41 | dest1 | taint.cpp:553:7:553:11 | dest1 | | +| taint.cpp:550:37:550:41 | dest1 | taint.cpp:554:8:554:12 | dest1 | | +| taint.cpp:550:65:550:67 | ptr | taint.cpp:552:43:552:45 | ptr | | +| taint.cpp:550:65:550:67 | ptr | taint.cpp:558:43:558:45 | ptr | | +| taint.cpp:550:85:550:89 | dest3 | taint.cpp:558:36:558:40 | dest3 | | +| taint.cpp:550:85:550:89 | dest3 | taint.cpp:559:7:559:11 | dest3 | | +| taint.cpp:550:85:550:89 | dest3 | taint.cpp:560:8:560:12 | dest3 | | +| taint.cpp:551:32:551:36 | clean | taint.cpp:558:51:558:55 | clean | | +| taint.cpp:551:49:551:54 | source | taint.cpp:552:51:552:56 | source | | +| taint.cpp:551:61:551:61 | n | taint.cpp:552:48:552:48 | n | | +| taint.cpp:551:61:551:61 | n | taint.cpp:558:48:558:48 | n | | +| taint.cpp:552:25:552:34 | call to _mbsncat_l | taint.cpp:555:7:555:11 | dest2 | | +| taint.cpp:552:25:552:34 | call to _mbsncat_l | taint.cpp:556:8:556:12 | dest2 | | +| taint.cpp:552:36:552:40 | dest1 | taint.cpp:552:25:552:34 | call to _mbsncat_l | | +| taint.cpp:552:36:552:40 | dest1 | taint.cpp:552:36:552:40 | ref arg dest1 | TAINT | +| taint.cpp:552:36:552:40 | ref arg dest1 | taint.cpp:553:7:553:11 | dest1 | | +| taint.cpp:552:36:552:40 | ref arg dest1 | taint.cpp:554:8:554:12 | dest1 | | +| taint.cpp:552:43:552:45 | ptr | taint.cpp:552:36:552:40 | ref arg dest1 | TAINT | +| taint.cpp:552:48:552:48 | n | taint.cpp:552:36:552:40 | ref arg dest1 | TAINT | +| taint.cpp:552:51:552:56 | source | taint.cpp:552:36:552:40 | ref arg dest1 | TAINT | +| taint.cpp:553:7:553:11 | ref arg dest1 | taint.cpp:554:8:554:12 | dest1 | | +| taint.cpp:554:8:554:12 | dest1 | taint.cpp:554:7:554:12 | * ... | TAINT | +| taint.cpp:555:7:555:11 | ref arg dest2 | taint.cpp:556:8:556:12 | dest2 | | +| taint.cpp:556:8:556:12 | dest2 | taint.cpp:556:7:556:12 | * ... | TAINT | +| taint.cpp:558:25:558:34 | call to _mbsncat_l | taint.cpp:561:7:561:11 | dest4 | | +| taint.cpp:558:25:558:34 | call to _mbsncat_l | taint.cpp:562:8:562:12 | dest4 | | +| taint.cpp:558:36:558:40 | dest3 | taint.cpp:558:25:558:34 | call to _mbsncat_l | | +| taint.cpp:558:36:558:40 | dest3 | taint.cpp:558:36:558:40 | ref arg dest3 | TAINT | +| taint.cpp:558:36:558:40 | ref arg dest3 | taint.cpp:559:7:559:11 | dest3 | | +| taint.cpp:558:36:558:40 | ref arg dest3 | taint.cpp:560:8:560:12 | dest3 | | +| taint.cpp:558:43:558:45 | ptr | taint.cpp:558:36:558:40 | ref arg dest3 | TAINT | +| taint.cpp:558:48:558:48 | n | taint.cpp:558:36:558:40 | ref arg dest3 | TAINT | +| taint.cpp:558:51:558:55 | clean | taint.cpp:558:36:558:40 | ref arg dest3 | TAINT | +| taint.cpp:559:7:559:11 | ref arg dest3 | taint.cpp:560:8:560:12 | dest3 | | +| taint.cpp:560:8:560:12 | dest3 | taint.cpp:560:7:560:12 | * ... | TAINT | +| taint.cpp:561:7:561:11 | ref arg dest4 | taint.cpp:562:8:562:12 | dest4 | | +| taint.cpp:562:8:562:12 | dest4 | taint.cpp:562:7:562:12 | * ... | TAINT | +| taint.cpp:569:24:569:29 | source | taint.cpp:572:29:572:34 | source | | +| taint.cpp:570:23:570:30 | ,.-;:_ | taint.cpp:572:37:572:41 | delim | | +| taint.cpp:572:9:572:17 | tokenized | taint.cpp:572:9:572:42 | ... = ... | | +| taint.cpp:572:21:572:26 | call to strsep | taint.cpp:572:9:572:42 | ... = ... | | +| taint.cpp:572:21:572:26 | call to strsep | taint.cpp:573:10:573:18 | tokenized | | +| taint.cpp:572:21:572:26 | call to strsep | taint.cpp:574:11:574:19 | tokenized | | +| taint.cpp:572:28:572:34 | & ... | taint.cpp:572:21:572:26 | call to strsep | TAINT | +| taint.cpp:572:28:572:34 | ref arg & ... | taint.cpp:572:29:572:34 | source | | +| taint.cpp:572:28:572:34 | ref arg & ... | taint.cpp:572:29:572:34 | source [inner post update] | | +| taint.cpp:572:29:572:34 | source | taint.cpp:572:21:572:26 | call to strsep | TAINT | +| taint.cpp:572:29:572:34 | source | taint.cpp:572:28:572:34 | & ... | | +| taint.cpp:572:37:572:41 | delim | taint.cpp:572:21:572:26 | call to strsep | TAINT | +| taint.cpp:573:10:573:18 | ref arg tokenized | taint.cpp:574:11:574:19 | tokenized | | +| taint.cpp:574:11:574:19 | tokenized | taint.cpp:574:10:574:19 | * ... | TAINT | +| taint.cpp:584:25:584:30 | source | taint.cpp:585:18:585:23 | source | | +| taint.cpp:584:39:584:43 | clean | taint.cpp:589:18:589:22 | clean | | +| taint.cpp:584:82:584:87 | locale | taint.cpp:585:26:585:31 | locale | | +| taint.cpp:584:82:584:87 | locale | taint.cpp:589:25:589:30 | locale | | +| taint.cpp:585:10:585:16 | call to _strinc | taint.cpp:585:2:585:32 | ... = ... | | +| taint.cpp:585:10:585:16 | call to _strinc | taint.cpp:586:7:586:11 | dest1 | | +| taint.cpp:585:10:585:16 | call to _strinc | taint.cpp:587:8:587:12 | dest1 | | +| taint.cpp:585:18:585:23 | source | taint.cpp:585:10:585:16 | call to _strinc | TAINT | +| taint.cpp:585:26:585:31 | locale | taint.cpp:585:10:585:16 | call to _strinc | TAINT | +| taint.cpp:585:26:585:31 | ref arg locale | taint.cpp:589:25:589:30 | locale | | +| taint.cpp:586:7:586:11 | ref arg dest1 | taint.cpp:587:8:587:12 | dest1 | | +| taint.cpp:587:8:587:12 | dest1 | taint.cpp:587:7:587:12 | * ... | TAINT | +| taint.cpp:589:10:589:16 | call to _strinc | taint.cpp:589:2:589:31 | ... = ... | | +| taint.cpp:589:10:589:16 | call to _strinc | taint.cpp:590:7:590:11 | dest2 | | +| taint.cpp:589:10:589:16 | call to _strinc | taint.cpp:591:8:591:12 | dest2 | | +| taint.cpp:589:18:589:22 | clean | taint.cpp:589:10:589:16 | call to _strinc | TAINT | +| taint.cpp:589:25:589:30 | locale | taint.cpp:589:10:589:16 | call to _strinc | TAINT | +| taint.cpp:590:7:590:11 | ref arg dest2 | taint.cpp:591:8:591:12 | dest2 | | +| taint.cpp:591:8:591:12 | dest2 | taint.cpp:591:7:591:12 | * ... | TAINT | +| taint.cpp:594:34:594:48 | source_unsigned | taint.cpp:595:26:595:40 | source_unsigned | | +| taint.cpp:594:57:594:62 | source | taint.cpp:599:40:599:45 | source | | +| taint.cpp:595:18:595:24 | call to _mbsinc | taint.cpp:595:2:595:41 | ... = ... | | +| taint.cpp:595:18:595:24 | call to _mbsinc | taint.cpp:596:7:596:19 | dest_unsigned | | +| taint.cpp:595:18:595:24 | call to _mbsinc | taint.cpp:597:8:597:20 | dest_unsigned | | +| taint.cpp:595:26:595:40 | source_unsigned | taint.cpp:595:18:595:24 | call to _mbsinc | TAINT | +| taint.cpp:596:7:596:19 | ref arg dest_unsigned | taint.cpp:597:8:597:20 | dest_unsigned | | +| taint.cpp:597:8:597:20 | dest_unsigned | taint.cpp:597:7:597:20 | * ... | TAINT | +| taint.cpp:599:16:599:22 | call to _mbsinc | taint.cpp:599:2:599:46 | ... = ... | | +| taint.cpp:599:16:599:22 | call to _mbsinc | taint.cpp:600:7:600:10 | dest | | +| taint.cpp:599:16:599:22 | call to _mbsinc | taint.cpp:601:8:601:11 | dest | | +| taint.cpp:599:40:599:45 | source | taint.cpp:599:16:599:22 | call to _mbsinc | TAINT | +| taint.cpp:600:7:600:10 | ref arg dest | taint.cpp:601:8:601:11 | dest | | +| taint.cpp:601:8:601:11 | dest | taint.cpp:601:7:601:11 | * ... | TAINT | +| taint.cpp:604:40:604:45 | source | taint.cpp:605:18:605:23 | source | | +| taint.cpp:604:40:604:45 | source | taint.cpp:605:31:605:36 | source | | +| taint.cpp:604:40:604:45 | source | taint.cpp:611:25:611:30 | source | | +| taint.cpp:604:40:604:45 | source | taint.cpp:616:18:616:23 | source | | +| taint.cpp:604:63:604:67 | clean | taint.cpp:611:18:611:22 | clean | | +| taint.cpp:604:63:604:67 | clean | taint.cpp:616:26:616:30 | clean | | +| taint.cpp:605:10:605:16 | call to _strdec | taint.cpp:605:2:605:37 | ... = ... | | +| taint.cpp:605:10:605:16 | call to _strdec | taint.cpp:606:7:606:11 | dest1 | | +| taint.cpp:605:10:605:16 | call to _strdec | taint.cpp:607:8:607:12 | dest1 | | +| taint.cpp:605:18:605:23 | source | taint.cpp:605:18:605:28 | ... + ... | TAINT | +| taint.cpp:605:18:605:28 | ... + ... | taint.cpp:605:10:605:16 | call to _strdec | TAINT | +| taint.cpp:605:27:605:28 | 12 | taint.cpp:605:18:605:28 | ... + ... | TAINT | +| taint.cpp:605:31:605:36 | source | taint.cpp:605:10:605:16 | call to _strdec | TAINT | +| taint.cpp:606:7:606:11 | ref arg dest1 | taint.cpp:607:8:607:12 | dest1 | | +| taint.cpp:607:8:607:12 | dest1 | taint.cpp:607:7:607:12 | * ... | TAINT | +| taint.cpp:611:10:611:16 | call to _strdec | taint.cpp:611:2:611:31 | ... = ... | | +| taint.cpp:611:10:611:16 | call to _strdec | taint.cpp:612:7:612:11 | dest2 | | +| taint.cpp:611:10:611:16 | call to _strdec | taint.cpp:613:8:613:12 | dest2 | | +| taint.cpp:611:18:611:22 | clean | taint.cpp:611:10:611:16 | call to _strdec | TAINT | +| taint.cpp:611:25:611:30 | source | taint.cpp:611:10:611:16 | call to _strdec | TAINT | +| taint.cpp:612:7:612:11 | ref arg dest2 | taint.cpp:613:8:613:12 | dest2 | | +| taint.cpp:613:8:613:12 | dest2 | taint.cpp:613:7:613:12 | * ... | TAINT | +| taint.cpp:616:10:616:16 | call to _strdec | taint.cpp:616:2:616:31 | ... = ... | | +| taint.cpp:616:10:616:16 | call to _strdec | taint.cpp:617:7:617:11 | dest3 | | +| taint.cpp:616:10:616:16 | call to _strdec | taint.cpp:618:8:618:12 | dest3 | | +| taint.cpp:616:18:616:23 | source | taint.cpp:616:10:616:16 | call to _strdec | TAINT | +| taint.cpp:616:26:616:30 | clean | taint.cpp:616:10:616:16 | call to _strdec | TAINT | +| taint.cpp:617:7:617:11 | ref arg dest3 | taint.cpp:618:8:618:12 | dest3 | | +| taint.cpp:618:8:618:12 | dest3 | taint.cpp:618:7:618:12 | * ... | TAINT | +| taint.cpp:625:33:625:38 | source | taint.cpp:628:17:628:22 | source | | +| taint.cpp:628:7:628:15 | call to _strnextc | taint.cpp:628:3:628:25 | ... = ... | | +| taint.cpp:628:7:628:15 | call to _strnextc | taint.cpp:629:8:629:8 | c | | +| taint.cpp:628:7:628:15 | call to _strnextc | taint.cpp:630:10:630:10 | c | | +| taint.cpp:628:17:628:22 | source | taint.cpp:628:17:628:24 | ... ++ | | +| taint.cpp:628:17:628:24 | ... ++ | taint.cpp:628:7:628:15 | call to _strnextc | TAINT | +| taint.cpp:628:17:628:24 | ... ++ | taint.cpp:628:17:628:22 | source | TAINT | +| taint.cpp:631:6:631:14 | call to _strnextc | taint.cpp:631:2:631:18 | ... = ... | | +| taint.cpp:631:6:631:14 | call to _strnextc | taint.cpp:632:7:632:7 | c | | +| taint.cpp:631:16:631:17 | | taint.cpp:631:6:631:14 | call to _strnextc | TAINT | | vector.cpp:16:43:16:49 | source1 | vector.cpp:17:26:17:32 | source1 | | | vector.cpp:16:43:16:49 | source1 | vector.cpp:31:38:31:44 | source1 | | | vector.cpp:17:21:17:33 | call to vector | vector.cpp:19:14:19:14 | v | | diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/standalone_iterators.cpp b/cpp/ql/test/library-tests/dataflow/taint-tests/standalone_iterators.cpp index 709ba8e7af4..3fb8c738305 100644 --- a/cpp/ql/test/library-tests/dataflow/taint-tests/standalone_iterators.cpp +++ b/cpp/ql/test/library-tests/dataflow/taint-tests/standalone_iterators.cpp @@ -38,13 +38,13 @@ public: void test_typedefs(int_iterator_by_typedefs source1) { sink(*source1); // $ ast,ir - sink(*(source1++)); // $ ast MISSING: ir + sink(*(source1++)); // $ ast,ir sink(*(++source1)); // $ ast MISSING: ir } void test_trait(int_iterator_by_trait source1) { sink(*source1); // $ ast,ir - sink(*(source1++)); // $ ast MISSING: ir + sink(*(source1++)); // $ ast,ir sink(*(++source1)); // $ ast MISSING: ir } diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/string.cpp b/cpp/ql/test/library-tests/dataflow/taint-tests/string.cpp index 3741c54285b..9169113c1d9 100644 --- a/cpp/ql/test/library-tests/dataflow/taint-tests/string.cpp +++ b/cpp/ql/test/library-tests/dataflow/taint-tests/string.cpp @@ -415,10 +415,10 @@ void test_string_iterators() { sink(*i9); // $ ast,ir i10 = i2; - sink(*(i10++)); // $ ast MISSING: ir + sink(*(i10++)); // $ ast,ir sink(i10); // $ ast,ir i11 = i2; - sink(*(i11--)); // $ ast MISSING: ir + sink(*(i11--)); // $ ast,ir sink(i11); // $ ast,ir } } diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/stringstream.cpp b/cpp/ql/test/library-tests/dataflow/taint-tests/stringstream.cpp index 794df6704da..7b7712f0c01 100644 --- a/cpp/ql/test/library-tests/dataflow/taint-tests/stringstream.cpp +++ b/cpp/ql/test/library-tests/dataflow/taint-tests/stringstream.cpp @@ -75,7 +75,7 @@ void test_stringstream_int(int source) sink(ss1 << 1234); sink(ss2 << source); // $ ast MISSING: ir sink(ss1 >> v1); - sink(ss2 >> v2); // $ ast MISSING: ir + sink(ss2 >> v2); // $ ast,ir sink(ss1); sink(ss2); // $ ast,ir @@ -143,27 +143,27 @@ void test_stringstream_in() sink(ss2 << source()); // $ ast,ir sink(ss1 >> s1); - sink(ss2 >> s2); // $ ast MISSING: ir - sink(ss2 >> s3 >> s4); // $ ast MISSING: ir + sink(ss2 >> s2); // $ ast,ir + sink(ss2 >> s3 >> s4); // $ ast,ir sink(s1); sink(s2); // $ ast,ir sink(s3); // $ ast,ir - sink(s4); // $ ast MISSING: ir + sink(s4); // $ ast,ir sink(ss1 >> b1); - sink(ss2 >> b2); // $ ast MISSING: ir - sink(ss2 >> b3 >> b4); // $ ast MISSING: ir + sink(ss2 >> b2); // $ ast,ir + sink(ss2 >> b3 >> b4); // $ ast,ir sink(b1); sink(b2); // $ ast,ir sink(b3); // $ ast,ir - sink(b4); // $ ast MISSING: ir + sink(b4); // $ ast,ir sink(ss1.read(b5, 100)); - sink(ss2.read(b6, 100)); // $ ast MISSING: ir + sink(ss2.read(b6, 100)); // $ ast,ir sink(ss1.readsome(b7, 100)); sink(ss2.readsome(b8, 100)); // (returns a length, not significantly tainted) sink(ss1.get(b9, 100)); - sink(ss2.get(b10, 100)); // $ ast MISSING: ir + sink(ss2.get(b10, 100)); // $ ast,ir sink(b5); sink(b6); // $ ast,ir sink(b7); @@ -176,7 +176,7 @@ void test_stringstream_in() sink(c3 = ss1.peek()); sink(c4 = ss2.peek()); // $ ast,ir sink(ss1.get(c5)); - sink(ss2.get(c6)); // $ ast MISSING: ir + sink(ss2.get(c6)); // $ ast,ir sink(c1); sink(c2); // $ ast,ir sink(c3); @@ -212,44 +212,44 @@ void test_getline() std::string s1, s2, s3, s4, s5, s6, s7, s8; sink(ss1.getline(b1, 1000)); - sink(ss2.getline(b2, 1000)); // $ ast MISSING: ir - sink(ss2.getline(b3, 1000)); // $ ast MISSING: ir + sink(ss2.getline(b2, 1000)); // $ ast,ir + sink(ss2.getline(b3, 1000)); // $ ast,ir sink(ss1.getline(b3, 1000)); sink(b1); sink(b2); // $ ast,ir sink(b3); // $ SPURIOUS: ast,ir sink(ss1.getline(b4, 1000, ' ')); - sink(ss2.getline(b5, 1000, ' ')); // $ ast MISSING: ir - sink(ss2.getline(b6, 1000, ' ')); // $ ast MISSING: ir + sink(ss2.getline(b5, 1000, ' ')); // $ ast,ir + sink(ss2.getline(b6, 1000, ' ')); // $ ast,ir sink(ss1.getline(b6, 1000, ' ')); sink(b4); sink(b5); // $ ast,ir sink(b6); // $ SPURIOUS: ast,ir - sink(ss2.getline(b7, 1000).getline(b8, 1000)); // $ ast MISSING: ir + sink(ss2.getline(b7, 1000).getline(b8, 1000)); // $ ast,ir sink(b7); // $ ast,ir sink(b8); // $ ast MISSING: ir sink(getline(ss1, s1)); - sink(getline(ss2, s2)); // $ ast MISSING: ir - sink(getline(ss2, s3)); // $ ast MISSING: ir + sink(getline(ss2, s2)); // $ ast,ir + sink(getline(ss2, s3)); // $ ast,ir sink(getline(ss1, s3)); sink(s1); sink(s2); // $ ast,ir sink(s3); // $ SPURIOUS: ast,ir sink(getline(ss1, s4, ' ')); - sink(getline(ss2, s5, ' ')); // $ ast MISSING: ir - sink(getline(ss2, s6, ' ')); // $ ast MISSING: ir + sink(getline(ss2, s5, ' ')); // $ ast,ir + sink(getline(ss2, s6, ' ')); // $ ast,ir sink(getline(ss1, s6, ' ')); sink(s4); sink(s5); // $ ast,ir sink(s6); // $ SPURIOUS: ast,ir - sink(getline(getline(ss2, s7), s8)); // $ ast MISSING: ir + sink(getline(getline(ss2, s7), s8)); // $ ast,ir sink(s7); // $ ast,ir - sink(s8); // $ ast MISSING: ir + sink(s8); // $ ast,ir } void test_chaining() @@ -259,7 +259,7 @@ void test_chaining() char b1[1000] = {0}; char b2[1000] = {0}; - sink(ss1.get(b1, 100).unget().get(b2, 100)); // $ ast MISSING: ir + sink(ss1.get(b1, 100).unget().get(b2, 100)); // $ ast,ir sink(b1); // $ ast,ir sink(b2); // $ ast MISSING: ir diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/taint.cpp b/cpp/ql/test/library-tests/dataflow/taint-tests/taint.cpp index 5ccedc7fc1c..44d84c0c0b0 100644 --- a/cpp/ql/test/library-tests/dataflow/taint-tests/taint.cpp +++ b/cpp/ql/test/library-tests/dataflow/taint-tests/taint.cpp @@ -484,3 +484,150 @@ void test_getdelim(FILE* source1) { sink(line); // $ ir,ast } + +// --- strtok --- + +char *strtok(char *str, const char *delim); + +void test_strtok(char *source) { + const char* delim = ",.-;:_"; + char* tokenized = strtok(source, delim); + sink(tokenized); // $ ast,ir + sink(delim); +} + +// --- strset --- + +char *_strset(char *str, int c); + +void test_strset_1(char* ptr, char source) { + _strset(ptr, source); + sink(ptr); // $ SPURIOUS: ast,ir + sink(*ptr); // $ ast,ir +} + +void test_strset_2(char* source) { + _strset(source, 0); + sink(source); // $ ast,ir +} + +// --- mempcpy --- + +void *mempcpy(void *dest, const void *src, size_t n); + +void test_mempcpy(int *source) { + int x; + mempcpy(&x, source, sizeof(int)); + sink(x); // $ ast=518:24 MISSING: ir SPURIOUS: ast=519:6 +} + +// --- memccpy --- + +void *memccpy(void *dest, const void *src, int c, size_t n); + +void test_memccpy(int *source) { + int dest[16]; + memccpy(dest, source, 42, sizeof(dest)); + sink(dest); // $ ast=528:24 MISSING: ir SPURIOUS: ast=529:6 +} + +// --- strcat and related functions --- + +char* strcat (char*, const char*); + +void test_strcat(char* dest1, char* dest2, char* clean, char* source) { + strcat(dest1, source); + sink(dest1); // $ ast,ir + + strcat(dest2, clean); + sink(dest2); +} + +typedef void* _locale_t; + +unsigned char *_mbsncat_l(unsigned char *, const unsigned char *, int, _locale_t); + +void test__mbsncat_l(unsigned char* dest1, unsigned const char* ptr, unsigned char* dest3, + _locale_t clean, _locale_t source, int n) { + unsigned char* dest2 = _mbsncat_l(dest1, ptr, n, source); + sink(dest1); // $ SPURIOUS: ast,ir + sink(*dest1); // $ ast,ir + sink(dest2); // $ SPURIOUS: ir + sink(*dest2); // $ ir + + unsigned char* dest4 = _mbsncat_l(dest3, ptr, n, clean); + sink(dest3); + sink(*dest3); + sink(dest4); + sink(*dest4); +} + +// --- strsep --- + +char *strsep(char**, const char *); + +void test_strsep(char *source) { + const char* delim = ",.-;:_"; + char* tokenized; + while(tokenized = strsep(&source, delim)) { + sink(tokenized); // $ ast,ir + sink(*tokenized); // $ ast,ir + } +} + +// --- _strinc and related functions --- + +char* _strinc(const char*, _locale_t); +unsigned char* _mbsinc(const unsigned char*); +unsigned char *_strdec(const unsigned char*, const unsigned char*); + +void test__strinc(char* source, char* clean, char* dest1, char* dest2, _locale_t locale) { + dest1 = _strinc(source, locale); + sink(dest1); // $ ast,ir + sink(*dest1); // $ ast,ir + + dest2 = _strinc(clean, locale); + sink(dest2); + sink(*dest2); +} + +void test__mbsinc(unsigned char* source_unsigned, char* source, unsigned char* dest_unsigned, char* dest) { + dest_unsigned = _mbsinc(source_unsigned); + sink(dest_unsigned); // $ ast,ir + sink(*dest_unsigned); // $ ast,ir + + dest = (char*)_mbsinc((unsigned char*)source); + sink(dest); // $ ast,ir + sink(*dest); // $ ast,ir +} + +void test__strdec(const unsigned char* source, unsigned char* clean, unsigned char* dest1, unsigned char* dest2, unsigned char* dest3) { + dest1 = _strdec(source + 12, source); + sink(dest1); // $ ast,ir + sink(*dest1); // $ ast,ir + + // If `clean` does not precede `source` this technically breaks the precondition of _strdec. + // We would still like to have taint, though. + dest2 = _strdec(clean, source); + sink(dest2); // $ ast,ir + sink(*dest2); // $ ast,ir + + // Also breaks the precondition on _strdec. + dest3 = _strdec(source, clean); + sink(dest3); // $ ast,ir + sink(*dest3); // $ ast,ir +} + +// --- strnextc --- + +unsigned int _strnextc(const char*); + +void test__strnextc(const char* source) { + unsigned c = 0; + do { + c = _strnextc(source++); + sink(c); // $ ast,ir + } while(c != '\0'); + c = _strnextc(""); + sink(c); +} \ No newline at end of file diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/vector.cpp b/cpp/ql/test/library-tests/dataflow/taint-tests/vector.cpp index 7e7fc8176ce..ec354da548c 100644 --- a/cpp/ql/test/library-tests/dataflow/taint-tests/vector.cpp +++ b/cpp/ql/test/library-tests/dataflow/taint-tests/vector.cpp @@ -491,8 +491,8 @@ void test_vector_emplace() { std::vector v1(10), v2(10); v1.emplace_back(source()); - sink(v1); // $ ast MISSING: ir + sink(v1); // $ ast,ir v2.emplace(v2.begin(), source()); - sink(v2); // $ ast MISSING: ir + sink(v2); // $ ast,ir } diff --git a/cpp/ql/test/library-tests/ir/ssa/aliased_ssa_ir.expected b/cpp/ql/test/library-tests/ir/ssa/aliased_ssa_ir.expected index f241c851109..c4019a38251 100644 --- a/cpp/ql/test/library-tests/ir/ssa/aliased_ssa_ir.expected +++ b/cpp/ql/test/library-tests/ir/ssa/aliased_ssa_ir.expected @@ -889,10 +889,8 @@ ssa.cpp: # 207| m207_4(unknown) = Chi : total:m207_2, partial:m207_3 # 207| r207_5(glval) = VariableAddress[x] : # 207| m207_6(int) = InitializeParameter[x] : &:r207_5 -# 207| m207_7(unknown) = Chi : total:m207_4, partial:m207_6 # 208| r208_1(glval) = VariableAddress[y] : # 208| m208_2(int) = Uninitialized[y] : &:r208_1 -# 208| m208_3(unknown) = Chi : total:m207_7, partial:m208_2 # 209| r209_1(glval) = FunctionAddress[memcpy] : # 209| r209_2(glval) = VariableAddress[y] : # 209| r209_3(int *) = CopyValue : r209_2 @@ -904,15 +902,15 @@ ssa.cpp: # 209| r209_9(void *) = Call[memcpy] : func:r209_1, 0:r209_4, 1:r209_7, 2:r209_8 # 209| v209_10(void) = ^SizedBufferReadSideEffect[1] : &:r209_7, r209_8, ~m207_6 # 209| m209_11(unknown) = ^SizedBufferMustWriteSideEffect[0] : &:r209_4, r209_8 -# 209| m209_12(unknown) = Chi : total:m208_3, partial:m209_11 +# 209| m209_12(int) = Chi : total:m208_2, partial:m209_11 # 210| r210_1(glval) = VariableAddress[#return] : # 210| r210_2(glval) = VariableAddress[y] : -# 210| r210_3(int) = Load[y] : &:r210_2, ~m209_12 +# 210| r210_3(int) = Load[y] : &:r210_2, m209_12 # 210| m210_4(int) = Store[#return] : &:r210_1, r210_3 -# 207| r207_8(glval) = VariableAddress[#return] : -# 207| v207_9(void) = ReturnValue : &:r207_8, m210_4 -# 207| v207_10(void) = AliasedUse : m207_3 -# 207| v207_11(void) = ExitFunction : +# 207| r207_7(glval) = VariableAddress[#return] : +# 207| v207_8(void) = ReturnValue : &:r207_7, m210_4 +# 207| v207_9(void) = AliasedUse : m207_3 +# 207| v207_10(void) = ExitFunction : # 213| void InitArray() # 213| Block 0 @@ -1104,51 +1102,49 @@ ssa.cpp: # 247| m247_6(char *) = InitializeParameter[src] : &:r247_5 # 247| r247_7(char *) = Load[src] : &:r247_5, m247_6 # 247| m247_8(unknown) = InitializeIndirection[src] : &:r247_7 -# 247| m247_9(unknown) = Chi : total:m247_4, partial:m247_8 -# 247| r247_10(glval) = VariableAddress[size] : -# 247| m247_11(int) = InitializeParameter[size] : &:r247_10 +# 247| r247_9(glval) = VariableAddress[size] : +# 247| m247_10(int) = InitializeParameter[size] : &:r247_9 # 248| r248_1(glval) = VariableAddress[dst] : # 248| r248_2(glval) = FunctionAddress[operator new[]] : # 248| r248_3(glval) = VariableAddress[size] : -# 248| r248_4(int) = Load[size] : &:r248_3, m247_11 +# 248| r248_4(int) = Load[size] : &:r248_3, m247_10 # 248| r248_5(unsigned long) = Convert : r248_4 # 248| r248_6(unsigned long) = Constant[1] : # 248| r248_7(unsigned long) = Mul : r248_5, r248_6 # 248| r248_8(void *) = Call[operator new[]] : func:r248_2, 0:r248_7 -# 248| m248_9(unknown) = ^CallSideEffect : ~m247_9 -# 248| m248_10(unknown) = Chi : total:m247_9, partial:m248_9 +# 248| m248_9(unknown) = ^CallSideEffect : ~m247_4 +# 248| m248_10(unknown) = Chi : total:m247_4, partial:m248_9 # 248| m248_11(unknown) = ^InitializeDynamicAllocation : &:r248_8 -# 248| m248_12(unknown) = Chi : total:m248_10, partial:m248_11 -# 248| r248_13(char *) = Convert : r248_8 -# 248| m248_14(char *) = Store[dst] : &:r248_1, r248_13 +# 248| r248_12(char *) = Convert : r248_8 +# 248| m248_13(char *) = Store[dst] : &:r248_1, r248_12 # 249| r249_1(char) = Constant[97] : # 249| r249_2(glval) = VariableAddress[src] : # 249| r249_3(char *) = Load[src] : &:r249_2, m247_6 # 249| r249_4(glval) = CopyValue : r249_3 # 249| m249_5(char) = Store[?] : &:r249_4, r249_1 -# 249| m249_6(unknown) = Chi : total:m248_12, partial:m249_5 +# 249| m249_6(unknown) = Chi : total:m247_8, partial:m249_5 # 250| r250_1(glval) = FunctionAddress[memcpy] : # 250| r250_2(glval) = VariableAddress[dst] : -# 250| r250_3(char *) = Load[dst] : &:r250_2, m248_14 +# 250| r250_3(char *) = Load[dst] : &:r250_2, m248_13 # 250| r250_4(void *) = Convert : r250_3 # 250| r250_5(glval) = VariableAddress[src] : # 250| r250_6(char *) = Load[src] : &:r250_5, m247_6 # 250| r250_7(void *) = Convert : r250_6 # 250| r250_8(glval) = VariableAddress[size] : -# 250| r250_9(int) = Load[size] : &:r250_8, m247_11 +# 250| r250_9(int) = Load[size] : &:r250_8, m247_10 # 250| r250_10(void *) = Call[memcpy] : func:r250_1, 0:r250_4, 1:r250_7, 2:r250_9 # 250| v250_11(void) = ^SizedBufferReadSideEffect[1] : &:r250_7, r250_9, ~m249_6 # 250| m250_12(unknown) = ^SizedBufferMustWriteSideEffect[0] : &:r250_4, r250_9 -# 250| m250_13(unknown) = Chi : total:m249_6, partial:m250_12 +# 250| m250_13(unknown) = Chi : total:m248_11, partial:m250_12 # 251| r251_1(glval) = VariableAddress[#return] : # 251| r251_2(glval) = VariableAddress[dst] : -# 251| r251_3(char *) = Load[dst] : &:r251_2, m248_14 +# 251| r251_3(char *) = Load[dst] : &:r251_2, m248_13 # 251| m251_4(char *) = Store[#return] : &:r251_1, r251_3 -# 247| v247_12(void) = ReturnIndirection[src] : &:r247_7, ~m250_13 -# 247| r247_13(glval) = VariableAddress[#return] : -# 247| v247_14(void) = ReturnValue : &:r247_13, m251_4 -# 247| v247_15(void) = AliasedUse : ~m250_13 -# 247| v247_16(void) = ExitFunction : +# 247| v247_11(void) = ReturnIndirection[src] : &:r247_7, m249_6 +# 247| r247_12(glval) = VariableAddress[#return] : +# 247| v247_13(void) = ReturnValue : &:r247_12, m251_4 +# 247| v247_14(void) = AliasedUse : ~m248_10 +# 247| v247_15(void) = ExitFunction : # 254| char StringLiteralAliasing2(bool) # 254| Block 0 @@ -1206,39 +1202,37 @@ ssa.cpp: # 268| m268_6(void *) = InitializeParameter[s] : &:r268_5 # 268| r268_7(void *) = Load[s] : &:r268_5, m268_6 # 268| m268_8(unknown) = InitializeIndirection[s] : &:r268_7 -# 268| m268_9(unknown) = Chi : total:m268_4, partial:m268_8 -# 268| r268_10(glval) = VariableAddress[size] : -# 268| m268_11(int) = InitializeParameter[size] : &:r268_10 +# 268| r268_9(glval) = VariableAddress[size] : +# 268| m268_10(int) = InitializeParameter[size] : &:r268_9 # 269| r269_1(glval) = VariableAddress[buf] : # 269| r269_2(glval) = FunctionAddress[malloc] : # 269| r269_3(glval) = VariableAddress[size] : -# 269| r269_4(int) = Load[size] : &:r269_3, m268_11 +# 269| r269_4(int) = Load[size] : &:r269_3, m268_10 # 269| r269_5(void *) = Call[malloc] : func:r269_2, 0:r269_4 -# 269| m269_6(unknown) = ^CallSideEffect : ~m268_9 -# 269| m269_7(unknown) = Chi : total:m268_9, partial:m269_6 +# 269| m269_6(unknown) = ^CallSideEffect : ~m268_4 +# 269| m269_7(unknown) = Chi : total:m268_4, partial:m269_6 # 269| m269_8(unknown) = ^InitializeDynamicAllocation : &:r269_5 -# 269| m269_9(unknown) = Chi : total:m269_7, partial:m269_8 -# 269| m269_10(void *) = Store[buf] : &:r269_1, r269_5 +# 269| m269_9(void *) = Store[buf] : &:r269_1, r269_5 # 270| r270_1(glval) = FunctionAddress[memcpy] : # 270| r270_2(glval) = VariableAddress[buf] : -# 270| r270_3(void *) = Load[buf] : &:r270_2, m269_10 +# 270| r270_3(void *) = Load[buf] : &:r270_2, m269_9 # 270| r270_4(glval) = VariableAddress[s] : # 270| r270_5(void *) = Load[s] : &:r270_4, m268_6 # 270| r270_6(glval) = VariableAddress[size] : -# 270| r270_7(int) = Load[size] : &:r270_6, m268_11 +# 270| r270_7(int) = Load[size] : &:r270_6, m268_10 # 270| r270_8(void *) = Call[memcpy] : func:r270_1, 0:r270_3, 1:r270_5, 2:r270_7 -# 270| v270_9(void) = ^SizedBufferReadSideEffect[1] : &:r270_5, r270_7, ~m269_7 +# 270| v270_9(void) = ^SizedBufferReadSideEffect[1] : &:r270_5, r270_7, ~m268_8 # 270| m270_10(unknown) = ^SizedBufferMustWriteSideEffect[0] : &:r270_3, r270_7 -# 270| m270_11(unknown) = Chi : total:m269_9, partial:m270_10 +# 270| m270_11(unknown) = Chi : total:m269_8, partial:m270_10 # 271| r271_1(glval) = VariableAddress[#return] : # 271| r271_2(glval) = VariableAddress[buf] : -# 271| r271_3(void *) = Load[buf] : &:r271_2, m269_10 +# 271| r271_3(void *) = Load[buf] : &:r271_2, m269_9 # 271| m271_4(void *) = Store[#return] : &:r271_1, r271_3 -# 268| v268_12(void) = ReturnIndirection[s] : &:r268_7, ~m270_11 -# 268| r268_13(glval) = VariableAddress[#return] : -# 268| v268_14(void) = ReturnValue : &:r268_13, m271_4 -# 268| v268_15(void) = AliasedUse : ~m270_11 -# 268| v268_16(void) = ExitFunction : +# 268| v268_11(void) = ReturnIndirection[s] : &:r268_7, m268_8 +# 268| r268_12(glval) = VariableAddress[#return] : +# 268| v268_13(void) = ReturnValue : &:r268_12, m271_4 +# 268| v268_14(void) = AliasedUse : ~m269_7 +# 268| v268_15(void) = ExitFunction : # 275| void EscapedButNotConflated(bool, Point, int) # 275| Block 0 diff --git a/cpp/ql/test/library-tests/valuenumbering/GlobalValueNumbering/ast_ir_gvn.expected b/cpp/ql/test/library-tests/valuenumbering/GlobalValueNumbering/ast_ir_gvn.expected new file mode 100644 index 00000000000..2e8aecd11a6 --- /dev/null +++ b/cpp/ql/test/library-tests/valuenumbering/GlobalValueNumbering/ast_ir_gvn.expected @@ -0,0 +1,46 @@ +| test.cpp:5:3:5:3 | GVN | 5:c3-c3 6:c3-c3 | +| test.cpp:5:7:5:8 | GVN | 5:c7-c8 6:c7-c8 | +| test.cpp:5:7:5:13 | GVN | 5:c7-c13 6:c7-c13 7:c7-c7 | +| test.cpp:5:12:5:13 | GVN | 5:c12-c13 6:c12-c13 | +| test.cpp:16:3:16:3 | GVN | 16:c3-c3 17:c3-c3 | +| test.cpp:16:7:16:8 | GVN | 16:c7-c8 17:c7-c8 | +| test.cpp:16:7:16:13 | GVN | 16:c7-c13 17:c7-c13 | +| test.cpp:16:7:16:24 | GVN | 16:c7-c24 17:c7-c24 18:c7-c7 | +| test.cpp:16:12:16:13 | GVN | 16:c12-c13 17:c12-c13 | +| test.cpp:16:17:16:24 | GVN | 16:c17-c24 17:c17-c24 | +| test.cpp:29:3:29:3 | GVN | 29:c3-c3 31:c3-c3 | +| test.cpp:29:7:29:8 | GVN | 29:c7-c8 31:c7-c8 | +| test.cpp:29:7:29:13 | GVN | 29:c7-c13 31:c7-c13 | +| test.cpp:29:12:29:13 | GVN | 29:c12-c13 31:c12-c13 | +| test.cpp:31:7:31:24 | GVN | 31:c7-c24 32:c7-c7 | +| test.cpp:43:3:43:3 | GVN | 43:c3-c3 45:c3-c3 | +| test.cpp:43:7:43:8 | GVN | 43:c7-c8 45:c7-c8 | +| test.cpp:43:7:43:13 | GVN | 43:c7-c13 45:c7-c13 | +| test.cpp:43:7:43:24 | GVN | 43:c7-c24 45:c7-c24 46:c7-c7 | +| test.cpp:43:12:43:13 | GVN | 43:c12-c13 45:c12-c13 | +| test.cpp:43:17:43:24 | GVN | 43:c17-c24 45:c17-c24 | +| test.cpp:44:3:44:5 | GVN | 44:c3-c5 44:c4-c5 | +| test.cpp:53:10:53:13 | GVN | 53:c10-c13 56:c21-c24 | +| test.cpp:53:10:53:13 | GVN | 53:c10-c13 56:c21-c24 | +| test.cpp:53:11:53:13 | GVN | 53:c11-c13 56:c22-c24 | +| test.cpp:53:18:53:21 | GVN | 53:c18-c21 56:c39-c42 59:c17-c20 | +| test.cpp:56:13:56:16 | GVN | 56:c13-c16 56:c31-c34 59:c9-c12 | +| test.cpp:56:13:56:16 | GVN | 56:c13-c16 56:c31-c34 59:c9-c12 | +| test.cpp:56:14:56:16 | GVN | 56:c14-c16 56:c32-c34 56:c47-c49 59:c10-c12 | +| test.cpp:62:5:62:10 | GVN | 62:c5-c10 65:c10-c15 | +| test.cpp:77:20:77:28 | GVN | 77:c20-c28 79:c7-c7 | +| test.cpp:79:11:79:14 | GVN | 79:c11-c14 79:c24-c27 | +| test.cpp:92:11:92:16 | GVN | 92:c11-c16 92:c15-c16 93:c10-c10 | +| test.cpp:105:11:105:12 | GVN | 105:c11-c12 106:c33-c34 | +| test.cpp:105:11:105:12 | GVN | 105:c11-c12 106:c33-c34 107:c11-c12 | +| test.cpp:105:15:105:15 | GVN | 105:c15-c15 107:c15-c15 109:c10-c10 | +| test.cpp:113:3:113:5 | GVN | 113:c3-c5 115:c3-c5 | +| test.cpp:125:11:125:12 | GVN | 125:c11-c12 126:c11-c12 128:c3-c4 129:c11-c12 | +| test.cpp:125:15:125:15 | GVN | 125:c15-c15 126:c15-c15 | +| test.cpp:128:11:128:11 | GVN | 128:c11-c11 129:c15-c15 | +| test.cpp:136:11:136:18 | GVN | 136:c11-c18 137:c11-c18 139:c3-c10 | +| test.cpp:136:21:136:21 | GVN | 136:c21-c21 137:c21-c21 | +| test.cpp:144:11:144:12 | GVN | 144:c11-c12 145:c11-c12 147:c3-c4 149:c11-c12 | +| test.cpp:144:15:144:15 | GVN | 144:c15-c15 149:c15-c15 | +| test.cpp:153:11:153:18 | GVN | 153:c11-c18 154:c11-c18 156:c3-c10 | +| test.cpp:153:21:153:21 | GVN | 153:c21-c21 154:c21-c21 | diff --git a/cpp/ql/test/library-tests/valuenumbering/GlobalValueNumbering/ast_ir_gvn.ql b/cpp/ql/test/library-tests/valuenumbering/GlobalValueNumbering/ast_ir_gvn.ql new file mode 100644 index 00000000000..0e525a753b5 --- /dev/null +++ b/cpp/ql/test/library-tests/valuenumbering/GlobalValueNumbering/ast_ir_gvn.ql @@ -0,0 +1,11 @@ +import cpp +import semmle.code.cpp.ir.internal.ASTValueNumbering + +from GVN g +where strictcount(g.getAnExpr()) > 1 +select g, + strictconcat(Location loc | + loc = g.getAnExpr().getLocation() + | + loc.getStartLine() + ":c" + loc.getStartColumn() + "-c" + loc.getEndColumn(), " " + ) diff --git a/cpp/ql/test/qlpack.yml b/cpp/ql/test/qlpack.yml index 008af57baef..89f684e9e3e 100644 --- a/cpp/ql/test/qlpack.yml +++ b/cpp/ql/test/qlpack.yml @@ -2,3 +2,4 @@ name: codeql-cpp-tests version: 0.0.0 libraryPathDependencies: codeql-cpp extractor: cpp +tests: . diff --git a/cpp/ql/test/query-tests/Critical/NewFree/NewFreeMismatch.expected b/cpp/ql/test/query-tests/Critical/NewFree/NewFreeMismatch.expected index 45f88d426c9..3326d94a7d2 100644 --- a/cpp/ql/test/query-tests/Critical/NewFree/NewFreeMismatch.expected +++ b/cpp/ql/test/query-tests/Critical/NewFree/NewFreeMismatch.expected @@ -18,3 +18,6 @@ | test.cpp:235:2:235:5 | call to free | There is a new/free mismatch between this free and the corresponding $@. | test.cpp:227:7:227:13 | new | new | | test.cpp:239:2:239:5 | call to free | There is a new/free mismatch between this free and the corresponding $@. | test.cpp:228:7:228:17 | new[] | new[] | | test.cpp:272:3:272:6 | call to free | There is a new/free mismatch between this free and the corresponding $@. | test.cpp:265:7:265:13 | new | new | +| test.cpp:441:2:441:10 | delete | There is a malloc/delete mismatch between this delete and the corresponding $@. | test.cpp:434:13:434:18 | call to strdup | malloc | +| test.cpp:443:2:443:10 | delete | There is a malloc/delete mismatch between this delete and the corresponding $@. | test.cpp:436:13:436:19 | call to strndup | malloc | +| test.cpp:445:2:445:10 | delete | There is a malloc/delete mismatch between this delete and the corresponding $@. | test.cpp:438:16:438:21 | call to wcsdup | malloc | diff --git a/cpp/ql/test/query-tests/Critical/NewFree/test.cpp b/cpp/ql/test/query-tests/Critical/NewFree/test.cpp index 9a9483b7f72..0807eadb333 100644 --- a/cpp/ql/test/query-tests/Critical/NewFree/test.cpp +++ b/cpp/ql/test/query-tests/Critical/NewFree/test.cpp @@ -424,3 +424,24 @@ void test13() delete myPointer3.getPointer(); // GOOD } + +char *strdup(const char *s1); +char *strndup(const char *s1, size_t n); +wchar_t* wcsdup(const wchar_t* s1); + +void test14() +{ + char *s1 = strdup("string"); + char *s2 = strdup("string"); + char *s3 = strndup("string", 3); + char *s4 = strndup("string", 3); + wchar_t *s5 = wcsdup(L"string"); + wchar_t *s6 = wcsdup(L"string"); + + delete s1; // BAD: strdup -> delete + free(s2); // GOOD + delete s3; // BAD: strndup -> delete + free(s4); // GOOD + delete s5; // BAD: wcsdup -> delete + free(s6); // GOOD +} diff --git a/cpp/ql/test/query-tests/Likely Bugs/Format/WrongNumberOfFormatArguments/test.c b/cpp/ql/test/query-tests/Likely Bugs/Format/WrongNumberOfFormatArguments/test.c index 8fc3fbe0425..2feb8db9a5a 100644 --- a/cpp/ql/test/query-tests/Likely Bugs/Format/WrongNumberOfFormatArguments/test.c +++ b/cpp/ql/test/query-tests/Likely Bugs/Format/WrongNumberOfFormatArguments/test.c @@ -42,4 +42,8 @@ void test(int i, const char *str) } printf("%@ %i %i", 1, 2); // GOOD + + printf("%Y", 1, 2); // GOOD (unknown format character, this might be correct) + printf("%1.1Y", 1, 2); // GOOD (unknown format character, this might be correct) + printf("%*.*Y", 1, 2); // GOOD (unknown format character, this might be correct) } diff --git a/cpp/ql/test/query-tests/Likely Bugs/Format/WrongTypeFormatArguments/Linux_two_byte_wprintf/WrongTypeFormatArguments.expected b/cpp/ql/test/query-tests/Likely Bugs/Format/WrongTypeFormatArguments/Linux_two_byte_wprintf/WrongTypeFormatArguments.expected index c5e9fa9aa7a..dbbf2c125bc 100644 --- a/cpp/ql/test/query-tests/Likely Bugs/Format/WrongTypeFormatArguments/Linux_two_byte_wprintf/WrongTypeFormatArguments.expected +++ b/cpp/ql/test/query-tests/Likely Bugs/Format/WrongTypeFormatArguments/Linux_two_byte_wprintf/WrongTypeFormatArguments.expected @@ -1,3 +1,3 @@ -| printf.cpp:33:31:33:37 | test | This argument should be of type 'char *' but is of type 'char16_t *' | -| printf.cpp:45:29:45:35 | test | This argument should be of type 'char *' but is of type 'char16_t *' | -| printf.cpp:52:29:52:35 | test | This argument should be of type 'char16_t *' but is of type 'wchar_t *' | +| printf.cpp:31:31:31:37 | test | This argument should be of type 'char *' but is of type 'char16_t *' | +| printf.cpp:43:29:43:35 | test | This argument should be of type 'char *' but is of type 'char16_t *' | +| printf.cpp:50:29:50:35 | test | This argument should be of type 'char16_t *' but is of type 'wchar_t *' | diff --git a/cpp/ql/test/query-tests/Likely Bugs/Format/WrongTypeFormatArguments/Linux_two_byte_wprintf/formattingFunction.expected b/cpp/ql/test/query-tests/Likely Bugs/Format/WrongTypeFormatArguments/Linux_two_byte_wprintf/formattingFunction.expected index b6f89c398e5..1fc280ab011 100644 --- a/cpp/ql/test/query-tests/Likely Bugs/Format/WrongTypeFormatArguments/Linux_two_byte_wprintf/formattingFunction.expected +++ b/cpp/ql/test/query-tests/Likely Bugs/Format/WrongTypeFormatArguments/Linux_two_byte_wprintf/formattingFunction.expected @@ -1,2 +1,2 @@ -| printf.cpp:15:5:15:12 | swprintf | char | char16_t | char16_t | -| printf.cpp:26:5:26:11 | sprintf | char | char16_t | char16_t | +| printf.cpp:13:5:13:12 | swprintf | char | char16_t | char16_t | +| printf.cpp:24:5:24:11 | sprintf | char | char16_t | char16_t | diff --git a/cpp/ql/test/query-tests/Likely Bugs/Format/WrongTypeFormatArguments/Linux_two_byte_wprintf/printf.cpp b/cpp/ql/test/query-tests/Likely Bugs/Format/WrongTypeFormatArguments/Linux_two_byte_wprintf/printf.cpp index 013df87ff5d..deb022d3b12 100644 --- a/cpp/ql/test/query-tests/Likely Bugs/Format/WrongTypeFormatArguments/Linux_two_byte_wprintf/printf.cpp +++ b/cpp/ql/test/query-tests/Likely Bugs/Format/WrongTypeFormatArguments/Linux_two_byte_wprintf/printf.cpp @@ -8,9 +8,7 @@ typedef void *va_list; #define va_start(va, other) #define va_end(args) -int vswprintf(WCHAR *dest, WCHAR *format, va_list args) { - return 0; -} +int vswprintf(WCHAR *dest, WCHAR *format, va_list args); int swprintf(WCHAR *dest, WCHAR *format, ...) { va_list args; diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-089/SqlTainted/SqlTainted.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-089/SqlTainted/SqlTainted.expected new file mode 100644 index 00000000000..af50f184740 --- /dev/null +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-089/SqlTainted/SqlTainted.expected @@ -0,0 +1,13 @@ +edges +| test.c:15:20:15:23 | argv | test.c:21:18:21:23 | (const char *)... | +| test.c:15:20:15:23 | argv | test.c:21:18:21:23 | (const char *)... | +| test.c:15:20:15:23 | argv | test.c:21:18:21:23 | query1 | +| test.c:15:20:15:23 | argv | test.c:21:18:21:23 | query1 | +nodes +| test.c:15:20:15:23 | argv | semmle.label | argv | +| test.c:15:20:15:23 | argv | semmle.label | argv | +| test.c:21:18:21:23 | (const char *)... | semmle.label | (const char *)... | +| test.c:21:18:21:23 | (const char *)... | semmle.label | (const char *)... | +| test.c:21:18:21:23 | query1 | semmle.label | query1 | +#select +| test.c:21:18:21:23 | query1 | test.c:15:20:15:23 | argv | test.c:21:18:21:23 | query1 | This argument to a SQL query function is derived from $@ and then passed to mysql_query(sqlArg) | test.c:15:20:15:23 | argv | user input (argv) | diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-089/SqlTainted/SqlTainted.qlref b/cpp/ql/test/query-tests/Security/CWE/CWE-089/SqlTainted/SqlTainted.qlref new file mode 100644 index 00000000000..21a12e5eadd --- /dev/null +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-089/SqlTainted/SqlTainted.qlref @@ -0,0 +1 @@ +Security/CWE/CWE-089/SqlTainted.ql diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-089/SqlTainted/test.c b/cpp/ql/test/query-tests/Security/CWE/CWE-089/SqlTainted/test.c new file mode 100644 index 00000000000..45304f13872 --- /dev/null +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-089/SqlTainted/test.c @@ -0,0 +1,34 @@ +// Semmle test case for rule SprintfToSqlQuery.ql (Uncontrolled sprintf for SQL query) +// Associated with CWE-089: SQL injection. http://cwe.mitre.org/data/definitions/89.html + +///// Library routines ///// + +typedef unsigned long size_t; +int snprintf(char *s, size_t n, const char *format, ...); +void sanitizeString(char *stringOut, size_t len, const char *strIn); +int mysql_query(int arg1, const char *sqlArg); +int atoi(const char *nptr); + +///// Test code ///// + +int main(int argc, char** argv) { + char *userName = argv[2]; + int userNumber = atoi(argv[3]); + + // a string from the user is injected directly into an SQL query. + char query1[1000] = {0}; + snprintf(query1, 1000, "SELECT UID FROM USERS where name = \"%s\"", userName); + mysql_query(0, query1); // BAD + + // the user string is encoded by a library routine. + char userNameSanitized[1000] = {0}; + sanitizeString(userNameSanitized, 1000, userName); + char query2[1000] = {0}; + snprintf(query2, 1000, "SELECT UID FROM USERS where name = \"%s\"", userNameSanitized); + mysql_query(0, query2); // GOOD + + // an integer from the user is injected into an SQL query. + char query3[1000] = {0}; + snprintf(query3, 1000, "SELECT UID FROM USERS where number = \"%i\"", userNumber); + mysql_query(0, query3); // GOOD +} diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-134/semmle/globalVars/UncontrolledFormatStringThroughGlobalVar.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-134/semmle/globalVars/UncontrolledFormatStringThroughGlobalVar.expected index 826a659755d..6e90a21c7e1 100644 --- a/cpp/ql/test/query-tests/Security/CWE/CWE-134/semmle/globalVars/UncontrolledFormatStringThroughGlobalVar.expected +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-134/semmle/globalVars/UncontrolledFormatStringThroughGlobalVar.expected @@ -4,12 +4,14 @@ edges | globalVars.c:8:7:8:10 | copy | globalVars.c:27:9:27:12 | copy | | globalVars.c:8:7:8:10 | copy | globalVars.c:30:15:30:18 | copy | | globalVars.c:8:7:8:10 | copy | globalVars.c:30:15:30:18 | copy | +| globalVars.c:8:7:8:10 | copy | globalVars.c:30:15:30:18 | copy | | globalVars.c:8:7:8:10 | copy | globalVars.c:35:11:35:14 | copy | | globalVars.c:9:7:9:11 | copy2 | globalVars.c:38:9:38:13 | copy2 | | globalVars.c:9:7:9:11 | copy2 | globalVars.c:38:9:38:13 | copy2 | | globalVars.c:9:7:9:11 | copy2 | globalVars.c:38:9:38:13 | copy2 | | globalVars.c:9:7:9:11 | copy2 | globalVars.c:41:15:41:19 | copy2 | | globalVars.c:9:7:9:11 | copy2 | globalVars.c:41:15:41:19 | copy2 | +| globalVars.c:9:7:9:11 | copy2 | globalVars.c:41:15:41:19 | copy2 | | globalVars.c:9:7:9:11 | copy2 | globalVars.c:50:9:50:13 | copy2 | | globalVars.c:9:7:9:11 | copy2 | globalVars.c:50:9:50:13 | copy2 | | globalVars.c:9:7:9:11 | copy2 | globalVars.c:50:9:50:13 | copy2 | @@ -25,9 +27,15 @@ edges | globalVars.c:24:11:24:14 | argv | globalVars.c:11:22:11:25 | argv | | globalVars.c:27:9:27:12 | copy | globalVars.c:27:9:27:12 | (const char *)... | | globalVars.c:27:9:27:12 | copy | globalVars.c:27:9:27:12 | copy | +| globalVars.c:30:15:30:18 | copy | globalVars.c:30:15:30:18 | copy | +| globalVars.c:30:15:30:18 | copy | globalVars.c:30:15:30:18 | copy | +| globalVars.c:30:15:30:18 | copy | globalVars.c:30:15:30:18 | copy | | globalVars.c:35:11:35:14 | copy | globalVars.c:15:21:15:23 | val | | globalVars.c:38:9:38:13 | copy2 | globalVars.c:38:9:38:13 | (const char *)... | | globalVars.c:38:9:38:13 | copy2 | globalVars.c:38:9:38:13 | copy2 | +| globalVars.c:41:15:41:19 | copy2 | globalVars.c:41:15:41:19 | copy2 | +| globalVars.c:41:15:41:19 | copy2 | globalVars.c:41:15:41:19 | copy2 | +| globalVars.c:41:15:41:19 | copy2 | globalVars.c:41:15:41:19 | copy2 | | globalVars.c:50:9:50:13 | copy2 | globalVars.c:50:9:50:13 | (const char *)... | | globalVars.c:50:9:50:13 | copy2 | globalVars.c:50:9:50:13 | copy2 | nodes diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-191/UnsignedDifferenceExpressionComparedZero/UnsignedDifferenceExpressionComparedZero.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-191/UnsignedDifferenceExpressionComparedZero/UnsignedDifferenceExpressionComparedZero.expected new file mode 100644 index 00000000000..2d28795d126 --- /dev/null +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-191/UnsignedDifferenceExpressionComparedZero/UnsignedDifferenceExpressionComparedZero.expected @@ -0,0 +1,10 @@ +| test.cpp:6:5:6:13 | ... > ... | Unsigned subtraction can never be negative. | +| test.cpp:10:8:10:24 | ... > ... | Unsigned subtraction can never be negative. | +| test.cpp:15:9:15:25 | ... > ... | Unsigned subtraction can never be negative. | +| test.cpp:32:12:32:20 | ... > ... | Unsigned subtraction can never be negative. | +| test.cpp:39:12:39:20 | ... > ... | Unsigned subtraction can never be negative. | +| test.cpp:47:5:47:13 | ... > ... | Unsigned subtraction can never be negative. | +| test.cpp:55:5:55:13 | ... > ... | Unsigned subtraction can never be negative. | +| test.cpp:62:5:62:13 | ... > ... | Unsigned subtraction can never be negative. | +| test.cpp:69:5:69:13 | ... > ... | Unsigned subtraction can never be negative. | +| test.cpp:75:8:75:16 | ... > ... | Unsigned subtraction can never be negative. | diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-191/UnsignedDifferenceExpressionComparedZero/UnsignedDifferenceExpressionComparedZero.qlref b/cpp/ql/test/query-tests/Security/CWE/CWE-191/UnsignedDifferenceExpressionComparedZero/UnsignedDifferenceExpressionComparedZero.qlref new file mode 100644 index 00000000000..9681978c0ad --- /dev/null +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-191/UnsignedDifferenceExpressionComparedZero/UnsignedDifferenceExpressionComparedZero.qlref @@ -0,0 +1 @@ +Security/CWE/CWE-191/UnsignedDifferenceExpressionComparedZero.ql diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-191/UnsignedDifferenceExpressionComparedZero/test.cpp b/cpp/ql/test/query-tests/Security/CWE/CWE-191/UnsignedDifferenceExpressionComparedZero/test.cpp new file mode 100644 index 00000000000..11de69e8c62 --- /dev/null +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-191/UnsignedDifferenceExpressionComparedZero/test.cpp @@ -0,0 +1,77 @@ +int getAnInt(); + +bool cond(); + +void test(unsigned x, unsigned y, bool unknown) { + if(x - y > 0) { } // BAD + + unsigned total = getAnInt(); + unsigned limit = getAnInt(); + while(limit - total > 0) { // BAD + total += getAnInt(); + } + + if(total <= limit) { + while(limit - total > 0) { // GOOD [FALSE POSITIVE] + total += getAnInt(); + if(total > limit) break; + } + } + + if(x >= y) { + bool b = x - y > 0; // GOOD + } + + if((int)(x - y) >= 0) { } // GOOD. Maybe an overflow happened, but the result is converted to the "likely intended" result before the comparison + + if(unknown) { + y = x & 0xFF; + } else { + y = x; + } + bool b1 = x - y > 0; // GOOD [FALSE POSITIVE] + + x = getAnInt(); + y = getAnInt(); + if(y > x) { + y = x - 1; + } + bool b2 = x - y > 0; // GOOD [FALSE POSITIVE] + + int N = getAnInt(); + y = x; + while(cond()) { + if(unknown) { y--; } + } + + if(x - y > 0) { } // GOOD [FALSE POSITIVE] + + x = y; + while(cond()) { + if(unknown) break; + y--; + } + + if(x - y > 0) { } // GOOD [FALSE POSITIVE] + + y = 0; + for(int i = 0; i < x; ++i) { + if(unknown) { ++y; } + } + + if(x - y > 0) { } // GOOD [FALSE POSITIVE] + + x = y; + while(cond()) { + if(unknown) { x++; } + } + + if(x - y > 0) { } // GOOD [FALSE POSITIVE] + + int n = getAnInt(); + if (n > x - y) { n = x - y; } + if (n > 0) { + y += n; // NOTE: `n` is at most `x - y` at this point. + if (x - y > 0) {} // GOOD [FALSE POSITIVE] + } +} \ No newline at end of file diff --git a/cpp/upgrades/c82db4c596b8979eba9a8958e24353a5756d7a02/old.dbscheme b/cpp/upgrades/c82db4c596b8979eba9a8958e24353a5756d7a02/old.dbscheme new file mode 100644 index 00000000000..c82db4c596b --- /dev/null +++ b/cpp/upgrades/c82db4c596b8979eba9a8958e24353a5756d7a02/old.dbscheme @@ -0,0 +1,2125 @@ + +/** + * An invocation of the compiler. Note that more than one file may be + * compiled per invocation. For example, this command compiles three + * source files: + * + * gcc -c f1.c f2.c f3.c + * + * The `id` simply identifies the invocation, while `cwd` is the working + * directory from which the compiler was invoked. + */ +compilations( + /** + * An invocation of the compiler. Note that more than one file may + * be compiled per invocation. For example, this command compiles + * three source files: + * + * gcc -c f1.c f2.c f3.c + */ + unique int id : @compilation, + string cwd : string ref +); + +/** + * The arguments that were passed to the extractor for a compiler + * invocation. If `id` is for the compiler invocation + * + * gcc -c f1.c f2.c f3.c + * + * then typically there will be rows for + * + * num | arg + * --- | --- + * 0 | *path to extractor* + * 1 | `--mimic` + * 2 | `/usr/bin/gcc` + * 3 | `-c` + * 4 | f1.c + * 5 | f2.c + * 6 | f3.c + */ +#keyset[id, num] +compilation_args( + int id : @compilation ref, + int num : int ref, + string arg : string ref +); + +/** + * The source files that are compiled by a compiler invocation. + * If `id` is for the compiler invocation + * + * gcc -c f1.c f2.c f3.c + * + * then there will be rows for + * + * num | arg + * --- | --- + * 0 | f1.c + * 1 | f2.c + * 2 | f3.c + * + * Note that even if those files `#include` headers, those headers + * do not appear as rows. + */ +#keyset[id, num] +compilation_compiling_files( + int id : @compilation ref, + int num : int ref, + int file : @file ref +); + +/** + * The time taken by the extractor for a compiler invocation. + * + * For each file `num`, there will be rows for + * + * kind | seconds + * ---- | --- + * 1 | CPU seconds used by the extractor frontend + * 2 | Elapsed seconds during the extractor frontend + * 3 | CPU seconds used by the extractor backend + * 4 | Elapsed seconds during the extractor backend + */ +#keyset[id, num, kind] +compilation_time( + int id : @compilation ref, + int num : int ref, + /* kind: + 1 = frontend_cpu_seconds + 2 = frontend_elapsed_seconds + 3 = extractor_cpu_seconds + 4 = extractor_elapsed_seconds + */ + int kind : int ref, + float seconds : float ref +); + +/** + * An error or warning generated by the extractor. + * The diagnostic message `diagnostic` was generated during compiler + * invocation `compilation`, and is the `file_number_diagnostic_number`th + * message generated while extracting the `file_number`th file of that + * invocation. + */ +#keyset[compilation, file_number, file_number_diagnostic_number] +diagnostic_for( + int diagnostic : @diagnostic ref, + int compilation : @compilation ref, + int file_number : int ref, + int file_number_diagnostic_number : int ref +); + +/** + * If extraction was successful, then `cpu_seconds` and + * `elapsed_seconds` are the CPU time and elapsed time (respectively) + * that extraction took for compiler invocation `id`. + */ +compilation_finished( + unique int id : @compilation ref, + float cpu_seconds : float ref, + float elapsed_seconds : float ref +); + + +/** + * External data, loaded from CSV files during snapshot creation. See + * [Tutorial: Incorporating external data](https://help.semmle.com/wiki/display/SD/Tutorial%3A+Incorporating+external+data) + * for more information. + */ +externalData( + int id : @externalDataElement, + string path : string ref, + int column: int ref, + string value : string ref +); + +/** + * The date of the snapshot. + */ +snapshotDate(unique date snapshotDate : date ref); + +/** + * The source location of the snapshot. + */ +sourceLocationPrefix(string prefix : string ref); + +/** + * Data used by the 'duplicate code' detection. + */ +duplicateCode( + unique int id : @duplication, + string relativePath : string ref, + int equivClass : int ref +); + +/** + * Data used by the 'similar code' detection. + */ +similarCode( + unique int id : @similarity, + string relativePath : string ref, + int equivClass : int ref +); + +/** + * Data used by the 'duplicate code' and 'similar code' detection. + */ +@duplication_or_similarity = @duplication | @similarity + +/** + * Data used by the 'duplicate code' and 'similar code' detection. + */ +#keyset[id, offset] +tokens( + int id : @duplication_or_similarity ref, + int offset : int ref, + int beginLine : int ref, + int beginColumn : int ref, + int endLine : int ref, + int endColumn : int ref +); + +/** + * Information about packages that provide code used during compilation. + * The `id` is just a unique identifier. + * The `namespace` is typically the name of the package manager that + * provided the package (e.g. "dpkg" or "yum"). + * The `package_name` is the name of the package, and `version` is its + * version (as a string). + */ +external_packages( + unique int id: @external_package, + string namespace : string ref, + string package_name : string ref, + string version : string ref +); + +/** + * Holds if File `fileid` was provided by package `package`. + */ +header_to_external_package( + int fileid : @file ref, + int package : @external_package ref +); + +/* + * Version history + */ + +svnentries( + unique int id : @svnentry, + string revision : string ref, + string author : string ref, + date revisionDate : date ref, + int changeSize : int ref +) + +svnaffectedfiles( + int id : @svnentry ref, + int file : @file ref, + string action : string ref +) + +svnentrymsg( + unique int id : @svnentry ref, + string message : string ref +) + +svnchurn( + int commit : @svnentry ref, + int file : @file ref, + int addedLines : int ref, + int deletedLines : int ref +) + +/* + * C++ dbscheme + */ + +@location = @location_stmt | @location_expr | @location_default ; + +/** + * The location of an element that is not an expression or a statement. + * The location spans column `startcolumn` of line `startline` to + * column `endcolumn` of line `endline` in file `file`. + * For more information, see + * [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html). + */ +locations_default( + /** The location of an element that is not an expression or a statement. */ + unique int id: @location_default, + int container: @container ref, + int startLine: int ref, + int startColumn: int ref, + int endLine: int ref, + int endColumn: int ref +); + +/** + * The location of a statement. + * The location spans column `startcolumn` of line `startline` to + * column `endcolumn` of line `endline` in file `file`. + * For more information, see + * [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html). + */ +locations_stmt( + /** The location of a statement. */ + unique int id: @location_stmt, + int container: @container ref, + int startLine: int ref, + int startColumn: int ref, + int endLine: int ref, + int endColumn: int ref +); + +/** + * The location of an expression. + * The location spans column `startcolumn` of line `startline` to + * column `endcolumn` of line `endline` in file `file`. + * For more information, see + * [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html). + */ +locations_expr( + /** The location of an expression. */ + unique int id: @location_expr, + int container: @container ref, + int startLine: int ref, + int startColumn: int ref, + int endLine: int ref, + int endColumn: int ref +); + +/** An element for which line-count information is available. */ +@sourceline = @file | @function | @variable | @enumconstant | @xmllocatable; + +numlines( + int element_id: @sourceline ref, + int num_lines: int ref, + int num_code: int ref, + int num_comment: int ref +); + +diagnostics( + unique int id: @diagnostic, + int severity: int ref, + string error_tag: string ref, + string error_message: string ref, + string full_error_message: string ref, + int location: @location_default ref +); + +/* + fromSource(0) = unknown, + fromSource(1) = from source, + fromSource(2) = from library +*/ +files( + unique int id: @file, + string name: string ref, + string simple: string ref, + string ext: string ref, + int fromSource: int ref +); + +folders( + unique int id: @folder, + string name: string ref, + string simple: string ref +); + +@container = @folder | @file + +containerparent( + int parent: @container ref, + unique int child: @container ref +); + +fileannotations( + int id: @file ref, + int kind: int ref, + string name: string ref, + string value: string ref +); + +inmacroexpansion( + int id: @element ref, + int inv: @macroinvocation ref +); + +affectedbymacroexpansion( + int id: @element ref, + int inv: @macroinvocation ref +); + +/* + case @macroinvocations.kind of + 1 = macro expansion + | 2 = other macro reference + ; +*/ +macroinvocations( + unique int id: @macroinvocation, + int macro_id: @ppd_define ref, + int location: @location_default ref, + int kind: int ref +); + +macroparent( + unique int id: @macroinvocation ref, + int parent_id: @macroinvocation ref +); + +// a macroinvocation may be part of another location +// the way to find a constant expression that uses a macro +// is thus to find a constant expression that has a location +// to which a macro invocation is bound +macrolocationbind( + int id: @macroinvocation ref, + int location: @location ref +); + +#keyset[invocation, argument_index] +macro_argument_unexpanded( + int invocation: @macroinvocation ref, + int argument_index: int ref, + string text: string ref +); + +#keyset[invocation, argument_index] +macro_argument_expanded( + int invocation: @macroinvocation ref, + int argument_index: int ref, + string text: string ref +); + +/* + case @function.kind of + 1 = normal + | 2 = constructor + | 3 = destructor + | 4 = conversion + | 5 = operator + | 6 = builtin // GCC built-in functions, e.g. __builtin___memcpy_chk + ; +*/ +functions( + unique int id: @function, + string name: string ref, + int kind: int ref +); + +function_entry_point(int id: @function ref, unique int entry_point: @stmt ref); + +function_return_type(int id: @function ref, int return_type: @type ref); + +/** If `function` is a coroutine, then this gives the + std::experimental::resumable_traits instance associated with it, + and the variables representing the `handle` and `promise` for it. */ +coroutine( + unique int function: @function ref, + int traits: @type ref, + int handle: @variable ref, + int promise: @variable ref +); + +/** The `new` function used for allocating the coroutine state, if any. */ +coroutine_new( + unique int function: @function ref, + int new: @function ref +); + +/** The `delete` function used for deallocating the coroutine state, if any. */ +coroutine_delete( + unique int function: @function ref, + int delete: @function ref +); + +purefunctions(unique int id: @function ref); + +function_deleted(unique int id: @function ref); + +function_defaulted(unique int id: @function ref); + +member_function_this_type(unique int id: @function ref, int this_type: @type ref); + +#keyset[id, type_id] +fun_decls( + int id: @fun_decl, + int function: @function ref, + int type_id: @type ref, + string name: string ref, + int location: @location_default ref +); +fun_def(unique int id: @fun_decl ref); +fun_specialized(unique int id: @fun_decl ref); +fun_implicit(unique int id: @fun_decl ref); +fun_decl_specifiers( + int id: @fun_decl ref, + string name: string ref +) +#keyset[fun_decl, index] +fun_decl_throws( + int fun_decl: @fun_decl ref, + int index: int ref, + int type_id: @type ref +); +/* an empty throw specification is different from none */ +fun_decl_empty_throws(unique int fun_decl: @fun_decl ref); +fun_decl_noexcept( + int fun_decl: @fun_decl ref, + int constant: @expr ref +); +fun_decl_empty_noexcept(int fun_decl: @fun_decl ref); +fun_decl_typedef_type( + unique int fun_decl: @fun_decl ref, + int typedeftype_id: @usertype ref +); + +param_decl_bind( + unique int id: @var_decl ref, + int index: int ref, + int fun_decl: @fun_decl ref +); + +#keyset[id, type_id] +var_decls( + int id: @var_decl, + int variable: @variable ref, + int type_id: @type ref, + string name: string ref, + int location: @location_default ref +); +var_def(unique int id: @var_decl ref); +var_decl_specifiers( + int id: @var_decl ref, + string name: string ref +) + +type_decls( + unique int id: @type_decl, + int type_id: @type ref, + int location: @location_default ref +); +type_def(unique int id: @type_decl ref); +type_decl_top( + unique int type_decl: @type_decl ref +); + +namespace_decls( + unique int id: @namespace_decl, + int namespace_id: @namespace ref, + int location: @location_default ref, + int bodylocation: @location_default ref +); + +usings( + unique int id: @using, + int element_id: @element ref, + int location: @location_default ref +); + +/** The element which contains the `using` declaration. */ +using_container( + int parent: @element ref, + int child: @using ref +); + +static_asserts( + unique int id: @static_assert, + int condition : @expr ref, + string message : string ref, + int location: @location_default ref, + int enclosing : @element ref +); + +// each function has an ordered list of parameters +#keyset[id, type_id] +#keyset[function, index, type_id] +params( + int id: @parameter, + int function: @functionorblock ref, + int index: int ref, + int type_id: @type ref +); + +overrides(int new: @function ref, int old: @function ref); + +#keyset[id, type_id] +membervariables( + int id: @membervariable, + int type_id: @type ref, + string name: string ref +); + +#keyset[id, type_id] +globalvariables( + int id: @globalvariable, + int type_id: @type ref, + string name: string ref +); + +#keyset[id, type_id] +localvariables( + int id: @localvariable, + int type_id: @type ref, + string name: string ref +); + +autoderivation( + unique int var: @variable ref, + int derivation_type: @type ref +); + +enumconstants( + unique int id: @enumconstant, + int parent: @usertype ref, + int index: int ref, + int type_id: @type ref, + string name: string ref, + int location: @location_default ref +); + +@variable = @localscopevariable | @globalvariable | @membervariable; + +@localscopevariable = @localvariable | @parameter; + +/* + Built-in types are the fundamental types, e.g., integral, floating, and void. + + case @builtintype.kind of + 1 = error + | 2 = unknown + | 3 = void + | 4 = boolean + | 5 = char + | 6 = unsigned_char + | 7 = signed_char + | 8 = short + | 9 = unsigned_short + | 10 = signed_short + | 11 = int + | 12 = unsigned_int + | 13 = signed_int + | 14 = long + | 15 = unsigned_long + | 16 = signed_long + | 17 = long_long + | 18 = unsigned_long_long + | 19 = signed_long_long + | 20 = __int8 // Microsoft-specific + | 21 = __int16 // Microsoft-specific + | 22 = __int32 // Microsoft-specific + | 23 = __int64 // Microsoft-specific + | 24 = float + | 25 = double + | 26 = long_double + | 27 = _Complex_float // C99-specific + | 28 = _Complex_double // C99-specific + | 29 = _Complex_long double // C99-specific + | 30 = _Imaginary_float // C99-specific + | 31 = _Imaginary_double // C99-specific + | 32 = _Imaginary_long_double // C99-specific + | 33 = wchar_t // Microsoft-specific + | 34 = decltype_nullptr // C++11 + | 35 = __int128 + | 36 = unsigned___int128 + | 37 = signed___int128 + | 38 = __float128 + | 39 = _Complex___float128 + | 40 = _Decimal32 + | 41 = _Decimal64 + | 42 = _Decimal128 + | 43 = char16_t + | 44 = char32_t + | 45 = _Float32 + | 46 = _Float32x + | 47 = _Float64 + | 48 = _Float64x + | 49 = _Float128 + | 50 = _Float128x + | 51 = char8_t + ; +*/ +builtintypes( + unique int id: @builtintype, + string name: string ref, + int kind: int ref, + int size: int ref, + int sign: int ref, + int alignment: int ref +); + +/* + Derived types are types that are directly derived from existing types and + point to, refer to, transform type data to return a new type. + + case @derivedtype.kind of + 1 = pointer + | 2 = reference + | 3 = type_with_specifiers + | 4 = array + | 5 = gnu_vector + | 6 = routineptr + | 7 = routinereference + | 8 = rvalue_reference // C++11 +// ... 9 type_conforming_to_protocols deprecated + | 10 = block + ; +*/ +derivedtypes( + unique int id: @derivedtype, + string name: string ref, + int kind: int ref, + int type_id: @type ref +); + +pointerishsize(unique int id: @derivedtype ref, + int size: int ref, + int alignment: int ref); + +arraysizes( + unique int id: @derivedtype ref, + int num_elements: int ref, + int bytesize: int ref, + int alignment: int ref +); + +typedefbase( + unique int id: @usertype ref, + int type_id: @type ref +); + +decltypes( + unique int id: @decltype, + int expr: @expr ref, + int base_type: @type ref, + boolean parentheses_would_change_meaning: boolean ref +); + +/* + case @usertype.kind of + 1 = struct + | 2 = class + | 3 = union + | 4 = enum + | 5 = typedef // classic C: typedef typedef type name + | 6 = template + | 7 = template_parameter + | 8 = template_template_parameter + | 9 = proxy_class // a proxy class associated with a template parameter +// ... 10 objc_class deprecated +// ... 11 objc_protocol deprecated +// ... 12 objc_category deprecated + | 13 = scoped_enum + | 14 = using_alias // a using name = type style typedef + ; +*/ +usertypes( + unique int id: @usertype, + string name: string ref, + int kind: int ref +); + +usertypesize( + unique int id: @usertype ref, + int size: int ref, + int alignment: int ref +); + +usertype_final(unique int id: @usertype ref); + +usertype_uuid( + unique int id: @usertype ref, + unique string uuid: string ref +); + +mangled_name( + unique int id: @declaration ref, + int mangled_name : @mangledname +); + +is_pod_class(unique int id: @usertype ref); +is_standard_layout_class(unique int id: @usertype ref); + +is_complete(unique int id: @usertype ref); + +is_class_template(unique int id: @usertype ref); +class_instantiation( + int to: @usertype ref, + int from: @usertype ref +); +class_template_argument( + int type_id: @usertype ref, + int index: int ref, + int arg_type: @type ref +); +class_template_argument_value( + int type_id: @usertype ref, + int index: int ref, + int arg_value: @expr ref +); + +is_proxy_class_for( + unique int id: @usertype ref, + unique int templ_param_id: @usertype ref +); + +type_mentions( + unique int id: @type_mention, + int type_id: @type ref, + int location: @location ref, + // a_symbol_reference_kind from the EDG frontend. See symbol_ref.h there. + int kind: int ref +); + +is_function_template(unique int id: @function ref); +function_instantiation( + unique int to: @function ref, + int from: @function ref +); +function_template_argument( + int function_id: @function ref, + int index: int ref, + int arg_type: @type ref +); +function_template_argument_value( + int function_id: @function ref, + int index: int ref, + int arg_value: @expr ref +); + +is_variable_template(unique int id: @variable ref); +variable_instantiation( + unique int to: @variable ref, + int from: @variable ref +); +variable_template_argument( + int variable_id: @variable ref, + int index: int ref, + int arg_type: @type ref +); +variable_template_argument_value( + int variable_id: @variable ref, + int index: int ref, + int arg_value: @expr ref +); + +/* + Fixed point types + precision(1) = short, precision(2) = default, precision(3) = long + is_unsigned(1) = unsigned is_unsigned(2) = signed + is_fract_type(1) = declared with _Fract + saturating(1) = declared with _Sat +*/ +/* TODO +fixedpointtypes( + unique int id: @fixedpointtype, + int precision: int ref, + int is_unsigned: int ref, + int is_fract_type: int ref, + int saturating: int ref); +*/ + +routinetypes( + unique int id: @routinetype, + int return_type: @type ref +); + +routinetypeargs( + int routine: @routinetype ref, + int index: int ref, + int type_id: @type ref +); + +ptrtomembers( + unique int id: @ptrtomember, + int type_id: @type ref, + int class_id: @type ref +); + +/* + specifiers for types, functions, and variables + + "public", + "protected", + "private", + + "const", + "volatile", + "static", + + "pure", + "virtual", + "sealed", // Microsoft + "__interface", // Microsoft + "inline", + "explicit", + + "near", // near far extension + "far", // near far extension + "__ptr32", // Microsoft + "__ptr64", // Microsoft + "__sptr", // Microsoft + "__uptr", // Microsoft + "dllimport", // Microsoft + "dllexport", // Microsoft + "thread", // Microsoft + "naked", // Microsoft + "microsoft_inline", // Microsoft + "forceinline", // Microsoft + "selectany", // Microsoft + "nothrow", // Microsoft + "novtable", // Microsoft + "noreturn", // Microsoft + "noinline", // Microsoft + "noalias", // Microsoft + "restrict", // Microsoft +*/ + +specifiers( + unique int id: @specifier, + unique string str: string ref +); + +typespecifiers( + int type_id: @type ref, + int spec_id: @specifier ref +); + +funspecifiers( + int func_id: @function ref, + int spec_id: @specifier ref +); + +varspecifiers( + int var_id: @accessible ref, + int spec_id: @specifier ref +); + +attributes( + unique int id: @attribute, + int kind: int ref, + string name: string ref, + string name_space: string ref, + int location: @location_default ref +); + +case @attribute.kind of + 0 = @gnuattribute +| 1 = @stdattribute +| 2 = @declspec +| 3 = @msattribute +| 4 = @alignas +// ... 5 @objc_propertyattribute deprecated +; + +attribute_args( + unique int id: @attribute_arg, + int kind: int ref, + int attribute: @attribute ref, + int index: int ref, + int location: @location_default ref +); + +case @attribute_arg.kind of + 0 = @attribute_arg_empty +| 1 = @attribute_arg_token +| 2 = @attribute_arg_constant +| 3 = @attribute_arg_type +; + +attribute_arg_value( + unique int arg: @attribute_arg ref, + string value: string ref +); +attribute_arg_type( + unique int arg: @attribute_arg ref, + int type_id: @type ref +); +attribute_arg_name( + unique int arg: @attribute_arg ref, + string name: string ref +); + +typeattributes( + int type_id: @type ref, + int spec_id: @attribute ref +); + +funcattributes( + int func_id: @function ref, + int spec_id: @attribute ref +); + +varattributes( + int var_id: @accessible ref, + int spec_id: @attribute ref +); + +stmtattributes( + int stmt_id: @stmt ref, + int spec_id: @attribute ref +); + +@type = @builtintype + | @derivedtype + | @usertype + /* TODO | @fixedpointtype */ + | @routinetype + | @ptrtomember + | @decltype; + +unspecifiedtype( + unique int type_id: @type ref, + int unspecified_type_id: @type ref +); + +member( + int parent: @type ref, + int index: int ref, + int child: @member ref +); + +@enclosingfunction_child = @usertype | @variable | @namespace + +enclosingfunction( + unique int child: @enclosingfunction_child ref, + int parent: @function ref +); + +derivations( + unique int derivation: @derivation, + int sub: @type ref, + int index: int ref, + int super: @type ref, + int location: @location_default ref +); + +derspecifiers( + int der_id: @derivation ref, + int spec_id: @specifier ref +); + +/** + * Contains the byte offset of the base class subobject within the derived + * class. Only holds for non-virtual base classes, but see table + * `virtual_base_offsets` for offsets of virtual base class subobjects. + */ +direct_base_offsets( + unique int der_id: @derivation ref, + int offset: int ref +); + +/** + * Contains the byte offset of the virtual base class subobject for class + * `super` within a most-derived object of class `sub`. `super` can be either a + * direct or indirect base class. + */ +#keyset[sub, super] +virtual_base_offsets( + int sub: @usertype ref, + int super: @usertype ref, + int offset: int ref +); + +frienddecls( + unique int id: @frienddecl, + int type_id: @type ref, + int decl_id: @declaration ref, + int location: @location_default ref +); + +@declaredtype = @usertype ; + +@declaration = @function + | @declaredtype + | @variable + | @enumconstant + | @frienddecl; + +@member = @membervariable + | @function + | @declaredtype + | @enumconstant; + +@locatable = @diagnostic + | @declaration + | @ppd_include + | @ppd_define + | @macroinvocation + /*| @funcall*/ + | @xmllocatable + | @attribute + | @attribute_arg; + +@namedscope = @namespace | @usertype; + +@element = @locatable + | @file + | @folder + | @specifier + | @type + | @expr + | @namespace + | @initialiser + | @stmt + | @derivation + | @comment + | @preprocdirect + | @fun_decl + | @var_decl + | @type_decl + | @namespace_decl + | @using + | @namequalifier + | @specialnamequalifyingelement + | @static_assert + | @type_mention + | @lambdacapture; + +@exprparent = @element; + +comments( + unique int id: @comment, + string contents: string ref, + int location: @location_default ref +); + +commentbinding( + int id: @comment ref, + int element: @element ref +); + +exprconv( + int converted: @expr ref, + unique int conversion: @expr ref +); + +compgenerated(unique int id: @element ref); + +/** + * `destructor_call` destructs the `i`'th entity that should be + * destructed following `element`. Note that entities should be + * destructed in reverse construction order, so for a given `element` + * these should be called from highest to lowest `i`. + */ +#keyset[element, destructor_call] +#keyset[element, i] +synthetic_destructor_call( + int element: @element ref, + int i: int ref, + int destructor_call: @routineexpr ref +); + +namespaces( + unique int id: @namespace, + string name: string ref +); + +namespace_inline( + unique int id: @namespace ref +); + +namespacembrs( + int parentid: @namespace ref, + unique int memberid: @namespacembr ref +); + +@namespacembr = @declaration | @namespace; + +exprparents( + int expr_id: @expr ref, + int child_index: int ref, + int parent_id: @exprparent ref +); + +expr_isload(unique int expr_id: @expr ref); + +@cast = @c_style_cast + | @const_cast + | @dynamic_cast + | @reinterpret_cast + | @static_cast + ; + +/* +case @conversion.kind of + 0 = @simple_conversion // a numeric conversion, qualification conversion, or a reinterpret_cast +| 1 = @bool_conversion // conversion to 'bool' +| 2 = @base_class_conversion // a derived-to-base conversion +| 3 = @derived_class_conversion // a base-to-derived conversion +| 4 = @pm_base_class_conversion // a derived-to-base conversion of a pointer to member +| 5 = @pm_derived_class_conversion // a base-to-derived conversion of a pointer to member +| 6 = @glvalue_adjust // an adjustment of the type of a glvalue +| 7 = @prvalue_adjust // an adjustment of the type of a prvalue +; +*/ +/** + * Describes the semantics represented by a cast expression. This is largely + * independent of the source syntax of the cast, so it is separate from the + * regular expression kind. + */ +conversionkinds( + unique int expr_id: @cast ref, + int kind: int ref +); + +@conversion = @cast + | @array_to_pointer + | @parexpr + | @reference_to + | @ref_indirect + | @temp_init + ; + +/* +case @funbindexpr.kind of + 0 = @normal_call // a normal call +| 1 = @virtual_call // a virtual call +| 2 = @adl_call // a call whose target is only found by ADL +; +*/ +iscall(unique int caller: @funbindexpr ref, int kind: int ref); + +numtemplatearguments( + unique int expr_id: @expr ref, + int num: int ref +); + +specialnamequalifyingelements( + unique int id: @specialnamequalifyingelement, + unique string name: string ref +); + +@namequalifiableelement = @expr | @namequalifier; +@namequalifyingelement = @namespace + | @specialnamequalifyingelement + | @usertype; + +namequalifiers( + unique int id: @namequalifier, + unique int qualifiableelement: @namequalifiableelement ref, + int qualifyingelement: @namequalifyingelement ref, + int location: @location_default ref +); + +varbind( + int expr: @varbindexpr ref, + int var: @accessible ref +); + +funbind( + int expr: @funbindexpr ref, + int fun: @function ref +); + +@any_new_expr = @new_expr + | @new_array_expr; + +@new_or_delete_expr = @any_new_expr + | @delete_expr + | @delete_array_expr; + +@prefix_crement_expr = @preincrexpr | @predecrexpr; + +@postfix_crement_expr = @postincrexpr | @postdecrexpr; + +@increment_expr = @preincrexpr | @postincrexpr; + +@decrement_expr = @predecrexpr | @postdecrexpr; + +@crement_expr = @increment_expr | @decrement_expr; + +@un_arith_op_expr = @arithnegexpr + | @unaryplusexpr + | @conjugation + | @realpartexpr + | @imagpartexpr + | @crement_expr + ; + +@un_bitwise_op_expr = @complementexpr; + +@un_log_op_expr = @notexpr; + +@un_op_expr = @address_of + | @indirect + | @un_arith_op_expr + | @un_bitwise_op_expr + | @builtinaddressof + | @vec_fill + | @un_log_op_expr + | @co_await + | @co_yield + ; + +@bin_log_op_expr = @andlogicalexpr | @orlogicalexpr; + +@cmp_op_expr = @eq_op_expr | @rel_op_expr; + +@eq_op_expr = @eqexpr | @neexpr; + +@rel_op_expr = @gtexpr + | @ltexpr + | @geexpr + | @leexpr + | @spaceshipexpr + ; + +@bin_bitwise_op_expr = @lshiftexpr + | @rshiftexpr + | @andexpr + | @orexpr + | @xorexpr + ; + +@p_arith_op_expr = @paddexpr + | @psubexpr + | @pdiffexpr + ; + +@bin_arith_op_expr = @addexpr + | @subexpr + | @mulexpr + | @divexpr + | @remexpr + | @jmulexpr + | @jdivexpr + | @fjaddexpr + | @jfaddexpr + | @fjsubexpr + | @jfsubexpr + | @minexpr + | @maxexpr + | @p_arith_op_expr + ; + +@bin_op_expr = @bin_arith_op_expr + | @bin_bitwise_op_expr + | @cmp_op_expr + | @bin_log_op_expr + ; + +@op_expr = @un_op_expr + | @bin_op_expr + | @assign_expr + | @conditionalexpr + ; + +@assign_arith_expr = @assignaddexpr + | @assignsubexpr + | @assignmulexpr + | @assigndivexpr + | @assignremexpr + ; + +@assign_bitwise_expr = @assignandexpr + | @assignorexpr + | @assignxorexpr + | @assignlshiftexpr + | @assignrshiftexpr + | @assignpaddexpr + | @assignpsubexpr + ; + +@assign_op_expr = @assign_arith_expr | @assign_bitwise_expr + +@assign_expr = @assignexpr | @assign_op_expr + +/* + case @allocator.form of + 0 = plain + | 1 = alignment + ; +*/ + +/** + * The allocator function associated with a `new` or `new[]` expression. + * The `form` column specified whether the allocation call contains an alignment + * argument. + */ +expr_allocator( + unique int expr: @any_new_expr ref, + int func: @function ref, + int form: int ref +); + +/* + case @deallocator.form of + 0 = plain + | 1 = size + | 2 = alignment + | 3 = size_and_alignment + ; +*/ + +/** + * The deallocator function associated with a `delete`, `delete[]`, `new`, or + * `new[]` expression. For a `new` or `new[]` expression, the deallocator is the + * one used to free memory if the initialization throws an exception. + * The `form` column specifies whether the deallocation call contains a size + * argument, and alignment argument, or both. + */ +expr_deallocator( + unique int expr: @new_or_delete_expr ref, + int func: @function ref, + int form: int ref +); + +/** + * Holds if the `@conditionalexpr` is of the two operand form + * `guard ? : false`. + */ +expr_cond_two_operand( + unique int cond: @conditionalexpr ref +); + +/** + * The guard of `@conditionalexpr` `guard ? true : false` + */ +expr_cond_guard( + unique int cond: @conditionalexpr ref, + int guard: @expr ref +); + +/** + * The expression used when the guard of `@conditionalexpr` + * `guard ? true : false` holds. For the two operand form + * `guard ?: false` consider using `expr_cond_guard` instead. + */ +expr_cond_true( + unique int cond: @conditionalexpr ref, + int true: @expr ref +); + +/** + * The expression used when the guard of `@conditionalexpr` + * `guard ? true : false` does not hold. + */ +expr_cond_false( + unique int cond: @conditionalexpr ref, + int false: @expr ref +); + +/** A string representation of the value. */ +values( + unique int id: @value, + string str: string ref +); + +/** The actual text in the source code for the value, if any. */ +valuetext( + unique int id: @value ref, + string text: string ref +); + +valuebind( + int val: @value ref, + unique int expr: @expr ref +); + +fieldoffsets( + unique int id: @variable ref, + int byteoffset: int ref, + int bitoffset: int ref +); + +bitfield( + unique int id: @variable ref, + int bits: int ref, + int declared_bits: int ref +); + +/* TODO +memberprefix( + int member: @expr ref, + int prefix: @expr ref +); +*/ + +/* + kind(1) = mbrcallexpr + kind(2) = mbrptrcallexpr + kind(3) = mbrptrmbrcallexpr + kind(4) = ptrmbrptrmbrcallexpr + kind(5) = mbrreadexpr // x.y + kind(6) = mbrptrreadexpr // p->y + kind(7) = mbrptrmbrreadexpr // x.*pm + kind(8) = mbrptrmbrptrreadexpr // x->*pm + kind(9) = staticmbrreadexpr // static x.y + kind(10) = staticmbrptrreadexpr // static p->y +*/ +/* TODO +memberaccess( + int member: @expr ref, + int kind: int ref +); +*/ + +initialisers( + unique int init: @initialiser, + int var: @accessible ref, + unique int expr: @expr ref, + int location: @location_expr ref +); + +/** + * An ancestor for the expression, for cases in which we cannot + * otherwise find the expression's parent. + */ +expr_ancestor( + int exp: @expr ref, + int ancestor: @element ref +); + +exprs( + unique int id: @expr, + int kind: int ref, + int location: @location_expr ref +); + +/* + case @value.category of + 1 = prval + | 2 = xval + | 3 = lval + ; +*/ +expr_types( + int id: @expr ref, + int typeid: @type ref, + int value_category: int ref +); + +case @expr.kind of + 1 = @errorexpr +| 2 = @address_of // & AddressOfExpr +| 3 = @reference_to // ReferenceToExpr (implicit?) +| 4 = @indirect // * PointerDereferenceExpr +| 5 = @ref_indirect // ReferenceDereferenceExpr (implicit?) +// ... +| 8 = @array_to_pointer // (???) +| 9 = @vacuous_destructor_call // VacuousDestructorCall +// ... +| 11 = @assume // Microsoft +| 12 = @parexpr +| 13 = @arithnegexpr +| 14 = @unaryplusexpr +| 15 = @complementexpr +| 16 = @notexpr +| 17 = @conjugation // GNU ~ operator +| 18 = @realpartexpr // GNU __real +| 19 = @imagpartexpr // GNU __imag +| 20 = @postincrexpr +| 21 = @postdecrexpr +| 22 = @preincrexpr +| 23 = @predecrexpr +| 24 = @conditionalexpr +| 25 = @addexpr +| 26 = @subexpr +| 27 = @mulexpr +| 28 = @divexpr +| 29 = @remexpr +| 30 = @jmulexpr // C99 mul imaginary +| 31 = @jdivexpr // C99 div imaginary +| 32 = @fjaddexpr // C99 add real + imaginary +| 33 = @jfaddexpr // C99 add imaginary + real +| 34 = @fjsubexpr // C99 sub real - imaginary +| 35 = @jfsubexpr // C99 sub imaginary - real +| 36 = @paddexpr // pointer add (pointer + int or int + pointer) +| 37 = @psubexpr // pointer sub (pointer - integer) +| 38 = @pdiffexpr // difference between two pointers +| 39 = @lshiftexpr +| 40 = @rshiftexpr +| 41 = @andexpr +| 42 = @orexpr +| 43 = @xorexpr +| 44 = @eqexpr +| 45 = @neexpr +| 46 = @gtexpr +| 47 = @ltexpr +| 48 = @geexpr +| 49 = @leexpr +| 50 = @minexpr // GNU minimum +| 51 = @maxexpr // GNU maximum +| 52 = @assignexpr +| 53 = @assignaddexpr +| 54 = @assignsubexpr +| 55 = @assignmulexpr +| 56 = @assigndivexpr +| 57 = @assignremexpr +| 58 = @assignlshiftexpr +| 59 = @assignrshiftexpr +| 60 = @assignandexpr +| 61 = @assignorexpr +| 62 = @assignxorexpr +| 63 = @assignpaddexpr // assign pointer add +| 64 = @assignpsubexpr // assign pointer sub +| 65 = @andlogicalexpr +| 66 = @orlogicalexpr +| 67 = @commaexpr +| 68 = @subscriptexpr // access to member of an array, e.g., a[5] +// ... 69 @objc_subscriptexpr deprecated +// ... 70 @cmdaccess deprecated +// ... +| 73 = @virtfunptrexpr +| 74 = @callexpr +// ... 75 @msgexpr_normal deprecated +// ... 76 @msgexpr_super deprecated +// ... 77 @atselectorexpr deprecated +// ... 78 @atprotocolexpr deprecated +| 79 = @vastartexpr +| 80 = @vaargexpr +| 81 = @vaendexpr +| 82 = @vacopyexpr +// ... 83 @atencodeexpr deprecated +| 84 = @varaccess +| 85 = @thisaccess +// ... 86 @objc_box_expr deprecated +| 87 = @new_expr +| 88 = @delete_expr +| 89 = @throw_expr +| 90 = @condition_decl // a variable declared in a condition, e.g., if(int x = y > 2) +| 91 = @braced_init_list +| 92 = @type_id +| 93 = @runtime_sizeof +| 94 = @runtime_alignof +| 95 = @sizeof_pack +| 96 = @expr_stmt // GNU extension +| 97 = @routineexpr +| 98 = @type_operand // used to access a type in certain contexts (haven't found any examples yet....) +| 99 = @offsetofexpr // offsetof ::= type and field +| 100 = @hasassignexpr // __has_assign ::= type +| 101 = @hascopyexpr // __has_copy ::= type +| 102 = @hasnothrowassign // __has_nothrow_assign ::= type +| 103 = @hasnothrowconstr // __has_nothrow_constructor ::= type +| 104 = @hasnothrowcopy // __has_nothrow_copy ::= type +| 105 = @hastrivialassign // __has_trivial_assign ::= type +| 106 = @hastrivialconstr // __has_trivial_constructor ::= type +| 107 = @hastrivialcopy // __has_trivial_copy ::= type +| 108 = @hasuserdestr // __has_user_destructor ::= type +| 109 = @hasvirtualdestr // __has_virtual_destructor ::= type +| 110 = @isabstractexpr // __is_abstract ::= type +| 111 = @isbaseofexpr // __is_base_of ::= type type +| 112 = @isclassexpr // __is_class ::= type +| 113 = @isconvtoexpr // __is_convertible_to ::= type type +| 114 = @isemptyexpr // __is_empty ::= type +| 115 = @isenumexpr // __is_enum ::= type +| 116 = @ispodexpr // __is_pod ::= type +| 117 = @ispolyexpr // __is_polymorphic ::= type +| 118 = @isunionexpr // __is_union ::= type +| 119 = @typescompexpr // GNU __builtin_types_compatible ::= type type +| 120 = @intaddrexpr // EDG internal builtin, used to implement offsetof +// ... +| 122 = @hastrivialdestructor // __has_trivial_destructor ::= type +| 123 = @literal +| 124 = @uuidof +| 127 = @aggregateliteral +| 128 = @delete_array_expr +| 129 = @new_array_expr +// ... 130 @objc_array_literal deprecated +// ... 131 @objc_dictionary_literal deprecated +| 132 = @foldexpr +// ... +| 200 = @ctordirectinit +| 201 = @ctorvirtualinit +| 202 = @ctorfieldinit +| 203 = @ctordelegatinginit +| 204 = @dtordirectdestruct +| 205 = @dtorvirtualdestruct +| 206 = @dtorfielddestruct +// ... +| 210 = @static_cast +| 211 = @reinterpret_cast +| 212 = @const_cast +| 213 = @dynamic_cast +| 214 = @c_style_cast +| 215 = @lambdaexpr +| 216 = @param_ref +| 217 = @noopexpr +// ... +| 294 = @istriviallyconstructibleexpr +| 295 = @isdestructibleexpr +| 296 = @isnothrowdestructibleexpr +| 297 = @istriviallydestructibleexpr +| 298 = @istriviallyassignableexpr +| 299 = @isnothrowassignableexpr +| 300 = @istrivialexpr +| 301 = @isstandardlayoutexpr +| 302 = @istriviallycopyableexpr +| 303 = @isliteraltypeexpr +| 304 = @hastrivialmoveconstructorexpr +| 305 = @hastrivialmoveassignexpr +| 306 = @hasnothrowmoveassignexpr +| 307 = @isconstructibleexpr +| 308 = @isnothrowconstructibleexpr +| 309 = @hasfinalizerexpr +| 310 = @isdelegateexpr +| 311 = @isinterfaceclassexpr +| 312 = @isrefarrayexpr +| 313 = @isrefclassexpr +| 314 = @issealedexpr +| 315 = @issimplevalueclassexpr +| 316 = @isvalueclassexpr +| 317 = @isfinalexpr +| 319 = @noexceptexpr +| 320 = @builtinshufflevector +| 321 = @builtinchooseexpr +| 322 = @builtinaddressof +| 323 = @vec_fill +| 324 = @builtinconvertvector +| 325 = @builtincomplex +| 326 = @spaceshipexpr +| 327 = @co_await +| 328 = @co_yield +| 329 = @temp_init +; + +@var_args_expr = @vastartexpr + | @vaendexpr + | @vaargexpr + | @vacopyexpr + ; + +@builtin_op = @var_args_expr + | @noopexpr + | @offsetofexpr + | @intaddrexpr + | @hasassignexpr + | @hascopyexpr + | @hasnothrowassign + | @hasnothrowconstr + | @hasnothrowcopy + | @hastrivialassign + | @hastrivialconstr + | @hastrivialcopy + | @hastrivialdestructor + | @hasuserdestr + | @hasvirtualdestr + | @isabstractexpr + | @isbaseofexpr + | @isclassexpr + | @isconvtoexpr + | @isemptyexpr + | @isenumexpr + | @ispodexpr + | @ispolyexpr + | @isunionexpr + | @typescompexpr + | @builtinshufflevector + | @builtinconvertvector + | @builtinaddressof + | @istriviallyconstructibleexpr + | @isdestructibleexpr + | @isnothrowdestructibleexpr + | @istriviallydestructibleexpr + | @istriviallyassignableexpr + | @isnothrowassignableexpr + | @isstandardlayoutexpr + | @istriviallycopyableexpr + | @isliteraltypeexpr + | @hastrivialmoveconstructorexpr + | @hastrivialmoveassignexpr + | @hasnothrowmoveassignexpr + | @isconstructibleexpr + | @isnothrowconstructibleexpr + | @hasfinalizerexpr + | @isdelegateexpr + | @isinterfaceclassexpr + | @isrefarrayexpr + | @isrefclassexpr + | @issealedexpr + | @issimplevalueclassexpr + | @isvalueclassexpr + | @isfinalexpr + | @builtinchooseexpr + | @builtincomplex + ; + +new_allocated_type( + unique int expr: @new_expr ref, + int type_id: @type ref +); + +new_array_allocated_type( + unique int expr: @new_array_expr ref, + int type_id: @type ref +); + +/** + * The field being initialized by an initializer expression within an aggregate + * initializer for a class/struct/union. + */ +#keyset[aggregate, field] +aggregate_field_init( + int aggregate: @aggregateliteral ref, + int initializer: @expr ref, + int field: @membervariable ref +); + +/** + * The index of the element being initialized by an initializer expression + * within an aggregate initializer for an array. + */ +#keyset[aggregate, element_index] +aggregate_array_init( + int aggregate: @aggregateliteral ref, + int initializer: @expr ref, + int element_index: int ref +); + +@ctorinit = @ctordirectinit + | @ctorvirtualinit + | @ctorfieldinit + | @ctordelegatinginit; +@dtordestruct = @dtordirectdestruct + | @dtorvirtualdestruct + | @dtorfielddestruct; + + +condition_decl_bind( + unique int expr: @condition_decl ref, + unique int decl: @declaration ref +); + +typeid_bind( + unique int expr: @type_id ref, + int type_id: @type ref +); + +uuidof_bind( + unique int expr: @uuidof ref, + int type_id: @type ref +); + +@runtime_sizeof_or_alignof = @runtime_sizeof | @runtime_alignof; + +sizeof_bind( + unique int expr: @runtime_sizeof_or_alignof ref, + int type_id: @type ref +); + +code_block( + unique int block: @literal ref, + unique int routine: @function ref +); + +lambdas( + unique int expr: @lambdaexpr ref, + string default_capture: string ref, + boolean has_explicit_return_type: boolean ref +); + +lambda_capture( + unique int id: @lambdacapture, + int lambda: @lambdaexpr ref, + int index: int ref, + int field: @membervariable ref, + boolean captured_by_reference: boolean ref, + boolean is_implicit: boolean ref, + int location: @location_default ref +); + +@funbindexpr = @routineexpr + | @new_expr + | @delete_expr + | @delete_array_expr + | @ctordirectinit + | @ctorvirtualinit + | @ctordelegatinginit + | @dtordirectdestruct + | @dtorvirtualdestruct; + +@varbindexpr = @varaccess | @ctorfieldinit | @dtorfielddestruct; +@addressable = @function | @variable ; +@accessible = @addressable | @enumconstant ; + +@access = @varaccess | @routineexpr ; + +fold( + int expr: @foldexpr ref, + string operator: string ref, + boolean is_left_fold: boolean ref +); + +stmts( + unique int id: @stmt, + int kind: int ref, + int location: @location_stmt ref +); + +case @stmt.kind of + 1 = @stmt_expr +| 2 = @stmt_if +| 3 = @stmt_while +| 4 = @stmt_goto +| 5 = @stmt_label +| 6 = @stmt_return +| 7 = @stmt_block +| 8 = @stmt_end_test_while // do { ... } while ( ... ) +| 9 = @stmt_for +| 10 = @stmt_switch_case +| 11 = @stmt_switch +| 13 = @stmt_asm // "asm" statement or the body of an asm function +| 15 = @stmt_try_block +| 16 = @stmt_microsoft_try // Microsoft +| 17 = @stmt_decl +| 18 = @stmt_set_vla_size // C99 +| 19 = @stmt_vla_decl // C99 +| 25 = @stmt_assigned_goto // GNU +| 26 = @stmt_empty +| 27 = @stmt_continue +| 28 = @stmt_break +| 29 = @stmt_range_based_for // C++11 +// ... 30 @stmt_at_autoreleasepool_block deprecated +// ... 31 @stmt_objc_for_in deprecated +// ... 32 @stmt_at_synchronized deprecated +| 33 = @stmt_handler +// ... 34 @stmt_finally_end deprecated +| 35 = @stmt_constexpr_if +| 37 = @stmt_co_return +; + +type_vla( + int type_id: @type ref, + int decl: @stmt_vla_decl ref +); + +variable_vla( + int var: @variable ref, + int decl: @stmt_vla_decl ref +); + +if_then( + unique int if_stmt: @stmt_if ref, + int then_id: @stmt ref +); + +if_else( + unique int if_stmt: @stmt_if ref, + int else_id: @stmt ref +); + +constexpr_if_then( + unique int constexpr_if_stmt: @stmt_constexpr_if ref, + int then_id: @stmt ref +); + +constexpr_if_else( + unique int constexpr_if_stmt: @stmt_constexpr_if ref, + int else_id: @stmt ref +); + +while_body( + unique int while_stmt: @stmt_while ref, + int body_id: @stmt ref +); + +do_body( + unique int do_stmt: @stmt_end_test_while ref, + int body_id: @stmt ref +); + +#keyset[switch_stmt, index] +switch_case( + int switch_stmt: @stmt_switch ref, + int index: int ref, + int case_id: @stmt_switch_case ref +); + +switch_body( + unique int switch_stmt: @stmt_switch ref, + int body_id: @stmt ref +); + +for_initialization( + unique int for_stmt: @stmt_for ref, + int init_id: @stmt ref +); + +for_condition( + unique int for_stmt: @stmt_for ref, + int condition_id: @expr ref +); + +for_update( + unique int for_stmt: @stmt_for ref, + int update_id: @expr ref +); + +for_body( + unique int for_stmt: @stmt_for ref, + int body_id: @stmt ref +); + +@stmtparent = @stmt | @expr_stmt ; +stmtparents( + unique int id: @stmt ref, + int index: int ref, + int parent: @stmtparent ref +); + +ishandler(unique int block: @stmt_block ref); + +@cfgnode = @stmt | @expr | @function | @initialiser ; + +stmt_decl_bind( + int stmt: @stmt_decl ref, + int num: int ref, + int decl: @declaration ref +); + +stmt_decl_entry_bind( + int stmt: @stmt_decl ref, + int num: int ref, + int decl_entry: @element ref +); + +@functionorblock = @function | @stmt_block; + +blockscope( + unique int block: @stmt_block ref, + int enclosing: @functionorblock ref +); + +@jump = @stmt_goto | @stmt_break | @stmt_continue; + +@jumporlabel = @jump | @stmt_label | @literal; + +jumpinfo( + unique int id: @jumporlabel ref, + string str: string ref, + int target: @stmt ref +); + +preprocdirects( + unique int id: @preprocdirect, + int kind: int ref, + int location: @location_default ref +); +case @preprocdirect.kind of + 0 = @ppd_if +| 1 = @ppd_ifdef +| 2 = @ppd_ifndef +| 3 = @ppd_elif +| 4 = @ppd_else +| 5 = @ppd_endif +| 6 = @ppd_plain_include +| 7 = @ppd_define +| 8 = @ppd_undef +| 9 = @ppd_line +| 10 = @ppd_error +| 11 = @ppd_pragma +| 12 = @ppd_objc_import +| 13 = @ppd_include_next +| 18 = @ppd_warning +; + +@ppd_include = @ppd_plain_include | @ppd_objc_import | @ppd_include_next; + +@ppd_branch = @ppd_if | @ppd_ifdef | @ppd_ifndef | @ppd_elif; + +preprocpair( + int begin : @ppd_branch ref, + int elseelifend : @preprocdirect ref +); + +preproctrue(int branch : @ppd_branch ref); +preprocfalse(int branch : @ppd_branch ref); + +preproctext( + unique int id: @preprocdirect ref, + string head: string ref, + string body: string ref +); + +includes( + unique int id: @ppd_include ref, + int included: @file ref +); + +link_targets( + unique int id: @link_target, + int binary: @file ref +); + +link_parent( + int element : @element ref, + int link_target : @link_target ref +); + +/* XML Files */ + +xmlEncoding(unique int id: @file ref, string encoding: string ref); + +xmlDTDs( + unique int id: @xmldtd, + string root: string ref, + string publicId: string ref, + string systemId: string ref, + int fileid: @file ref +); + +xmlElements( + unique int id: @xmlelement, + string name: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int fileid: @file ref +); + +xmlAttrs( + unique int id: @xmlattribute, + int elementid: @xmlelement ref, + string name: string ref, + string value: string ref, + int idx: int ref, + int fileid: @file ref +); + +xmlNs( + int id: @xmlnamespace, + string prefixName: string ref, + string URI: string ref, + int fileid: @file ref +); + +xmlHasNs( + int elementId: @xmlnamespaceable ref, + int nsId: @xmlnamespace ref, + int fileid: @file ref +); + +xmlComments( + unique int id: @xmlcomment, + string text: string ref, + int parentid: @xmlparent ref, + int fileid: @file ref +); + +xmlChars( + unique int id: @xmlcharacters, + string text: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int isCDATA: int ref, + int fileid: @file ref +); + +@xmlparent = @file | @xmlelement; +@xmlnamespaceable = @xmlelement | @xmlattribute; + +xmllocations( + int xmlElement: @xmllocatable ref, + int location: @location_default ref +); + +@xmllocatable = @xmlcharacters + | @xmlelement + | @xmlcomment + | @xmlattribute + | @xmldtd + | @file + | @xmlnamespace; diff --git a/cpp/upgrades/c82db4c596b8979eba9a8958e24353a5756d7a02/semmlecode.cpp.dbscheme b/cpp/upgrades/c82db4c596b8979eba9a8958e24353a5756d7a02/semmlecode.cpp.dbscheme new file mode 100644 index 00000000000..ddd31fd02e5 --- /dev/null +++ b/cpp/upgrades/c82db4c596b8979eba9a8958e24353a5756d7a02/semmlecode.cpp.dbscheme @@ -0,0 +1,2145 @@ + +/** + * An invocation of the compiler. Note that more than one file may be + * compiled per invocation. For example, this command compiles three + * source files: + * + * gcc -c f1.c f2.c f3.c + * + * The `id` simply identifies the invocation, while `cwd` is the working + * directory from which the compiler was invoked. + */ +compilations( + /** + * An invocation of the compiler. Note that more than one file may + * be compiled per invocation. For example, this command compiles + * three source files: + * + * gcc -c f1.c f2.c f3.c + */ + unique int id : @compilation, + string cwd : string ref +); + +/** + * The arguments that were passed to the extractor for a compiler + * invocation. If `id` is for the compiler invocation + * + * gcc -c f1.c f2.c f3.c + * + * then typically there will be rows for + * + * num | arg + * --- | --- + * 0 | *path to extractor* + * 1 | `--mimic` + * 2 | `/usr/bin/gcc` + * 3 | `-c` + * 4 | f1.c + * 5 | f2.c + * 6 | f3.c + */ +#keyset[id, num] +compilation_args( + int id : @compilation ref, + int num : int ref, + string arg : string ref +); + +/** + * The source files that are compiled by a compiler invocation. + * If `id` is for the compiler invocation + * + * gcc -c f1.c f2.c f3.c + * + * then there will be rows for + * + * num | arg + * --- | --- + * 0 | f1.c + * 1 | f2.c + * 2 | f3.c + * + * Note that even if those files `#include` headers, those headers + * do not appear as rows. + */ +#keyset[id, num] +compilation_compiling_files( + int id : @compilation ref, + int num : int ref, + int file : @file ref +); + +/** + * The time taken by the extractor for a compiler invocation. + * + * For each file `num`, there will be rows for + * + * kind | seconds + * ---- | --- + * 1 | CPU seconds used by the extractor frontend + * 2 | Elapsed seconds during the extractor frontend + * 3 | CPU seconds used by the extractor backend + * 4 | Elapsed seconds during the extractor backend + */ +#keyset[id, num, kind] +compilation_time( + int id : @compilation ref, + int num : int ref, + /* kind: + 1 = frontend_cpu_seconds + 2 = frontend_elapsed_seconds + 3 = extractor_cpu_seconds + 4 = extractor_elapsed_seconds + */ + int kind : int ref, + float seconds : float ref +); + +/** + * An error or warning generated by the extractor. + * The diagnostic message `diagnostic` was generated during compiler + * invocation `compilation`, and is the `file_number_diagnostic_number`th + * message generated while extracting the `file_number`th file of that + * invocation. + */ +#keyset[compilation, file_number, file_number_diagnostic_number] +diagnostic_for( + int diagnostic : @diagnostic ref, + int compilation : @compilation ref, + int file_number : int ref, + int file_number_diagnostic_number : int ref +); + +/** + * If extraction was successful, then `cpu_seconds` and + * `elapsed_seconds` are the CPU time and elapsed time (respectively) + * that extraction took for compiler invocation `id`. + */ +compilation_finished( + unique int id : @compilation ref, + float cpu_seconds : float ref, + float elapsed_seconds : float ref +); + + +/** + * External data, loaded from CSV files during snapshot creation. See + * [Tutorial: Incorporating external data](https://help.semmle.com/wiki/display/SD/Tutorial%3A+Incorporating+external+data) + * for more information. + */ +externalData( + int id : @externalDataElement, + string path : string ref, + int column: int ref, + string value : string ref +); + +/** + * The date of the snapshot. + */ +snapshotDate(unique date snapshotDate : date ref); + +/** + * The source location of the snapshot. + */ +sourceLocationPrefix(string prefix : string ref); + +/** + * Data used by the 'duplicate code' detection. + */ +duplicateCode( + unique int id : @duplication, + string relativePath : string ref, + int equivClass : int ref +); + +/** + * Data used by the 'similar code' detection. + */ +similarCode( + unique int id : @similarity, + string relativePath : string ref, + int equivClass : int ref +); + +/** + * Data used by the 'duplicate code' and 'similar code' detection. + */ +@duplication_or_similarity = @duplication | @similarity + +/** + * Data used by the 'duplicate code' and 'similar code' detection. + */ +#keyset[id, offset] +tokens( + int id : @duplication_or_similarity ref, + int offset : int ref, + int beginLine : int ref, + int beginColumn : int ref, + int endLine : int ref, + int endColumn : int ref +); + +/** + * Information about packages that provide code used during compilation. + * The `id` is just a unique identifier. + * The `namespace` is typically the name of the package manager that + * provided the package (e.g. "dpkg" or "yum"). + * The `package_name` is the name of the package, and `version` is its + * version (as a string). + */ +external_packages( + unique int id: @external_package, + string namespace : string ref, + string package_name : string ref, + string version : string ref +); + +/** + * Holds if File `fileid` was provided by package `package`. + */ +header_to_external_package( + int fileid : @file ref, + int package : @external_package ref +); + +/* + * Version history + */ + +svnentries( + unique int id : @svnentry, + string revision : string ref, + string author : string ref, + date revisionDate : date ref, + int changeSize : int ref +) + +svnaffectedfiles( + int id : @svnentry ref, + int file : @file ref, + string action : string ref +) + +svnentrymsg( + unique int id : @svnentry ref, + string message : string ref +) + +svnchurn( + int commit : @svnentry ref, + int file : @file ref, + int addedLines : int ref, + int deletedLines : int ref +) + +/* + * C++ dbscheme + */ + +@location = @location_stmt | @location_expr | @location_default ; + +/** + * The location of an element that is not an expression or a statement. + * The location spans column `startcolumn` of line `startline` to + * column `endcolumn` of line `endline` in file `file`. + * For more information, see + * [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html). + */ +locations_default( + /** The location of an element that is not an expression or a statement. */ + unique int id: @location_default, + int container: @container ref, + int startLine: int ref, + int startColumn: int ref, + int endLine: int ref, + int endColumn: int ref +); + +/** + * The location of a statement. + * The location spans column `startcolumn` of line `startline` to + * column `endcolumn` of line `endline` in file `file`. + * For more information, see + * [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html). + */ +locations_stmt( + /** The location of a statement. */ + unique int id: @location_stmt, + int container: @container ref, + int startLine: int ref, + int startColumn: int ref, + int endLine: int ref, + int endColumn: int ref +); + +/** + * The location of an expression. + * The location spans column `startcolumn` of line `startline` to + * column `endcolumn` of line `endline` in file `file`. + * For more information, see + * [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html). + */ +locations_expr( + /** The location of an expression. */ + unique int id: @location_expr, + int container: @container ref, + int startLine: int ref, + int startColumn: int ref, + int endLine: int ref, + int endColumn: int ref +); + +/** An element for which line-count information is available. */ +@sourceline = @file | @function | @variable | @enumconstant | @xmllocatable; + +numlines( + int element_id: @sourceline ref, + int num_lines: int ref, + int num_code: int ref, + int num_comment: int ref +); + +diagnostics( + unique int id: @diagnostic, + int severity: int ref, + string error_tag: string ref, + string error_message: string ref, + string full_error_message: string ref, + int location: @location_default ref +); + +/* + fromSource(0) = unknown, + fromSource(1) = from source, + fromSource(2) = from library +*/ +files( + unique int id: @file, + string name: string ref, + string simple: string ref, + string ext: string ref, + int fromSource: int ref +); + +folders( + unique int id: @folder, + string name: string ref, + string simple: string ref +); + +@container = @folder | @file + +containerparent( + int parent: @container ref, + unique int child: @container ref +); + +fileannotations( + int id: @file ref, + int kind: int ref, + string name: string ref, + string value: string ref +); + +inmacroexpansion( + int id: @element ref, + int inv: @macroinvocation ref +); + +affectedbymacroexpansion( + int id: @element ref, + int inv: @macroinvocation ref +); + +/* + case @macroinvocations.kind of + 1 = macro expansion + | 2 = other macro reference + ; +*/ +macroinvocations( + unique int id: @macroinvocation, + int macro_id: @ppd_define ref, + int location: @location_default ref, + int kind: int ref +); + +macroparent( + unique int id: @macroinvocation ref, + int parent_id: @macroinvocation ref +); + +// a macroinvocation may be part of another location +// the way to find a constant expression that uses a macro +// is thus to find a constant expression that has a location +// to which a macro invocation is bound +macrolocationbind( + int id: @macroinvocation ref, + int location: @location ref +); + +#keyset[invocation, argument_index] +macro_argument_unexpanded( + int invocation: @macroinvocation ref, + int argument_index: int ref, + string text: string ref +); + +#keyset[invocation, argument_index] +macro_argument_expanded( + int invocation: @macroinvocation ref, + int argument_index: int ref, + string text: string ref +); + +/* + case @function.kind of + 1 = normal + | 2 = constructor + | 3 = destructor + | 4 = conversion + | 5 = operator + | 6 = builtin // GCC built-in functions, e.g. __builtin___memcpy_chk + ; +*/ +functions( + unique int id: @function, + string name: string ref, + int kind: int ref +); + +function_entry_point(int id: @function ref, unique int entry_point: @stmt ref); + +function_return_type(int id: @function ref, int return_type: @type ref); + +/** If `function` is a coroutine, then this gives the + std::experimental::resumable_traits instance associated with it, + and the variables representing the `handle` and `promise` for it. */ +coroutine( + unique int function: @function ref, + int traits: @type ref, + int handle: @variable ref, + int promise: @variable ref +); + +/** The `new` function used for allocating the coroutine state, if any. */ +coroutine_new( + unique int function: @function ref, + int new: @function ref +); + +/** The `delete` function used for deallocating the coroutine state, if any. */ +coroutine_delete( + unique int function: @function ref, + int delete: @function ref +); + +purefunctions(unique int id: @function ref); + +function_deleted(unique int id: @function ref); + +function_defaulted(unique int id: @function ref); + +member_function_this_type(unique int id: @function ref, int this_type: @type ref); + +#keyset[id, type_id] +fun_decls( + int id: @fun_decl, + int function: @function ref, + int type_id: @type ref, + string name: string ref, + int location: @location_default ref +); +fun_def(unique int id: @fun_decl ref); +fun_specialized(unique int id: @fun_decl ref); +fun_implicit(unique int id: @fun_decl ref); +fun_decl_specifiers( + int id: @fun_decl ref, + string name: string ref +) +#keyset[fun_decl, index] +fun_decl_throws( + int fun_decl: @fun_decl ref, + int index: int ref, + int type_id: @type ref +); +/* an empty throw specification is different from none */ +fun_decl_empty_throws(unique int fun_decl: @fun_decl ref); +fun_decl_noexcept( + int fun_decl: @fun_decl ref, + int constant: @expr ref +); +fun_decl_empty_noexcept(int fun_decl: @fun_decl ref); +fun_decl_typedef_type( + unique int fun_decl: @fun_decl ref, + int typedeftype_id: @usertype ref +); + +param_decl_bind( + unique int id: @var_decl ref, + int index: int ref, + int fun_decl: @fun_decl ref +); + +#keyset[id, type_id] +var_decls( + int id: @var_decl, + int variable: @variable ref, + int type_id: @type ref, + string name: string ref, + int location: @location_default ref +); +var_def(unique int id: @var_decl ref); +var_decl_specifiers( + int id: @var_decl ref, + string name: string ref +) + +type_decls( + unique int id: @type_decl, + int type_id: @type ref, + int location: @location_default ref +); +type_def(unique int id: @type_decl ref); +type_decl_top( + unique int type_decl: @type_decl ref +); + +namespace_decls( + unique int id: @namespace_decl, + int namespace_id: @namespace ref, + int location: @location_default ref, + int bodylocation: @location_default ref +); + +usings( + unique int id: @using, + int element_id: @element ref, + int location: @location_default ref +); + +/** The element which contains the `using` declaration. */ +using_container( + int parent: @element ref, + int child: @using ref +); + +static_asserts( + unique int id: @static_assert, + int condition : @expr ref, + string message : string ref, + int location: @location_default ref, + int enclosing : @element ref +); + +// each function has an ordered list of parameters +#keyset[id, type_id] +#keyset[function, index, type_id] +params( + int id: @parameter, + int function: @functionorblock ref, + int index: int ref, + int type_id: @type ref +); + +overrides(int new: @function ref, int old: @function ref); + +#keyset[id, type_id] +membervariables( + int id: @membervariable, + int type_id: @type ref, + string name: string ref +); + +#keyset[id, type_id] +globalvariables( + int id: @globalvariable, + int type_id: @type ref, + string name: string ref +); + +#keyset[id, type_id] +localvariables( + int id: @localvariable, + int type_id: @type ref, + string name: string ref +); + +autoderivation( + unique int var: @variable ref, + int derivation_type: @type ref +); + +enumconstants( + unique int id: @enumconstant, + int parent: @usertype ref, + int index: int ref, + int type_id: @type ref, + string name: string ref, + int location: @location_default ref +); + +@variable = @localscopevariable | @globalvariable | @membervariable; + +@localscopevariable = @localvariable | @parameter; + +/* + Built-in types are the fundamental types, e.g., integral, floating, and void. + + case @builtintype.kind of + 1 = error + | 2 = unknown + | 3 = void + | 4 = boolean + | 5 = char + | 6 = unsigned_char + | 7 = signed_char + | 8 = short + | 9 = unsigned_short + | 10 = signed_short + | 11 = int + | 12 = unsigned_int + | 13 = signed_int + | 14 = long + | 15 = unsigned_long + | 16 = signed_long + | 17 = long_long + | 18 = unsigned_long_long + | 19 = signed_long_long + | 20 = __int8 // Microsoft-specific + | 21 = __int16 // Microsoft-specific + | 22 = __int32 // Microsoft-specific + | 23 = __int64 // Microsoft-specific + | 24 = float + | 25 = double + | 26 = long_double + | 27 = _Complex_float // C99-specific + | 28 = _Complex_double // C99-specific + | 29 = _Complex_long double // C99-specific + | 30 = _Imaginary_float // C99-specific + | 31 = _Imaginary_double // C99-specific + | 32 = _Imaginary_long_double // C99-specific + | 33 = wchar_t // Microsoft-specific + | 34 = decltype_nullptr // C++11 + | 35 = __int128 + | 36 = unsigned___int128 + | 37 = signed___int128 + | 38 = __float128 + | 39 = _Complex___float128 + | 40 = _Decimal32 + | 41 = _Decimal64 + | 42 = _Decimal128 + | 43 = char16_t + | 44 = char32_t + | 45 = _Float32 + | 46 = _Float32x + | 47 = _Float64 + | 48 = _Float64x + | 49 = _Float128 + | 50 = _Float128x + | 51 = char8_t + ; +*/ +builtintypes( + unique int id: @builtintype, + string name: string ref, + int kind: int ref, + int size: int ref, + int sign: int ref, + int alignment: int ref +); + +/* + Derived types are types that are directly derived from existing types and + point to, refer to, transform type data to return a new type. + + case @derivedtype.kind of + 1 = pointer + | 2 = reference + | 3 = type_with_specifiers + | 4 = array + | 5 = gnu_vector + | 6 = routineptr + | 7 = routinereference + | 8 = rvalue_reference // C++11 +// ... 9 type_conforming_to_protocols deprecated + | 10 = block + ; +*/ +derivedtypes( + unique int id: @derivedtype, + string name: string ref, + int kind: int ref, + int type_id: @type ref +); + +pointerishsize(unique int id: @derivedtype ref, + int size: int ref, + int alignment: int ref); + +arraysizes( + unique int id: @derivedtype ref, + int num_elements: int ref, + int bytesize: int ref, + int alignment: int ref +); + +typedefbase( + unique int id: @usertype ref, + int type_id: @type ref +); + +/** + * An instance of the C++11 `decltype` operator. For example: + * ``` + * int a; + * decltype(1+a) b; + * ``` + * Here `expr` is `1+a`. + * + * Sometimes an additional pair of parentheses around the expression + * would change the semantics of this decltype, e.g. + * ``` + * struct A { double x; }; + * const A* a = new A(); + * decltype( a->x ); // type is double + * decltype((a->x)); // type is const double& + * ``` + * (Please consult the C++11 standard for more details). + * `parentheses_would_change_meaning` is `true` iff that is the case. + */ +#keyset[id, expr] +decltypes( + int id: @decltype, + int expr: @expr ref, + int base_type: @type ref, + boolean parentheses_would_change_meaning: boolean ref +); + +/* + case @usertype.kind of + 1 = struct + | 2 = class + | 3 = union + | 4 = enum + | 5 = typedef // classic C: typedef typedef type name + | 6 = template + | 7 = template_parameter + | 8 = template_template_parameter + | 9 = proxy_class // a proxy class associated with a template parameter +// ... 10 objc_class deprecated +// ... 11 objc_protocol deprecated +// ... 12 objc_category deprecated + | 13 = scoped_enum + | 14 = using_alias // a using name = type style typedef + ; +*/ +usertypes( + unique int id: @usertype, + string name: string ref, + int kind: int ref +); + +usertypesize( + unique int id: @usertype ref, + int size: int ref, + int alignment: int ref +); + +usertype_final(unique int id: @usertype ref); + +usertype_uuid( + unique int id: @usertype ref, + unique string uuid: string ref +); + +mangled_name( + unique int id: @declaration ref, + int mangled_name : @mangledname +); + +is_pod_class(unique int id: @usertype ref); +is_standard_layout_class(unique int id: @usertype ref); + +is_complete(unique int id: @usertype ref); + +is_class_template(unique int id: @usertype ref); +class_instantiation( + int to: @usertype ref, + int from: @usertype ref +); +class_template_argument( + int type_id: @usertype ref, + int index: int ref, + int arg_type: @type ref +); +class_template_argument_value( + int type_id: @usertype ref, + int index: int ref, + int arg_value: @expr ref +); + +is_proxy_class_for( + unique int id: @usertype ref, + unique int templ_param_id: @usertype ref +); + +type_mentions( + unique int id: @type_mention, + int type_id: @type ref, + int location: @location ref, + // a_symbol_reference_kind from the EDG frontend. See symbol_ref.h there. + int kind: int ref +); + +is_function_template(unique int id: @function ref); +function_instantiation( + unique int to: @function ref, + int from: @function ref +); +function_template_argument( + int function_id: @function ref, + int index: int ref, + int arg_type: @type ref +); +function_template_argument_value( + int function_id: @function ref, + int index: int ref, + int arg_value: @expr ref +); + +is_variable_template(unique int id: @variable ref); +variable_instantiation( + unique int to: @variable ref, + int from: @variable ref +); +variable_template_argument( + int variable_id: @variable ref, + int index: int ref, + int arg_type: @type ref +); +variable_template_argument_value( + int variable_id: @variable ref, + int index: int ref, + int arg_value: @expr ref +); + +/* + Fixed point types + precision(1) = short, precision(2) = default, precision(3) = long + is_unsigned(1) = unsigned is_unsigned(2) = signed + is_fract_type(1) = declared with _Fract + saturating(1) = declared with _Sat +*/ +/* TODO +fixedpointtypes( + unique int id: @fixedpointtype, + int precision: int ref, + int is_unsigned: int ref, + int is_fract_type: int ref, + int saturating: int ref); +*/ + +routinetypes( + unique int id: @routinetype, + int return_type: @type ref +); + +routinetypeargs( + int routine: @routinetype ref, + int index: int ref, + int type_id: @type ref +); + +ptrtomembers( + unique int id: @ptrtomember, + int type_id: @type ref, + int class_id: @type ref +); + +/* + specifiers for types, functions, and variables + + "public", + "protected", + "private", + + "const", + "volatile", + "static", + + "pure", + "virtual", + "sealed", // Microsoft + "__interface", // Microsoft + "inline", + "explicit", + + "near", // near far extension + "far", // near far extension + "__ptr32", // Microsoft + "__ptr64", // Microsoft + "__sptr", // Microsoft + "__uptr", // Microsoft + "dllimport", // Microsoft + "dllexport", // Microsoft + "thread", // Microsoft + "naked", // Microsoft + "microsoft_inline", // Microsoft + "forceinline", // Microsoft + "selectany", // Microsoft + "nothrow", // Microsoft + "novtable", // Microsoft + "noreturn", // Microsoft + "noinline", // Microsoft + "noalias", // Microsoft + "restrict", // Microsoft +*/ + +specifiers( + unique int id: @specifier, + unique string str: string ref +); + +typespecifiers( + int type_id: @type ref, + int spec_id: @specifier ref +); + +funspecifiers( + int func_id: @function ref, + int spec_id: @specifier ref +); + +varspecifiers( + int var_id: @accessible ref, + int spec_id: @specifier ref +); + +attributes( + unique int id: @attribute, + int kind: int ref, + string name: string ref, + string name_space: string ref, + int location: @location_default ref +); + +case @attribute.kind of + 0 = @gnuattribute +| 1 = @stdattribute +| 2 = @declspec +| 3 = @msattribute +| 4 = @alignas +// ... 5 @objc_propertyattribute deprecated +; + +attribute_args( + unique int id: @attribute_arg, + int kind: int ref, + int attribute: @attribute ref, + int index: int ref, + int location: @location_default ref +); + +case @attribute_arg.kind of + 0 = @attribute_arg_empty +| 1 = @attribute_arg_token +| 2 = @attribute_arg_constant +| 3 = @attribute_arg_type +; + +attribute_arg_value( + unique int arg: @attribute_arg ref, + string value: string ref +); +attribute_arg_type( + unique int arg: @attribute_arg ref, + int type_id: @type ref +); +attribute_arg_name( + unique int arg: @attribute_arg ref, + string name: string ref +); + +typeattributes( + int type_id: @type ref, + int spec_id: @attribute ref +); + +funcattributes( + int func_id: @function ref, + int spec_id: @attribute ref +); + +varattributes( + int var_id: @accessible ref, + int spec_id: @attribute ref +); + +stmtattributes( + int stmt_id: @stmt ref, + int spec_id: @attribute ref +); + +@type = @builtintype + | @derivedtype + | @usertype + /* TODO | @fixedpointtype */ + | @routinetype + | @ptrtomember + | @decltype; + +unspecifiedtype( + unique int type_id: @type ref, + int unspecified_type_id: @type ref +); + +member( + int parent: @type ref, + int index: int ref, + int child: @member ref +); + +@enclosingfunction_child = @usertype | @variable | @namespace + +enclosingfunction( + unique int child: @enclosingfunction_child ref, + int parent: @function ref +); + +derivations( + unique int derivation: @derivation, + int sub: @type ref, + int index: int ref, + int super: @type ref, + int location: @location_default ref +); + +derspecifiers( + int der_id: @derivation ref, + int spec_id: @specifier ref +); + +/** + * Contains the byte offset of the base class subobject within the derived + * class. Only holds for non-virtual base classes, but see table + * `virtual_base_offsets` for offsets of virtual base class subobjects. + */ +direct_base_offsets( + unique int der_id: @derivation ref, + int offset: int ref +); + +/** + * Contains the byte offset of the virtual base class subobject for class + * `super` within a most-derived object of class `sub`. `super` can be either a + * direct or indirect base class. + */ +#keyset[sub, super] +virtual_base_offsets( + int sub: @usertype ref, + int super: @usertype ref, + int offset: int ref +); + +frienddecls( + unique int id: @frienddecl, + int type_id: @type ref, + int decl_id: @declaration ref, + int location: @location_default ref +); + +@declaredtype = @usertype ; + +@declaration = @function + | @declaredtype + | @variable + | @enumconstant + | @frienddecl; + +@member = @membervariable + | @function + | @declaredtype + | @enumconstant; + +@locatable = @diagnostic + | @declaration + | @ppd_include + | @ppd_define + | @macroinvocation + /*| @funcall*/ + | @xmllocatable + | @attribute + | @attribute_arg; + +@namedscope = @namespace | @usertype; + +@element = @locatable + | @file + | @folder + | @specifier + | @type + | @expr + | @namespace + | @initialiser + | @stmt + | @derivation + | @comment + | @preprocdirect + | @fun_decl + | @var_decl + | @type_decl + | @namespace_decl + | @using + | @namequalifier + | @specialnamequalifyingelement + | @static_assert + | @type_mention + | @lambdacapture; + +@exprparent = @element; + +comments( + unique int id: @comment, + string contents: string ref, + int location: @location_default ref +); + +commentbinding( + int id: @comment ref, + int element: @element ref +); + +exprconv( + int converted: @expr ref, + unique int conversion: @expr ref +); + +compgenerated(unique int id: @element ref); + +/** + * `destructor_call` destructs the `i`'th entity that should be + * destructed following `element`. Note that entities should be + * destructed in reverse construction order, so for a given `element` + * these should be called from highest to lowest `i`. + */ +#keyset[element, destructor_call] +#keyset[element, i] +synthetic_destructor_call( + int element: @element ref, + int i: int ref, + int destructor_call: @routineexpr ref +); + +namespaces( + unique int id: @namespace, + string name: string ref +); + +namespace_inline( + unique int id: @namespace ref +); + +namespacembrs( + int parentid: @namespace ref, + unique int memberid: @namespacembr ref +); + +@namespacembr = @declaration | @namespace; + +exprparents( + int expr_id: @expr ref, + int child_index: int ref, + int parent_id: @exprparent ref +); + +expr_isload(unique int expr_id: @expr ref); + +@cast = @c_style_cast + | @const_cast + | @dynamic_cast + | @reinterpret_cast + | @static_cast + ; + +/* +case @conversion.kind of + 0 = @simple_conversion // a numeric conversion, qualification conversion, or a reinterpret_cast +| 1 = @bool_conversion // conversion to 'bool' +| 2 = @base_class_conversion // a derived-to-base conversion +| 3 = @derived_class_conversion // a base-to-derived conversion +| 4 = @pm_base_class_conversion // a derived-to-base conversion of a pointer to member +| 5 = @pm_derived_class_conversion // a base-to-derived conversion of a pointer to member +| 6 = @glvalue_adjust // an adjustment of the type of a glvalue +| 7 = @prvalue_adjust // an adjustment of the type of a prvalue +; +*/ +/** + * Describes the semantics represented by a cast expression. This is largely + * independent of the source syntax of the cast, so it is separate from the + * regular expression kind. + */ +conversionkinds( + unique int expr_id: @cast ref, + int kind: int ref +); + +@conversion = @cast + | @array_to_pointer + | @parexpr + | @reference_to + | @ref_indirect + | @temp_init + ; + +/* +case @funbindexpr.kind of + 0 = @normal_call // a normal call +| 1 = @virtual_call // a virtual call +| 2 = @adl_call // a call whose target is only found by ADL +; +*/ +iscall(unique int caller: @funbindexpr ref, int kind: int ref); + +numtemplatearguments( + unique int expr_id: @expr ref, + int num: int ref +); + +specialnamequalifyingelements( + unique int id: @specialnamequalifyingelement, + unique string name: string ref +); + +@namequalifiableelement = @expr | @namequalifier; +@namequalifyingelement = @namespace + | @specialnamequalifyingelement + | @usertype; + +namequalifiers( + unique int id: @namequalifier, + unique int qualifiableelement: @namequalifiableelement ref, + int qualifyingelement: @namequalifyingelement ref, + int location: @location_default ref +); + +varbind( + int expr: @varbindexpr ref, + int var: @accessible ref +); + +funbind( + int expr: @funbindexpr ref, + int fun: @function ref +); + +@any_new_expr = @new_expr + | @new_array_expr; + +@new_or_delete_expr = @any_new_expr + | @delete_expr + | @delete_array_expr; + +@prefix_crement_expr = @preincrexpr | @predecrexpr; + +@postfix_crement_expr = @postincrexpr | @postdecrexpr; + +@increment_expr = @preincrexpr | @postincrexpr; + +@decrement_expr = @predecrexpr | @postdecrexpr; + +@crement_expr = @increment_expr | @decrement_expr; + +@un_arith_op_expr = @arithnegexpr + | @unaryplusexpr + | @conjugation + | @realpartexpr + | @imagpartexpr + | @crement_expr + ; + +@un_bitwise_op_expr = @complementexpr; + +@un_log_op_expr = @notexpr; + +@un_op_expr = @address_of + | @indirect + | @un_arith_op_expr + | @un_bitwise_op_expr + | @builtinaddressof + | @vec_fill + | @un_log_op_expr + | @co_await + | @co_yield + ; + +@bin_log_op_expr = @andlogicalexpr | @orlogicalexpr; + +@cmp_op_expr = @eq_op_expr | @rel_op_expr; + +@eq_op_expr = @eqexpr | @neexpr; + +@rel_op_expr = @gtexpr + | @ltexpr + | @geexpr + | @leexpr + | @spaceshipexpr + ; + +@bin_bitwise_op_expr = @lshiftexpr + | @rshiftexpr + | @andexpr + | @orexpr + | @xorexpr + ; + +@p_arith_op_expr = @paddexpr + | @psubexpr + | @pdiffexpr + ; + +@bin_arith_op_expr = @addexpr + | @subexpr + | @mulexpr + | @divexpr + | @remexpr + | @jmulexpr + | @jdivexpr + | @fjaddexpr + | @jfaddexpr + | @fjsubexpr + | @jfsubexpr + | @minexpr + | @maxexpr + | @p_arith_op_expr + ; + +@bin_op_expr = @bin_arith_op_expr + | @bin_bitwise_op_expr + | @cmp_op_expr + | @bin_log_op_expr + ; + +@op_expr = @un_op_expr + | @bin_op_expr + | @assign_expr + | @conditionalexpr + ; + +@assign_arith_expr = @assignaddexpr + | @assignsubexpr + | @assignmulexpr + | @assigndivexpr + | @assignremexpr + ; + +@assign_bitwise_expr = @assignandexpr + | @assignorexpr + | @assignxorexpr + | @assignlshiftexpr + | @assignrshiftexpr + | @assignpaddexpr + | @assignpsubexpr + ; + +@assign_op_expr = @assign_arith_expr | @assign_bitwise_expr + +@assign_expr = @assignexpr | @assign_op_expr + +/* + case @allocator.form of + 0 = plain + | 1 = alignment + ; +*/ + +/** + * The allocator function associated with a `new` or `new[]` expression. + * The `form` column specified whether the allocation call contains an alignment + * argument. + */ +expr_allocator( + unique int expr: @any_new_expr ref, + int func: @function ref, + int form: int ref +); + +/* + case @deallocator.form of + 0 = plain + | 1 = size + | 2 = alignment + | 3 = size_and_alignment + ; +*/ + +/** + * The deallocator function associated with a `delete`, `delete[]`, `new`, or + * `new[]` expression. For a `new` or `new[]` expression, the deallocator is the + * one used to free memory if the initialization throws an exception. + * The `form` column specifies whether the deallocation call contains a size + * argument, and alignment argument, or both. + */ +expr_deallocator( + unique int expr: @new_or_delete_expr ref, + int func: @function ref, + int form: int ref +); + +/** + * Holds if the `@conditionalexpr` is of the two operand form + * `guard ? : false`. + */ +expr_cond_two_operand( + unique int cond: @conditionalexpr ref +); + +/** + * The guard of `@conditionalexpr` `guard ? true : false` + */ +expr_cond_guard( + unique int cond: @conditionalexpr ref, + int guard: @expr ref +); + +/** + * The expression used when the guard of `@conditionalexpr` + * `guard ? true : false` holds. For the two operand form + * `guard ?: false` consider using `expr_cond_guard` instead. + */ +expr_cond_true( + unique int cond: @conditionalexpr ref, + int true: @expr ref +); + +/** + * The expression used when the guard of `@conditionalexpr` + * `guard ? true : false` does not hold. + */ +expr_cond_false( + unique int cond: @conditionalexpr ref, + int false: @expr ref +); + +/** A string representation of the value. */ +values( + unique int id: @value, + string str: string ref +); + +/** The actual text in the source code for the value, if any. */ +valuetext( + unique int id: @value ref, + string text: string ref +); + +valuebind( + int val: @value ref, + unique int expr: @expr ref +); + +fieldoffsets( + unique int id: @variable ref, + int byteoffset: int ref, + int bitoffset: int ref +); + +bitfield( + unique int id: @variable ref, + int bits: int ref, + int declared_bits: int ref +); + +/* TODO +memberprefix( + int member: @expr ref, + int prefix: @expr ref +); +*/ + +/* + kind(1) = mbrcallexpr + kind(2) = mbrptrcallexpr + kind(3) = mbrptrmbrcallexpr + kind(4) = ptrmbrptrmbrcallexpr + kind(5) = mbrreadexpr // x.y + kind(6) = mbrptrreadexpr // p->y + kind(7) = mbrptrmbrreadexpr // x.*pm + kind(8) = mbrptrmbrptrreadexpr // x->*pm + kind(9) = staticmbrreadexpr // static x.y + kind(10) = staticmbrptrreadexpr // static p->y +*/ +/* TODO +memberaccess( + int member: @expr ref, + int kind: int ref +); +*/ + +initialisers( + unique int init: @initialiser, + int var: @accessible ref, + unique int expr: @expr ref, + int location: @location_expr ref +); + +/** + * An ancestor for the expression, for cases in which we cannot + * otherwise find the expression's parent. + */ +expr_ancestor( + int exp: @expr ref, + int ancestor: @element ref +); + +exprs( + unique int id: @expr, + int kind: int ref, + int location: @location_expr ref +); + +/* + case @value.category of + 1 = prval + | 2 = xval + | 3 = lval + ; +*/ +expr_types( + int id: @expr ref, + int typeid: @type ref, + int value_category: int ref +); + +case @expr.kind of + 1 = @errorexpr +| 2 = @address_of // & AddressOfExpr +| 3 = @reference_to // ReferenceToExpr (implicit?) +| 4 = @indirect // * PointerDereferenceExpr +| 5 = @ref_indirect // ReferenceDereferenceExpr (implicit?) +// ... +| 8 = @array_to_pointer // (???) +| 9 = @vacuous_destructor_call // VacuousDestructorCall +// ... +| 11 = @assume // Microsoft +| 12 = @parexpr +| 13 = @arithnegexpr +| 14 = @unaryplusexpr +| 15 = @complementexpr +| 16 = @notexpr +| 17 = @conjugation // GNU ~ operator +| 18 = @realpartexpr // GNU __real +| 19 = @imagpartexpr // GNU __imag +| 20 = @postincrexpr +| 21 = @postdecrexpr +| 22 = @preincrexpr +| 23 = @predecrexpr +| 24 = @conditionalexpr +| 25 = @addexpr +| 26 = @subexpr +| 27 = @mulexpr +| 28 = @divexpr +| 29 = @remexpr +| 30 = @jmulexpr // C99 mul imaginary +| 31 = @jdivexpr // C99 div imaginary +| 32 = @fjaddexpr // C99 add real + imaginary +| 33 = @jfaddexpr // C99 add imaginary + real +| 34 = @fjsubexpr // C99 sub real - imaginary +| 35 = @jfsubexpr // C99 sub imaginary - real +| 36 = @paddexpr // pointer add (pointer + int or int + pointer) +| 37 = @psubexpr // pointer sub (pointer - integer) +| 38 = @pdiffexpr // difference between two pointers +| 39 = @lshiftexpr +| 40 = @rshiftexpr +| 41 = @andexpr +| 42 = @orexpr +| 43 = @xorexpr +| 44 = @eqexpr +| 45 = @neexpr +| 46 = @gtexpr +| 47 = @ltexpr +| 48 = @geexpr +| 49 = @leexpr +| 50 = @minexpr // GNU minimum +| 51 = @maxexpr // GNU maximum +| 52 = @assignexpr +| 53 = @assignaddexpr +| 54 = @assignsubexpr +| 55 = @assignmulexpr +| 56 = @assigndivexpr +| 57 = @assignremexpr +| 58 = @assignlshiftexpr +| 59 = @assignrshiftexpr +| 60 = @assignandexpr +| 61 = @assignorexpr +| 62 = @assignxorexpr +| 63 = @assignpaddexpr // assign pointer add +| 64 = @assignpsubexpr // assign pointer sub +| 65 = @andlogicalexpr +| 66 = @orlogicalexpr +| 67 = @commaexpr +| 68 = @subscriptexpr // access to member of an array, e.g., a[5] +// ... 69 @objc_subscriptexpr deprecated +// ... 70 @cmdaccess deprecated +// ... +| 73 = @virtfunptrexpr +| 74 = @callexpr +// ... 75 @msgexpr_normal deprecated +// ... 76 @msgexpr_super deprecated +// ... 77 @atselectorexpr deprecated +// ... 78 @atprotocolexpr deprecated +| 79 = @vastartexpr +| 80 = @vaargexpr +| 81 = @vaendexpr +| 82 = @vacopyexpr +// ... 83 @atencodeexpr deprecated +| 84 = @varaccess +| 85 = @thisaccess +// ... 86 @objc_box_expr deprecated +| 87 = @new_expr +| 88 = @delete_expr +| 89 = @throw_expr +| 90 = @condition_decl // a variable declared in a condition, e.g., if(int x = y > 2) +| 91 = @braced_init_list +| 92 = @type_id +| 93 = @runtime_sizeof +| 94 = @runtime_alignof +| 95 = @sizeof_pack +| 96 = @expr_stmt // GNU extension +| 97 = @routineexpr +| 98 = @type_operand // used to access a type in certain contexts (haven't found any examples yet....) +| 99 = @offsetofexpr // offsetof ::= type and field +| 100 = @hasassignexpr // __has_assign ::= type +| 101 = @hascopyexpr // __has_copy ::= type +| 102 = @hasnothrowassign // __has_nothrow_assign ::= type +| 103 = @hasnothrowconstr // __has_nothrow_constructor ::= type +| 104 = @hasnothrowcopy // __has_nothrow_copy ::= type +| 105 = @hastrivialassign // __has_trivial_assign ::= type +| 106 = @hastrivialconstr // __has_trivial_constructor ::= type +| 107 = @hastrivialcopy // __has_trivial_copy ::= type +| 108 = @hasuserdestr // __has_user_destructor ::= type +| 109 = @hasvirtualdestr // __has_virtual_destructor ::= type +| 110 = @isabstractexpr // __is_abstract ::= type +| 111 = @isbaseofexpr // __is_base_of ::= type type +| 112 = @isclassexpr // __is_class ::= type +| 113 = @isconvtoexpr // __is_convertible_to ::= type type +| 114 = @isemptyexpr // __is_empty ::= type +| 115 = @isenumexpr // __is_enum ::= type +| 116 = @ispodexpr // __is_pod ::= type +| 117 = @ispolyexpr // __is_polymorphic ::= type +| 118 = @isunionexpr // __is_union ::= type +| 119 = @typescompexpr // GNU __builtin_types_compatible ::= type type +| 120 = @intaddrexpr // EDG internal builtin, used to implement offsetof +// ... +| 122 = @hastrivialdestructor // __has_trivial_destructor ::= type +| 123 = @literal +| 124 = @uuidof +| 127 = @aggregateliteral +| 128 = @delete_array_expr +| 129 = @new_array_expr +// ... 130 @objc_array_literal deprecated +// ... 131 @objc_dictionary_literal deprecated +| 132 = @foldexpr +// ... +| 200 = @ctordirectinit +| 201 = @ctorvirtualinit +| 202 = @ctorfieldinit +| 203 = @ctordelegatinginit +| 204 = @dtordirectdestruct +| 205 = @dtorvirtualdestruct +| 206 = @dtorfielddestruct +// ... +| 210 = @static_cast +| 211 = @reinterpret_cast +| 212 = @const_cast +| 213 = @dynamic_cast +| 214 = @c_style_cast +| 215 = @lambdaexpr +| 216 = @param_ref +| 217 = @noopexpr +// ... +| 294 = @istriviallyconstructibleexpr +| 295 = @isdestructibleexpr +| 296 = @isnothrowdestructibleexpr +| 297 = @istriviallydestructibleexpr +| 298 = @istriviallyassignableexpr +| 299 = @isnothrowassignableexpr +| 300 = @istrivialexpr +| 301 = @isstandardlayoutexpr +| 302 = @istriviallycopyableexpr +| 303 = @isliteraltypeexpr +| 304 = @hastrivialmoveconstructorexpr +| 305 = @hastrivialmoveassignexpr +| 306 = @hasnothrowmoveassignexpr +| 307 = @isconstructibleexpr +| 308 = @isnothrowconstructibleexpr +| 309 = @hasfinalizerexpr +| 310 = @isdelegateexpr +| 311 = @isinterfaceclassexpr +| 312 = @isrefarrayexpr +| 313 = @isrefclassexpr +| 314 = @issealedexpr +| 315 = @issimplevalueclassexpr +| 316 = @isvalueclassexpr +| 317 = @isfinalexpr +| 319 = @noexceptexpr +| 320 = @builtinshufflevector +| 321 = @builtinchooseexpr +| 322 = @builtinaddressof +| 323 = @vec_fill +| 324 = @builtinconvertvector +| 325 = @builtincomplex +| 326 = @spaceshipexpr +| 327 = @co_await +| 328 = @co_yield +| 329 = @temp_init +; + +@var_args_expr = @vastartexpr + | @vaendexpr + | @vaargexpr + | @vacopyexpr + ; + +@builtin_op = @var_args_expr + | @noopexpr + | @offsetofexpr + | @intaddrexpr + | @hasassignexpr + | @hascopyexpr + | @hasnothrowassign + | @hasnothrowconstr + | @hasnothrowcopy + | @hastrivialassign + | @hastrivialconstr + | @hastrivialcopy + | @hastrivialdestructor + | @hasuserdestr + | @hasvirtualdestr + | @isabstractexpr + | @isbaseofexpr + | @isclassexpr + | @isconvtoexpr + | @isemptyexpr + | @isenumexpr + | @ispodexpr + | @ispolyexpr + | @isunionexpr + | @typescompexpr + | @builtinshufflevector + | @builtinconvertvector + | @builtinaddressof + | @istriviallyconstructibleexpr + | @isdestructibleexpr + | @isnothrowdestructibleexpr + | @istriviallydestructibleexpr + | @istriviallyassignableexpr + | @isnothrowassignableexpr + | @isstandardlayoutexpr + | @istriviallycopyableexpr + | @isliteraltypeexpr + | @hastrivialmoveconstructorexpr + | @hastrivialmoveassignexpr + | @hasnothrowmoveassignexpr + | @isconstructibleexpr + | @isnothrowconstructibleexpr + | @hasfinalizerexpr + | @isdelegateexpr + | @isinterfaceclassexpr + | @isrefarrayexpr + | @isrefclassexpr + | @issealedexpr + | @issimplevalueclassexpr + | @isvalueclassexpr + | @isfinalexpr + | @builtinchooseexpr + | @builtincomplex + ; + +new_allocated_type( + unique int expr: @new_expr ref, + int type_id: @type ref +); + +new_array_allocated_type( + unique int expr: @new_array_expr ref, + int type_id: @type ref +); + +/** + * The field being initialized by an initializer expression within an aggregate + * initializer for a class/struct/union. + */ +#keyset[aggregate, field] +aggregate_field_init( + int aggregate: @aggregateliteral ref, + int initializer: @expr ref, + int field: @membervariable ref +); + +/** + * The index of the element being initialized by an initializer expression + * within an aggregate initializer for an array. + */ +#keyset[aggregate, element_index] +aggregate_array_init( + int aggregate: @aggregateliteral ref, + int initializer: @expr ref, + int element_index: int ref +); + +@ctorinit = @ctordirectinit + | @ctorvirtualinit + | @ctorfieldinit + | @ctordelegatinginit; +@dtordestruct = @dtordirectdestruct + | @dtorvirtualdestruct + | @dtorfielddestruct; + + +condition_decl_bind( + unique int expr: @condition_decl ref, + unique int decl: @declaration ref +); + +typeid_bind( + unique int expr: @type_id ref, + int type_id: @type ref +); + +uuidof_bind( + unique int expr: @uuidof ref, + int type_id: @type ref +); + +@runtime_sizeof_or_alignof = @runtime_sizeof | @runtime_alignof; + +sizeof_bind( + unique int expr: @runtime_sizeof_or_alignof ref, + int type_id: @type ref +); + +code_block( + unique int block: @literal ref, + unique int routine: @function ref +); + +lambdas( + unique int expr: @lambdaexpr ref, + string default_capture: string ref, + boolean has_explicit_return_type: boolean ref +); + +lambda_capture( + unique int id: @lambdacapture, + int lambda: @lambdaexpr ref, + int index: int ref, + int field: @membervariable ref, + boolean captured_by_reference: boolean ref, + boolean is_implicit: boolean ref, + int location: @location_default ref +); + +@funbindexpr = @routineexpr + | @new_expr + | @delete_expr + | @delete_array_expr + | @ctordirectinit + | @ctorvirtualinit + | @ctordelegatinginit + | @dtordirectdestruct + | @dtorvirtualdestruct; + +@varbindexpr = @varaccess | @ctorfieldinit | @dtorfielddestruct; +@addressable = @function | @variable ; +@accessible = @addressable | @enumconstant ; + +@access = @varaccess | @routineexpr ; + +fold( + int expr: @foldexpr ref, + string operator: string ref, + boolean is_left_fold: boolean ref +); + +stmts( + unique int id: @stmt, + int kind: int ref, + int location: @location_stmt ref +); + +case @stmt.kind of + 1 = @stmt_expr +| 2 = @stmt_if +| 3 = @stmt_while +| 4 = @stmt_goto +| 5 = @stmt_label +| 6 = @stmt_return +| 7 = @stmt_block +| 8 = @stmt_end_test_while // do { ... } while ( ... ) +| 9 = @stmt_for +| 10 = @stmt_switch_case +| 11 = @stmt_switch +| 13 = @stmt_asm // "asm" statement or the body of an asm function +| 15 = @stmt_try_block +| 16 = @stmt_microsoft_try // Microsoft +| 17 = @stmt_decl +| 18 = @stmt_set_vla_size // C99 +| 19 = @stmt_vla_decl // C99 +| 25 = @stmt_assigned_goto // GNU +| 26 = @stmt_empty +| 27 = @stmt_continue +| 28 = @stmt_break +| 29 = @stmt_range_based_for // C++11 +// ... 30 @stmt_at_autoreleasepool_block deprecated +// ... 31 @stmt_objc_for_in deprecated +// ... 32 @stmt_at_synchronized deprecated +| 33 = @stmt_handler +// ... 34 @stmt_finally_end deprecated +| 35 = @stmt_constexpr_if +| 37 = @stmt_co_return +; + +type_vla( + int type_id: @type ref, + int decl: @stmt_vla_decl ref +); + +variable_vla( + int var: @variable ref, + int decl: @stmt_vla_decl ref +); + +if_then( + unique int if_stmt: @stmt_if ref, + int then_id: @stmt ref +); + +if_else( + unique int if_stmt: @stmt_if ref, + int else_id: @stmt ref +); + +constexpr_if_then( + unique int constexpr_if_stmt: @stmt_constexpr_if ref, + int then_id: @stmt ref +); + +constexpr_if_else( + unique int constexpr_if_stmt: @stmt_constexpr_if ref, + int else_id: @stmt ref +); + +while_body( + unique int while_stmt: @stmt_while ref, + int body_id: @stmt ref +); + +do_body( + unique int do_stmt: @stmt_end_test_while ref, + int body_id: @stmt ref +); + +#keyset[switch_stmt, index] +switch_case( + int switch_stmt: @stmt_switch ref, + int index: int ref, + int case_id: @stmt_switch_case ref +); + +switch_body( + unique int switch_stmt: @stmt_switch ref, + int body_id: @stmt ref +); + +for_initialization( + unique int for_stmt: @stmt_for ref, + int init_id: @stmt ref +); + +for_condition( + unique int for_stmt: @stmt_for ref, + int condition_id: @expr ref +); + +for_update( + unique int for_stmt: @stmt_for ref, + int update_id: @expr ref +); + +for_body( + unique int for_stmt: @stmt_for ref, + int body_id: @stmt ref +); + +@stmtparent = @stmt | @expr_stmt ; +stmtparents( + unique int id: @stmt ref, + int index: int ref, + int parent: @stmtparent ref +); + +ishandler(unique int block: @stmt_block ref); + +@cfgnode = @stmt | @expr | @function | @initialiser ; + +stmt_decl_bind( + int stmt: @stmt_decl ref, + int num: int ref, + int decl: @declaration ref +); + +stmt_decl_entry_bind( + int stmt: @stmt_decl ref, + int num: int ref, + int decl_entry: @element ref +); + +@functionorblock = @function | @stmt_block; + +blockscope( + unique int block: @stmt_block ref, + int enclosing: @functionorblock ref +); + +@jump = @stmt_goto | @stmt_break | @stmt_continue; + +@jumporlabel = @jump | @stmt_label | @literal; + +jumpinfo( + unique int id: @jumporlabel ref, + string str: string ref, + int target: @stmt ref +); + +preprocdirects( + unique int id: @preprocdirect, + int kind: int ref, + int location: @location_default ref +); +case @preprocdirect.kind of + 0 = @ppd_if +| 1 = @ppd_ifdef +| 2 = @ppd_ifndef +| 3 = @ppd_elif +| 4 = @ppd_else +| 5 = @ppd_endif +| 6 = @ppd_plain_include +| 7 = @ppd_define +| 8 = @ppd_undef +| 9 = @ppd_line +| 10 = @ppd_error +| 11 = @ppd_pragma +| 12 = @ppd_objc_import +| 13 = @ppd_include_next +| 18 = @ppd_warning +; + +@ppd_include = @ppd_plain_include | @ppd_objc_import | @ppd_include_next; + +@ppd_branch = @ppd_if | @ppd_ifdef | @ppd_ifndef | @ppd_elif; + +preprocpair( + int begin : @ppd_branch ref, + int elseelifend : @preprocdirect ref +); + +preproctrue(int branch : @ppd_branch ref); +preprocfalse(int branch : @ppd_branch ref); + +preproctext( + unique int id: @preprocdirect ref, + string head: string ref, + string body: string ref +); + +includes( + unique int id: @ppd_include ref, + int included: @file ref +); + +link_targets( + unique int id: @link_target, + int binary: @file ref +); + +link_parent( + int element : @element ref, + int link_target : @link_target ref +); + +/* XML Files */ + +xmlEncoding(unique int id: @file ref, string encoding: string ref); + +xmlDTDs( + unique int id: @xmldtd, + string root: string ref, + string publicId: string ref, + string systemId: string ref, + int fileid: @file ref +); + +xmlElements( + unique int id: @xmlelement, + string name: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int fileid: @file ref +); + +xmlAttrs( + unique int id: @xmlattribute, + int elementid: @xmlelement ref, + string name: string ref, + string value: string ref, + int idx: int ref, + int fileid: @file ref +); + +xmlNs( + int id: @xmlnamespace, + string prefixName: string ref, + string URI: string ref, + int fileid: @file ref +); + +xmlHasNs( + int elementId: @xmlnamespaceable ref, + int nsId: @xmlnamespace ref, + int fileid: @file ref +); + +xmlComments( + unique int id: @xmlcomment, + string text: string ref, + int parentid: @xmlparent ref, + int fileid: @file ref +); + +xmlChars( + unique int id: @xmlcharacters, + string text: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int isCDATA: int ref, + int fileid: @file ref +); + +@xmlparent = @file | @xmlelement; +@xmlnamespaceable = @xmlelement | @xmlattribute; + +xmllocations( + int xmlElement: @xmllocatable ref, + int location: @location_default ref +); + +@xmllocatable = @xmlcharacters + | @xmlelement + | @xmlcomment + | @xmlattribute + | @xmldtd + | @file + | @xmlnamespace; diff --git a/cpp/upgrades/c82db4c596b8979eba9a8958e24353a5756d7a02/upgrade.properties b/cpp/upgrades/c82db4c596b8979eba9a8958e24353a5756d7a02/upgrade.properties new file mode 100644 index 00000000000..df9dcbdef5e --- /dev/null +++ b/cpp/upgrades/c82db4c596b8979eba9a8958e24353a5756d7a02/upgrade.properties @@ -0,0 +1,3 @@ +description: Change decltype keysets +compatibility: backwards + diff --git a/csharp/autobuilder/Semmle.Autobuild.Shared/Solution.cs b/csharp/autobuilder/Semmle.Autobuild.Shared/Solution.cs index 2f16872dd74..c5d65794fb5 100644 --- a/csharp/autobuilder/Semmle.Autobuild.Shared/Solution.cs +++ b/csharp/autobuilder/Semmle.Autobuild.Shared/Solution.cs @@ -45,6 +45,7 @@ namespace Semmle.Autobuild.Shared private readonly SolutionFile? solution; private readonly IEnumerable includedProjects; + public override IEnumerable IncludedProjects => includedProjects; public IEnumerable Configurations => @@ -84,8 +85,12 @@ namespace Semmle.Autobuild.Shared .ToArray(); } - private IEnumerable ToolsVersions => includedProjects.Where(p => p.ValidToolsVersion).Select(p => p.ToolsVersion); + private IEnumerable ToolsVersions => includedProjects + .Where(p => p.ValidToolsVersion) + .Select(p => p.ToolsVersion); - public Version ToolsVersion => ToolsVersions.Any() ? ToolsVersions.Max() : new Version(); + public Version ToolsVersion => ToolsVersions.Any() + ? ToolsVersions.Max() + : new Version(); } } diff --git a/csharp/change-notes/2020-12-08-cil-enum-underlying-type.md b/csharp/change-notes/2020-12-08-cil-enum-underlying-type.md new file mode 100644 index 00000000000..bf0dce9232c --- /dev/null +++ b/csharp/change-notes/2020-12-08-cil-enum-underlying-type.md @@ -0,0 +1,2 @@ +lgtm,codescanning +* CIL extraction has been improved to store numeric underlying type of `enum` declarations. \ No newline at end of file diff --git a/csharp/change-notes/2020-12-17-format-method-empty-overload.md b/csharp/change-notes/2020-12-17-format-method-empty-overload.md new file mode 100644 index 00000000000..9341f2c39a7 --- /dev/null +++ b/csharp/change-notes/2020-12-17-format-method-empty-overload.md @@ -0,0 +1,2 @@ +lgtm,codescanning +* For string formatting methods, such as `System.Console.WriteLine(string format, params object[] arg)`, we now also recognize overloads without insertion parameters as string formatting methods. For example, `System.Console.WriteLine(string value)` is now also a member of the class `FormatMethod` in `frameworks/Format.qll`. \ No newline at end of file diff --git a/csharp/change-notes/2020-12-18-extract-custom-modifiers.md b/csharp/change-notes/2020-12-18-extract-custom-modifiers.md new file mode 100644 index 00000000000..92f141e041e --- /dev/null +++ b/csharp/change-notes/2020-12-18-extract-custom-modifiers.md @@ -0,0 +1,4 @@ +lgtm,codescanning +* CIL extraction has been improved to store `modreq` and `modopt` custom modifiers. +The extracted information is surfaced through the `CustomModifierReceiver` class. Additionally, +the information is also used to evaluate the new `Setter::isInitOnly` predicate. \ No newline at end of file diff --git a/csharp/change-notes/2020-12-21-merge-format-queries.md b/csharp/change-notes/2020-12-21-merge-format-queries.md new file mode 100644 index 00000000000..9845a991b90 --- /dev/null +++ b/csharp/change-notes/2020-12-21-merge-format-queries.md @@ -0,0 +1,2 @@ +lgtm,codescanning +* The queries `FormatInvalid.ql`, `FormatMissingArgument.ql`, and `FormatUnusedArgument.ql` have been merged into a single `FormatInvalid.ql` query. \ No newline at end of file diff --git a/csharp/change-notes/2021-01-14-Unary-pattern.md b/csharp/change-notes/2021-01-14-Unary-pattern.md new file mode 100644 index 00000000000..0afd5f0c7c1 --- /dev/null +++ b/csharp/change-notes/2021-01-14-Unary-pattern.md @@ -0,0 +1,3 @@ +lgtm,codescanning +* The `UnaryPatternExpr` and `NotPatternExpr` classes have been added to support +C# 9 unary `not` pattern. diff --git a/csharp/change-notes/2021-01-15-Relational-pattern.md b/csharp/change-notes/2021-01-15-Relational-pattern.md new file mode 100644 index 00000000000..77179884d12 --- /dev/null +++ b/csharp/change-notes/2021-01-15-Relational-pattern.md @@ -0,0 +1,3 @@ +lgtm,codescanning +* The `RelationalPatternExpr` and its 4 sub class have been added to support C# 9 +relational `<`, `>`, `<=`, and `>=` patterns. diff --git a/csharp/change-notes/2021-01-19-Function-pointer.md b/csharp/change-notes/2021-01-19-Function-pointer.md new file mode 100644 index 00000000000..b48855d2f89 --- /dev/null +++ b/csharp/change-notes/2021-01-19-Function-pointer.md @@ -0,0 +1,3 @@ +lgtm,codescanning +* Function pointer types (`FunctionPointerType`) and call to function pointers +(`FunctionPointerCall`) are extracted. diff --git a/csharp/change-notes/2021-01-25-Function-pointer-cil.md b/csharp/change-notes/2021-01-25-Function-pointer-cil.md new file mode 100644 index 00000000000..097df002d0f --- /dev/null +++ b/csharp/change-notes/2021-01-25-Function-pointer-cil.md @@ -0,0 +1,2 @@ +lgtm,codescanning +* Function pointer types (`FunctionPointerType`) are extracted from IL. Also, `pinned` and `by-reference` (`cil_type_annotation`) type extraction is fixed. diff --git a/csharp/change-notes/2021-01-27-Add-binary-pattern.md b/csharp/change-notes/2021-01-27-Add-binary-pattern.md new file mode 100644 index 00000000000..27e8ce2a726 --- /dev/null +++ b/csharp/change-notes/2021-01-27-Add-binary-pattern.md @@ -0,0 +1,3 @@ +lgtm,codescanning +* The `BinaryPatternExpr` class has been added to support C# 9 `and` and `or` +patterns. diff --git a/csharp/change-notes/2021-02-01-Preprocessor-directives.md b/csharp/change-notes/2021-02-01-Preprocessor-directives.md new file mode 100644 index 00000000000..d81979c36cd --- /dev/null +++ b/csharp/change-notes/2021-02-01-Preprocessor-directives.md @@ -0,0 +1,8 @@ +lgtm,codescanning +* The `PreprocessorDirective` class and its base classes have been added to support +preprocessor directives, such as `#if`, `#define`, `#undef`, `#line`, `#region`, +`#warning`, `#error`, `#pragma warning`, `#pragma checksum` and `#nullable`. Furthermore, +`#line` directives are now taken into account when querying the location of any +code construct. Files referenced in preprocessor directives are also included in the +extraction sources. This change is expected to lead to better error reporting locations +in generated code, such as generated code from `.cshtml` files in ASP.NET Core. diff --git a/csharp/change-notes/2021-02-02-foreach-underlying-methods.md b/csharp/change-notes/2021-02-02-foreach-underlying-methods.md new file mode 100644 index 00000000000..a9e934a0e5d --- /dev/null +++ b/csharp/change-notes/2021-02-02-foreach-underlying-methods.md @@ -0,0 +1,3 @@ +lgtm,codescanning +* The underlying methods of `foreach` statements are now explicitly extracted and +they are made available on the `ForeachStmt` class. diff --git a/csharp/change-notes/2021-02-04-Records.md b/csharp/change-notes/2021-02-04-Records.md new file mode 100644 index 00000000000..069737e5239 --- /dev/null +++ b/csharp/change-notes/2021-02-04-Records.md @@ -0,0 +1,2 @@ +lgtm,codescanning +* Record types (`Record`) are extracted. diff --git a/csharp/extractor/Semmle.Extraction.CIL.Driver/ExtractorOptions.cs b/csharp/extractor/Semmle.Extraction.CIL.Driver/ExtractorOptions.cs index 9964ff5bf0c..75405d562fe 100644 --- a/csharp/extractor/Semmle.Extraction.CIL.Driver/ExtractorOptions.cs +++ b/csharp/extractor/Semmle.Extraction.CIL.Driver/ExtractorOptions.cs @@ -163,7 +163,7 @@ namespace Semmle.Extraction.CIL.Driver } private readonly HashSet filesAnalyzed = new HashSet(); - public HashSet MissingReferences {get;} = new HashSet(); + public HashSet MissingReferences { get; } = new HashSet(); } /// diff --git a/csharp/extractor/Semmle.Extraction.CIL/Context.cs b/csharp/extractor/Semmle.Extraction.CIL/Context.cs index 26a9298aa07..ae662f2e87c 100644 --- a/csharp/extractor/Semmle.Extraction.CIL/Context.cs +++ b/csharp/extractor/Semmle.Extraction.CIL/Context.cs @@ -1,6 +1,5 @@ using System; using System.IO; -using System.Linq; using System.Reflection.Metadata; using System.Reflection.PortableExecutable; @@ -83,7 +82,7 @@ namespace Semmle.Extraction.CIL trapFile.Write(GetString(def.Name)); trapFile.Write('_'); trapFile.Write(def.Version.ToString()); - trapFile.Write("::"); + trapFile.Write(Entities.Type.AssemblyTypeNameSeparator); } public Entities.TypeSignatureDecoder TypeSignatureDecoder { get; } diff --git a/csharp/extractor/Semmle.Extraction.CIL/Entities/ArrayType.cs b/csharp/extractor/Semmle.Extraction.CIL/Entities/ArrayType.cs index fef6d313a1a..ae04add2b12 100644 --- a/csharp/extractor/Semmle.Extraction.CIL/Entities/ArrayType.cs +++ b/csharp/extractor/Semmle.Extraction.CIL/Entities/ArrayType.cs @@ -27,27 +27,26 @@ namespace Semmle.Extraction.CIL.Entities return obj is ArrayType array && elementType.Equals(array.elementType) && rank == array.rank; } - public override int GetHashCode() - { - return elementType.GetHashCode() * 5 + rank; - } + public override int GetHashCode() => HashCode.Combine(elementType, rank); public override void WriteId(TextWriter trapFile, bool inContext) { - elementType.GetId(trapFile, inContext); + elementType.WriteId(trapFile, inContext); trapFile.Write('['); for (var i = 1; i < rank; ++i) + { trapFile.Write(','); + } trapFile.Write(']'); } public override string Name => elementType.Name + "[]"; - public override Namespace Namespace => Cx.SystemNamespace; + public override Namespace ContainingNamespace => Cx.SystemNamespace; public override Type? ContainingType => null; - public override int ThisTypeParameters => elementType.ThisTypeParameters; + public override int ThisTypeParameterCount => elementType.ThisTypeParameterCount; public override CilTypeKind Kind => CilTypeKind.Array; @@ -71,7 +70,5 @@ namespace Semmle.Extraction.CIL.Entities public override IEnumerable GenericArguments => elementType.GenericArguments; public override IEnumerable TypeParameters => elementType.TypeParameters; - - public override IEnumerable MethodParameters => throw new NotImplementedException(); } } diff --git a/csharp/extractor/Semmle.Extraction.CIL/Entities/Assembly.cs b/csharp/extractor/Semmle.Extraction.CIL/Entities/Assembly.cs index 8a843f1672d..5c0a834909c 100644 --- a/csharp/extractor/Semmle.Extraction.CIL/Entities/Assembly.cs +++ b/csharp/extractor/Semmle.Extraction.CIL/Entities/Assembly.cs @@ -136,7 +136,7 @@ namespace Semmle.Extraction.CIL.Entities trapFile = trapWriter.TrapFile; if (nocache || !System.IO.File.Exists(trapFile)) { - var cx = extractor.CreateContext(null, trapWriter, null, false); + var cx = new Extraction.Context(extractor, trapWriter); ExtractCIL(cx, assemblyPath, extractPdbs); extracted = true; } diff --git a/csharp/extractor/Semmle.Extraction.CIL/Entities/Attribute.cs b/csharp/extractor/Semmle.Extraction.CIL/Entities/Attribute.cs index bfbe8ccc854..c862bc3fc4e 100644 --- a/csharp/extractor/Semmle.Extraction.CIL/Entities/Attribute.cs +++ b/csharp/extractor/Semmle.Extraction.CIL/Entities/Attribute.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Linq; using System.Reflection.Metadata; namespace Semmle.Extraction.CIL.Entities @@ -42,28 +43,43 @@ namespace Semmle.Extraction.CIL.Entities { decoded = attrib.DecodeValue(new CustomAttributeDecoder(Cx)); } - catch (NotImplementedException) + catch { - // Attribute decoding is only partial at this stage. + Cx.Cx.Extractor.Logger.Log(Util.Logging.Severity.Info, + $"Attribute decoding is partial. Decoding attribute {constructor.DeclaringType.GetQualifiedName()} failed on {@object}."); yield break; } for (var index = 0; index < decoded.FixedArguments.Length; ++index) { - var value = decoded.FixedArguments[index].Value; - var stringValue = value?.ToString(); - yield return Tuples.cil_attribute_positional_argument(this, index, stringValue ?? "null"); + var stringValue = GetStringValue(decoded.FixedArguments[index].Type, decoded.FixedArguments[index].Value); + yield return Tuples.cil_attribute_positional_argument(this, index, stringValue); } foreach (var p in decoded.NamedArguments) { - var value = p.Value; - var stringValue = value?.ToString(); - yield return Tuples.cil_attribute_named_argument(this, p.Name, stringValue ?? "null"); + var stringValue = GetStringValue(p.Type, p.Value); + yield return Tuples.cil_attribute_named_argument(this, p.Name!, stringValue); } } } + private static string GetStringValue(Type type, object? value) + { + if (value is System.Collections.Immutable.ImmutableArray> values) + { + return "[" + string.Join(",", values.Select(v => GetStringValue(v.Type, v.Value))) + "]"; + } + + if (type.GetQualifiedName() == "System.Type" && + value is Type t) + { + return t.GetQualifiedName(); + } + + return value?.ToString() ?? "null"; + } + public static IEnumerable Populate(Context cx, IEntity @object, CustomAttributeHandleCollection attributes) { foreach (var attrib in attributes) diff --git a/csharp/extractor/Semmle.Extraction.CIL/Entities/ByRefType.cs b/csharp/extractor/Semmle.Extraction.CIL/Entities/ByRefType.cs new file mode 100644 index 00000000000..2a527419249 --- /dev/null +++ b/csharp/extractor/Semmle.Extraction.CIL/Entities/ByRefType.cs @@ -0,0 +1,42 @@ +using System; +using System.Collections.Generic; +using System.IO; + +namespace Semmle.Extraction.CIL.Entities +{ + /// + /// Types that are passed by reference are not written directly to trap files. Instead, the annotation is stored on + /// the entity. + /// + internal sealed class ByRefType : Type + { + public ByRefType(Context cx, Type elementType) : base(cx) + { + ElementType = elementType; + } + + public override CilTypeKind Kind => throw new NotImplementedException(); + + public override Namespace? ContainingNamespace => throw new NotImplementedException(); + + public override Type? ContainingType => throw new NotImplementedException(); + + public override int ThisTypeParameterCount => throw new NotImplementedException(); + + public override IEnumerable TypeParameters => throw new NotImplementedException(); + + public override Type Construct(IEnumerable typeArguments) => throw new NotImplementedException(); + + public override string Name => $"{ElementType.Name}&"; + + public Type ElementType { get; } + + public override void WriteAssemblyPrefix(TextWriter trapFile) => throw new NotImplementedException(); + + public override void WriteId(TextWriter trapFile, bool inContext) + { + ElementType.WriteId(trapFile, inContext); + trapFile.Write('&'); + } + } +} diff --git a/csharp/extractor/Semmle.Extraction.CIL/Entities/CilTypeKind.cs b/csharp/extractor/Semmle.Extraction.CIL/Entities/CilTypeKind.cs index f5ccf5057f7..e95fe0e28c0 100644 --- a/csharp/extractor/Semmle.Extraction.CIL/Entities/CilTypeKind.cs +++ b/csharp/extractor/Semmle.Extraction.CIL/Entities/CilTypeKind.cs @@ -8,6 +8,7 @@ namespace Semmle.Extraction.CIL.Entities ValueOrRefType, TypeParameter, Array, - Pointer + Pointer, + FunctionPointer } } diff --git a/csharp/extractor/Semmle.Extraction.CIL/Entities/ConstructedType.cs b/csharp/extractor/Semmle.Extraction.CIL/Entities/ConstructedType.cs index 165883a8663..be2ab5da4d8 100644 --- a/csharp/extractor/Semmle.Extraction.CIL/Entities/ConstructedType.cs +++ b/csharp/extractor/Semmle.Extraction.CIL/Entities/ConstructedType.cs @@ -1,5 +1,4 @@ using System; -using Microsoft.CodeAnalysis; using System.Linq; using System.Collections.Generic; using System.IO; @@ -17,36 +16,18 @@ namespace Semmle.Extraction.CIL.Entities // Either null or notEmpty private readonly Type[]? thisTypeArguments; - public override IEnumerable ThisTypeArguments => thisTypeArguments.EnumerateNull(); - - public override IEnumerable ThisGenericArguments => thisTypeArguments.EnumerateNull(); - - public override IEnumerable Contents - { - get - { - foreach (var c in base.Contents) - yield return c; - - var i = 0; - foreach (var type in ThisGenericArguments) - { - yield return type; - yield return Tuples.cil_type_argument(this, i++, type); - } - } - } - - public override Type SourceDeclaration => unboundGenericType; + private readonly Type? containingType; + private readonly NamedTypeIdWriter idWriter; public ConstructedType(Context cx, Type unboundType, IEnumerable typeArguments) : base(cx) { + idWriter = new NamedTypeIdWriter(this); var suppliedArgs = typeArguments.Count(); - if (suppliedArgs != unboundType.TotalTypeParametersCheck) + if (suppliedArgs != unboundType.TotalTypeParametersCount) throw new InternalError("Unexpected number of type arguments in ConstructedType"); unboundGenericType = unboundType; - var thisParams = unboundType.ThisTypeParameters; + var thisParams = unboundType.ThisTypeParameterCount; if (typeArguments.Count() == thisParams) { @@ -88,14 +69,29 @@ namespace Semmle.Extraction.CIL.Entities return h; } - private readonly Type? containingType; + public override IEnumerable Contents + { + get + { + foreach (var c in base.Contents) + yield return c; + + var i = 0; + foreach (var type in ThisTypeArguments) + { + yield return type; + yield return Tuples.cil_type_argument(this, i++, type); + } + } + } + + public override Type SourceDeclaration => unboundGenericType; + public override Type? ContainingType => containingType; public override string Name => unboundGenericType.Name; - public override Namespace Namespace => unboundGenericType.Namespace!; - - public override int ThisTypeParameters => thisTypeArguments == null ? 0 : thisTypeArguments.Length; + public override Namespace ContainingNamespace => unboundGenericType.ContainingNamespace!; public override CilTypeKind Kind => unboundGenericType.Kind; @@ -106,40 +102,17 @@ namespace Semmle.Extraction.CIL.Entities public override void WriteId(TextWriter trapFile, bool inContext) { - if (ContainingType != null) - { - ContainingType.GetId(trapFile, inContext); - trapFile.Write('.'); - } - else - { - WriteAssemblyPrefix(trapFile); - - if (!Namespace.IsGlobalNamespace) - { - Namespace.WriteId(trapFile); - trapFile.Write('.'); - } - } - trapFile.Write(unboundGenericType.Name); - - if (thisTypeArguments != null && thisTypeArguments.Any()) - { - trapFile.Write('<'); - var index = 0; - foreach (var t in thisTypeArguments) - { - trapFile.WriteSeparator(",", ref index); - t.WriteId(trapFile); - } - trapFile.Write('>'); - } + idWriter.WriteId(trapFile, inContext); } public override void WriteAssemblyPrefix(TextWriter trapFile) => unboundGenericType.WriteAssemblyPrefix(trapFile); + public override int ThisTypeParameterCount => thisTypeArguments?.Length ?? 0; + public override IEnumerable TypeParameters => GenericArguments; - public override IEnumerable MethodParameters => throw new NotImplementedException(); + public override IEnumerable ThisTypeArguments => thisTypeArguments.EnumerateNull(); + + public override IEnumerable ThisGenericArguments => thisTypeArguments.EnumerateNull(); } } diff --git a/csharp/extractor/Semmle.Extraction.CIL/Entities/CustomAttributeDecoder.cs b/csharp/extractor/Semmle.Extraction.CIL/Entities/CustomAttributeDecoder.cs index 25ea18e3229..94d6cc0ab6d 100644 --- a/csharp/extractor/Semmle.Extraction.CIL/Entities/CustomAttributeDecoder.cs +++ b/csharp/extractor/Semmle.Extraction.CIL/Entities/CustomAttributeDecoder.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using System.Reflection.Metadata; namespace Semmle.Extraction.CIL.Entities @@ -14,7 +15,7 @@ namespace Semmle.Extraction.CIL.Entities public Type GetPrimitiveType(PrimitiveTypeCode typeCode) => cx.Create(typeCode); - public Type GetSystemType() => throw new NotImplementedException(); + public Type GetSystemType() => new NoMetadataHandleType(cx, "System.Type"); public Type GetSZArrayType(Type elementType) => cx.Populate(new ArrayType(cx, elementType)); @@ -25,10 +26,37 @@ namespace Semmle.Extraction.CIL.Entities public Type GetTypeFromReference(MetadataReader reader, TypeReferenceHandle handle, byte rawTypeKind) => (Type)cx.Create(handle); - public Type GetTypeFromSerializedName(string name) => throw new NotImplementedException(); + public Type GetTypeFromSerializedName(string name) => new NoMetadataHandleType(cx, name); - public PrimitiveTypeCode GetUnderlyingEnumType(Type type) => throw new NotImplementedException(); + public PrimitiveTypeCode GetUnderlyingEnumType(Type type) + { + if (type is TypeDefinitionType tdt && + tdt.GetUnderlyingEnumType() is PrimitiveTypeCode underlying) + { + return underlying; + } - public bool IsSystemType(Type type) => type is PrimitiveType; // ?? + var name = type.GetQualifiedName(); + + if (wellKnownEnums.TryGetValue(name, out var code)) + { + cx.Cx.Extractor.Logger.Log(Util.Logging.Severity.Debug, $"Using hard coded underlying enum type for {name}"); + return code; + } + + cx.Cx.Extractor.Logger.Log(Util.Logging.Severity.Info, $"Couldn't get underlying enum type for {name}"); + + // We can't fall back to Int32, because the type returned here defines how many bytes are read from the + // stream and how those bytes are interpreted. + throw new NotImplementedException(); + } + + public bool IsSystemType(Type type) => type.GetQualifiedName() == "System.Type"; + + private static readonly Dictionary wellKnownEnums = new Dictionary + { + { "System.AttributeTargets", PrimitiveTypeCode.Int32 }, + { "System.ComponentModel.EditorBrowsableState", PrimitiveTypeCode.Int32 } + }; } } diff --git a/csharp/extractor/Semmle.Extraction.CIL/Entities/DefinitionMethod.cs b/csharp/extractor/Semmle.Extraction.CIL/Entities/DefinitionMethod.cs index 43bee72a9c0..175da806597 100644 --- a/csharp/extractor/Semmle.Extraction.CIL/Entities/DefinitionMethod.cs +++ b/csharp/extractor/Semmle.Extraction.CIL/Entities/DefinitionMethod.cs @@ -76,9 +76,10 @@ namespace Semmle.Extraction.CIL.Entities var typeSignature = md.DecodeSignature(Cx.TypeSignatureDecoder, this); - Parameters = MakeParameters(typeSignature.ParameterTypes).ToArray(); + var parameters = GetParameterExtractionProducts(typeSignature.ParameterTypes).ToArray(); + Parameters = parameters.OfType().ToArray(); - foreach (var c in Parameters) + foreach (var c in parameters) yield return c; foreach (var c in PopulateFlags) @@ -95,7 +96,12 @@ namespace Semmle.Extraction.CIL.Entities } yield return Tuples.metadata_handle(this, Cx.Assembly, MetadataTokens.GetToken(handle)); - yield return Tuples.cil_method(this, Name, declaringType, typeSignature.ReturnType); + + foreach (var m in GetMethodExtractionProducts(Name, declaringType, typeSignature.ReturnType)) + { + yield return m; + } + yield return Tuples.cil_method_source_declaration(this, this); yield return Tuples.cil_method_location(this, Cx.Assembly); @@ -115,8 +121,19 @@ namespace Semmle.Extraction.CIL.Entities for (var l = 0; l < this.locals.Length; ++l) { - this.locals[l] = Cx.Populate(new LocalVariable(Cx, Implementation, l, localVariableTypes[l])); - yield return this.locals[l]; + var t = localVariableTypes[l]; + if (t is ByRefType brt) + { + t = brt.ElementType; + this.locals[l] = Cx.Populate(new LocalVariable(Cx, Implementation, l, t)); + yield return this.locals[l]; + yield return Tuples.cil_type_annotation(this.locals[l], TypeAnnotation.Ref); + } + else + { + this.locals[l] = Cx.Populate(new LocalVariable(Cx, Implementation, l, t)); + yield return this.locals[l]; + } } } @@ -178,7 +195,7 @@ namespace Semmle.Extraction.CIL.Entities } } - private IEnumerable Decode(byte[] ilbytes, Dictionary jump_table) + private IEnumerable Decode(byte[]? ilbytes, Dictionary jump_table) { // Sequence points are stored in order of offset. // We use an enumerator to locate the correct sequence point for each instruction. @@ -203,9 +220,9 @@ namespace Semmle.Extraction.CIL.Entities } var child = 0; - for (var offset = 0; offset < ilbytes.Length;) + for (var offset = 0; offset < (ilbytes?.Length ?? 0);) { - var instruction = new Instruction(Cx, this, ilbytes, offset, child++); + var instruction = new Instruction(Cx, this, ilbytes!, offset, child++); yield return instruction; if (nextSequencePoint != null && offset >= nextSequencePoint.Current.Offset) @@ -245,12 +262,12 @@ namespace Semmle.Extraction.CIL.Entities var ilbytes = body.GetILBytes(); var child = 0; - for (var offset = 0; offset < ilbytes.Length;) + for (var offset = 0; offset < (ilbytes?.Length ?? 0);) { Instruction decoded; try { - decoded = new Instruction(Cx, this, ilbytes, offset, child++); + decoded = new Instruction(Cx, this, ilbytes!, offset, child++); offset += decoded.Width; } catch // lgtm[cs/catch-of-all-exceptions] diff --git a/csharp/extractor/Semmle.Extraction.CIL/Entities/ErrorType.cs b/csharp/extractor/Semmle.Extraction.CIL/Entities/ErrorType.cs index 67a2a495322..e99fd8b4bc3 100644 --- a/csharp/extractor/Semmle.Extraction.CIL/Entities/ErrorType.cs +++ b/csharp/extractor/Semmle.Extraction.CIL/Entities/ErrorType.cs @@ -16,18 +16,16 @@ namespace Semmle.Extraction.CIL.Entities public override string Name => "!error"; - public override Namespace Namespace => Cx.GlobalNamespace; + public override Namespace ContainingNamespace => Cx.GlobalNamespace; public override Type? ContainingType => null; - public override int ThisTypeParameters => 0; + public override int ThisTypeParameterCount => 0; public override void WriteAssemblyPrefix(TextWriter trapFile) => throw new NotImplementedException(); public override IEnumerable TypeParameters => throw new NotImplementedException(); - public override IEnumerable MethodParameters => throw new NotImplementedException(); - public override Type Construct(IEnumerable typeArguments) => throw new NotImplementedException(); } } diff --git a/csharp/extractor/Semmle.Extraction.CIL/Entities/Field.cs b/csharp/extractor/Semmle.Extraction.CIL/Entities/Field.cs index 98a28f36286..3f051796887 100644 --- a/csharp/extractor/Semmle.Extraction.CIL/Entities/Field.cs +++ b/csharp/extractor/Semmle.Extraction.CIL/Entities/Field.cs @@ -8,7 +8,7 @@ namespace Semmle.Extraction.CIL.Entities /// /// An entity representing a field. /// - internal abstract class Field : GenericContext, IMember + internal abstract class Field : GenericContext, IMember, ICustomModifierReceiver { protected Field(Context cx) : base(cx) { @@ -45,7 +45,13 @@ namespace Semmle.Extraction.CIL.Entities { get { - yield return Tuples.cil_field(this, DeclaringType, Name, Type); + var t = Type; + if (t is ModifiedType mt) + { + t = mt.Unmodified; + yield return Tuples.cil_custom_modifiers(this, mt.Modifier, mt.IsRequired); + } + yield return Tuples.cil_field(this, DeclaringType, Name, t); } } diff --git a/csharp/extractor/Semmle.Extraction.CIL/Entities/FunctionPointerType.cs b/csharp/extractor/Semmle.Extraction.CIL/Entities/FunctionPointerType.cs new file mode 100644 index 00000000000..e92dd957cb5 --- /dev/null +++ b/csharp/extractor/Semmle.Extraction.CIL/Entities/FunctionPointerType.cs @@ -0,0 +1,114 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Reflection.Metadata; + +namespace Semmle.Extraction.CIL.Entities +{ + internal sealed class FunctionPointerType : Type, IParameterizable, ICustomModifierReceiver + { + private readonly MethodSignature signature; + + public FunctionPointerType(Context cx, MethodSignature signature) : base(cx) + { + this.signature = signature; + } + + public override CilTypeKind Kind => CilTypeKind.FunctionPointer; + + public override string Name + { + get + { + using var id = new StringWriter(); + WriteName( + id.Write, + t => id.Write(t.Name), + signature + ); + return id.ToString(); + } + } + + public override Namespace? ContainingNamespace => Cx.GlobalNamespace; + + public override Type? ContainingType => null; + + public override int ThisTypeParameterCount => throw new System.NotImplementedException(); + + public override IEnumerable TypeParameters => throw new System.NotImplementedException(); + + public override Type Construct(IEnumerable typeArguments) => throw new System.NotImplementedException(); + + public override void WriteAssemblyPrefix(TextWriter trapFile) { } + + public override void WriteId(TextWriter trapFile, bool inContext) + { + WriteName( + trapFile.Write, + t => t.WriteId(trapFile, inContext), + signature + ); + } + + internal static void WriteName(Action write, Action writeType, MethodSignature signature) + { + write("delegate* "); + write(GetCallingConvention(signature.Header.CallingConvention)); + write("<"); + foreach (var pt in signature.ParameterTypes) + { + writeType(pt); + write(","); + } + writeType(signature.ReturnType); + write(">"); + } + + internal static string GetCallingConvention(SignatureCallingConvention callingConvention) + { + if (callingConvention == SignatureCallingConvention.Default) + { + return "managed"; + } + + if (callingConvention == SignatureCallingConvention.Unmanaged) + { + return "unmanaged"; + } + + return $"unmanaged[{callingConvention}]"; + } + + public override IEnumerable Contents + { + get + { + foreach (var c in base.Contents) + { + yield return c; + } + + var retType = signature.ReturnType; + if (retType is ModifiedType mt) + { + retType = mt.Unmodified; + yield return Tuples.cil_custom_modifiers(this, mt.Modifier, mt.IsRequired); + } + if (retType is ByRefType byRefType) + { + retType = byRefType.ElementType; + yield return Tuples.cil_type_annotation(this, TypeAnnotation.Ref); + } + yield return Tuples.cil_function_pointer_return_type(this, retType); + + yield return Tuples.cil_function_pointer_calling_conventions(this, signature.Header.CallingConvention); + + foreach (var p in Method.GetParameterExtractionProducts(signature.ParameterTypes, this, this, Cx, 0)) + { + yield return p; + } + } + } + } +} diff --git a/csharp/extractor/Semmle.Extraction.CIL/Entities/GenericsHelper.cs b/csharp/extractor/Semmle.Extraction.CIL/Entities/GenericsHelper.cs new file mode 100644 index 00000000000..311d4e48134 --- /dev/null +++ b/csharp/extractor/Semmle.Extraction.CIL/Entities/GenericsHelper.cs @@ -0,0 +1,59 @@ +using System.Collections.Generic; +using System.Reflection.Metadata; + +namespace Semmle.Extraction.CIL.Entities +{ + internal static class GenericsHelper + { + public static TypeTypeParameter[] MakeTypeParameters(Type container, int count) + { + var newTypeParams = new TypeTypeParameter[count]; + for (var i = 0; i < newTypeParams.Length; ++i) + { + newTypeParams[i] = new TypeTypeParameter(container, i); + } + return newTypeParams; + } + + public static string GetNonGenericName(StringHandle name, MetadataReader reader) + { + var n = reader.GetString(name); + return GetNonGenericName(n); + } + + public static string GetNonGenericName(string name) + { + var tick = name.LastIndexOf('`'); + return tick == -1 + ? name + : name.Substring(0, tick); + } + + public static int GetGenericTypeParameterCount(StringHandle name, MetadataReader reader) + { + var n = reader.GetString(name); + return GetGenericTypeParameterCount(n); + } + + public static int GetGenericTypeParameterCount(string name) + { + var tick = name.LastIndexOf('`'); + return tick == -1 + ? 0 + : int.Parse(name.Substring(tick + 1)); + } + + public static IEnumerable GetAllTypeParameters(Type? container, IEnumerable thisTypeParameters) + { + if (container != null) + { + foreach (var t in container.TypeParameters) + yield return t; + } + + foreach (var t in thisTypeParameters) + yield return t; + + } + } +} diff --git a/csharp/extractor/Semmle.Extraction.CIL/Entities/IParameterizable.cs b/csharp/extractor/Semmle.Extraction.CIL/Entities/IParameterizable.cs new file mode 100644 index 00000000000..ad9347848e4 --- /dev/null +++ b/csharp/extractor/Semmle.Extraction.CIL/Entities/IParameterizable.cs @@ -0,0 +1,7 @@ +namespace Semmle.Extraction.CIL.Entities +{ + internal interface IParameterizable : IEntity + { + + } +} diff --git a/csharp/extractor/Semmle.Extraction.CIL/Entities/Instruction.cs b/csharp/extractor/Semmle.Extraction.CIL/Entities/Instruction.cs index 9512cfc5690..75d0aab454a 100644 --- a/csharp/extractor/Semmle.Extraction.CIL/Entities/Instruction.cs +++ b/csharp/extractor/Semmle.Extraction.CIL/Entities/Instruction.cs @@ -481,7 +481,7 @@ namespace Semmle.Extraction.CIL.Entities // TODO: Find a solution to this. // For now, just log the error - Cx.Cx.ExtractionError("A CIL instruction jumps outside the current method", "", Extraction.Entities.GeneratedLocation.Create(Cx.Cx), "", Util.Logging.Severity.Warning); + Cx.Cx.ExtractionError("A CIL instruction jumps outside the current method", null, Extraction.Entities.GeneratedLocation.Create(Cx.Cx), "", Util.Logging.Severity.Warning); } } } diff --git a/csharp/extractor/Semmle.Extraction.CIL/Entities/MemberReferenceMethod.cs b/csharp/extractor/Semmle.Extraction.CIL/Entities/MemberReferenceMethod.cs index f515f7190e6..cacbc6ab874 100644 --- a/csharp/extractor/Semmle.Extraction.CIL/Entities/MemberReferenceMethod.cs +++ b/csharp/extractor/Semmle.Extraction.CIL/Entities/MemberReferenceMethod.cs @@ -76,12 +76,16 @@ namespace Semmle.Extraction.CIL.Entities var typeSignature = mr.DecodeMethodSignature(Cx.TypeSignatureDecoder, this); - Parameters = MakeParameters(typeSignature.ParameterTypes).ToArray(); - foreach (var p in Parameters) yield return p; + var parameters = GetParameterExtractionProducts(typeSignature.ParameterTypes).ToArray(); + Parameters = parameters.OfType().ToArray(); + foreach (var p in parameters) yield return p; foreach (var f in PopulateFlags) yield return f; - yield return Tuples.cil_method(this, Name, DeclaringType, typeSignature.ReturnType); + foreach (var m in GetMethodExtractionProducts(Name, DeclaringType, typeSignature.ReturnType)) + { + yield return m; + } if (SourceDeclaration != null) yield return Tuples.cil_method_source_declaration(this, SourceDeclaration); diff --git a/csharp/extractor/Semmle.Extraction.CIL/Entities/Method.cs b/csharp/extractor/Semmle.Extraction.CIL/Entities/Method.cs index ade2189e665..30e94c8e16a 100644 --- a/csharp/extractor/Semmle.Extraction.CIL/Entities/Method.cs +++ b/csharp/extractor/Semmle.Extraction.CIL/Entities/Method.cs @@ -3,14 +3,13 @@ using System.Reflection.Metadata; using System.Collections.Generic; using System.Linq; using System.IO; -using Semmle.Util; namespace Semmle.Extraction.CIL.Entities { /// /// A method entity. /// - internal abstract class Method : TypeContainer, IMember + internal abstract class Method : TypeContainer, IMember, ICustomModifierReceiver, IParameterizable { protected MethodTypeParameter[]? genericParams; protected GenericContext gc; @@ -21,6 +20,8 @@ namespace Semmle.Extraction.CIL.Entities this.gc = gc; } + public ITypeSignature ReturnType => signature.ReturnType; + public override IEnumerable TypeParameters => gc.TypeParameters.Concat(DeclaringType.TypeParameters); public override IEnumerable MethodParameters => @@ -76,7 +77,7 @@ namespace Semmle.Extraction.CIL.Entities public abstract bool IsStatic { get; } - protected IEnumerable MakeParameters(IEnumerable parameterTypes) + protected IEnumerable GetParameterExtractionProducts(IEnumerable parameterTypes) { var i = 0; @@ -85,8 +86,51 @@ namespace Semmle.Extraction.CIL.Entities yield return Cx.Populate(new Parameter(Cx, this, i++, DeclaringType)); } + foreach (var p in GetParameterExtractionProducts(parameterTypes, this, this, Cx, i)) + { + yield return p; + } + } + + internal static IEnumerable GetParameterExtractionProducts(IEnumerable parameterTypes, IParameterizable parameterizable, ICustomModifierReceiver receiver, Context cx, int firstChildIndex) + { + var i = firstChildIndex; foreach (var p in parameterTypes) - yield return Cx.Populate(new Parameter(Cx, this, i++, p)); + { + var t = p; + if (t is ModifiedType mt) + { + t = mt.Unmodified; + yield return Tuples.cil_custom_modifiers(receiver, mt.Modifier, mt.IsRequired); + } + if (t is ByRefType brt) + { + t = brt.ElementType; + var parameter = cx.Populate(new Parameter(cx, parameterizable, i++, t)); + yield return parameter; + yield return Tuples.cil_type_annotation(parameter, TypeAnnotation.Ref); + } + else + { + yield return cx.Populate(new Parameter(cx, parameterizable, i++, t)); + } + } + } + + protected IEnumerable GetMethodExtractionProducts(string name, Type declaringType, Type returnType) + { + var t = returnType; + if (t is ModifiedType mt) + { + t = mt.Unmodified; + yield return Tuples.cil_custom_modifiers(this, mt.Modifier, mt.IsRequired); + } + if (t is ByRefType brt) + { + t = brt.ElementType; + yield return Tuples.cil_type_annotation(this, TypeAnnotation.Ref); + } + yield return Tuples.cil_method(this, name, declaringType, t); } } } diff --git a/csharp/extractor/Semmle.Extraction.CIL/Entities/MethodSpecificationMethod.cs b/csharp/extractor/Semmle.Extraction.CIL/Entities/MethodSpecificationMethod.cs index 60ec9f21bc4..26811ce6c80 100644 --- a/csharp/extractor/Semmle.Extraction.CIL/Entities/MethodSpecificationMethod.cs +++ b/csharp/extractor/Semmle.Extraction.CIL/Entities/MethodSpecificationMethod.cs @@ -77,14 +77,19 @@ namespace Semmle.Extraction.CIL.Entities throw new InternalError($"Unexpected constructed method handle kind {ms.Method.Kind}"); } - Parameters = MakeParameters(constructedTypeSignature.ParameterTypes).ToArray(); - foreach (var p in Parameters) + var parameters = GetParameterExtractionProducts(constructedTypeSignature.ParameterTypes).ToArray(); + Parameters = parameters.OfType().ToArray(); + foreach (var p in parameters) yield return p; foreach (var f in PopulateFlags) yield return f; - yield return Tuples.cil_method(this, Name, DeclaringType, constructedTypeSignature.ReturnType); + foreach (var m in GetMethodExtractionProducts(Name, DeclaringType, constructedTypeSignature.ReturnType)) + { + yield return m; + } + yield return Tuples.cil_method_source_declaration(this, SourceDeclaration); if (typeParams.Length != unboundMethod.GenericParameterCount) diff --git a/csharp/extractor/Semmle.Extraction.CIL/Entities/MethodTypeParameter.cs b/csharp/extractor/Semmle.Extraction.CIL/Entities/MethodTypeParameter.cs index 38790ce3827..db5e56acb17 100644 --- a/csharp/extractor/Semmle.Extraction.CIL/Entities/MethodTypeParameter.cs +++ b/csharp/extractor/Semmle.Extraction.CIL/Entities/MethodTypeParameter.cs @@ -41,8 +41,6 @@ namespace Semmle.Extraction.CIL.Entities public override IEnumerable TypeParameters => throw new NotImplementedException(); - public override IEnumerable MethodParameters => throw new NotImplementedException(); - public override IEnumerable Contents { get diff --git a/csharp/extractor/Semmle.Extraction.CIL/Entities/ModifiedType.cs b/csharp/extractor/Semmle.Extraction.CIL/Entities/ModifiedType.cs new file mode 100644 index 00000000000..f160c6869de --- /dev/null +++ b/csharp/extractor/Semmle.Extraction.CIL/Entities/ModifiedType.cs @@ -0,0 +1,49 @@ +using System; +using System.Collections.Generic; +using System.IO; + +namespace Semmle.Extraction.CIL.Entities +{ + /// + /// Modified types are not written directly to trap files. Instead, the modifiers are stored + /// on the modifiable entity (field type, property/method/function pointer parameter or return types). + /// + internal sealed class ModifiedType : Type + { + public ModifiedType(Context cx, Type unmodified, Type modifier, bool isRequired) : base(cx) + { + Unmodified = unmodified; + Modifier = modifier; + IsRequired = isRequired; + } + + public Type Unmodified { get; } + public Type Modifier { get; } + public bool IsRequired { get; } + + public override CilTypeKind Kind => throw new NotImplementedException(); + + public override Namespace? ContainingNamespace => throw new NotImplementedException(); + + public override Type? ContainingType => throw new NotImplementedException(); + + public override IEnumerable TypeParameters => throw new NotImplementedException(); + + public override int ThisTypeParameterCount => throw new NotImplementedException(); + + public override Type Construct(IEnumerable typeArguments) => throw new NotImplementedException(); + + public override string Name => $"{Unmodified.Name} {(IsRequired ? "modreq" : "modopt")}({Modifier.Name})"; + + public override void WriteAssemblyPrefix(TextWriter trapFile) => throw new NotImplementedException(); + + public override void WriteId(TextWriter trapFile, bool inContext) + { + Unmodified.WriteId(trapFile, inContext); + trapFile.Write(IsRequired ? " modreq" : " modopt"); + trapFile.Write("("); + Modifier.WriteId(trapFile, inContext); + trapFile.Write(")"); + } + } +} diff --git a/csharp/extractor/Semmle.Extraction.CIL/Entities/NamedTypeIdWriter.cs b/csharp/extractor/Semmle.Extraction.CIL/Entities/NamedTypeIdWriter.cs new file mode 100644 index 00000000000..98f9e94ec82 --- /dev/null +++ b/csharp/extractor/Semmle.Extraction.CIL/Entities/NamedTypeIdWriter.cs @@ -0,0 +1,62 @@ +using System.Linq; +using System.IO; + +namespace Semmle.Extraction.CIL.Entities +{ + internal class NamedTypeIdWriter + { + private readonly Type type; + + public NamedTypeIdWriter(Type type) + { + this.type = type; + } + + public void WriteId(TextWriter trapFile, bool inContext) + { + if (type.IsPrimitiveType) + { + Type.WritePrimitiveTypeId(trapFile, type.Name); + return; + } + + var ct = type.ContainingType; + if (ct != null) + { + ct.WriteId(trapFile, inContext); + trapFile.Write('.'); + } + else + { + type.WriteAssemblyPrefix(trapFile); + + var ns = type.ContainingNamespace!; + if (!ns.IsGlobalNamespace) + { + ns.WriteId(trapFile); + trapFile.Write('.'); + } + } + + trapFile.Write(type.Name); + + var thisTypeArguments = type.ThisTypeArguments; + if (thisTypeArguments != null && thisTypeArguments.Any()) + { + trapFile.Write('<'); + var index = 0; + foreach (var t in thisTypeArguments) + { + trapFile.WriteSeparator(",", ref index); + t.WriteId(trapFile); + } + trapFile.Write('>'); + } + else if (type.ThisTypeParameterCount > 0) + { + trapFile.Write('`'); + trapFile.Write(type.ThisTypeParameterCount); + } + } + } +} diff --git a/csharp/extractor/Semmle.Extraction.CIL/Entities/NoMetadataHandleType.FullyQualifiedNameParser.cs b/csharp/extractor/Semmle.Extraction.CIL/Entities/NoMetadataHandleType.FullyQualifiedNameParser.cs new file mode 100644 index 00000000000..999259e9ad6 --- /dev/null +++ b/csharp/extractor/Semmle.Extraction.CIL/Entities/NoMetadataHandleType.FullyQualifiedNameParser.cs @@ -0,0 +1,163 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using Semmle.Util; + +namespace Semmle.Extraction.CIL.Entities +{ + internal sealed partial class NoMetadataHandleType + { + /// + /// Parser to split a fully qualified name into short name, namespace or declaring type name, assembly name, and + /// type argument names. Names are in the following format: + /// N1.N2.T1`2+T2`2[T3,[T4, A1, Version=...],T5,T6], A2, Version=... + /// + /// + /// typeof(System.Collections.Generic.List.Enumerator) + /// -> System.Collections.Generic.List`1+Enumerator[[System.Int32, System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]], System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e + /// typeof(System.Collections.Generic.List<>.Enumerator) + /// -> System.Collections.Generic.List`1+Enumerator, System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e + /// + /// + private class FullyQualifiedNameParser + { + public string ShortName { get; internal set; } + public string? AssemblyName { get; private set; } + public IEnumerable? TypeArguments { get; internal set; } + public string? UnboundGenericTypeName { get; internal set; } + public string ContainerName { get; internal set; } + public bool IsContainerNamespace { get; internal set; } + + private string AssemblySuffix => string.IsNullOrWhiteSpace(AssemblyName) ? "" : $", {AssemblyName}"; + + public FullyQualifiedNameParser(string name) + { + ExtractAssemblyName(ref name, out var lastBracketIndex); + ExtractTypeArguments(ref name, lastBracketIndex, out var containerTypeArguments); + ContainerName = ExtractContainer(ref name, containerTypeArguments); + + ShortName = name; + } + + private void ExtractTypeArguments(ref string name, int lastBracketIndex, out string containerTypeArguments) + { + var firstBracketIndex = name.IndexOf('['); + if (firstBracketIndex < 0) + { + // not generic or non-constructed generic + TypeArguments = null; + containerTypeArguments = ""; + UnboundGenericTypeName = null; + return; + } + + // "T3,[T4, Assembly1, Version=...],T5,T6" + string typeArgs; + (name, _, typeArgs, _) = name.Split(firstBracketIndex, firstBracketIndex + 1, lastBracketIndex - firstBracketIndex - 1); + + var thisTypeArgCount = GenericsHelper.GetGenericTypeParameterCount(name); + if (thisTypeArgCount == 0) + { + // not generic or non-constructed generic; container is constructed + TypeArguments = null; + containerTypeArguments = $"[{typeArgs}]"; + UnboundGenericTypeName = null; + return; + } + + // constructed generic + // "T3,[T4, Assembly1, Version=...]", ["T5", "T6"] + var (containerTypeArgs, thisTypeArgs) = ParseTypeArgumentStrings(typeArgs, thisTypeArgCount); + + TypeArguments = thisTypeArgs; + + containerTypeArguments = string.IsNullOrWhiteSpace(containerTypeArgs) + ? "" // containing type is not constructed generics + : $"[{containerTypeArgs}]"; // "T3,[T4, Assembly1, Version=...],,]" + + UnboundGenericTypeName = $"{name}{AssemblySuffix}"; + } + + private string ExtractContainer(ref string name, string containerTypeArguments) + { + var lastPlusIndex = name.LastIndexOf('+'); + IsContainerNamespace = lastPlusIndex < 0; + if (IsContainerNamespace) + { + return ExtractContainerNamespace(ref name); + } + + return ExtractContainerType(ref name, containerTypeArguments, lastPlusIndex); + } + + private static string ExtractContainerNamespace(ref string name) + { + var lastDotIndex = name.LastIndexOf('.'); + if (lastDotIndex >= 0) + { + string containerName; + (containerName, _, name) = name.Split(lastDotIndex, lastDotIndex + 1); + return containerName; + } + + return ""; // global namespace name + } + + private string ExtractContainerType(ref string name, string containerTypeArguments, int lastPlusIndex) + { + string containerName; + (containerName, _, name) = name.Split(lastPlusIndex, lastPlusIndex + 1); + return $"{containerName}{containerTypeArguments}{AssemblySuffix}"; + } + + private void ExtractAssemblyName(ref string name, out int lastBracketIndex) + { + lastBracketIndex = name.LastIndexOf(']'); + var assemblyCommaIndex = name.IndexOf(',', lastBracketIndex < 0 ? 0 : lastBracketIndex); + if (assemblyCommaIndex >= 0) + { + // "Assembly2, Version=..." + (name, _, AssemblyName) = name.Split(assemblyCommaIndex, assemblyCommaIndex + 2); + } + } + + private static (string, IEnumerable) ParseTypeArgumentStrings(string typeArgs, int thisTypeArgCount) + { + var thisTypeArgs = new Stack(thisTypeArgCount); + while (typeArgs.Length > 0 && thisTypeArgCount > 0) + { + int startCurrentType; + if (typeArgs[^1] != ']') + { + startCurrentType = typeArgs.LastIndexOf(',') + 1; + thisTypeArgs.Push(typeArgs.Substring(startCurrentType)); + } + else + { + var bracketCount = 1; + for (startCurrentType = typeArgs.Length - 2; startCurrentType >= 0 && bracketCount > 0; startCurrentType--) + { + if (typeArgs[startCurrentType] == ']') + { + bracketCount++; + } + else if (typeArgs[startCurrentType] == '[') + { + bracketCount--; + } + } + startCurrentType++; + thisTypeArgs.Push(typeArgs[(startCurrentType + 1)..^1]); + } + + typeArgs = startCurrentType != 0 + ? typeArgs.Substring(0, startCurrentType - 1) + : ""; + + thisTypeArgCount--; + } + return (typeArgs, thisTypeArgs.ToList()); + } + } + } +} diff --git a/csharp/extractor/Semmle.Extraction.CIL/Entities/NoMetadataHandleType.cs b/csharp/extractor/Semmle.Extraction.CIL/Entities/NoMetadataHandleType.cs new file mode 100644 index 00000000000..c1259534f79 --- /dev/null +++ b/csharp/extractor/Semmle.Extraction.CIL/Entities/NoMetadataHandleType.cs @@ -0,0 +1,161 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Reflection; + +namespace Semmle.Extraction.CIL.Entities +{ + internal sealed partial class NoMetadataHandleType : Type + { + private readonly string originalName; + private readonly string name; + private readonly string? assemblyName; + private readonly string containerName; + private readonly bool isContainerNamespace; + + private readonly Lazy? typeParams; + + // Either null or notEmpty + private readonly Type[]? thisTypeArguments; + private readonly Type unboundGenericType; + private readonly Type? containingType; + private readonly Namespace? containingNamespace; + + private readonly NamedTypeIdWriter idWriter; + + public NoMetadataHandleType(Context cx, string originalName) : base(cx) + { + this.originalName = originalName; + this.idWriter = new NamedTypeIdWriter(this); + + var nameParser = new FullyQualifiedNameParser(originalName); + + name = nameParser.ShortName; + assemblyName = nameParser.AssemblyName; + isContainerNamespace = nameParser.IsContainerNamespace; + containerName = nameParser.ContainerName; + + unboundGenericType = nameParser.UnboundGenericTypeName == null + ? this + : new NoMetadataHandleType(Cx, nameParser.UnboundGenericTypeName); + + if (nameParser.TypeArguments != null) + { + thisTypeArguments = nameParser.TypeArguments.Select(t => new NoMetadataHandleType(Cx, t)).ToArray(); + } + else + { + typeParams = new Lazy(GenericsHelper.MakeTypeParameters(this, ThisTypeParameterCount)); + } + + containingType = isContainerNamespace + ? null + : new NoMetadataHandleType(Cx, containerName); + + containingNamespace = isContainerNamespace + ? containerName == Cx.GlobalNamespace.Name + ? Cx.GlobalNamespace + : containerName == Cx.SystemNamespace.Name + ? Cx.SystemNamespace + : new Namespace(Cx, containerName) + : null; + + Populate(); + } + + private void Populate() + { + if (ContainingNamespace is object) + { + Cx.Populate(ContainingNamespace); + } + + Cx.Populate(this); + } + + public override bool Equals(object? obj) + { + return obj is NoMetadataHandleType t && originalName.Equals(t.originalName, StringComparison.Ordinal); + } + + public override int GetHashCode() + { + return originalName.GetHashCode(StringComparison.Ordinal); + } + + public override IEnumerable Contents + { + get + { + foreach (var tp in typeParams?.Value ?? Array.Empty()) + yield return tp; + + foreach (var c in base.Contents) + yield return c; + + var i = 0; + foreach (var type in ThisTypeArguments) + { + yield return type; + yield return Tuples.cil_type_argument(this, i++, type); + } + } + } + + public override CilTypeKind Kind => CilTypeKind.ValueOrRefType; + + public override string Name => GenericsHelper.GetNonGenericName(name); + + public override Namespace? ContainingNamespace => containingNamespace; + + public override Type? ContainingType => containingType; + + public override Type SourceDeclaration => unboundGenericType; + + public override Type Construct(IEnumerable typeArguments) + { + if (TotalTypeParametersCount != typeArguments.Count()) + throw new InternalError("Mismatched type arguments"); + + return Cx.Populate(new ConstructedType(Cx, this, typeArguments)); + } + + public override void WriteAssemblyPrefix(TextWriter trapFile) + { + if (!string.IsNullOrWhiteSpace(assemblyName)) + { + var an = new AssemblyName(assemblyName); + trapFile.Write(an.Name); + trapFile.Write('_'); + trapFile.Write((an.Version ?? new Version(0, 0, 0, 0)).ToString()); + trapFile.Write(Type.AssemblyTypeNameSeparator); + } + else + { + Cx.WriteAssemblyPrefix(trapFile); + } + } + + public override void WriteId(TextWriter trapFile, bool inContext) + { + idWriter.WriteId(trapFile, inContext); + } + + public override int ThisTypeParameterCount => unboundGenericType == this + ? GenericsHelper.GetGenericTypeParameterCount(name) + : thisTypeArguments!.Length; + + public override IEnumerable TypeParameters => unboundGenericType == this + ? GenericsHelper.GetAllTypeParameters(containingType, typeParams!.Value) + : GenericArguments; + + public override IEnumerable ThisTypeArguments => unboundGenericType == this + ? base.ThisTypeArguments + : thisTypeArguments!; + + public override IEnumerable ThisGenericArguments => unboundGenericType == this + ? typeParams!.Value + : thisTypeArguments!; + } +} diff --git a/csharp/extractor/Semmle.Extraction.CIL/Entities/Parameter.cs b/csharp/extractor/Semmle.Extraction.CIL/Entities/Parameter.cs index dea5f2db30b..90452fe9265 100644 --- a/csharp/extractor/Semmle.Extraction.CIL/Entities/Parameter.cs +++ b/csharp/extractor/Semmle.Extraction.CIL/Entities/Parameter.cs @@ -8,11 +8,11 @@ namespace Semmle.Extraction.CIL.Entities /// internal sealed class Parameter : LabelledEntity { - private readonly Method method; + private readonly IParameterizable method; private readonly int index; private readonly Type type; - public Parameter(Context cx, Method m, int i, Type t) : base(cx) + public Parameter(Context cx, IParameterizable m, int i, Type t) : base(cx) { method = m; index = i; diff --git a/csharp/extractor/Semmle.Extraction.CIL/Entities/PointerType.cs b/csharp/extractor/Semmle.Extraction.CIL/Entities/PointerType.cs index 2f12de982ef..8b1209925b6 100644 --- a/csharp/extractor/Semmle.Extraction.CIL/Entities/PointerType.cs +++ b/csharp/extractor/Semmle.Extraction.CIL/Entities/PointerType.cs @@ -18,11 +18,7 @@ namespace Semmle.Extraction.CIL.Entities return obj is PointerType pt && pointee.Equals(pt.pointee); } - - public override int GetHashCode() - { - return pointee.GetHashCode() * 29; - } + public override int GetHashCode() => HashCode.Combine(pointee, nameof(PointerType)); public override void WriteId(TextWriter trapFile, bool inContext) { @@ -32,13 +28,13 @@ namespace Semmle.Extraction.CIL.Entities public override string Name => pointee.Name + "*"; - public override Namespace? Namespace => pointee.Namespace; + public override Namespace? ContainingNamespace => pointee.ContainingNamespace; public override Type? ContainingType => pointee.ContainingType; public override TypeContainer Parent => pointee.Parent; - public override int ThisTypeParameters => 0; + public override int ThisTypeParameterCount => 0; public override CilTypeKind Kind => CilTypeKind.Pointer; @@ -46,8 +42,6 @@ namespace Semmle.Extraction.CIL.Entities public override IEnumerable TypeParameters => throw new NotImplementedException(); - public override IEnumerable MethodParameters => throw new NotImplementedException(); - public override Type Construct(IEnumerable typeArguments) => throw new NotImplementedException(); public override IEnumerable Contents diff --git a/csharp/extractor/Semmle.Extraction.CIL/Entities/PrimitiveType.cs b/csharp/extractor/Semmle.Extraction.CIL/Entities/PrimitiveType.cs index 5ec0911c5ef..661ae0f535b 100644 --- a/csharp/extractor/Semmle.Extraction.CIL/Entities/PrimitiveType.cs +++ b/csharp/extractor/Semmle.Extraction.CIL/Entities/PrimitiveType.cs @@ -18,24 +18,20 @@ namespace Semmle.Extraction.CIL.Entities return obj is PrimitiveType pt && typeCode == pt.typeCode; } - public override int GetHashCode() - { - return 1337 * (int)typeCode; - } + public override int GetHashCode() => typeCode.GetHashCode(); public override void WriteId(TextWriter trapFile, bool inContext) { - trapFile.Write("builtin:"); - trapFile.Write(Name); + Type.WritePrimitiveTypeId(trapFile, Name); } public override string Name => typeCode.Id(); - public override Namespace Namespace => Cx.SystemNamespace; + public override Namespace ContainingNamespace => Cx.SystemNamespace; public override Type? ContainingType => null; - public override int ThisTypeParameters => 0; + public override int ThisTypeParameterCount => 0; public override CilTypeKind Kind => CilTypeKind.ValueOrRefType; @@ -43,8 +39,6 @@ namespace Semmle.Extraction.CIL.Entities public override IEnumerable TypeParameters => throw new NotImplementedException(); - public override IEnumerable MethodParameters => throw new NotImplementedException(); - public override Type Construct(IEnumerable typeArguments) => throw new NotImplementedException(); } } diff --git a/csharp/extractor/Semmle.Extraction.CIL/Entities/Property.cs b/csharp/extractor/Semmle.Extraction.CIL/Entities/Property.cs index 6fc588b1d34..5fb22b40409 100644 --- a/csharp/extractor/Semmle.Extraction.CIL/Entities/Property.cs +++ b/csharp/extractor/Semmle.Extraction.CIL/Entities/Property.cs @@ -8,7 +8,7 @@ namespace Semmle.Extraction.CIL.Entities /// /// A property. /// - internal sealed class Property : LabelledEntity + internal sealed class Property : LabelledEntity, ICustomModifierReceiver { private readonly Handle handle; private readonly Type type; @@ -54,7 +54,20 @@ namespace Semmle.Extraction.CIL.Entities yield return Tuples.metadata_handle(this, Cx.Assembly, MetadataTokens.GetToken(handle)); var sig = pd.DecodeSignature(Cx.TypeSignatureDecoder, type); - yield return Tuples.cil_property(this, type, Cx.ShortName(pd.Name), sig.ReturnType); + var name = Cx.ShortName(pd.Name); + + var t = sig.ReturnType; + if (t is ModifiedType mt) + { + t = mt.Unmodified; + yield return Tuples.cil_custom_modifiers(this, mt.Modifier, mt.IsRequired); + } + if (t is ByRefType brt) + { + t = brt.ElementType; + yield return Tuples.cil_type_annotation(this, TypeAnnotation.Ref); + } + yield return Tuples.cil_property(this, type, name, t); var accessors = pd.GetAccessors(); if (!accessors.Getter.IsNil) diff --git a/csharp/extractor/Semmle.Extraction.CIL/Entities/SignatureDecoder.cs b/csharp/extractor/Semmle.Extraction.CIL/Entities/SignatureDecoder.cs index fcb860b6d13..a955ef685c0 100644 --- a/csharp/extractor/Semmle.Extraction.CIL/Entities/SignatureDecoder.cs +++ b/csharp/extractor/Semmle.Extraction.CIL/Entities/SignatureDecoder.cs @@ -22,7 +22,9 @@ namespace Semmle.Extraction.CIL.Entities elementType.WriteId(trapFile, gc); trapFile.Write('['); for (var i = 1; i < shape.Rank; ++i) + { trapFile.Write(','); + } trapFile.Write(']'); } } @@ -38,17 +40,27 @@ namespace Semmle.Extraction.CIL.Entities public void WriteId(TextWriter trapFile, GenericContext gc) { - trapFile.Write("ref "); elementType.WriteId(trapFile, gc); + trapFile.Write('&'); } } private struct FnPtr : ITypeSignature { + private readonly MethodSignature signature; + + public FnPtr(MethodSignature signature) + { + this.signature = signature; + } public void WriteId(TextWriter trapFile, GenericContext gc) { - trapFile.Write(""); + FunctionPointerType.WriteName( + trapFile.Write, + t => t.WriteId(trapFile, gc), + signature + ); } } @@ -59,7 +71,7 @@ namespace Semmle.Extraction.CIL.Entities new ByRef(elementType); ITypeSignature ISignatureTypeProvider.GetFunctionPointerType(MethodSignature signature) => - new FnPtr(); + new FnPtr(signature); private class Instantiation : ITypeSignature { @@ -136,42 +148,33 @@ namespace Semmle.Extraction.CIL.Entities private class Modified : ITypeSignature { private readonly ITypeSignature unmodifiedType; + private readonly ITypeSignature modifier; + private readonly bool isRequired; - public Modified(ITypeSignature unmodifiedType) + public Modified(ITypeSignature unmodifiedType, ITypeSignature modifier, bool isRequired) { this.unmodifiedType = unmodifiedType; + this.modifier = modifier; + this.isRequired = isRequired; } public void WriteId(TextWriter trapFile, GenericContext gc) { unmodifiedType.WriteId(trapFile, gc); + trapFile.Write(isRequired ? " modreq(" : " modopt("); + modifier.WriteId(trapFile, gc); + trapFile.Write(")"); } } ITypeSignature ISignatureTypeProvider.GetModifiedType(ITypeSignature modifier, ITypeSignature unmodifiedType, bool isRequired) { - return new Modified(unmodifiedType); - } - - private class Pinned : ITypeSignature - { - private readonly ITypeSignature elementType; - - public Pinned(ITypeSignature elementType) - { - this.elementType = elementType; - } - - public void WriteId(TextWriter trapFile, GenericContext gc) - { - trapFile.Write("pinned "); - elementType.WriteId(trapFile, gc); - } + return new Modified(unmodifiedType, modifier, isRequired); } ITypeSignature ISignatureTypeProvider.GetPinnedType(ITypeSignature elementType) { - return new Pinned(elementType); + return elementType; } private class PointerType : ITypeSignature diff --git a/csharp/extractor/Semmle.Extraction.CIL/Entities/Type.cs b/csharp/extractor/Semmle.Extraction.CIL/Entities/Type.cs index 5434e55aa69..edeb1a54136 100644 --- a/csharp/extractor/Semmle.Extraction.CIL/Entities/Type.cs +++ b/csharp/extractor/Semmle.Extraction.CIL/Entities/Type.cs @@ -1,8 +1,8 @@ using System.Reflection.Metadata; using System.Collections.Generic; -using Semmle.Util; using System.IO; using System.Diagnostics.CodeAnalysis; +using System.Linq; namespace Semmle.Extraction.CIL.Entities { @@ -12,8 +12,10 @@ namespace Semmle.Extraction.CIL.Entities public abstract class Type : TypeContainer, IMember { public override string IdSuffix => ";cil-type"; + internal const string AssemblyTypeNameSeparator = "::"; + internal const string PrimitiveTypePrefix = "builtin" + AssemblyTypeNameSeparator + "System."; - public sealed override void WriteId(TextWriter trapFile) => WriteId(trapFile, false); + protected Type(Context cx) : base(cx) { } /// /// Find the method in this type matching the name and signature. @@ -29,29 +31,6 @@ namespace Semmle.Extraction.CIL.Entities return null; } - public IEnumerable TypeArguments - { - get - { - if (ContainingType != null) - { - foreach (var t in ContainingType.TypeArguments) - yield return t; - } - foreach (var t in ThisTypeArguments) - yield return t; - - } - } - - public virtual IEnumerable ThisTypeArguments - { - get - { - yield break; - } - } - /// /// Writes the assembly identifier of this type. /// @@ -67,22 +46,24 @@ namespace Semmle.Extraction.CIL.Entities /// public abstract void WriteId(TextWriter trapFile, bool inContext); - public void GetId(TextWriter trapFile, bool inContext) + public sealed override void WriteId(TextWriter trapFile) => WriteId(trapFile, false); + + /// + /// Returns the friendly qualified name of types, such as + /// ``"System.Collection.Generic.List`1"`` or + /// ``"System.Collection.Generic.List"``. + /// + /// Note that method/type generic type parameters never show up in the returned name. + /// + public string GetQualifiedName() { - if (inContext) - WriteId(trapFile, true); - else - WriteId(trapFile); + using var writer = new StringWriter(); + WriteId(writer, false); + var name = writer.ToString(); + return name.Substring(name.IndexOf(AssemblyTypeNameSeparator) + 2); } - protected Type(Context cx) : base(cx) { } - - public abstract CilTypeKind Kind - { - get; - } - - public virtual TypeContainer Parent => (TypeContainer?)ContainingType ?? Namespace!; + public abstract CilTypeKind Kind { get; } public override IEnumerable Contents { @@ -92,35 +73,43 @@ namespace Semmle.Extraction.CIL.Entities } } - /// - /// Whether this type is visible outside the current assembly. - /// - public virtual bool IsVisible => true; - public abstract string Name { get; } - public abstract Namespace? Namespace { get; } + public abstract Namespace? ContainingNamespace { get; } public abstract Type? ContainingType { get; } + public virtual TypeContainer Parent => (TypeContainer?)ContainingType ?? ContainingNamespace!; + public abstract Type Construct(IEnumerable typeArguments); /// - /// The number of type arguments, or 0 if this isn't generic. - /// The containing type may also have type arguments. + /// Returns the type arguments of constructed types. For non-constructed types it returns an + /// empty collection. /// - public abstract int ThisTypeParameters { get; } + public virtual IEnumerable ThisTypeArguments + { + get + { + yield break; + } + } /// - /// The total number of type parameters (including parent types). + /// The number of type parameters for non-constructed generic types, the number of type arguments + /// for constructed types, or 0. + /// + public abstract int ThisTypeParameterCount { get; } + + /// + /// The total number of type parameters/type arguments (including parent types). /// This is used for internal consistency checking only. /// - public int TotalTypeParametersCheck => - ContainingType == null ? ThisTypeParameters : ThisTypeParameters + ContainingType.TotalTypeParametersCheck; + public int TotalTypeParametersCount => + ThisTypeParameterCount + (ContainingType?.TotalTypeParametersCount ?? 0); /// - /// Returns all bound/unbound generic arguments - /// of a constructed/unbound generic type. + /// Returns all bound/unbound generic arguments of a constructed/unbound generic type. /// public virtual IEnumerable ThisGenericArguments { @@ -139,6 +128,7 @@ namespace Semmle.Extraction.CIL.Entities foreach (var t in ContainingType.GenericArguments) yield return t; } + foreach (var t in ThisGenericArguments) yield return t; } @@ -146,12 +136,34 @@ namespace Semmle.Extraction.CIL.Entities public virtual Type SourceDeclaration => this; - public void PrimitiveTypeId(TextWriter trapFile) + public static void WritePrimitiveTypeId(TextWriter trapFile, string name) { - trapFile.Write("builtin:"); - trapFile.Write(Name); + trapFile.Write(PrimitiveTypePrefix); + trapFile.Write(name); } + private static readonly Dictionary primitiveTypeCodeMapping = new Dictionary + { + {"Boolean", PrimitiveTypeCode.Boolean}, + {"Object", PrimitiveTypeCode.Object}, + {"Byte", PrimitiveTypeCode.Byte}, + {"SByte", PrimitiveTypeCode.SByte}, + {"Int16", PrimitiveTypeCode.Int16}, + {"UInt16", PrimitiveTypeCode.UInt16}, + {"Int32", PrimitiveTypeCode.Int32}, + {"UInt32", PrimitiveTypeCode.UInt32}, + {"Int64", PrimitiveTypeCode.Int64}, + {"UInt64", PrimitiveTypeCode.UInt64}, + {"Single", PrimitiveTypeCode.Single}, + {"Double", PrimitiveTypeCode.Double}, + {"String", PrimitiveTypeCode.String}, + {"Void", PrimitiveTypeCode.Void}, + {"IntPtr", PrimitiveTypeCode.IntPtr}, + {"UIntPtr", PrimitiveTypeCode.UIntPtr}, + {"Char", PrimitiveTypeCode.Char}, + {"TypedReference", PrimitiveTypeCode.TypedReference} + }; + /// /// Gets the primitive type corresponding to this type, if possible. /// @@ -171,72 +183,20 @@ namespace Semmle.Extraction.CIL.Entities private bool TryGetPrimitiveTypeCode(out PrimitiveTypeCode code) { - if (ContainingType == null && Namespace?.Name == Cx.SystemNamespace.Name) + if (ContainingType == null && + ContainingNamespace?.Name == Cx.SystemNamespace.Name && + primitiveTypeCodeMapping.TryGetValue(Name, out code)) { - switch (Name) - { - case "Boolean": - code = PrimitiveTypeCode.Boolean; - return true; - case "Object": - code = PrimitiveTypeCode.Object; - return true; - case "Byte": - code = PrimitiveTypeCode.Byte; - return true; - case "SByte": - code = PrimitiveTypeCode.SByte; - return true; - case "Int16": - code = PrimitiveTypeCode.Int16; - return true; - case "UInt16": - code = PrimitiveTypeCode.UInt16; - return true; - case "Int32": - code = PrimitiveTypeCode.Int32; - return true; - case "UInt32": - code = PrimitiveTypeCode.UInt32; - return true; - case "Int64": - code = PrimitiveTypeCode.Int64; - return true; - case "UInt64": - code = PrimitiveTypeCode.UInt64; - return true; - case "Single": - code = PrimitiveTypeCode.Single; - return true; - case "Double": - code = PrimitiveTypeCode.Double; - return true; - case "String": - code = PrimitiveTypeCode.String; - return true; - case "Void": - code = PrimitiveTypeCode.Void; - return true; - case "IntPtr": - code = PrimitiveTypeCode.IntPtr; - return true; - case "UIntPtr": - code = PrimitiveTypeCode.UIntPtr; - return true; - case "Char": - code = PrimitiveTypeCode.Char; - return true; - case "TypedReference": - code = PrimitiveTypeCode.TypedReference; - return true; - } + return true; } - code = default(PrimitiveTypeCode); + code = default; return false; } - protected bool IsPrimitiveType => TryGetPrimitiveTypeCode(out _); + protected internal bool IsPrimitiveType => TryGetPrimitiveTypeCode(out _); + + public sealed override IEnumerable MethodParameters => Enumerable.Empty(); public static Type DecodeType(GenericContext gc, TypeSpecificationHandle handle) => gc.Cx.MdReader.GetTypeSpecification(handle).DecodeSignature(gc.Cx.TypeSignatureDecoder, gc); diff --git a/csharp/extractor/Semmle.Extraction.CIL/Entities/TypeAnnotation.cs b/csharp/extractor/Semmle.Extraction.CIL/Entities/TypeAnnotation.cs new file mode 100644 index 00000000000..fe005326b95 --- /dev/null +++ b/csharp/extractor/Semmle.Extraction.CIL/Entities/TypeAnnotation.cs @@ -0,0 +1,11 @@ +using System; + +namespace Semmle.Extraction.CIL.Entities +{ + [Flags] + public enum TypeAnnotation + { + None = 0, + Ref = 32 + } +} diff --git a/csharp/extractor/Semmle.Extraction.CIL/Entities/TypeDefinitionType.cs b/csharp/extractor/Semmle.Extraction.CIL/Entities/TypeDefinitionType.cs index 61a761b4cba..461141ae719 100644 --- a/csharp/extractor/Semmle.Extraction.CIL/Entities/TypeDefinitionType.cs +++ b/csharp/extractor/Semmle.Extraction.CIL/Entities/TypeDefinitionType.cs @@ -1,11 +1,10 @@ using System; -using Microsoft.CodeAnalysis; -using System.Reflection.Metadata; -using System.Collections.Immutable; using System.Linq; using System.Collections.Generic; using System.Reflection; using System.IO; +using System.Reflection.Metadata.Ecma335; +using System.Reflection.Metadata; namespace Semmle.Extraction.CIL.Entities { @@ -14,11 +13,15 @@ namespace Semmle.Extraction.CIL.Entities /// public sealed class TypeDefinitionType : Type { - private readonly Handle handle; + private readonly TypeDefinitionHandle handle; private readonly TypeDefinition td; + private readonly Lazy> typeParams; + private readonly Type? declType; + private readonly NamedTypeIdWriter idWriter; public TypeDefinitionType(Context cx, TypeDefinitionHandle handle) : base(cx) { + idWriter = new NamedTypeIdWriter(this); td = cx.MdReader.GetTypeDefinition(handle); this.handle = handle; @@ -39,66 +42,22 @@ namespace Semmle.Extraction.CIL.Entities public override void WriteId(TextWriter trapFile, bool inContext) { - if (IsPrimitiveType) - { - PrimitiveTypeId(trapFile); - return; - } - - var name = Cx.GetString(td.Name); - - if (ContainingType != null) - { - ContainingType.GetId(trapFile, inContext); - trapFile.Write('.'); - } - else - { - WriteAssemblyPrefix(trapFile); - - var ns = Namespace; - if (!ns.IsGlobalNamespace) - { - ns.WriteId(trapFile); - trapFile.Write('.'); - } - } - - trapFile.Write(name); + idWriter.WriteId(trapFile, inContext); } - public override string Name - { - get - { - var name = Cx.GetString(td.Name); - var tick = name.IndexOf('`'); - return tick == -1 ? name : name.Substring(0, tick); - } - } + public override string Name => GenericsHelper.GetNonGenericName(td.Name, Cx.MdReader); - public override Namespace Namespace => Cx.Create(td.NamespaceDefinition); - - private readonly Type? declType; + public override Namespace ContainingNamespace => Cx.Create(td.NamespaceDefinition); public override Type? ContainingType => declType; - public override int ThisTypeParameters - { - get - { - var containingType = td.GetDeclaringType(); - var parentTypeParameters = containingType.IsNil ? 0 : - Cx.MdReader.GetTypeDefinition(containingType).GetGenericParameters().Count; - - return td.GetGenericParameters().Count - parentTypeParameters; - } - } - public override CilTypeKind Kind => CilTypeKind.ValueOrRefType; public override Type Construct(IEnumerable typeArguments) { + if (TotalTypeParametersCount != typeArguments.Count()) + throw new InternalError("Mismatched type arguments"); + return Cx.Populate(new ConstructedType(Cx, this, typeArguments)); } @@ -108,52 +67,50 @@ namespace Semmle.Extraction.CIL.Entities if (ct is null) Cx.WriteAssemblyPrefix(trapFile); else if (IsPrimitiveType) - trapFile.Write("builtin:"); + trapFile.Write(Type.PrimitiveTypePrefix); else ct.WriteAssemblyPrefix(trapFile); } private IEnumerable MakeTypeParameters() { - if (ThisTypeParameters == 0) + if (ThisTypeParameterCount == 0) return Enumerable.Empty(); - var newTypeParams = new TypeTypeParameter[ThisTypeParameters]; + var newTypeParams = new TypeTypeParameter[ThisTypeParameterCount]; var genericParams = td.GetGenericParameters(); var toSkip = genericParams.Count - newTypeParams.Length; // Two-phase population because type parameters can be mutually dependent for (var i = 0; i < newTypeParams.Length; ++i) - newTypeParams[i] = Cx.Populate(new TypeTypeParameter(this, this, i)); + newTypeParams[i] = Cx.Populate(new TypeTypeParameter(this, i)); for (var i = 0; i < newTypeParams.Length; ++i) newTypeParams[i].PopulateHandle(genericParams[i + toSkip]); return newTypeParams; } - private readonly Lazy> typeParams; - - public override IEnumerable MethodParameters => Enumerable.Empty(); - - public override IEnumerable TypeParameters + public override int ThisTypeParameterCount { get { - if (declType != null) - { - foreach (var t in declType.TypeParameters) - yield return t; - } + var containingType = td.GetDeclaringType(); + var parentTypeParameters = containingType.IsNil + ? 0 + : Cx.MdReader.GetTypeDefinition(containingType).GetGenericParameters().Count; - foreach (var t in typeParams.Value) - yield return t; + return td.GetGenericParameters().Count - parentTypeParameters; } } + public override IEnumerable TypeParameters => GenericsHelper.GetAllTypeParameters(declType, typeParams!.Value); + + public override IEnumerable ThisGenericArguments => typeParams.Value; + public override IEnumerable Contents { get { - yield return Tuples.metadata_handle(this, Cx.Assembly, handle.GetHashCode()); + yield return Tuples.metadata_handle(this, Cx.Assembly, MetadataTokens.GetToken(handle)); foreach (var c in base.Contents) yield return c; @@ -212,6 +169,15 @@ namespace Semmle.Extraction.CIL.Entities var @base = (Type)Cx.CreateGeneric(this, td.BaseType); yield return @base; yield return Tuples.cil_base_class(this, @base); + + if (IsSystemEnum(td.BaseType) && + GetUnderlyingEnumType() is var underlying && + underlying.HasValue) + { + var underlyingType = Cx.Create(underlying.Value); + yield return underlyingType; + yield return Tuples.cil_enum_underlying_type(this, underlyingType); + } } foreach (var @interface in td.GetInterfaceImplementations().Select(i => Cx.MdReader.GetInterfaceImplementation(i))) @@ -226,6 +192,59 @@ namespace Semmle.Extraction.CIL.Entities } } + private bool IsSystemEnum(EntityHandle baseType) + { + return baseType.Kind switch + { + HandleKind.TypeReference => IsSystemEnum((TypeReferenceHandle)baseType), + HandleKind.TypeDefinition => IsSystemEnum((TypeDefinitionHandle)baseType), + _ => false, + }; + } + + private bool IsSystemEnum(TypeReferenceHandle baseType) + { + var baseTypeReference = Cx.MdReader.GetTypeReference(baseType); + + return IsSystemEnum(baseTypeReference.Name, baseTypeReference.Namespace); + } + + private bool IsSystemEnum(TypeDefinitionHandle baseType) + { + var baseTypeDefinition = Cx.MdReader.GetTypeDefinition(baseType); + + return IsSystemEnum(baseTypeDefinition.Name, baseTypeDefinition.Namespace); + } + + private bool IsSystemEnum(StringHandle typeName, StringHandle namespaceName) + { + return Cx.MdReader.StringComparer.Equals(typeName, "Enum") && + !namespaceName.IsNil && + Cx.MdReader.StringComparer.Equals(namespaceName, "System"); + } + + internal PrimitiveTypeCode? GetUnderlyingEnumType() + { + foreach (var handle in td.GetFields()) + { + var field = Cx.MdReader.GetFieldDefinition(handle); + if (field.Attributes.HasFlag(FieldAttributes.Static)) + { + continue; + } + + var blob = Cx.MdReader.GetBlobReader(field.Signature); + if (blob.ReadSignatureHeader().Kind != SignatureKind.Field) + { + break; + } + + return (PrimitiveTypeCode)blob.ReadByte(); + } + + return null; + } + internal override Method LookupMethod(StringHandle name, BlobHandle signature) { foreach (var h in td.GetMethods()) diff --git a/csharp/extractor/Semmle.Extraction.CIL/Entities/TypeParameter.cs b/csharp/extractor/Semmle.Extraction.CIL/Entities/TypeParameter.cs index 91a1c6f925b..7c8d2222fa5 100644 --- a/csharp/extractor/Semmle.Extraction.CIL/Entities/TypeParameter.cs +++ b/csharp/extractor/Semmle.Extraction.CIL/Entities/TypeParameter.cs @@ -16,11 +16,11 @@ namespace Semmle.Extraction.CIL.Entities this.gc = gc; } - public override Namespace? Namespace => null; + public override Namespace? ContainingNamespace => null; public override Type? ContainingType => null; - public override int ThisTypeParameters => 0; + public override int ThisTypeParameterCount => 0; public override CilTypeKind Kind => CilTypeKind.TypeParameter; diff --git a/csharp/extractor/Semmle.Extraction.CIL/Entities/TypeReferenceType.cs b/csharp/extractor/Semmle.Extraction.CIL/Entities/TypeReferenceType.cs index ba789e87204..49a15965dd0 100644 --- a/csharp/extractor/Semmle.Extraction.CIL/Entities/TypeReferenceType.cs +++ b/csharp/extractor/Semmle.Extraction.CIL/Entities/TypeReferenceType.cs @@ -1,7 +1,5 @@ using System; -using Microsoft.CodeAnalysis; using System.Reflection.Metadata; -using System.Collections.Immutable; using System.Linq; using System.Collections.Generic; using System.IO; @@ -16,12 +14,14 @@ namespace Semmle.Extraction.CIL.Entities private readonly TypeReferenceHandle handle; private readonly TypeReference tr; private readonly Lazy typeParams; + private readonly NamedTypeIdWriter idWriter; public TypeReferenceType(Context cx, TypeReferenceHandle handle) : base(cx) { - this.typeParams = new Lazy(MakeTypeParameters); + this.idWriter = new NamedTypeIdWriter(this); this.handle = handle; this.tr = cx.MdReader.GetTypeReference(handle); + this.typeParams = new Lazy(GenericsHelper.MakeTypeParameters(this, ThisTypeParameterCount)); } public override bool Equals(object? obj) @@ -34,16 +34,6 @@ namespace Semmle.Extraction.CIL.Entities return handle.GetHashCode(); } - private TypeTypeParameter[] MakeTypeParameters() - { - var newTypeParams = new TypeTypeParameter[ThisTypeParameters]; - for (var i = 0; i < newTypeParams.Length; ++i) - { - newTypeParams[i] = new TypeTypeParameter(this, this, i); - } - return newTypeParams; - } - public override IEnumerable Contents { get @@ -56,45 +46,17 @@ namespace Semmle.Extraction.CIL.Entities } } - public override string Name - { - get - { - var name = Cx.GetString(tr.Name); - var tick = name.IndexOf('`'); - return tick == -1 ? name : name.Substring(0, tick); - } - } + public override string Name => GenericsHelper.GetNonGenericName(tr.Name, Cx.MdReader); - public override Namespace Namespace => Cx.CreateNamespace(tr.Namespace); - - public override int ThisTypeParameters - { - get - { - // Parse the name - var name = Cx.GetString(tr.Name); - var tick = name.IndexOf('`'); - return tick == -1 ? 0 : int.Parse(name.Substring(tick + 1)); - } - } - - public override IEnumerable ThisGenericArguments - { - get - { - foreach (var t in typeParams.Value) - yield return t; - } - } + public override Namespace ContainingNamespace => Cx.CreateNamespace(tr.Namespace); public override Type? ContainingType { get { - if (tr.ResolutionScope.Kind == HandleKind.TypeReference) - return (Type)Cx.Create((TypeReferenceHandle)tr.ResolutionScope); - return null; + return tr.ResolutionScope.Kind == HandleKind.TypeReference + ? (Type)Cx.Create((TypeReferenceHandle)tr.ResolutionScope) + : null; } } @@ -112,7 +74,7 @@ namespace Semmle.Extraction.CIL.Entities trapFile.Write(Cx.GetString(assemblyDef.Name)); trapFile.Write('_'); trapFile.Write(assemblyDef.Version.ToString()); - trapFile.Write("::"); + trapFile.Write(Entities.Type.AssemblyTypeNameSeparator); break; default: Cx.WriteAssemblyPrefix(trapFile); @@ -120,43 +82,20 @@ namespace Semmle.Extraction.CIL.Entities } } - public override IEnumerable TypeParameters => typeParams.Value; + public override int ThisTypeParameterCount => GenericsHelper.GetGenericTypeParameterCount(tr.Name, Cx.MdReader); - public override IEnumerable MethodParameters => throw new InternalError("This type does not have method parameters"); + public override IEnumerable TypeParameters => GenericsHelper.GetAllTypeParameters(ContainingType, typeParams!.Value); + + public override IEnumerable ThisGenericArguments => typeParams.Value; public override void WriteId(TextWriter trapFile, bool inContext) { - if (IsPrimitiveType) - { - PrimitiveTypeId(trapFile); - return; - } - - var ct = ContainingType; - if (ct != null) - { - ct.GetId(trapFile, inContext); - } - else - { - if (tr.ResolutionScope.Kind == HandleKind.AssemblyReference) - { - WriteAssemblyPrefix(trapFile); - } - - if (!Namespace.IsGlobalNamespace) - { - Namespace.WriteId(trapFile); - } - } - - trapFile.Write('.'); - trapFile.Write(Cx.GetString(tr.Name)); + idWriter.WriteId(trapFile, inContext); } public override Type Construct(IEnumerable typeArguments) { - if (TotalTypeParametersCheck != typeArguments.Count()) + if (TotalTypeParametersCount != typeArguments.Count()) throw new InternalError("Mismatched type arguments"); return Cx.Populate(new ConstructedType(Cx, this, typeArguments)); diff --git a/csharp/extractor/Semmle.Extraction.CIL/Entities/TypeSignatureDecoder.cs b/csharp/extractor/Semmle.Extraction.CIL/Entities/TypeSignatureDecoder.cs index 632933edcd6..dcb986f1526 100644 --- a/csharp/extractor/Semmle.Extraction.CIL/Entities/TypeSignatureDecoder.cs +++ b/csharp/extractor/Semmle.Extraction.CIL/Entities/TypeSignatureDecoder.cs @@ -20,10 +20,10 @@ namespace Semmle.Extraction.CIL.Entities cx.Populate(new ArrayType(cx, elementType, shape.Rank)); Type IConstructedTypeProvider.GetByReferenceType(Type elementType) => - elementType; // ?? + new ByRefType(cx, elementType); Type ISignatureTypeProvider.GetFunctionPointerType(MethodSignature signature) => - cx.ErrorType; // Don't know what to do !! + cx.Populate(new FunctionPointerType(cx, signature)); Type IConstructedTypeProvider.GetGenericInstantiation(Type genericType, ImmutableArray typeArguments) => genericType.Construct(typeArguments); @@ -35,10 +35,9 @@ namespace Semmle.Extraction.CIL.Entities genericContext.GetGenericTypeParameter(index); Type ISignatureTypeProvider.GetModifiedType(Type modifier, Type unmodifiedType, bool isRequired) => - unmodifiedType; // !! Not implemented properly + new ModifiedType(cx, unmodifiedType, modifier, isRequired); - Type ISignatureTypeProvider.GetPinnedType(Type elementType) => - cx.Populate(new PointerType(cx, elementType)); + Type ISignatureTypeProvider.GetPinnedType(Type elementType) => elementType; Type IConstructedTypeProvider.GetPointerType(Type elementType) => cx.Populate(new PointerType(cx, elementType)); diff --git a/csharp/extractor/Semmle.Extraction.CIL/Entities/TypeTypeParameter.cs b/csharp/extractor/Semmle.Extraction.CIL/Entities/TypeTypeParameter.cs index 790b8da2469..15db1536a3f 100644 --- a/csharp/extractor/Semmle.Extraction.CIL/Entities/TypeTypeParameter.cs +++ b/csharp/extractor/Semmle.Extraction.CIL/Entities/TypeTypeParameter.cs @@ -9,7 +9,7 @@ namespace Semmle.Extraction.CIL.Entities private readonly Type type; private readonly int index; - public TypeTypeParameter(GenericContext cx, Type t, int i) : base(cx) + public TypeTypeParameter(Type t, int i) : base(t) { index = i; type = t; @@ -37,8 +37,6 @@ namespace Semmle.Extraction.CIL.Entities public override IEnumerable TypeParameters => Enumerable.Empty(); - public override IEnumerable MethodParameters => Enumerable.Empty(); - public override IEnumerable Contents { get diff --git a/csharp/extractor/Semmle.Extraction.CIL/GenericContext.cs b/csharp/extractor/Semmle.Extraction.CIL/GenericContext.cs index 6dafcf1b1ea..6db62bf5bbf 100644 --- a/csharp/extractor/Semmle.Extraction.CIL/GenericContext.cs +++ b/csharp/extractor/Semmle.Extraction.CIL/GenericContext.cs @@ -17,7 +17,7 @@ namespace Semmle.Extraction.CIL } /// - /// The list of generic type parameters, including type parameters of + /// The list of generic type parameters/arguments, including type parameters/arguments of /// containing types. /// public abstract IEnumerable TypeParameters { get; } diff --git a/csharp/extractor/Semmle.Extraction.CIL/ICustomModifierReceiver.cs b/csharp/extractor/Semmle.Extraction.CIL/ICustomModifierReceiver.cs new file mode 100644 index 00000000000..24d2c057b2e --- /dev/null +++ b/csharp/extractor/Semmle.Extraction.CIL/ICustomModifierReceiver.cs @@ -0,0 +1,6 @@ +namespace Semmle.Extraction.CIL +{ + internal interface ICustomModifierReceiver + { + } +} \ No newline at end of file diff --git a/csharp/extractor/Semmle.Extraction.CIL/PDB/MdProvider.cs b/csharp/extractor/Semmle.Extraction.CIL/PDB/MdProvider.cs index c6c943032a6..fc22f1f6e94 100644 --- a/csharp/extractor/Semmle.Extraction.CIL/PDB/MdProvider.cs +++ b/csharp/extractor/Semmle.Extraction.CIL/PDB/MdProvider.cs @@ -2,6 +2,8 @@ using System; using Microsoft.DiaSymReader; using System.Reflection; +#pragma warning disable IDE0060, CA1822 + namespace Semmle.Extraction.PDB { /// @@ -31,3 +33,5 @@ namespace Semmle.Extraction.PDB throw new NotImplementedException(); } } + +#pragma warning restore diff --git a/csharp/extractor/Semmle.Extraction.CIL/PDB/MetadataPdbReader.cs b/csharp/extractor/Semmle.Extraction.CIL/PDB/MetadataPdbReader.cs index c6d02a119dc..81c91946657 100644 --- a/csharp/extractor/Semmle.Extraction.CIL/PDB/MetadataPdbReader.cs +++ b/csharp/extractor/Semmle.Extraction.CIL/PDB/MetadataPdbReader.cs @@ -76,7 +76,7 @@ namespace Semmle.Extraction.PDB out provider, out _)) { - return new MetadataPdbReader(provider); + return new MetadataPdbReader(provider!); } } diff --git a/csharp/extractor/Semmle.Extraction.CIL/PDB/Method.cs b/csharp/extractor/Semmle.Extraction.CIL/PDB/Method.cs index e0d41bed77a..6a534a4dd20 100644 --- a/csharp/extractor/Semmle.Extraction.CIL/PDB/Method.cs +++ b/csharp/extractor/Semmle.Extraction.CIL/PDB/Method.cs @@ -1,5 +1,4 @@ using System.Collections.Generic; -using System.Reflection.Metadata; using System.Linq; namespace Semmle.Extraction.PDB diff --git a/csharp/extractor/Semmle.Extraction.CIL/PDB/NativePdbReader.cs b/csharp/extractor/Semmle.Extraction.CIL/PDB/NativePdbReader.cs index 6d49dd8fd85..0a8479fb454 100644 --- a/csharp/extractor/Semmle.Extraction.CIL/PDB/NativePdbReader.cs +++ b/csharp/extractor/Semmle.Extraction.CIL/PDB/NativePdbReader.cs @@ -6,7 +6,6 @@ using Microsoft.DiaSymReader; using System.Reflection.Metadata.Ecma335; using System.Reflection.Metadata; using System.IO; -using System.Reflection; namespace Semmle.Extraction.PDB { diff --git a/csharp/extractor/Semmle.Extraction.CIL/PDB/PdbReader.cs b/csharp/extractor/Semmle.Extraction.CIL/PDB/PdbReader.cs index c84cd6a824f..1f0f1b455dc 100644 --- a/csharp/extractor/Semmle.Extraction.CIL/PDB/PdbReader.cs +++ b/csharp/extractor/Semmle.Extraction.CIL/PDB/PdbReader.cs @@ -1,9 +1,8 @@ -using System.Linq; -using System.Reflection.PortableExecutable; +using System.Reflection.PortableExecutable; namespace Semmle.Extraction.PDB { - internal class PdbReader + internal static class PdbReader { /// /// Returns the PDB information associated with an assembly. diff --git a/csharp/extractor/Semmle.Extraction.CIL/Tuples.cs b/csharp/extractor/Semmle.Extraction.CIL/Tuples.cs index 498fe629ed6..0ae92386c3e 100644 --- a/csharp/extractor/Semmle.Extraction.CIL/Tuples.cs +++ b/csharp/extractor/Semmle.Extraction.CIL/Tuples.cs @@ -32,6 +32,9 @@ namespace Semmle.Extraction.CIL internal static Tuple cil_base_class(Type t, Type @base) => new Tuple("cil_base_class", t, @base); + internal static Tuple cil_enum_underlying_type(Type t, PrimitiveType underlying) => + new Tuple("cil_enum_underlying_type", t, underlying); + internal static Tuple cil_base_interface(Type t, Type @base) => new Tuple("cil_base_interface", t, @base); @@ -83,6 +86,12 @@ namespace Semmle.Extraction.CIL internal static Tuple cil_method(Method method, string name, Type declType, Type returnType) => new Tuple("cil_method", method, name, declType, returnType); + internal static Tuple cil_function_pointer_return_type(FunctionPointerType fnptr, Type returnType) => + new Tuple("cil_function_pointer_return_type", fnptr, returnType); + + internal static Tuple cil_function_pointer_calling_conventions(FunctionPointerType fnptr, System.Reflection.Metadata.SignatureCallingConvention callingConvention) => + new Tuple("cil_function_pointer_calling_conventions", fnptr, (int)callingConvention); + internal static Tuple cil_method_implementation(MethodImplementation impl, Method method, Assembly assembly) => new Tuple("cil_method_implementation", impl, method, assembly); @@ -98,7 +107,7 @@ namespace Semmle.Extraction.CIL internal static Tuple cil_newslot(Method method) => new Tuple("cil_newslot", method); - internal static Tuple cil_parameter(Parameter p, Method m, int i, Type t) => + internal static Tuple cil_parameter(Parameter p, IParameterizable m, int i, Type t) => new Tuple("cil_parameter", p, m, i, t); internal static Tuple cil_parameter_in(Parameter p) => @@ -185,6 +194,12 @@ namespace Semmle.Extraction.CIL internal static Tuple cil_virtual(Method method) => new Tuple("cil_virtual", method); + internal static Tuple cil_custom_modifiers(ICustomModifierReceiver receiver, Type modifier, bool isRequired) => + new Tuple("cil_custom_modifiers", receiver, modifier, isRequired ? 1 : 0); + + internal static Tuple cil_type_annotation(IEntity receiver, TypeAnnotation annotation) => + new Tuple("cil_type_annotation", receiver, (int)annotation); + internal static Tuple containerparent(Folder parent, IFileOrFolder child) => new Tuple("containerparent", parent, child); diff --git a/csharp/extractor/Semmle.Extraction.CSharp.Driver/Driver.cs b/csharp/extractor/Semmle.Extraction.CSharp.Driver/Driver.cs index 5806bd375b1..1c4142097fe 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp.Driver/Driver.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp.Driver/Driver.cs @@ -3,7 +3,7 @@ namespace Semmle.Extraction.CSharp /// /// A command-line driver for the extractor. /// - public class Driver + public static class Driver { public static int Main(string[] args) { diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Analyser.cs b/csharp/extractor/Semmle.Extraction.CSharp/Analyser.cs index b5a4c79d8f2..b04b429993d 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp/Analyser.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp/Analyser.cs @@ -17,7 +17,7 @@ namespace Semmle.Extraction.CSharp /// public sealed class Analyser : IDisposable { - private IExtractor extractor; + private Extraction.Extractor extractor; private CSharpCompilation compilation; private Layout layout; private bool init; @@ -215,14 +215,12 @@ namespace Semmle.Extraction.CSharp /// /// Extracts compilation-wide entities, such as compilations and compiler diagnostics. /// - public void AnalyseCompilation(string cwd, string[] args) + public void AnalyseCompilation() { - extractionTasks.Add(() => DoAnalyseCompilation(cwd, args)); + extractionTasks.Add(() => DoAnalyseCompilation()); } - - - private void DoAnalyseCompilation(string cwd, string[] args) + private void DoAnalyseCompilation() { try { @@ -232,9 +230,9 @@ namespace Semmle.Extraction.CSharp var projectLayout = layout.LookupProjectOrDefault(transformedAssemblyPath); var trapWriter = projectLayout.CreateTrapWriter(Logger, transformedAssemblyPath, options.TrapCompression, discardDuplicates: false); compilationTrapFile = trapWriter; // Dispose later - var cx = extractor.CreateContext(compilation.Clone(), trapWriter, new AssemblyScope(assembly, assemblyPath, true), AddAssemblyTrapPrefix); + var cx = new Context(extractor, compilation.Clone(), trapWriter, new AssemblyScope(assembly, assemblyPath), AddAssemblyTrapPrefix); - compilationEntity = new Entities.Compilation(cx, cwd, args); + compilationEntity = Entities.Compilation.Create(cx); } catch (Exception ex) // lgtm[cs/catch-of-all-exceptions] { @@ -287,7 +285,7 @@ namespace Semmle.Extraction.CSharp if (c.GetAssemblyOrModuleSymbol(r) is IAssemblySymbol assembly) { - var cx = extractor.CreateContext(c, trapWriter, new AssemblyScope(assembly, assemblyPath, false), AddAssemblyTrapPrefix); + var cx = new Context(extractor, c, trapWriter, new AssemblyScope(assembly, assemblyPath), AddAssemblyTrapPrefix); foreach (var module in assembly.Modules) { @@ -373,10 +371,16 @@ namespace Semmle.Extraction.CSharp if (!upToDate) { - var cx = extractor.CreateContext(compilation.Clone(), trapWriter, new SourceScope(tree), AddAssemblyTrapPrefix); - Populators.CompilationUnit.Extract(cx, tree.GetRoot()); + var cx = new Context(extractor, compilation.Clone(), trapWriter, new SourceScope(tree), AddAssemblyTrapPrefix); + // Ensure that the file itself is populated in case the source file is totally empty + var root = tree.GetRoot(); + Extraction.Entities.File.Create(cx, root.SyntaxTree.FilePath); + + var csNode = (CSharpSyntaxNode)root; + csNode.Accept(new CompilationUnitVisitor(cx)); + csNode.Accept(new DirectiveVisitor(cx)); cx.PopulateAll(); - cx.ExtractComments(cx.CommentGenerator); + CommentPopulator.ExtractCommentBlocks(cx, cx.CommentGenerator); cx.PopulateAll(); } } @@ -389,7 +393,7 @@ namespace Semmle.Extraction.CSharp } catch (Exception ex) // lgtm[cs/catch-of-all-exceptions] { - extractor.Message(new Message("Unhandled exception processing syntax tree", tree.FilePath, null, ex.StackTrace)); + extractor.Message(new Message($"Unhandled exception processing syntax tree. {ex.Message}", tree.FilePath, null, ex.StackTrace)); } } diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Accessor.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Accessor.cs index c53a2c402e0..08782ec36a7 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Accessor.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Accessor.cs @@ -76,6 +76,11 @@ namespace Semmle.Extraction.CSharp.Entities { trapFile.compiler_generated(this); } + + if (symbol.IsInitOnly) + { + trapFile.init_only_accessors(this); + } } public static new Accessor Create(Context cx, IMethodSymbol symbol) => diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Attribute.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Attribute.cs index 9ef33f5ba47..e1663350055 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Attribute.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Attribute.cs @@ -66,12 +66,25 @@ namespace Semmle.Extraction.CSharp.Entities private void ExtractArguments(TextWriter trapFile) { + var ctorArguments = attributeSyntax?.ArgumentList?.Arguments.Where(a => a.NameEquals == null).ToList(); + var childIndex = 0; - foreach (var constructorArgument in symbol.ConstructorArguments) + for (var i = 0; i < symbol.ConstructorArguments.Length; i++) { + var constructorArgument = symbol.ConstructorArguments[i]; + var paramName = symbol.AttributeConstructor?.Parameters[i].Name; + var argSyntax = ctorArguments?.SingleOrDefault(a => a.NameColon != null && a.NameColon.Name.Identifier.Text == paramName); + + if (argSyntax == null && // couldn't find named argument + ctorArguments?.Count > childIndex && // there're more arguments + ctorArguments[childIndex].NameColon == null) // the argument is positional + { + argSyntax = ctorArguments[childIndex]; + } + CreateExpressionFromArgument( constructorArgument, - attributeSyntax?.ArgumentList.Arguments[childIndex].Expression, + argSyntax?.Expression, this, childIndex++); } @@ -105,7 +118,7 @@ namespace Semmle.Extraction.CSharp.Entities private Semmle.Extraction.Entities.Location location; private Semmle.Extraction.Entities.Location Location => - location ?? (location = Semmle.Extraction.Entities.Location.Create(Context, attributeSyntax is null ? entity.ReportingLocation : attributeSyntax.Name.GetLocation())); + location ?? (location = Context.CreateLocation(attributeSyntax is null ? entity.ReportingLocation : attributeSyntax.Name.GetLocation())); public override bool NeedsPopulation => true; diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/CallTypeExtensions.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/CallTypeExtensions.cs new file mode 100644 index 00000000000..6b9564e49dc --- /dev/null +++ b/csharp/extractor/Semmle.Extraction.CSharp/Entities/CallTypeExtensions.cs @@ -0,0 +1,27 @@ +using Semmle.Extraction.Kinds; + +namespace Semmle.Extraction.CSharp.Entities +{ + internal static class CallTypeExtensions + { + /// + /// Adjust the expression kind to match this call type. + /// + public static ExprKind AdjustKind(this Expression.CallType ct, ExprKind k) + { + if (k == ExprKind.ADDRESS_OF) + { + return k; + } + + switch (ct) + { + case Expression.CallType.Dynamic: + case Expression.CallType.UserOperator: + return ExprKind.OPERATOR_INVOCATION; + default: + return k; + } + } + } +} diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/CommentBlock.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/CommentBlock.cs index ab6802cf457..9f105bb1e1a 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp/Entities/CommentBlock.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp/Entities/CommentBlock.cs @@ -13,7 +13,7 @@ namespace Semmle.Extraction.CSharp.Entities { trapFile.commentblock(this); var child = 0; - trapFile.commentblock_location(this, Context.Create(symbol.Location)); + trapFile.commentblock_location(this, Context.CreateLocation(symbol.Location)); foreach (var l in symbol.CommentLines) { trapFile.commentblock_child(this, (CommentLine)l, child++); @@ -24,7 +24,7 @@ namespace Semmle.Extraction.CSharp.Entities public override void WriteId(TextWriter trapFile) { - trapFile.WriteSubId(Context.Create(symbol.Location)); + trapFile.WriteSubId(Context.CreateLocation(symbol.Location)); trapFile.Write(";commentblock"); } diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/CommentLine.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/CommentLine.cs index ba1770f20e5..5ba3bbd87f4 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp/Entities/CommentLine.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp/Entities/CommentLine.cs @@ -1,6 +1,4 @@ using Semmle.Extraction.CommentProcessing; -using Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.CSharp; using Semmle.Extraction.Entities; using System.IO; @@ -21,102 +19,11 @@ namespace Semmle.Extraction.CSharp.Entities public string Text { get { return symbol.Item2; } } public string RawText { get; private set; } - public static void Extract(Context cx, SyntaxTrivia trivia) - { - switch (trivia.Kind()) - { - case SyntaxKind.SingleLineDocumentationCommentTrivia: - /* - This is actually a multi-line comment consisting of /// lines. - So split it up. - */ - - var text = trivia.ToFullString(); - - var split = text.Split('\n'); - var currentLocation = trivia.GetLocation().SourceSpan.Start - 3; - - for (var line = 0; line < split.Length - 1; ++line) - { - var fullLine = split[line]; - var nextLineLocation = currentLocation + fullLine.Length + 1; - fullLine = fullLine.TrimEnd('\r'); - var trimmedLine = fullLine; - - var leadingSpaces = trimmedLine.IndexOf('/'); - if (leadingSpaces != -1) - { - fullLine = fullLine.Substring(leadingSpaces); - currentLocation += leadingSpaces; - trimmedLine = trimmedLine.Substring(leadingSpaces + 3); // Remove leading spaces and the "///" - trimmedLine = trimmedLine.Trim(); - - var span = Microsoft.CodeAnalysis.Text.TextSpan.FromBounds(currentLocation, currentLocation + fullLine.Length); - var location = Microsoft.CodeAnalysis.Location.Create(trivia.SyntaxTree, span); - var commentType = CommentLineType.XmlDoc; - cx.CommentGenerator.AddComment(Create(cx, location, commentType, trimmedLine, fullLine)); - } - else - { - cx.ModelError("Unexpected comment format"); - } - currentLocation = nextLineLocation; - } - break; - - case SyntaxKind.SingleLineCommentTrivia: - { - var contents = trivia.ToString().Substring(2); - var commentType = CommentLineType.Singleline; - if (contents.Length > 0 && contents[0] == '/') - { - commentType = CommentLineType.XmlDoc; - contents = contents.Substring(1); // An XML comment. - } - cx.CommentGenerator.AddComment(Create(cx, trivia.GetLocation(), commentType, contents.Trim(), trivia.ToFullString())); - } - break; - case SyntaxKind.MultiLineDocumentationCommentTrivia: - case SyntaxKind.MultiLineCommentTrivia: - /* We receive a single SyntaxTrivia for a multiline block spanning several lines. - So we split it into separate lines - */ - text = trivia.ToFullString(); - - split = text.Split('\n'); - currentLocation = trivia.GetLocation().SourceSpan.Start; - - for (var line = 0; line < split.Length; ++line) - { - var fullLine = split[line]; - var nextLineLocation = currentLocation + fullLine.Length + 1; - fullLine = fullLine.TrimEnd('\r'); - var trimmedLine = fullLine; - if (line == 0) - trimmedLine = trimmedLine.Substring(2); - if (line == split.Length - 1) - trimmedLine = trimmedLine.Substring(0, trimmedLine.Length - 2); - trimmedLine = trimmedLine.Trim(); - - var span = Microsoft.CodeAnalysis.Text.TextSpan.FromBounds(currentLocation, currentLocation + fullLine.Length); - var location = Microsoft.CodeAnalysis.Location.Create(trivia.SyntaxTree, span); - var commentType = line == 0 ? CommentLineType.Multiline : CommentLineType.MultilineContinuation; - cx.CommentGenerator.AddComment(Create(cx, location, commentType, trimmedLine, fullLine)); - currentLocation = nextLineLocation; - } - break; - // Strangely, these are reported as SingleLineCommentTrivia. - case SyntaxKind.DocumentationCommentExteriorTrivia: - cx.ModelError($"Unhandled comment type {trivia.Kind()} for {trivia}"); - break; - } - } - - private Extraction.Entities.Location location; + private Location location; public override void Populate(TextWriter trapFile) { - location = Context.Create(Location); + location = Context.CreateLocation(Location); trapFile.commentline(this, Type == CommentLineType.MultilineContinuation ? CommentLineType.Multiline : Type, Text, RawText); trapFile.commentline_location(this, location); } @@ -127,11 +34,11 @@ namespace Semmle.Extraction.CSharp.Entities public override void WriteId(TextWriter trapFile) { - trapFile.WriteSubId(Context.Create(Location)); + trapFile.WriteSubId(Context.CreateLocation(Location)); trapFile.Write(";commentline"); } - private static CommentLine Create(Context cx, Microsoft.CodeAnalysis.Location loc, CommentLineType type, string text, string raw) + internal static CommentLine Create(Context cx, Microsoft.CodeAnalysis.Location loc, CommentLineType type, string text, string raw) { var init = (loc, type, text, raw); return CommentLineFactory.Instance.CreateEntity(cx, init, init); diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Compilation.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Compilation.cs deleted file mode 100644 index 67a4325ce35..00000000000 --- a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Compilation.cs +++ /dev/null @@ -1,124 +0,0 @@ -using Microsoft.CodeAnalysis; -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using Semmle.Util; - -namespace Semmle.Extraction.CSharp.Entities -{ - internal class Compilation : FreshEntity - { - private readonly string cwd; - private readonly string[] args; - - public Compilation(Context cx, string cwd, string[] args) : base(cx) - { - this.cwd = cwd; - this.args = args; - TryPopulate(); - } - - protected override void Populate(TextWriter trapFile) - { - Extraction.Entities.Assembly.CreateOutputAssembly(cx); - - trapFile.compilations(this, FileUtils.ConvertToUnix(cwd)); - - // Arguments - var index = 0; - foreach (var arg in args) - { - trapFile.compilation_args(this, index++, arg); - } - - // Files - index = 0; - foreach (var file in cx.Compilation.SyntaxTrees.Select(tree => Extraction.Entities.File.Create(cx, tree.FilePath))) - { - trapFile.compilation_compiling_files(this, index++, file); - } - - // References - index = 0; - foreach (var file in cx.Compilation.References.OfType().Select(r => Extraction.Entities.File.Create(cx, r.FilePath))) - { - trapFile.compilation_referencing_files(this, index++, file); - } - - // Diagnostics - index = 0; - foreach (var diag in cx.Compilation.GetDiagnostics().Select(d => new Diagnostic(cx, d))) - { - trapFile.diagnostic_for(diag, this, 0, index++); - } - } - - public void PopulatePerformance(PerformanceMetrics p) - { - var trapFile = cx.TrapWriter.Writer; - var index = 0; - foreach (var metric in p.Metrics) - { - trapFile.compilation_time(this, -1, index++, metric); - } - trapFile.compilation_finished(this, (float)p.Total.Cpu.TotalSeconds, (float)p.Total.Elapsed.TotalSeconds); - } - - public override TrapStackBehaviour TrapStackBehaviour => TrapStackBehaviour.NoLabel; - } - - internal class Diagnostic : FreshEntity - { - public override TrapStackBehaviour TrapStackBehaviour => TrapStackBehaviour.NoLabel; - - private readonly Microsoft.CodeAnalysis.Diagnostic diagnostic; - - public Diagnostic(Context cx, Microsoft.CodeAnalysis.Diagnostic diag) : base(cx) - { - diagnostic = diag; - TryPopulate(); - } - - protected override void Populate(TextWriter trapFile) - { - trapFile.diagnostics(this, (int)diagnostic.Severity, diagnostic.Id, diagnostic.Descriptor.Title.ToString(), - diagnostic.GetMessage(), Extraction.Entities.Location.Create(cx, diagnostic.Location)); - } - } - - public struct Timings - { - public TimeSpan Elapsed { get; set; } - public TimeSpan Cpu { get; set; } - public TimeSpan User { get; set; } - } - - /// - /// The various performance metrics to log. - /// - public struct PerformanceMetrics - { - public Timings Frontend { get; set; } - public Timings Extractor { get; set; } - public Timings Total { get; set; } - public long PeakWorkingSet { get; set; } - - /// - /// These are in database order (0 indexed) - /// - public IEnumerable Metrics - { - get - { - yield return (float)Frontend.Cpu.TotalSeconds; - yield return (float)Frontend.Elapsed.TotalSeconds; - yield return (float)Extractor.Cpu.TotalSeconds; - yield return (float)Extractor.Elapsed.TotalSeconds; - yield return (float)Frontend.User.TotalSeconds; - yield return (float)Extractor.User.TotalSeconds; - yield return PeakWorkingSet / 1024.0f / 1024.0f; - } - } - } -} diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Compilations/Compilation.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Compilations/Compilation.cs new file mode 100644 index 00000000000..800e35d5ff4 --- /dev/null +++ b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Compilations/Compilation.cs @@ -0,0 +1,105 @@ +using Microsoft.CodeAnalysis; +using System; +using System.IO; +using System.Linq; +using Semmle.Util; + +namespace Semmle.Extraction.CSharp.Entities +{ + public class Compilation : CachedEntity + { + private static (string Cwd, string[] Args) settings; + private static int hashCode; + + public static (string Cwd, string[] Args) Settings + { + get { return settings; } + set + { + settings = value; + hashCode = settings.Cwd.GetHashCode(); + for (var i = 0; i < settings.Args.Length; i++) + { + hashCode = HashCode.Combine(hashCode, settings.Args[i].GetHashCode()); + } + } + } + + private Compilation(Context cx) : base(cx, null) + { + } + + public override void Populate(TextWriter trapFile) + { + var assembly = Extraction.Entities.Assembly.CreateOutputAssembly(Context); + + trapFile.compilations(this, FileUtils.ConvertToUnix(Compilation.Settings.Cwd)); + trapFile.compilation_assembly(this, assembly); + + // Arguments + var index = 0; + foreach (var arg in Compilation.Settings.Args) + { + trapFile.compilation_args(this, index++, arg); + } + + // Files + index = 0; + foreach (var file in Context.Compilation.SyntaxTrees.Select(tree => Extraction.Entities.File.Create(Context, tree.FilePath))) + { + trapFile.compilation_compiling_files(this, index++, file); + } + + // References + index = 0; + foreach (var file in Context.Compilation.References + .OfType() + .Select(r => Extraction.Entities.File.Create(Context, r.FilePath))) + { + trapFile.compilation_referencing_files(this, index++, file); + } + + // Diagnostics + index = 0; + foreach (var diag in Context.Compilation.GetDiagnostics().Select(d => new Diagnostic(Context, d))) + { + trapFile.diagnostic_for(diag, this, 0, index++); + } + } + + public void PopulatePerformance(PerformanceMetrics p) + { + var trapFile = Context.TrapWriter.Writer; + var index = 0; + foreach (var metric in p.Metrics) + { + trapFile.compilation_time(this, -1, index++, metric); + } + trapFile.compilation_finished(this, (float)p.Total.Cpu.TotalSeconds, (float)p.Total.Elapsed.TotalSeconds); + } + + public override void WriteId(TextWriter trapFile) + { + trapFile.Write(hashCode); + trapFile.Write(";compilation"); + } + + public override TrapStackBehaviour TrapStackBehaviour => TrapStackBehaviour.NoLabel; + + public override Location ReportingLocation => throw new NotImplementedException(); + + public override bool NeedsPopulation => Context.IsAssemblyScope; + + private class CompilationFactory : ICachedEntityFactory + { + public static CompilationFactory Instance { get; } = new CompilationFactory(); + + public Compilation Create(Context cx, object init) => new Compilation(cx); + } + + private static readonly object compilationCacheKey = new object(); + + public static Compilation Create(Context cx) + => CompilationFactory.Instance.CreateEntity(cx, compilationCacheKey, null); + } +} diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Compilations/Diagnostic.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Compilations/Diagnostic.cs new file mode 100644 index 00000000000..ddf53d6bbe1 --- /dev/null +++ b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Compilations/Diagnostic.cs @@ -0,0 +1,23 @@ +using System.IO; + +namespace Semmle.Extraction.CSharp.Entities +{ + internal class Diagnostic : FreshEntity + { + public override TrapStackBehaviour TrapStackBehaviour => TrapStackBehaviour.NoLabel; + + private readonly Microsoft.CodeAnalysis.Diagnostic diagnostic; + + public Diagnostic(Context cx, Microsoft.CodeAnalysis.Diagnostic diag) : base(cx) + { + diagnostic = diag; + TryPopulate(); + } + + protected override void Populate(TextWriter trapFile) + { + trapFile.diagnostics(this, (int)diagnostic.Severity, diagnostic.Id, diagnostic.Descriptor.Title.ToString(), + diagnostic.GetMessage(), cx.CreateLocation(diagnostic.Location)); + } + } +} diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Compilations/PerformanceMetrics.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Compilations/PerformanceMetrics.cs new file mode 100644 index 00000000000..67aa2f25a88 --- /dev/null +++ b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Compilations/PerformanceMetrics.cs @@ -0,0 +1,32 @@ +using System.Collections.Generic; + +namespace Semmle.Extraction.CSharp.Entities +{ + /// + /// The various performance metrics to log. + /// + public struct PerformanceMetrics + { + public Timings Frontend { get; set; } + public Timings Extractor { get; set; } + public Timings Total { get; set; } + public long PeakWorkingSet { get; set; } + + /// + /// These are in database order (0 indexed) + /// + public IEnumerable Metrics + { + get + { + yield return (float)Frontend.Cpu.TotalSeconds; + yield return (float)Frontend.Elapsed.TotalSeconds; + yield return (float)Extractor.Cpu.TotalSeconds; + yield return (float)Extractor.Elapsed.TotalSeconds; + yield return (float)Frontend.User.TotalSeconds; + yield return (float)Extractor.User.TotalSeconds; + yield return PeakWorkingSet / 1024.0f / 1024.0f; + } + } + } +} diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Compilations/Timings.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Compilations/Timings.cs new file mode 100644 index 00000000000..43f22922309 --- /dev/null +++ b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Compilations/Timings.cs @@ -0,0 +1,11 @@ +using System; + +namespace Semmle.Extraction.CSharp.Entities +{ + public struct Timings + { + public TimeSpan Elapsed { get; set; } + public TimeSpan Cpu { get; set; } + public TimeSpan User { get; set; } + } +} diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Constructor.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Constructor.cs index 35b3f2eb808..0e4c2bbe9c0 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Constructor.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Constructor.cs @@ -42,16 +42,16 @@ namespace Semmle.Extraction.CSharp.Entities if (initializer == null) return; - Type initializerType; + ITypeSymbol initializerType; var symbolInfo = Context.GetSymbolInfo(initializer); switch (initializer.Kind()) { case SyntaxKind.BaseConstructorInitializer: - initializerType = Type.Create(Context, symbol.ContainingType.BaseType); + initializerType = symbol.ContainingType.BaseType; break; case SyntaxKind.ThisConstructorInitializer: - initializerType = ContainingType; + initializerType = symbol.ContainingType; break; default: Context.ModelError(initializer, "Unknown initializer"); @@ -59,8 +59,8 @@ namespace Semmle.Extraction.CSharp.Entities } var initInfo = new ExpressionInfo(Context, - new AnnotatedType(initializerType, NullableAnnotation.None), - Context.Create(initializer.ThisOrBaseKeyword.GetLocation()), + AnnotatedTypeSymbol.CreateNotAnnotated(initializerType), + Context.CreateLocation(initializer.ThisOrBaseKeyword.GetLocation()), Kinds.ExprKind.CONSTRUCTOR_INIT, this, -1, diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expression.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expression.cs index 0c0fbca6489..e343414a4cb 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expression.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expression.cs @@ -2,8 +2,6 @@ using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp.Syntax; using Semmle.Extraction.CSharp.Entities.Expressions; -using Semmle.Extraction.CSharp.Populators; -using Semmle.Extraction.Entities; using Semmle.Extraction.Kinds; using System; using System.IO; @@ -11,18 +9,10 @@ using System.Linq; namespace Semmle.Extraction.CSharp.Entities { - public interface IExpressionParentEntity : IEntity - { - /// - /// Whether this entity is the parent of a top-level expression. - /// - bool IsTopLevelParent { get; } - } - internal class Expression : FreshEntity, IExpressionParentEntity { private readonly IExpressionInfo info; - public AnnotatedType Type { get; } + public AnnotatedTypeSymbol? Type { get; } public Extraction.Entities.Location Location { get; } public ExprKind Kind { get; } @@ -33,25 +23,23 @@ namespace Semmle.Extraction.CSharp.Entities Location = info.Location; Kind = info.Kind; Type = info.Type; - if (Type.Type is null) - Type = NullType.Create(cx); TryPopulate(); } protected sealed override void Populate(TextWriter trapFile) { - trapFile.expressions(this, Kind, Type.Type.TypeRef); + var type = Type.HasValue ? Entities.Type.Create(cx, Type.Value) : NullType.Create(cx); + trapFile.expressions(this, Kind, type.TypeRef); if (info.Parent.IsTopLevelParent) trapFile.expr_parent_top_level(this, info.Child, info.Parent); else trapFile.expr_parent(this, info.Child, info.Parent); trapFile.expr_location(this, Location); - var annotatedType = Type.Symbol; - if (!annotatedType.HasObliviousNullability()) + if (Type.HasValue && !Type.Value.HasObliviousNullability()) { - var n = NullabilityEntity.Create(cx, Nullability.Create(annotatedType)); + var n = NullabilityEntity.Create(cx, Nullability.Create(Type.Value)); trapFile.type_nullability(this, n); } @@ -66,7 +54,7 @@ namespace Semmle.Extraction.CSharp.Entities if (info.ExprValue is string value) trapFile.expr_value(this, value); - Type.Type.PopulateGenerics(); + type.PopulateGenerics(); } public override Microsoft.CodeAnalysis.Location ReportingLocation => Location.symbol; @@ -310,292 +298,4 @@ namespace Semmle.Extraction.CSharp.Entities public override TrapStackBehaviour TrapStackBehaviour => TrapStackBehaviour.OptionalLabel; } - - internal static class CallTypeExtensions - { - /// - /// Adjust the expression kind to match this call type. - /// - public static ExprKind AdjustKind(this Expression.CallType ct, ExprKind k) - { - switch (ct) - { - case Expression.CallType.Dynamic: - case Expression.CallType.UserOperator: - return ExprKind.OPERATOR_INVOCATION; - default: - return k; - } - } - } - - internal abstract class Expression : Expression - where TExpressionSyntax : ExpressionSyntax - { - public TExpressionSyntax Syntax { get; } - - protected Expression(ExpressionNodeInfo info) - : base(info) - { - Syntax = (TExpressionSyntax)info.Node; - } - - /// - /// Populates expression-type specific relations in the trap file. The general relations - /// expressions and expr_location are populated by the constructor - /// (should not fail), so even if expression-type specific population fails (e.g., in - /// standalone extraction), the expression created via - /// will - /// still be valid. - /// - protected abstract void PopulateExpression(TextWriter trapFile); - - protected new Expression TryPopulate() - { - cx.Try(Syntax, null, () => PopulateExpression(cx.TrapWriter.Writer)); - return this; - } - } - - /// - /// Holds all information required to create an Expression entity. - /// - internal interface IExpressionInfo - { - Context Context { get; } - - /// - /// The type of the expression. - /// - AnnotatedType Type { get; } - - /// - /// The location of the expression. - /// - Extraction.Entities.Location Location { get; } - - /// - /// The kind of the expression. - /// - ExprKind Kind { get; } - - /// - /// The parent of the expression. - /// - IExpressionParentEntity Parent { get; } - - /// - /// The child index of the expression. - /// - int Child { get; } - - /// - /// Holds if this is an implicit expression. - /// - bool IsCompilerGenerated { get; } - - /// - /// Gets a string representation of the value. - /// null is encoded as the string "null". - /// If the expression does not have a value, then this - /// is null. - /// - string ExprValue { get; } - - NullableFlowState FlowState { get; } - } - - /// - /// Explicitly constructed expression information. - /// - internal class ExpressionInfo : IExpressionInfo - { - public Context Context { get; } - public AnnotatedType Type { get; } - public Extraction.Entities.Location Location { get; } - public ExprKind Kind { get; } - public IExpressionParentEntity Parent { get; } - public int Child { get; } - public bool IsCompilerGenerated { get; } - public string ExprValue { get; } - - public ExpressionInfo(Context cx, AnnotatedType type, Extraction.Entities.Location location, ExprKind kind, - IExpressionParentEntity parent, int child, bool isCompilerGenerated, string value) - { - Context = cx; - Type = type; - Location = location; - Kind = kind; - Parent = parent; - Child = child; - ExprValue = value; - IsCompilerGenerated = isCompilerGenerated; - } - - // Synthetic expressions don't have a flow state. - public NullableFlowState FlowState => NullableFlowState.None; - } - - /// - /// Expression information constructed from a syntax node. - /// - internal class ExpressionNodeInfo : IExpressionInfo - { - public ExpressionNodeInfo(Context cx, ExpressionSyntax node, IExpressionParentEntity parent, int child) : - this(cx, node, parent, child, cx.GetTypeInfo(node)) - { - } - - public ExpressionNodeInfo(Context cx, ExpressionSyntax node, IExpressionParentEntity parent, int child, TypeInfo typeInfo) - { - Context = cx; - Node = node; - Parent = parent; - Child = child; - TypeInfo = typeInfo; - Conversion = cx.GetModel(node).GetConversion(node); - } - - public Context Context { get; } - public ExpressionSyntax Node { get; private set; } - public IExpressionParentEntity Parent { get; set; } - public int Child { get; set; } - public TypeInfo TypeInfo { get; } - public Microsoft.CodeAnalysis.CSharp.Conversion Conversion { get; } - - public AnnotatedTypeSymbol ResolvedType => new AnnotatedTypeSymbol(TypeInfo.Type.DisambiguateType(), TypeInfo.Nullability.Annotation); - public AnnotatedTypeSymbol ConvertedType => new AnnotatedTypeSymbol(TypeInfo.ConvertedType.DisambiguateType(), TypeInfo.ConvertedNullability.Annotation); - - public AnnotatedTypeSymbol ExpressionType - { - get - { - var type = ResolvedType; - - if (type.Symbol == null) - type.Symbol = (TypeInfo.Type ?? TypeInfo.ConvertedType).DisambiguateType(); - - // Roslyn workaround: It can't work out the type of "new object[0]" - // Clearly a bug. - if (type.Symbol?.TypeKind == Microsoft.CodeAnalysis.TypeKind.Error) - { - if (Node is ArrayCreationExpressionSyntax arrayCreation) - { - var elementType = Context.GetType(arrayCreation.Type.ElementType); - - if (elementType.Symbol != null) - // There seems to be no way to create an array with a nullable element at present. - return new AnnotatedTypeSymbol(Context.Compilation.CreateArrayTypeSymbol(elementType.Symbol, arrayCreation.Type.RankSpecifiers.Count), NullableAnnotation.NotAnnotated); - } - - Context.ModelError(Node, "Failed to determine type"); - } - - return type; - } - } - - private Microsoft.CodeAnalysis.Location location; - - public Microsoft.CodeAnalysis.Location CodeAnalysisLocation - { - get - { - if (location == null) - location = Node.FixedLocation(); - return location; - } - set - { - location = value; - } - } - - public SemanticModel Model => Context.GetModel(Node); - - public string ExprValue - { - get - { - var c = Model.GetConstantValue(Node); - return c.HasValue ? Expression.ValueAsString(c.Value) : null; - } - } - - private AnnotatedType cachedType; - - public AnnotatedType Type - { - get - { - if (cachedType.Type == null) - cachedType = Entities.Type.Create(Context, ExpressionType); - return cachedType; - } - set - { - cachedType = value; - } - } - - private Extraction.Entities.Location cachedLocation; - - public Extraction.Entities.Location Location - { - get - { - if (cachedLocation == null) - cachedLocation = Context.Create(CodeAnalysisLocation); - return cachedLocation; - } - - set - { - cachedLocation = value; - } - } - - public ExprKind Kind { get; set; } = ExprKind.UNKNOWN; - - public bool IsCompilerGenerated { get; set; } - - public ExpressionNodeInfo SetParent(IExpressionParentEntity parent, int child) - { - Parent = parent; - Child = child; - return this; - } - - public ExpressionNodeInfo SetKind(ExprKind kind) - { - Kind = kind; - return this; - } - - public ExpressionNodeInfo SetType(AnnotatedType type) - { - Type = type; - return this; - } - - public ExpressionNodeInfo SetNode(ExpressionSyntax node) - { - Node = node; - return this; - } - - private SymbolInfo cachedSymbolInfo; - - public SymbolInfo SymbolInfo - { - get - { - if (cachedSymbolInfo.Symbol == null && cachedSymbolInfo.CandidateReason == CandidateReason.None) - cachedSymbolInfo = Model.GetSymbolInfo(Node); - return cachedSymbolInfo; - } - } - - public NullableFlowState FlowState => TypeInfo.Nullability.FlowState; - } } diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/ExpressionInfo.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/ExpressionInfo.cs new file mode 100644 index 00000000000..feb1eaa2d93 --- /dev/null +++ b/csharp/extractor/Semmle.Extraction.CSharp/Entities/ExpressionInfo.cs @@ -0,0 +1,36 @@ +using Microsoft.CodeAnalysis; +using Semmle.Extraction.Kinds; + +namespace Semmle.Extraction.CSharp.Entities +{ + /// + /// Explicitly constructed expression information. + /// + internal class ExpressionInfo : IExpressionInfo + { + public Context Context { get; } + public AnnotatedTypeSymbol? Type { get; } + public Extraction.Entities.Location Location { get; } + public ExprKind Kind { get; } + public IExpressionParentEntity Parent { get; } + public int Child { get; } + public bool IsCompilerGenerated { get; } + public string ExprValue { get; } + + public ExpressionInfo(Context cx, AnnotatedTypeSymbol? type, Extraction.Entities.Location location, ExprKind kind, + IExpressionParentEntity parent, int child, bool isCompilerGenerated, string value) + { + Context = cx; + Type = type; + Location = location; + Kind = kind; + Parent = parent; + Child = child; + ExprValue = value; + IsCompilerGenerated = isCompilerGenerated; + } + + // Synthetic expressions don't have a flow state. + public NullableFlowState FlowState => NullableFlowState.None; + } +} diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/ExpressionNodeInfo.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/ExpressionNodeInfo.cs new file mode 100644 index 00000000000..6968ca65abb --- /dev/null +++ b/csharp/extractor/Semmle.Extraction.CSharp/Entities/ExpressionNodeInfo.cs @@ -0,0 +1,189 @@ +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CSharp; +using Microsoft.CodeAnalysis.CSharp.Syntax; +using Semmle.Extraction.CSharp.Populators; +using Semmle.Extraction.Entities; +using Semmle.Extraction.Kinds; + +namespace Semmle.Extraction.CSharp.Entities +{ + /// + /// Expression information constructed from a syntax node. + /// + internal class ExpressionNodeInfo : IExpressionInfo + { + public ExpressionNodeInfo(Context cx, ExpressionSyntax node, IExpressionParentEntity parent, int child) : + this(cx, node, parent, child, cx.GetTypeInfo(node)) + { + } + + public ExpressionNodeInfo(Context cx, ExpressionSyntax node, IExpressionParentEntity parent, int child, TypeInfo typeInfo) + { + Context = cx; + Node = node; + Parent = parent; + Child = child; + TypeInfo = typeInfo; + Conversion = cx.GetModel(node).GetConversion(node); + } + + public Context Context { get; } + public ExpressionSyntax Node { get; private set; } + public IExpressionParentEntity Parent { get; set; } + public int Child { get; set; } + public TypeInfo TypeInfo { get; } + public Microsoft.CodeAnalysis.CSharp.Conversion Conversion { get; } + + public AnnotatedTypeSymbol ResolvedType => new AnnotatedTypeSymbol(TypeInfo.Type.DisambiguateType(), TypeInfo.Nullability.Annotation); + public AnnotatedTypeSymbol ConvertedType => new AnnotatedTypeSymbol(TypeInfo.ConvertedType.DisambiguateType(), TypeInfo.ConvertedNullability.Annotation); + + private AnnotatedTypeSymbol? cachedType; + private bool cachedTypeSet; + public AnnotatedTypeSymbol? Type + { + get + { + if (cachedTypeSet) + return cachedType; + + var type = ResolvedType; + + if (type.Symbol == null) + type.Symbol = (TypeInfo.Type ?? TypeInfo.ConvertedType).DisambiguateType(); + + // Roslyn workaround: It can't work out the type of "new object[0]" + // Clearly a bug. + if (type.Symbol?.TypeKind == Microsoft.CodeAnalysis.TypeKind.Error) + { + if (Node is ArrayCreationExpressionSyntax arrayCreation) + { + var elementType = Context.GetType(arrayCreation.Type.ElementType); + + if (elementType.Symbol != null) + // There seems to be no way to create an array with a nullable element at present. + return new AnnotatedTypeSymbol(Context.Compilation.CreateArrayTypeSymbol(elementType.Symbol, arrayCreation.Type.RankSpecifiers.Count), NullableAnnotation.NotAnnotated); + } + + Context.ModelError(Node, "Failed to determine type"); + } + + cachedType = type; + cachedTypeSet = true; + + return type; + } + } + + private Microsoft.CodeAnalysis.Location location; + + public Microsoft.CodeAnalysis.Location CodeAnalysisLocation + { + get + { + if (location == null) + location = Node.FixedLocation(); + return location; + } + set + { + location = value; + } + } + + public SemanticModel Model => Context.GetModel(Node); + + public string ExprValue + { + get + { + var c = Model.GetConstantValue(Node); + if (c.HasValue) + { + return Expression.ValueAsString(c.Value); + } + + if (TryGetBoolValueFromLiteral(out var val)) + { + return Expression.ValueAsString(val); + } + + return null; + } + } + + private Extraction.Entities.Location cachedLocation; + + public Extraction.Entities.Location Location + { + get + { + if (cachedLocation == null) + cachedLocation = Context.CreateLocation(CodeAnalysisLocation); + return cachedLocation; + } + + set + { + cachedLocation = value; + } + } + + public ExprKind Kind { get; set; } = ExprKind.UNKNOWN; + + public bool IsCompilerGenerated { get; set; } + + public ExpressionNodeInfo SetParent(IExpressionParentEntity parent, int child) + { + Parent = parent; + Child = child; + return this; + } + + public ExpressionNodeInfo SetKind(ExprKind kind) + { + Kind = kind; + return this; + } + + public ExpressionNodeInfo SetType(AnnotatedTypeSymbol? type) + { + cachedType = type; + cachedTypeSet = true; + return this; + } + + public ExpressionNodeInfo SetNode(ExpressionSyntax node) + { + Node = node; + return this; + } + + private SymbolInfo cachedSymbolInfo; + + public SymbolInfo SymbolInfo + { + get + { + if (cachedSymbolInfo.Symbol == null && cachedSymbolInfo.CandidateReason == CandidateReason.None) + cachedSymbolInfo = Model.GetSymbolInfo(Node); + return cachedSymbolInfo; + } + } + + public NullableFlowState FlowState => TypeInfo.Nullability.FlowState; + + private bool TryGetBoolValueFromLiteral(out bool val) + { + var isTrue = Node.IsKind(SyntaxKind.TrueLiteralExpression); + var isFalse = Node.IsKind(SyntaxKind.FalseLiteralExpression); + + val = isTrue; + return isTrue || isFalse; + } + + public bool IsBoolLiteral() + { + return TryGetBoolValueFromLiteral(out var _); + } + } +} diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expression`1.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expression`1.cs new file mode 100644 index 00000000000..c16f0679c10 --- /dev/null +++ b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expression`1.cs @@ -0,0 +1,34 @@ +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CSharp.Syntax; +using System.IO; + +namespace Semmle.Extraction.CSharp.Entities +{ + internal abstract class Expression : Expression + where TExpressionSyntax : ExpressionSyntax + { + public TExpressionSyntax Syntax { get; } + + protected Expression(ExpressionNodeInfo info) + : base(info) + { + Syntax = (TExpressionSyntax)info.Node; + } + + /// + /// Populates expression-type specific relations in the trap file. The general relations + /// expressions and expr_location are populated by the constructor + /// (should not fail), so even if expression-type specific population fails (e.g., in + /// standalone extraction), the expression created via + /// will + /// still be valid. + /// + protected abstract void PopulateExpression(TextWriter trapFile); + + protected new Expression TryPopulate() + { + cx.Try(Syntax, null, () => PopulateExpression(cx.TrapWriter.Writer)); + return this; + } + } +} diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/Access.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/Access.cs index e91b81a3d77..d4d4c86c507 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/Access.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/Access.cs @@ -52,7 +52,7 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions if (implicitThis && !symbol.IsStatic) { - This.CreateImplicit(cx, Entities.Type.Create(cx, symbol.ContainingType), Location, this, -1); + This.CreateImplicit(cx, symbol.ContainingType, Location, this, -1); } } diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/ArrayCreation.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/ArrayCreation.cs index d8d12229f62..ea818862d80 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/ArrayCreation.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/ArrayCreation.cs @@ -90,7 +90,7 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions { var info = new ExpressionInfo( cx, - new AnnotatedType(Entities.Type.Create(cx, type), NullableAnnotation.None), + AnnotatedTypeSymbol.CreateNotAnnotated(type), location, ExprKind.ARRAY_CREATION, parent, diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/Cast.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/Cast.cs index 8048d4da2cd..6f2551ec904 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/Cast.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/Cast.cs @@ -36,7 +36,7 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions { var info = new ExpressionInfo( cx, - new AnnotatedType(Entities.Type.Create(cx, type), Microsoft.CodeAnalysis.NullableAnnotation.None), + AnnotatedTypeSymbol.CreateNotAnnotated(type), location, ExprKind.CAST, parent, diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/DefineSymbol.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/DefineSymbol.cs new file mode 100644 index 00000000000..d0111c010b2 --- /dev/null +++ b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/DefineSymbol.cs @@ -0,0 +1,18 @@ +using Microsoft.CodeAnalysis.CSharp.Syntax; +using Semmle.Extraction.Kinds; +using System.IO; + +namespace Semmle.Extraction.CSharp.Entities.Expressions +{ + internal class DefineSymbol : Expression + { + private DefineSymbol(ExpressionNodeInfo info) : base(info.SetKind(ExprKind.DEFINE_SYMBOL)) { } + + public static Expression Create(ExpressionNodeInfo info) => new DefineSymbol(info).TryPopulate(); + + protected override void PopulateExpression(TextWriter trapFile) + { + trapFile.directive_define_symbols(this, Syntax.Identifier.Text); + } + } +} diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/Discard.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/Discard.cs index 194261c4614..4f2eecca9da 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/Discard.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/Discard.cs @@ -12,7 +12,7 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions } private Discard(Context cx, CSharpSyntaxNode syntax, IExpressionParentEntity parent, int child) : - base(new ExpressionInfo(cx, Entities.Type.Create(cx, cx.GetType(syntax)), cx.Create(syntax.GetLocation()), ExprKind.DISCARD, parent, child, false, null)) + base(new ExpressionInfo(cx, cx.GetType(syntax), cx.CreateLocation(syntax.GetLocation()), ExprKind.DISCARD, parent, child, false, null)) { } diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/ElementAccess.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/ElementAccess.cs index afc4cd2cd93..59e573984fe 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/ElementAccess.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/ElementAccess.cs @@ -30,12 +30,8 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions } else { - var child = -1; - Create(cx, qualifier, this, child++); - foreach (var a in argumentList.Arguments) - { - cx.Extract(a, this, child++); - } + Create(cx, qualifier, this, -1); + PopulateArguments(trapFile, argumentList, 0); var symbolInfo = cx.GetSymbolInfo(base.Syntax); diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/Factory.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/Factory.cs index 889dbfd378b..a21379d897c 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/Factory.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/Factory.cs @@ -84,6 +84,9 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions case SyntaxKind.ObjectCreationExpression: return ExplicitObjectCreation.Create(info); + case SyntaxKind.ImplicitObjectCreationExpression: + return ImplicitObjectCreation.Create(info); + case SyntaxKind.ArrayCreationExpression: return NormalArrayCreation.Create(info); @@ -179,7 +182,7 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions return ImplicitArrayCreation.Create(info); case SyntaxKind.AnonymousObjectCreationExpression: - return ImplicitObjectCreation.Create(info); + return AnonymousObjectCreation.Create(info); case SyntaxKind.ComplexElementInitializerExpression: return CollectionInitializer.Create(info); diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/ImplicitCast.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/ImplicitCast.cs index a9884a5df5d..eccead4a4de 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/ImplicitCast.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/ImplicitCast.cs @@ -12,13 +12,13 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions } public ImplicitCast(ExpressionNodeInfo info) - : base(new ExpressionInfo(info.Context, Entities.Type.Create(info.Context, info.ConvertedType), info.Location, ExprKind.CAST, info.Parent, info.Child, true, info.ExprValue)) + : base(new ExpressionInfo(info.Context, info.ConvertedType, info.Location, ExprKind.CAST, info.Parent, info.Child, true, info.ExprValue)) { Expr = Factory.Create(new ExpressionNodeInfo(cx, info.Node, this, 0)); } public ImplicitCast(ExpressionNodeInfo info, IMethodSymbol method) - : base(new ExpressionInfo(info.Context, Entities.Type.Create(info.Context, info.ConvertedType), info.Location, ExprKind.OPERATOR_INVOCATION, info.Parent, info.Child, true, info.ExprValue)) + : base(new ExpressionInfo(info.Context, info.ConvertedType, info.Location, ExprKind.OPERATOR_INVOCATION, info.Parent, info.Child, true, info.ExprValue)) { Expr = Factory.Create(info.SetParent(this, 0)); diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/Initializer.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/Initializer.cs index 7a7dd1b9170..14fea3d4ce7 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/Initializer.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/Initializer.cs @@ -14,7 +14,7 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions internal class ArrayInitializer : Expression { - private ArrayInitializer(ExpressionNodeInfo info) : base(info.SetType(NullType.Create(info.Context)).SetKind(ExprKind.ARRAY_INIT)) { } + private ArrayInitializer(ExpressionNodeInfo info) : base(info.SetType(null).SetKind(ExprKind.ARRAY_INIT)) { } public static Expression Create(ExpressionNodeInfo info) => new ArrayInitializer(info).TryPopulate(); @@ -40,7 +40,7 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions { var info = new ExpressionInfo( cx, - NullType.Create(cx), + null, location, ExprKind.ARRAY_INIT, parent, @@ -135,9 +135,9 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions { var collectionInfo = cx.GetModel(Syntax).GetCollectionInitializerSymbolInfo(i); var addMethod = Method.Create(cx, collectionInfo.Symbol as IMethodSymbol); - var voidType = Entities.Type.Create(cx, new AnnotatedTypeSymbol(cx.Compilation.GetSpecialType(SpecialType.System_Void), NullableAnnotation.None)); + var voidType = AnnotatedTypeSymbol.CreateNotAnnotated(cx.Compilation.GetSpecialType(SpecialType.System_Void)); - var invocation = new Expression(new ExpressionInfo(cx, voidType, cx.Create(i.GetLocation()), ExprKind.METHOD_INVOCATION, this, child++, false, null)); + var invocation = new Expression(new ExpressionInfo(cx, voidType, cx.CreateLocation(i.GetLocation()), ExprKind.METHOD_INVOCATION, this, child++, false, null)); if (addMethod != null) trapFile.expr_call(invocation, addMethod); diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/InterpolatedString.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/InterpolatedString.cs index 152ff145897..836aae35beb 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/InterpolatedString.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/InterpolatedString.cs @@ -27,7 +27,7 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions case SyntaxKind.InterpolatedStringText: // Create a string literal var interpolatedText = (InterpolatedStringTextSyntax)c; - new Expression(new ExpressionInfo(cx, Type, cx.Create(c.GetLocation()), ExprKind.STRING_LITERAL, this, child++, false, interpolatedText.TextToken.Text)); + new Expression(new ExpressionInfo(cx, Type, cx.CreateLocation(c.GetLocation()), ExprKind.STRING_LITERAL, this, child++, false, interpolatedText.TextToken.Text)); break; default: throw new InternalError(c, $"Unhandled interpolation kind {c.Kind()}"); diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/Invocation.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/Invocation.cs index 7a0e2fcc683..638822f3d27 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/Invocation.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/Invocation.cs @@ -4,6 +4,7 @@ using System.Linq; using Microsoft.CodeAnalysis.CSharp; using Semmle.Extraction.Kinds; using System.IO; +using System; namespace Semmle.Extraction.CSharp.Entities.Expressions { @@ -55,7 +56,7 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions // Implicit `this` qualifier; add explicitly if (cx.GetModel(Syntax).GetEnclosingSymbol(Location.symbol.SourceSpan.Start) is IMethodSymbol callingMethod) - This.CreateImplicit(cx, Entities.Type.Create(cx, callingMethod.ContainingType), Location, this, child++); + This.CreateImplicit(cx, callingMethod.ContainingType, Location, this, child++); else cx.ModelError(Syntax, "Couldn't determine implicit this type"); } @@ -66,7 +67,7 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions } break; default: - // Delegate call; `d()` + // Delegate or function pointer call; `d()` Create(cx, Syntax.Expression, this, child++); break; } @@ -84,7 +85,7 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions if (target == null) { - if (!isDynamicCall && !IsDelegateCall(info)) + if (!isDynamicCall && !IsDelegateLikeCall(info)) cx.ModelError(Syntax, "Unable to resolve target for call. (Compilation error?)"); return; } @@ -98,7 +99,7 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions // Either the qualifier (Expression) is dynamic, // or one of the arguments is dynamic. var node = (InvocationExpressionSyntax)info.Node; - return !IsDelegateCall(info) && + return !IsDelegateLikeCall(info) && (IsDynamic(info.Context, node.Expression) || node.ArgumentList.Arguments.Any(arg => IsDynamic(info.Context, arg.Expression))); } @@ -133,12 +134,22 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions } } - private static bool IsDelegateCall(ExpressionNodeInfo info) + private static bool IsDelegateLikeCall(ExpressionNodeInfo info) + { + return IsDelegateLikeCall(info, symbol => IsFunctionPointer(symbol) || IsDelegateInvoke(symbol)); + } + + private static bool IsDelegateInvokeCall(ExpressionNodeInfo info) + { + return IsDelegateLikeCall(info, IsDelegateInvoke); + } + + private static bool IsDelegateLikeCall(ExpressionNodeInfo info, Func check) { var si = info.SymbolInfo; if (si.CandidateReason == CandidateReason.OverloadResolutionFailure && - si.CandidateSymbols.OfType().All(s => s.MethodKind == MethodKind.DelegateInvoke)) + si.CandidateSymbols.All(check)) { return true; } @@ -153,9 +164,20 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions return true; } - return si.Symbol != null && - si.Symbol.Kind == SymbolKind.Method && - ((IMethodSymbol)si.Symbol).MethodKind == MethodKind.DelegateInvoke; + return check(si.Symbol); + } + + private static bool IsFunctionPointer(ISymbol symbol) + { + return symbol != null && + symbol.Kind == SymbolKind.FunctionPointerType; + } + + private static bool IsDelegateInvoke(ISymbol symbol) + { + return symbol != null && + symbol.Kind == SymbolKind.Method && + ((IMethodSymbol)symbol).MethodKind == MethodKind.DelegateInvoke; } private static bool IsLocalFunctionInvocation(ExpressionNodeInfo info) @@ -168,8 +190,10 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions { return IsNameof((InvocationExpressionSyntax)info.Node) ? ExprKind.NAMEOF - : IsDelegateCall(info) - ? ExprKind.DELEGATE_INVOCATION + : IsDelegateLikeCall(info) + ? IsDelegateInvokeCall(info) + ? ExprKind.DELEGATE_INVOCATION + : ExprKind.FUNCTION_POINTER_INVOCATION : IsLocalFunctionInvocation(info) ? ExprKind.LOCAL_FUNCTION_INVOCATION : ExprKind.METHOD_INVOCATION; diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/Literal.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/Literal.cs index d31a75b33d4..51acebef5c8 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/Literal.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/Literal.cs @@ -21,11 +21,17 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions case SyntaxKind.DefaultLiteralExpression: return ExprKind.DEFAULT; case SyntaxKind.NullLiteralExpression: - info.Type = Entities.NullType.Create(info.Context); // Don't use converted type. + info.SetType(null); // Don't use converted type. return ExprKind.NULL_LITERAL; } - var type = info.Type.Type.symbol; + // short circuit bool literals, because they have no type in `#if A = true` + if (info.IsBoolLiteral()) + { + return ExprKind.BOOL_LITERAL; + } + + var type = info.Type?.Symbol; return GetExprKind(type, info.Node, info.Context); } @@ -82,7 +88,7 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions { var info = new ExpressionInfo( cx, - new AnnotatedType(Entities.Type.Create(cx, type), NullableAnnotation.None), + AnnotatedTypeSymbol.CreateNotAnnotated(type), location, GetExprKind(type, null, cx), parent, @@ -97,7 +103,7 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions { var info = new ExpressionInfo( cx, - NullType.Create(cx), + null, location, ExprKind.NULL_LITERAL, parent, diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/Name.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/Name.cs index d44c85d6ddc..faf5c9e2bd1 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/Name.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/Name.cs @@ -1,5 +1,6 @@ using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp; +using Microsoft.CodeAnalysis.CSharp.Syntax; using System.Linq; namespace Semmle.Extraction.CSharp.Entities.Expressions @@ -26,6 +27,11 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions if (target == null) { + if (IsInsideIfDirective(info.Node)) + { + return DefineSymbol.Create(info); + } + info.Context.ModelError(info.Node, "Failed to resolve name"); return new Unknown(info); } @@ -64,5 +70,10 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions throw new InternalError(info.Node, $"Unhandled identifier kind '{target.Kind}'"); } } + + private static bool IsInsideIfDirective(ExpressionSyntax node) + { + return node.Ancestors().Any(a => a is ElifDirectiveTriviaSyntax || a is IfDirectiveTriviaSyntax); + } } } diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/ObjectCreation.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/ObjectCreation.cs deleted file mode 100644 index ae3d0f10506..00000000000 --- a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/ObjectCreation.cs +++ /dev/null @@ -1,137 +0,0 @@ -using Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.CSharp; -using Microsoft.CodeAnalysis.CSharp.Syntax; -using Semmle.Extraction.Entities; -using Semmle.Extraction.Kinds; -using System.IO; -using System.Linq; - -namespace Semmle.Extraction.CSharp.Entities.Expressions -{ - internal abstract class ObjectCreation : Expression - where TExpressionSyntax : ExpressionSyntax - { - protected ObjectCreation(ExpressionNodeInfo info) - : base(info) { } - } - - // new Foo(...) { ... }. - internal class ExplicitObjectCreation : ObjectCreation - { - private static bool IsDynamicObjectCreation(Context cx, ObjectCreationExpressionSyntax node) - { - return node.ArgumentList != null && node.ArgumentList.Arguments.Any(arg => IsDynamic(cx, arg.Expression)); - } - - private static ExprKind GetKind(Context cx, ObjectCreationExpressionSyntax node) - { - var si = cx.GetModel(node).GetSymbolInfo(node.Type); - return Entities.Type.IsDelegate(si.Symbol as INamedTypeSymbol) ? ExprKind.EXPLICIT_DELEGATE_CREATION : ExprKind.OBJECT_CREATION; - } - - private ExplicitObjectCreation(ExpressionNodeInfo info) - : base(info.SetKind(GetKind(info.Context, (ObjectCreationExpressionSyntax)info.Node))) { } - - public static Expression Create(ExpressionNodeInfo info) => new ExplicitObjectCreation(info).TryPopulate(); - - protected override void PopulateExpression(TextWriter trapFile) - { - if (Syntax.ArgumentList != null) - { - PopulateArguments(trapFile, Syntax.ArgumentList, 0); - } - - var target = cx.GetModel(Syntax).GetSymbolInfo(Syntax); - var method = (IMethodSymbol)target.Symbol; - - if (method != null) - { - trapFile.expr_call(this, Method.Create(cx, method)); - } - - if (IsDynamicObjectCreation(cx, Syntax)) - { - var name = GetDynamicName(Syntax.Type); - if (name.HasValue) - trapFile.dynamic_member_name(this, name.Value.Text); - else - cx.ModelError(Syntax, "Unable to get name for dynamic object creation."); - } - - if (Syntax.Initializer != null) - { - switch (Syntax.Initializer.Kind()) - { - case SyntaxKind.CollectionInitializerExpression: - CollectionInitializer.Create(new ExpressionNodeInfo(cx, Syntax.Initializer, this, -1) { Type = Type }); - break; - case SyntaxKind.ObjectInitializerExpression: - ObjectInitializer.Create(new ExpressionNodeInfo(cx, Syntax.Initializer, this, -1) { Type = Type }); - break; - default: - cx.ModelError("Unhandled initializer in object creation"); - break; - } - } - - TypeMention.Create(cx, Syntax.Type, this, Type); - } - - private static SyntaxToken? GetDynamicName(CSharpSyntaxNode name) - { - switch (name.Kind()) - { - case SyntaxKind.IdentifierName: - return ((IdentifierNameSyntax)name).Identifier; - case SyntaxKind.GenericName: - return ((GenericNameSyntax)name).Identifier; - case SyntaxKind.QualifiedName: - // We ignore any qualifiers, for now - return GetDynamicName(((QualifiedNameSyntax)name).Right); - default: - return null; - } - } - } - - internal class ImplicitObjectCreation : ObjectCreation - { - public ImplicitObjectCreation(ExpressionNodeInfo info) - : base(info.SetKind(ExprKind.OBJECT_CREATION)) { } - - public static Expression Create(ExpressionNodeInfo info) => - new ImplicitObjectCreation(info).TryPopulate(); - - protected override void PopulateExpression(TextWriter trapFile) - { - var target = cx.GetSymbolInfo(Syntax); - var method = (IMethodSymbol)target.Symbol; - - if (method != null) - { - trapFile.expr_call(this, Method.Create(cx, method)); - } - var child = 0; - - var objectInitializer = Syntax.Initializers.Any() ? - new Expression(new ExpressionInfo(cx, Type, Location, ExprKind.OBJECT_INIT, this, -1, false, null)) : - null; - - foreach (var init in Syntax.Initializers) - { - // Create an "assignment" - var property = cx.GetModel(init).GetDeclaredSymbol(init); - var propEntity = Property.Create(cx, property); - var type = Entities.Type.Create(cx, property.GetAnnotatedType()); - var loc = cx.Create(init.GetLocation()); - - var assignment = new Expression(new ExpressionInfo(cx, type, loc, ExprKind.SIMPLE_ASSIGN, objectInitializer, child++, false, null)); - Create(cx, init.Expression, assignment, 0); - Property.Create(cx, property); - - var access = new Expression(new ExpressionInfo(cx, type, loc, ExprKind.PROPERTY_ACCESS, assignment, 1, false, null)); - trapFile.expr_access(access, propEntity); - } - } - } -} diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/ObjectCreation/AnonymousObjectCreation.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/ObjectCreation/AnonymousObjectCreation.cs new file mode 100644 index 00000000000..5a94a4333e8 --- /dev/null +++ b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/ObjectCreation/AnonymousObjectCreation.cs @@ -0,0 +1,50 @@ +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CSharp; +using Microsoft.CodeAnalysis.CSharp.Syntax; +using Semmle.Extraction.Entities; +using Semmle.Extraction.Kinds; +using System.IO; + +namespace Semmle.Extraction.CSharp.Entities.Expressions +{ + internal class AnonymousObjectCreation : Expression + { + public AnonymousObjectCreation(ExpressionNodeInfo info) + : base(info.SetKind(ExprKind.OBJECT_CREATION)) { } + + public static Expression Create(ExpressionNodeInfo info) => + new AnonymousObjectCreation(info).TryPopulate(); + + protected override void PopulateExpression(TextWriter trapFile) + { + var target = cx.GetSymbolInfo(Syntax); + var method = (IMethodSymbol)target.Symbol; + + if (method != null) + { + trapFile.expr_call(this, Method.Create(cx, method)); + } + var child = 0; + + var objectInitializer = Syntax.Initializers.Any() ? + new Expression(new ExpressionInfo(cx, Type, Location, ExprKind.OBJECT_INIT, this, -1, false, null)) : + null; + + foreach (var init in Syntax.Initializers) + { + // Create an "assignment" + var property = cx.GetModel(init).GetDeclaredSymbol(init); + var propEntity = Property.Create(cx, property); + var type = property.GetAnnotatedType(); + var loc = cx.CreateLocation(init.GetLocation()); + + var assignment = new Expression(new ExpressionInfo(cx, type, loc, ExprKind.SIMPLE_ASSIGN, objectInitializer, child++, false, null)); + Create(cx, init.Expression, assignment, 0); + Property.Create(cx, property); + + var access = new Expression(new ExpressionInfo(cx, type, loc, ExprKind.PROPERTY_ACCESS, assignment, 1, false, null)); + trapFile.expr_access(access, propEntity); + } + } + } +} diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/ObjectCreation/BaseObjectCreation.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/ObjectCreation/BaseObjectCreation.cs new file mode 100644 index 00000000000..10f4df8bf7f --- /dev/null +++ b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/ObjectCreation/BaseObjectCreation.cs @@ -0,0 +1,75 @@ +using System.IO; +using System.Linq; +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CSharp; +using Microsoft.CodeAnalysis.CSharp.Syntax; +using Semmle.Extraction.Kinds; + +namespace Semmle.Extraction.CSharp.Entities.Expressions +{ + internal abstract class BaseObjectCreation : Expression + where TExpressionSyntax : BaseObjectCreationExpressionSyntax + { + protected BaseObjectCreation(ExpressionNodeInfo info) + : base(info.SetKind(GetKind(info.Context, (BaseObjectCreationExpressionSyntax)info.Node))) + { + } + + protected override void PopulateExpression(TextWriter trapFile) + { + if (Syntax.ArgumentList != null) + { + PopulateArguments(trapFile, Syntax.ArgumentList, 0); + } + + var target = cx.GetModel(Syntax).GetSymbolInfo(Syntax); + if (target.Symbol is IMethodSymbol method) + { + trapFile.expr_call(this, Method.Create(cx, method)); + } + + if (IsDynamicObjectCreation(cx, Syntax)) + { + if (cx.GetModel(Syntax).GetTypeInfo(Syntax).Type is INamedTypeSymbol type && + !string.IsNullOrEmpty(type.Name)) + { + trapFile.dynamic_member_name(this, type.Name); + } + else + { + cx.ModelError(Syntax, "Unable to get name for dynamic object creation."); + } + } + + if (Syntax.Initializer != null) + { + switch (Syntax.Initializer.Kind()) + { + case SyntaxKind.CollectionInitializerExpression: + CollectionInitializer.Create(new ExpressionNodeInfo(cx, Syntax.Initializer, this, -1).SetType(Type)); + break; + case SyntaxKind.ObjectInitializerExpression: + ObjectInitializer.Create(new ExpressionNodeInfo(cx, Syntax.Initializer, this, -1).SetType(Type)); + break; + default: + cx.ModelError("Unhandled initializer in object creation"); + break; + } + } + } + + private static ExprKind GetKind(Context cx, BaseObjectCreationExpressionSyntax node) + { + var type = cx.GetModel(node).GetTypeInfo(node).Type; + return Entities.Type.IsDelegate(type as INamedTypeSymbol) + ? ExprKind.EXPLICIT_DELEGATE_CREATION + : ExprKind.OBJECT_CREATION; + } + + private static bool IsDynamicObjectCreation(Context cx, BaseObjectCreationExpressionSyntax node) + { + return node.ArgumentList != null && + node.ArgumentList.Arguments.Any(arg => IsDynamic(cx, arg.Expression)); + } + } +} diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/ObjectCreation/ExplicitObjectCreation.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/ObjectCreation/ExplicitObjectCreation.cs new file mode 100644 index 00000000000..51b2db20a9e --- /dev/null +++ b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/ObjectCreation/ExplicitObjectCreation.cs @@ -0,0 +1,20 @@ +using Microsoft.CodeAnalysis.CSharp.Syntax; +using System.IO; + +namespace Semmle.Extraction.CSharp.Entities.Expressions +{ + // new Foo(...) { ... }. + internal class ExplicitObjectCreation : BaseObjectCreation + { + private ExplicitObjectCreation(ExpressionNodeInfo info) : base(info) { } + + public static Expression Create(ExpressionNodeInfo info) => new ExplicitObjectCreation(info).TryPopulate(); + + protected override void PopulateExpression(TextWriter trapFile) + { + base.PopulateExpression(trapFile); + + TypeMention.Create(cx, Syntax.Type, this, Type); + } + } +} diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/ObjectCreation/ImplicitObjectCreation.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/ObjectCreation/ImplicitObjectCreation.cs new file mode 100644 index 00000000000..2cc49d2d542 --- /dev/null +++ b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/ObjectCreation/ImplicitObjectCreation.cs @@ -0,0 +1,19 @@ +using System.IO; +using Microsoft.CodeAnalysis.CSharp.Syntax; + +namespace Semmle.Extraction.CSharp.Entities.Expressions +{ + internal class ImplicitObjectCreation : BaseObjectCreation + { + private ImplicitObjectCreation(ExpressionNodeInfo info) : base(info) { } + + public static Expression Create(ExpressionNodeInfo info) => new ImplicitObjectCreation(info).TryPopulate(); + + protected override void PopulateExpression(TextWriter trapFile) + { + base.PopulateExpression(trapFile); + + trapFile.implicitly_typed_object_creation(this); + } + } +} diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/Patterns/BinaryPattern.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/Patterns/BinaryPattern.cs new file mode 100644 index 00000000000..2d0292ae720 --- /dev/null +++ b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/Patterns/BinaryPattern.cs @@ -0,0 +1,28 @@ +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CSharp; +using Microsoft.CodeAnalysis.CSharp.Syntax; +using Semmle.Extraction.Entities; +using Semmle.Extraction.Kinds; + +namespace Semmle.Extraction.CSharp.Entities.Expressions +{ + internal class BinaryPattern : Expression + { + public BinaryPattern(Context cx, BinaryPatternSyntax syntax, IExpressionParentEntity parent, int child) : + base(new ExpressionInfo(cx, null, cx.CreateLocation(syntax.GetLocation()), GetKind(syntax.OperatorToken, syntax), parent, child, false, null)) + { + Pattern.Create(cx, syntax.Left, this, 0); + Pattern.Create(cx, syntax.Right, this, 1); + } + + private static ExprKind GetKind(SyntaxToken operatorToken, BinaryPatternSyntax syntax) + { + return operatorToken.Kind() switch + { + SyntaxKind.AndKeyword => ExprKind.AND_PATTERN, + SyntaxKind.OrKeyword => ExprKind.OR_PATTERN, + _ => throw new InternalError(syntax, $"Operator '{operatorToken.Kind()}' is not supported in binary patterns.") + }; + } + } +} \ No newline at end of file diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/Patterns/Pattern.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/Patterns/Pattern.cs index 7fe552ec8e9..05f3aab2526 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/Patterns/Pattern.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/Patterns/Pattern.cs @@ -20,6 +20,12 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions case TypePatternSyntax typePattern: return Expressions.TypeAccess.Create(cx, typePattern.Type, parent, child); + case UnaryPatternSyntax unaryPattern: + return new UnaryPattern(cx, unaryPattern, parent, child); + + case BinaryPatternSyntax binaryPattern: + return new BinaryPattern(cx, binaryPattern, parent, child); + case DeclarationPatternSyntax declPattern: // Creates a single local variable declaration. { @@ -27,8 +33,8 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions { if (cx.GetModel(syntax).GetDeclaredSymbol(designation) is ILocalSymbol symbol) { - var type = Type.Create(cx, symbol.GetAnnotatedType()); - return VariableDeclaration.Create(cx, symbol, type, declPattern.Type, cx.Create(syntax.GetLocation()), false, parent, child); + var type = symbol.GetAnnotatedType(); + return VariableDeclaration.Create(cx, symbol, type, declPattern.Type, cx.CreateLocation(syntax.GetLocation()), false, parent, child); } if (designation is DiscardDesignationSyntax) { @@ -42,6 +48,9 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions case RecursivePatternSyntax recPattern: return new RecursivePattern(cx, recPattern, parent, child); + case RelationalPatternSyntax relPattern: + return new RelationalPattern(cx, relPattern, parent, child); + case VarPatternSyntax varPattern: switch (varPattern.Designation) { @@ -50,9 +59,9 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions case SingleVariableDesignationSyntax varDesignation: if (cx.GetModel(syntax).GetDeclaredSymbol(varDesignation) is ILocalSymbol symbol) { - var type = Type.Create(cx, symbol.GetAnnotatedType()); + var type = symbol.GetAnnotatedType(); - return VariableDeclaration.Create(cx, symbol, type, null, cx.Create(syntax.GetLocation()), true, parent, child); + return VariableDeclaration.Create(cx, symbol, type, null, cx.CreateLocation(syntax.GetLocation()), true, parent, child); } throw new InternalError(varPattern, "Unable to get the declared symbol of the var pattern designation."); diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/Patterns/PositionalPattern.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/Patterns/PositionalPattern.cs index b65b9020743..f0ae03ae9dc 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/Patterns/PositionalPattern.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/Patterns/PositionalPattern.cs @@ -7,7 +7,7 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions internal class PositionalPattern : Expression { internal PositionalPattern(Context cx, PositionalPatternClauseSyntax posPc, IExpressionParentEntity parent, int child) : - base(new ExpressionInfo(cx, Entities.NullType.Create(cx), cx.Create(posPc.GetLocation()), ExprKind.POSITIONAL_PATTERN, parent, child, false, null)) + base(new ExpressionInfo(cx, null, cx.CreateLocation(posPc.GetLocation()), ExprKind.POSITIONAL_PATTERN, parent, child, false, null)) { child = 0; foreach (var sub in posPc.Subpatterns) diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/Patterns/PropertyPattern.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/Patterns/PropertyPattern.cs index 147ac595c77..7bd13e7a8a3 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/Patterns/PropertyPattern.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/Patterns/PropertyPattern.cs @@ -7,7 +7,7 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions internal class PropertyPattern : Expression { internal PropertyPattern(Context cx, PropertyPatternClauseSyntax pp, IExpressionParentEntity parent, int child) : - base(new ExpressionInfo(cx, Entities.NullType.Create(cx), cx.Create(pp.GetLocation()), ExprKind.PROPERTY_PATTERN, parent, child, false, null)) + base(new ExpressionInfo(cx, null, cx.CreateLocation(pp.GetLocation()), ExprKind.PROPERTY_PATTERN, parent, child, false, null)) { child = 0; var trapFile = cx.TrapWriter.Writer; diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/Patterns/RecursivePattern.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/Patterns/RecursivePattern.cs index 997c622c818..d29292b3073 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/Patterns/RecursivePattern.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/Patterns/RecursivePattern.cs @@ -15,9 +15,8 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions /// The syntax node of the recursive pattern. /// The parent pattern/expression. /// The child index of this pattern. - /// If this pattern is in the top level of a case/is. In that case, the variable and type access are populated elsewhere. public RecursivePattern(Context cx, RecursivePatternSyntax syntax, IExpressionParentEntity parent, int child) : - base(new ExpressionInfo(cx, Entities.NullType.Create(cx), cx.Create(syntax.GetLocation()), ExprKind.RECURSIVE_PATTERN, parent, child, false, null)) + base(new ExpressionInfo(cx, null, cx.CreateLocation(syntax.GetLocation()), ExprKind.RECURSIVE_PATTERN, parent, child, false, null)) { // Extract the type access if (syntax.Type is TypeSyntax t) @@ -26,9 +25,9 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions // Extract the local variable declaration if (syntax.Designation is VariableDesignationSyntax designation && cx.GetModel(syntax).GetDeclaredSymbol(designation) is ILocalSymbol symbol) { - var type = Entities.Type.Create(cx, symbol.GetAnnotatedType()); + var type = symbol.GetAnnotatedType(); - VariableDeclaration.Create(cx, symbol, type, null, cx.Create(syntax.GetLocation()), false, this, 0); + VariableDeclaration.Create(cx, symbol, type, null, cx.CreateLocation(syntax.GetLocation()), false, this, 0); } if (syntax.PositionalPatternClause is PositionalPatternClauseSyntax posPc) diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/Patterns/RelationalPattern.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/Patterns/RelationalPattern.cs new file mode 100644 index 00000000000..c1a140005dc --- /dev/null +++ b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/Patterns/RelationalPattern.cs @@ -0,0 +1,29 @@ +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CSharp.Syntax; +using Microsoft.CodeAnalysis.CSharp; +using Semmle.Extraction.Kinds; +using Semmle.Extraction.Entities; + +namespace Semmle.Extraction.CSharp.Entities.Expressions +{ + internal class RelationalPattern : Expression + { + public RelationalPattern(Context cx, RelationalPatternSyntax syntax, IExpressionParentEntity parent, int child) : + base(new ExpressionInfo(cx, null, cx.CreateLocation(syntax.GetLocation()), GetKind(syntax.OperatorToken), parent, child, false, null)) + { + Expression.Create(cx, syntax.Expression, this, 0); + } + + private static ExprKind GetKind(SyntaxToken operatorToken) + { + return operatorToken.Kind() switch + { + SyntaxKind.LessThanEqualsToken => ExprKind.LE_PATTERN, + SyntaxKind.GreaterThanEqualsToken => ExprKind.GE_PATTERN, + SyntaxKind.LessThanToken => ExprKind.LT_PATTERN, + SyntaxKind.GreaterThanToken => ExprKind.GT_PATTERN, + _ => throw new InternalError(operatorToken.Parent, $"Relation pattern with operator token '{operatorToken.Kind()}' is not supported."), + }; + } + } +} diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/Patterns/UnaryPattern.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/Patterns/UnaryPattern.cs new file mode 100644 index 00000000000..ce2cf773a92 --- /dev/null +++ b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/Patterns/UnaryPattern.cs @@ -0,0 +1,15 @@ +using Microsoft.CodeAnalysis.CSharp.Syntax; +using Semmle.Extraction.Entities; +using Semmle.Extraction.Kinds; + +namespace Semmle.Extraction.CSharp.Entities.Expressions +{ + internal class UnaryPattern : Expression + { + public UnaryPattern(Context cx, UnaryPatternSyntax syntax, IExpressionParentEntity parent, int child) : + base(new ExpressionInfo(cx, null, cx.CreateLocation(syntax.GetLocation()), ExprKind.NOT_PATTERN, parent, child, false, null)) + { + Pattern.Create(cx, syntax.Pattern, this, 0); + } + } +} \ No newline at end of file diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/Query.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/Query.cs index 83c4a25d3a4..f919aaca568 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/Query.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/Query.cs @@ -22,8 +22,8 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions private class QueryCall : Expression { public QueryCall(Context cx, IMethodSymbol method, SyntaxNode clause, IExpressionParentEntity parent, int child) - : base(new ExpressionInfo(cx, method is null ? NullType.Create(cx) : Entities.Type.Create(cx, method.GetAnnotatedReturnType()), - cx.Create(clause.GetLocation()), + : base(new ExpressionInfo(cx, method?.GetAnnotatedReturnType(), + cx.CreateLocation(clause.GetLocation()), ExprKind.METHOD_INVOCATION, parent, child, false, null)) { if (method != null) @@ -63,21 +63,21 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions protected Expression DeclareRangeVariable(Context cx, IExpressionParentEntity parent, int child, bool getElement, ISymbol variableSymbol, SyntaxToken name) { - var type = Type.Create(cx, cx.GetType(Expr)); + var type = cx.GetType(Expr); - AnnotatedType declType; + AnnotatedTypeSymbol? declType; TypeSyntax declTypeSyntax = null; if (getElement) { if (node is FromClauseSyntax from && from.Type != null) { declTypeSyntax = from.Type; - declType = Type.Create(cx, cx.GetType(from.Type)); + declType = cx.GetType(from.Type); } else { declTypeSyntax = null; - declType = type.Type.ElementType; + declType = GetElementType(cx, type.Symbol); } } else @@ -89,7 +89,7 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions variableSymbol, declType, declTypeSyntax, - cx.Create(node.GetLocation()), + cx.CreateLocation(node.GetLocation()), true, parent, child @@ -97,13 +97,43 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions Expression.Create(cx, Expr, decl, 0); - var nameLoc = cx.Create(name.GetLocation()); + var nameLoc = cx.CreateLocation(name.GetLocation()); var access = new Expression(new ExpressionInfo(cx, type, nameLoc, ExprKind.LOCAL_VARIABLE_ACCESS, decl, 1, false, null)); cx.TrapWriter.Writer.expr_access(access, LocalVariable.Create(cx, variableSymbol)); return decl; } + private static AnnotatedTypeSymbol? GetEnumerableType(Context cx, INamedTypeSymbol type) + { + return type.SpecialType == SpecialType.System_Collections_IEnumerable + ? cx.Compilation.ObjectType.WithAnnotation(NullableAnnotation.NotAnnotated) + : type.OriginalDefinition.SpecialType == SpecialType.System_Collections_Generic_IEnumerable_T + ? type.GetAnnotatedTypeArguments().First() + : (AnnotatedTypeSymbol?)null; + } + + private static AnnotatedTypeSymbol? GetEnumerableElementType(Context cx, INamedTypeSymbol type) + { + var et = GetEnumerableType(cx, type); + if (et != null) + return et; + + return type.AllInterfaces + .Where(i => i.OriginalDefinition.SpecialType == SpecialType.System_Collections_Generic_IEnumerable_T) + .Concat(type.AllInterfaces.Where(i => i.SpecialType == SpecialType.System_Collections_IEnumerable)) + .Select(i => GetEnumerableType(cx, i)) + .FirstOrDefault(); + } + + private static AnnotatedTypeSymbol? GetElementType(Context cx, ITypeSymbol symbol) => + symbol switch + { + IArrayTypeSymbol a => a.GetAnnotatedElementType(), + INamedTypeSymbol n => GetEnumerableElementType(cx, n), + _ => null + }; + protected void PopulateArguments(Context cx, QueryCall callExpr, int child) { foreach (var e in arguments) diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/Switch.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/Switch.cs index 3585996c7db..a6095ec63a2 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/Switch.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/Switch.cs @@ -29,7 +29,7 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions { internal SwitchCase(Context cx, SwitchExpressionArmSyntax arm, Switch parent, int child) : base(new ExpressionInfo( - cx, Entities.Type.Create(cx, cx.GetType(arm.Expression)), cx.Create(arm.GetLocation()), + cx, cx.GetType(arm.Expression), cx.CreateLocation(arm.GetLocation()), ExprKind.SWITCH_CASE, parent, child, false, null)) { Expressions.Pattern.Create(cx, arm.Pattern, this, 0); diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/This.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/This.cs index 838e494ff00..a13c2cb95bc 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/This.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/This.cs @@ -7,8 +7,8 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions { private This(IExpressionInfo info) : base(info) { } - public static This CreateImplicit(Context cx, Type @class, Extraction.Entities.Location loc, IExpressionParentEntity parent, int child) => - new This(new ExpressionInfo(cx, new AnnotatedType(@class, NullableAnnotation.None), loc, Kinds.ExprKind.THIS_ACCESS, parent, child, true, null)); + public static This CreateImplicit(Context cx, ITypeSymbol @class, Extraction.Entities.Location loc, IExpressionParentEntity parent, int child) => + new This(new ExpressionInfo(cx, AnnotatedTypeSymbol.CreateNotAnnotated(@class), loc, Kinds.ExprKind.THIS_ACCESS, parent, child, true, null)); public static This CreateExplicit(ExpressionNodeInfo info) => new This(info.SetKind(ExprKind.THIS_ACCESS)); } diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/TypeAccess.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/TypeAccess.cs index 334ae764d26..e5c0fd3ac66 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/TypeAccess.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/TypeAccess.cs @@ -15,7 +15,7 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions { case SyntaxKind.SimpleMemberAccessExpression: var maes = (MemberAccessExpressionSyntax)Syntax; - if (Type.Type.ContainingType == null) + if (Type?.Symbol.ContainingType is null) { // namespace qualifier TypeMention.Create(cx, maes.Name, this, Type, Syntax.GetLocation()); @@ -39,7 +39,7 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions { var typeAccessInfo = new ExpressionInfo( cx, - new AnnotatedType(Entities.Type.Create(cx, type), Microsoft.CodeAnalysis.NullableAnnotation.None), + AnnotatedTypeSymbol.CreateNotAnnotated(type), location, ExprKind.TYPE_ACCESS, parent, diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/TypeOf.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/TypeOf.cs index e99b7d8b324..686e4156528 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/TypeOf.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/TypeOf.cs @@ -21,7 +21,7 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions { var info = new ExpressionInfo( cx, - new AnnotatedType(Entities.Type.Create(cx, type), Microsoft.CodeAnalysis.NullableAnnotation.None), + AnnotatedTypeSymbol.CreateNotAnnotated(type), location, ExprKind.TYPEOF, parent, diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/VariableDeclaration.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/VariableDeclaration.cs index 84b61956ae6..674f45b3f21 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/VariableDeclaration.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/VariableDeclaration.cs @@ -11,7 +11,7 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions { private VariableDeclaration(IExpressionInfo info) : base(info) { } - public static VariableDeclaration Create(Context cx, ISymbol symbol, AnnotatedType type, TypeSyntax optionalSyntax, Extraction.Entities.Location exprLocation, bool isVar, IExpressionParentEntity parent, int child) + public static VariableDeclaration Create(Context cx, ISymbol symbol, AnnotatedTypeSymbol? type, TypeSyntax optionalSyntax, Extraction.Entities.Location exprLocation, bool isVar, IExpressionParentEntity parent, int child) { var ret = new VariableDeclaration(new ExpressionInfo(cx, type, exprLocation, ExprKind.LOCAL_VAR_DECL, parent, child, false, null)); cx.Try(null, null, () => @@ -30,10 +30,10 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions if (variableSymbol == null) { cx.ModelError(node, "Failed to determine local variable"); - return Create(cx, node, NullType.Create(cx), parent, child); + return Create(cx, node, (AnnotatedTypeSymbol?)null, parent, child); } - var type = Entities.Type.Create(cx, variableSymbol.GetAnnotatedType()); + var type = variableSymbol.GetAnnotatedType(); var ret = Create(cx, designation, type, parent, child); cx.Try(null, null, () => { @@ -49,8 +49,8 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions /// public static Expression CreateParenthesized(Context cx, DeclarationExpressionSyntax node, ParenthesizedVariableDesignationSyntax designation, IExpressionParentEntity parent, int child) { - var type = Entities.NullType.Create(cx); // Should ideally be a corresponding tuple type - var tuple = new Expression(new ExpressionInfo(cx, type, cx.Create(node.GetLocation()), ExprKind.TUPLE, parent, child, false, null)); + AnnotatedTypeSymbol? type = null; // Should ideally be a corresponding tuple type + var tuple = new Expression(new ExpressionInfo(cx, type, cx.CreateLocation(node.GetLocation()), ExprKind.TUPLE, parent, child, false, null)); cx.Try(null, null, () => { @@ -64,8 +64,8 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions public static Expression CreateParenthesized(Context cx, VarPatternSyntax varPattern, ParenthesizedVariableDesignationSyntax designation, IExpressionParentEntity parent, int child) { - var type = NullType.Create(cx); // Should ideally be a corresponding tuple type - var tuple = new Expression(new ExpressionInfo(cx, type, cx.Create(varPattern.GetLocation()), ExprKind.TUPLE, parent, child, false, null)); + AnnotatedTypeSymbol? type = null; // Should ideally be a corresponding tuple type + var tuple = new Expression(new ExpressionInfo(cx, type, cx.CreateLocation(varPattern.GetLocation()), ExprKind.TUPLE, parent, child, false, null)); cx.Try(null, null, () => { @@ -80,7 +80,7 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions case SingleVariableDesignationSyntax single: if (cx.GetModel(variable).GetDeclaredSymbol(single) is ILocalSymbol local) { - var decl = Create(cx, variable, Entities.Type.Create(cx, local.GetAnnotatedType()), tuple, child0++); + var decl = Create(cx, variable, local.GetAnnotatedType(), tuple, child0++); var l = LocalVariable.Create(cx, local); l.PopulateManual(decl, true); } @@ -111,25 +111,24 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions case ParenthesizedVariableDesignationSyntax paren: return CreateParenthesized(cx, node, paren, parent, child); case DiscardDesignationSyntax discard: - var ti = cx.GetType(discard); - var type = Entities.Type.Create(cx, ti); + var type = cx.GetType(discard); return Create(cx, node, type, parent, child); default: cx.ModelError(node, "Failed to determine designation type"); - return Create(cx, node, NullType.Create(cx), parent, child); + return Create(cx, node, null, parent, child); } } public static Expression Create(Context cx, DeclarationExpressionSyntax node, IExpressionParentEntity parent, int child) => Create(cx, node, node.Designation, parent, child); - public static VariableDeclaration Create(Context cx, CSharpSyntaxNode c, AnnotatedType type, IExpressionParentEntity parent, int child) => - new VariableDeclaration(new ExpressionInfo(cx, type, cx.Create(c.FixedLocation()), ExprKind.LOCAL_VAR_DECL, parent, child, false, null)); + public static VariableDeclaration Create(Context cx, CSharpSyntaxNode c, AnnotatedTypeSymbol? type, IExpressionParentEntity parent, int child) => + new VariableDeclaration(new ExpressionInfo(cx, type, cx.CreateLocation(c.FixedLocation()), ExprKind.LOCAL_VAR_DECL, parent, child, false, null)); public static VariableDeclaration Create(Context cx, CatchDeclarationSyntax d, bool isVar, IExpressionParentEntity parent, int child) { var symbol = cx.GetModel(d).GetDeclaredSymbol(d); - var type = Entities.Type.Create(cx, symbol.GetAnnotatedType()); + var type = symbol.GetAnnotatedType(); var ret = Create(cx, d, type, parent, child); cx.Try(d, null, () => { @@ -141,7 +140,7 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions return ret; } - public static VariableDeclaration CreateDeclarator(Context cx, VariableDeclaratorSyntax d, AnnotatedType type, bool isVar, IExpressionParentEntity parent, int child) + public static VariableDeclaration CreateDeclarator(Context cx, VariableDeclaratorSyntax d, AnnotatedTypeSymbol type, bool isVar, IExpressionParentEntity parent, int child) { var ret = Create(cx, d, type, parent, child); cx.Try(d, null, () => @@ -170,7 +169,7 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions { public static void Populate(Context cx, VariableDeclarationSyntax decl, IExpressionParentEntity parent, int child, int childIncrement = 1) { - var type = Type.Create(cx, cx.GetType(decl.Type)); + var type = cx.GetType(decl.Type); foreach (var v in decl.Variables) { diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Field.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Field.cs index 2990332648d..d17b2f003aa 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Field.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Field.cs @@ -14,7 +14,7 @@ namespace Semmle.Extraction.CSharp.Entities private Field(Context cx, IFieldSymbol init) : base(cx, init) { - type = new Lazy(() => Entities.Type.Create(cx, symbol.GetAnnotatedType())); + type = new Lazy(() => Entities.Type.Create(cx, symbol.Type)); } public static Field Create(Context cx, IFieldSymbol field) => FieldFactory.Instance.CreateEntityFromSymbol(cx, field); @@ -32,7 +32,7 @@ namespace Semmle.Extraction.CSharp.Entities PopulateNullability(trapFile, symbol.GetAnnotatedType()); var unboundFieldKey = Field.Create(Context, symbol.OriginalDefinition); - trapFile.fields(this, (symbol.IsConst ? 2 : 1), symbol.Name, ContainingType, Type.Type.TypeRef, unboundFieldKey); + trapFile.fields(this, (symbol.IsConst ? 2 : 1), symbol.Name, ContainingType, Type.TypeRef, unboundFieldKey); PopulateModifiers(trapFile); @@ -65,13 +65,13 @@ namespace Semmle.Extraction.CSharp.Entities { Context.PopulateLater(() => { - var loc = Context.Create(initializer.GetLocation()); + var loc = Context.CreateLocation(initializer.GetLocation()); var fieldAccess = AddInitializerAssignment(trapFile, initializer.Initializer.Value, loc, null, ref child); if (!symbol.IsStatic) { - This.CreateImplicit(Context, Entities.Type.Create(Context, symbol.ContainingType), Location, fieldAccess, -1); + This.CreateImplicit(Context, symbol.ContainingType, Location, fieldAccess, -1); } }); } @@ -86,7 +86,7 @@ namespace Semmle.Extraction.CSharp.Entities ? Expression.ValueAsString(symbol.ConstantValue) : null; - var loc = Context.Create(initializer.GetLocation()); + var loc = Context.CreateLocation(initializer.GetLocation()); AddInitializerAssignment(trapFile, initializer.EqualsValue.Value, loc, constValue, ref child); } @@ -107,19 +107,20 @@ namespace Semmle.Extraction.CSharp.Entities private Expression AddInitializerAssignment(TextWriter trapFile, ExpressionSyntax initializer, Extraction.Entities.Location loc, string constValue, ref int child) { - var simpleAssignExpr = new Expression(new ExpressionInfo(Context, Type, loc, ExprKind.SIMPLE_ASSIGN, this, child++, false, constValue)); + var type = symbol.GetAnnotatedType(); + var simpleAssignExpr = new Expression(new ExpressionInfo(Context, type, loc, ExprKind.SIMPLE_ASSIGN, this, child++, false, constValue)); Expression.CreateFromNode(new ExpressionNodeInfo(Context, initializer, simpleAssignExpr, 0)); - var access = new Expression(new ExpressionInfo(Context, Type, Location, ExprKind.FIELD_ACCESS, simpleAssignExpr, 1, false, constValue)); + var access = new Expression(new ExpressionInfo(Context, type, Location, ExprKind.FIELD_ACCESS, simpleAssignExpr, 1, false, constValue)); trapFile.expr_access(access, this); return access; } - private readonly Lazy type; - public AnnotatedType Type => type.Value; + private readonly Lazy type; + public Type Type => type.Value; public override void WriteId(TextWriter trapFile) { - trapFile.WriteSubId(Type.Type); + trapFile.WriteSubId(Type); trapFile.Write(" "); trapFile.WriteSubId(ContainingType); trapFile.Write('.'); diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/IExpressionInfo.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/IExpressionInfo.cs new file mode 100644 index 00000000000..1a43a6fbd02 --- /dev/null +++ b/csharp/extractor/Semmle.Extraction.CSharp/Entities/IExpressionInfo.cs @@ -0,0 +1,53 @@ +using Microsoft.CodeAnalysis; +using Semmle.Extraction.Kinds; + +namespace Semmle.Extraction.CSharp.Entities +{ + /// + /// Holds all information required to create an Expression entity. + /// + internal interface IExpressionInfo + { + Context Context { get; } + + /// + /// The type of the expression. + /// + AnnotatedTypeSymbol? Type { get; } + + /// + /// The location of the expression. + /// + Extraction.Entities.Location Location { get; } + + /// + /// The kind of the expression. + /// + ExprKind Kind { get; } + + /// + /// The parent of the expression. + /// + IExpressionParentEntity Parent { get; } + + /// + /// The child index of the expression. + /// + int Child { get; } + + /// + /// Holds if this is an implicit expression. + /// + bool IsCompilerGenerated { get; } + + /// + /// Gets a string representation of the value. + /// null is encoded as the string "null". + /// If the expression does not have a value, then this + /// is null. + /// + string ExprValue { get; } + + NullableFlowState FlowState { get; } + } +} diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/IExpressionParentEntity.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/IExpressionParentEntity.cs new file mode 100644 index 00000000000..a8e4df3d6ca --- /dev/null +++ b/csharp/extractor/Semmle.Extraction.CSharp/Entities/IExpressionParentEntity.cs @@ -0,0 +1,10 @@ +namespace Semmle.Extraction.CSharp.Entities +{ + public interface IExpressionParentEntity : IEntity + { + /// + /// Whether this entity is the parent of a top-level expression. + /// + bool IsTopLevelParent { get; } + } +} diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/IStatementParentEntity.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/IStatementParentEntity.cs new file mode 100644 index 00000000000..40bc0f218c0 --- /dev/null +++ b/csharp/extractor/Semmle.Extraction.CSharp/Entities/IStatementParentEntity.cs @@ -0,0 +1,10 @@ +namespace Semmle.Extraction.CSharp.Entities +{ + /// + /// Whether this entity is the parent of a top-level statement. + /// + public interface IStatementParentEntity : IEntity + { + bool IsTopLevelParent { get; } + } +} diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Indexer.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Indexer.cs index 5873d3e19f4..70b15a6fe16 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Indexer.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Indexer.cs @@ -46,7 +46,7 @@ namespace Semmle.Extraction.CSharp.Entities { // The expression may need to reference parameters in the getter. // So we need to arrange that the expression is populated after the getter. - Context.PopulateLater(() => Expression.CreateFromNode(new ExpressionNodeInfo(Context, expressionBody, this, 0) { Type = Type.Create(Context, symbol.GetAnnotatedType()) })); + Context.PopulateLater(() => Expression.CreateFromNode(new ExpressionNodeInfo(Context, expressionBody, this, 0).SetType(symbol.GetAnnotatedType()))); } } diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/LocalFunction.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/LocalFunction.cs index 309feabfe3d..b376566e841 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp/Entities/LocalFunction.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp/Entities/LocalFunction.cs @@ -1,8 +1,6 @@ using Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.CSharp.Syntax; using System; using System.IO; -using System.Linq; namespace Semmle.Extraction.CSharp.Entities { @@ -39,7 +37,7 @@ namespace Semmle.Extraction.CSharp.Entities var originalDefinition = IsSourceDeclaration ? this : Create(Context, symbol.OriginalDefinition); var returnType = Type.Create(Context, symbol.ReturnType); trapFile.local_functions(this, symbol.Name, returnType, originalDefinition); - ExtractRefReturn(trapFile); + ExtractRefReturn(trapFile, symbol, this); } public override TrapStackBehaviour TrapStackBehaviour => TrapStackBehaviour.NeedsLabel; diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/LocalVariable.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/LocalVariable.cs index de44b16d69f..e988ec2c815 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp/Entities/LocalVariable.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp/Entities/LocalVariable.cs @@ -24,9 +24,9 @@ namespace Semmle.Extraction.CSharp.Entities { var trapFile = Context.TrapWriter.Writer; var (kind, type) = symbol is ILocalSymbol l - ? (l.IsRef ? 3 : l.IsConst ? 2 : 1, Type.Create(Context, l.GetAnnotatedType())) + ? (l.IsRef ? 3 : l.IsConst ? 2 : 1, l.GetAnnotatedType()) : (1, parent.Type); - trapFile.localvars(this, kind, symbol.Name, isVar ? 1 : 0, type.Type.TypeRef, parent); + trapFile.localvars(this, kind, symbol.Name, isVar ? 1 : 0, Type.Create(Context, type).TypeRef, parent); if (symbol is ILocalSymbol local) { diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Method.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Method.cs index 94e8c838e7b..00bf8f3638e 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Method.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Method.cs @@ -1,4 +1,5 @@ using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp.Syntax; using Semmle.Extraction.CSharp.Populators; using System.Collections.Generic; @@ -40,7 +41,9 @@ namespace Semmle.Extraction.CSharp.Entities foreach (var p in parameters.Zip(originalParameters, (paramSymbol, originalParam) => new { paramSymbol, originalParam })) { - var original = SymbolEqualityComparer.Default.Equals(p.paramSymbol, p.originalParam) ? null : Parameter.Create(Context, p.originalParam, originalMethod); + var original = SymbolEqualityComparer.Default.Equals(p.paramSymbol, p.originalParam) + ? null + : Parameter.Create(Context, p.originalParam, originalMethod); Parameter.Create(Context, p.paramSymbol, this, original); } @@ -81,11 +84,21 @@ namespace Semmle.Extraction.CSharp.Entities else Expression.Create(Context, expr, this, 0); - Context.NumberOfLines(trapFile, BodyDeclaringSymbol, this); + NumberOfLines(trapFile, BodyDeclaringSymbol, this); }); } } + public static void NumberOfLines(TextWriter trapFile, ISymbol symbol, IEntity callable) + { + foreach (var decl in symbol.DeclaringSyntaxReferences) + { + var node = (CSharpSyntaxNode)decl.GetSyntax(); + var lineCounts = node.Accept(new AstLineCounter()); + trapFile.numlines(callable, lineCounts); + } + } + public void Overrides(TextWriter trapFile) { foreach (var explicitInterface in symbol.ExplicitInterfaceImplementations @@ -110,7 +123,7 @@ namespace Semmle.Extraction.CSharp.Entities /// /// Factored out to share logic between `Method` and `UserOperator`. /// - protected static void BuildMethodId(Method m, TextWriter trapFile) + private static void BuildMethodId(Method m, TextWriter trapFile) { m.symbol.ReturnType.BuildOrWriteId(m.Context, trapFile, m.symbol); trapFile.Write(" "); @@ -324,12 +337,12 @@ namespace Semmle.Extraction.CSharp.Entities } } - protected void ExtractRefReturn(TextWriter trapFile) + public static void ExtractRefReturn(TextWriter trapFile, IMethodSymbol method, IEntity element) { - if (symbol.ReturnsByRef) - trapFile.type_annotation(this, Kinds.TypeAnnotation.Ref); - if (symbol.ReturnsByRefReadonly) - trapFile.type_annotation(this, Kinds.TypeAnnotation.ReadonlyRef); + if (method.ReturnsByRef) + trapFile.type_annotation(element, Kinds.TypeAnnotation.Ref); + if (method.ReturnsByRefReadonly) + trapFile.type_annotation(element, Kinds.TypeAnnotation.ReadonlyRef); } protected void PopulateMethod(TextWriter trapFile) diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/NamespaceDeclaration.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/NamespaceDeclaration.cs index 17f9a198a39..3a19417008a 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp/Entities/NamespaceDeclaration.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp/Entities/NamespaceDeclaration.cs @@ -22,7 +22,7 @@ namespace Semmle.Extraction.CSharp.Entities public override void WriteId(TextWriter trapFile) { - trapFile.WriteSubId(Context.Create(ReportingLocation)); + trapFile.WriteSubId(Context.CreateLocation(ReportingLocation)); trapFile.Write(";namespacedeclaration"); } @@ -31,7 +31,7 @@ namespace Semmle.Extraction.CSharp.Entities var @namespace = (INamespaceSymbol)Context.GetModel(node).GetSymbolInfo(node.Name).Symbol; var ns = Namespace.Create(Context, @namespace); trapFile.namespace_declarations(this, ns); - trapFile.namespace_declaration_location(this, Context.Create(node.Name.GetLocation())); + trapFile.namespace_declaration_location(this, Context.CreateLocation(node.Name.GetLocation())); var visitor = new Populators.TypeOrNamespaceVisitor(Context, trapFile, this); diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/OrdinaryMethod.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/OrdinaryMethod.cs index dbeab838b25..d81fc25f72b 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp/Entities/OrdinaryMethod.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp/Entities/OrdinaryMethod.cs @@ -49,7 +49,7 @@ namespace Semmle.Extraction.CSharp.Entities PopulateGenerics(trapFile); Overrides(trapFile); - ExtractRefReturn(trapFile); + ExtractRefReturn(trapFile, symbol, this); ExtractCompilerGenerated(trapFile); } diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Parameter.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Parameter.cs index c42a3edd236..bb87fccdd74 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Parameter.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Parameter.cs @@ -110,7 +110,15 @@ namespace Semmle.Extraction.CSharp.Entities trapFile.@params(this, Name, type.TypeRef, Ordinal, ParamKind, Parent, Original); foreach (var l in symbol.Locations) - trapFile.param_location(this, Context.Create(l)); + trapFile.param_location(this, Context.CreateLocation(l)); + + if (!symbol.Locations.Any() && + symbol.ContainingSymbol is IMethodSymbol ms && + ms.Name == WellKnownMemberNames.TopLevelStatementsEntryPointMethodName && + ms.ContainingType.Name == WellKnownMemberNames.TopLevelStatementsEntryPointTypeName) + { + trapFile.param_location(this, Context.CreateLocation()); + } if (!IsSourceDeclaration || !symbol.FromSource()) return; diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/PreprocessorDirectives/DefineDirective.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/PreprocessorDirectives/DefineDirective.cs new file mode 100644 index 00000000000..2ca967a4864 --- /dev/null +++ b/csharp/extractor/Semmle.Extraction.CSharp/Entities/PreprocessorDirectives/DefineDirective.cs @@ -0,0 +1,18 @@ +using Microsoft.CodeAnalysis.CSharp.Syntax; +using System.IO; + +namespace Semmle.Extraction.CSharp.Entities +{ + internal class DefineDirective : PreprocessorDirective + { + public DefineDirective(Context cx, DefineDirectiveTriviaSyntax trivia) + : base(cx, trivia) + { + } + + protected override void PopulatePreprocessor(TextWriter trapFile) + { + trapFile.directive_defines(this, trivia.Name.ToString()); + } + } +} diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/PreprocessorDirectives/ElifDirective.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/PreprocessorDirectives/ElifDirective.cs new file mode 100644 index 00000000000..ace89464b96 --- /dev/null +++ b/csharp/extractor/Semmle.Extraction.CSharp/Entities/PreprocessorDirectives/ElifDirective.cs @@ -0,0 +1,28 @@ +using Microsoft.CodeAnalysis.CSharp.Syntax; +using System.IO; + +namespace Semmle.Extraction.CSharp.Entities +{ + internal class ElifDirective : PreprocessorDirective, IIfSiblingDirective, IExpressionParentEntity + { + private readonly IfDirective start; + private readonly int index; + + public ElifDirective(Context cx, ElifDirectiveTriviaSyntax trivia, IfDirective start, int index) + : base(cx, trivia, populateFromBase: false) + { + this.start = start; + this.index = index; + TryPopulate(); + } + + public bool IsTopLevelParent => true; + + protected override void PopulatePreprocessor(TextWriter trapFile) + { + trapFile.directive_elifs(this, trivia.BranchTaken, trivia.ConditionValue, start, index); + + Expression.Create(cx, trivia.Condition, this, 0); + } + } +} diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/PreprocessorDirectives/ElseDirective.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/PreprocessorDirectives/ElseDirective.cs new file mode 100644 index 00000000000..7ab7d45b6e9 --- /dev/null +++ b/csharp/extractor/Semmle.Extraction.CSharp/Entities/PreprocessorDirectives/ElseDirective.cs @@ -0,0 +1,24 @@ +using Microsoft.CodeAnalysis.CSharp.Syntax; +using System.IO; + +namespace Semmle.Extraction.CSharp.Entities +{ + internal class ElseDirective : PreprocessorDirective, IIfSiblingDirective + { + private readonly IfDirective start; + private readonly int index; + + public ElseDirective(Context cx, ElseDirectiveTriviaSyntax trivia, IfDirective start, int index) + : base(cx, trivia, populateFromBase: false) + { + this.start = start; + this.index = index; + TryPopulate(); + } + + protected override void PopulatePreprocessor(TextWriter trapFile) + { + trapFile.directive_elses(this, trivia.BranchTaken, start, index); + } + } +} diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/PreprocessorDirectives/EndIfDirective.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/PreprocessorDirectives/EndIfDirective.cs new file mode 100644 index 00000000000..9c349844dc6 --- /dev/null +++ b/csharp/extractor/Semmle.Extraction.CSharp/Entities/PreprocessorDirectives/EndIfDirective.cs @@ -0,0 +1,22 @@ +using Microsoft.CodeAnalysis.CSharp.Syntax; +using System.IO; + +namespace Semmle.Extraction.CSharp.Entities +{ + internal class EndIfDirective : PreprocessorDirective + { + private readonly IfDirective start; + + public EndIfDirective(Context cx, EndIfDirectiveTriviaSyntax trivia, IfDirective start) + : base(cx, trivia, populateFromBase: false) + { + this.start = start; + TryPopulate(); + } + + protected override void PopulatePreprocessor(TextWriter trapFile) + { + trapFile.directive_endifs(this, start); + } + } +} diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/PreprocessorDirectives/EndRegionDirective.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/PreprocessorDirectives/EndRegionDirective.cs new file mode 100644 index 00000000000..d4d75470a97 --- /dev/null +++ b/csharp/extractor/Semmle.Extraction.CSharp/Entities/PreprocessorDirectives/EndRegionDirective.cs @@ -0,0 +1,22 @@ +using Microsoft.CodeAnalysis.CSharp.Syntax; +using System.IO; + +namespace Semmle.Extraction.CSharp.Entities +{ + internal class EndRegionDirective : PreprocessorDirective + { + private readonly RegionDirective region; + + public EndRegionDirective(Context cx, EndRegionDirectiveTriviaSyntax trivia, RegionDirective region) + : base(cx, trivia, populateFromBase: false) + { + this.region = region; + TryPopulate(); + } + + protected override void PopulatePreprocessor(TextWriter trapFile) + { + trapFile.directive_endregions(this, region); + } + } +} diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/PreprocessorDirectives/ErrorDirective.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/PreprocessorDirectives/ErrorDirective.cs new file mode 100644 index 00000000000..2917d077839 --- /dev/null +++ b/csharp/extractor/Semmle.Extraction.CSharp/Entities/PreprocessorDirectives/ErrorDirective.cs @@ -0,0 +1,18 @@ +using Microsoft.CodeAnalysis.CSharp.Syntax; +using System.IO; + +namespace Semmle.Extraction.CSharp.Entities +{ + internal class ErrorDirective : PreprocessorDirective + { + public ErrorDirective(Context cx, ErrorDirectiveTriviaSyntax trivia) + : base(cx, trivia) + { + } + + protected override void PopulatePreprocessor(TextWriter trapFile) + { + trapFile.directive_errors(this, trivia.EndOfDirectiveToken.LeadingTrivia.ToString()); + } + } +} diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/PreprocessorDirectives/IIfSiblingDirective.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/PreprocessorDirectives/IIfSiblingDirective.cs new file mode 100644 index 00000000000..7a849962f09 --- /dev/null +++ b/csharp/extractor/Semmle.Extraction.CSharp/Entities/PreprocessorDirectives/IIfSiblingDirective.cs @@ -0,0 +1,4 @@ +namespace Semmle.Extraction.CSharp.Entities +{ + internal interface IIfSiblingDirective { } +} diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/PreprocessorDirectives/IfDirective.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/PreprocessorDirectives/IfDirective.cs new file mode 100644 index 00000000000..e1b81e60d8a --- /dev/null +++ b/csharp/extractor/Semmle.Extraction.CSharp/Entities/PreprocessorDirectives/IfDirective.cs @@ -0,0 +1,22 @@ +using Microsoft.CodeAnalysis.CSharp.Syntax; +using System.IO; + +namespace Semmle.Extraction.CSharp.Entities +{ + internal class IfDirective : PreprocessorDirective, IExpressionParentEntity + { + public IfDirective(Context cx, IfDirectiveTriviaSyntax trivia) + : base(cx, trivia) + { + } + + public bool IsTopLevelParent => true; + + protected override void PopulatePreprocessor(TextWriter trapFile) + { + trapFile.directive_ifs(this, trivia.BranchTaken, trivia.ConditionValue); + + Expression.Create(cx, trivia.Condition, this, 0); + } + } +} diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/PreprocessorDirectives/LineDirective.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/PreprocessorDirectives/LineDirective.cs new file mode 100644 index 00000000000..54681d317e9 --- /dev/null +++ b/csharp/extractor/Semmle.Extraction.CSharp/Entities/PreprocessorDirectives/LineDirective.cs @@ -0,0 +1,40 @@ +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CSharp; +using Microsoft.CodeAnalysis.CSharp.Syntax; +using System.IO; + +namespace Semmle.Extraction.CSharp.Entities +{ + internal class LineDirective : PreprocessorDirective + { + public LineDirective(Context cx, LineDirectiveTriviaSyntax trivia) + : base(cx, trivia) + { + } + + protected override void PopulatePreprocessor(TextWriter trapFile) + { + var type = trivia.Line.Kind() switch + { + SyntaxKind.DefaultKeyword => 0, + SyntaxKind.HiddenKeyword => 1, + SyntaxKind.NumericLiteralToken => 2, + _ => throw new InternalError(trivia, "Unhandled line token kind") + }; + + trapFile.directive_lines(this, type); + + if (trivia.Line.IsKind(SyntaxKind.NumericLiteralToken)) + { + var value = (int)trivia.Line.Value; + trapFile.directive_line_value(this, value); + + if (!string.IsNullOrWhiteSpace(trivia.File.ValueText)) + { + var file = Extraction.Entities.File.Create(cx, trivia.File.ValueText); + trapFile.directive_line_file(this, file); + } + } + } + } +} diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/PreprocessorDirectives/NullableDirective.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/PreprocessorDirectives/NullableDirective.cs new file mode 100644 index 00000000000..e6bb4e79fed --- /dev/null +++ b/csharp/extractor/Semmle.Extraction.CSharp/Entities/PreprocessorDirectives/NullableDirective.cs @@ -0,0 +1,35 @@ +using Microsoft.CodeAnalysis.CSharp; +using Microsoft.CodeAnalysis.CSharp.Syntax; +using System.IO; + +namespace Semmle.Extraction.CSharp.Entities +{ + internal class NullableDirective : PreprocessorDirective + { + public NullableDirective(Context cx, NullableDirectiveTriviaSyntax trivia) + : base(cx, trivia) + { + } + + protected override void PopulatePreprocessor(TextWriter trapFile) + { + var setting = trivia.SettingToken.Kind() switch + { + SyntaxKind.DisableKeyword => 0, + SyntaxKind.EnableKeyword => 1, + SyntaxKind.RestoreKeyword => 2, + _ => throw new InternalError(trivia, "Unhandled setting token kind") + }; + + var target = trivia.TargetToken.Kind() switch + { + SyntaxKind.None => 0, + SyntaxKind.AnnotationsKeyword => 1, + SyntaxKind.WarningsKeyword => 2, + _ => throw new InternalError(trivia, "Unhandled target token kind") + }; + + trapFile.directive_nullables(this, setting, target); + } + } +} diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/PreprocessorDirectives/PragmaChecksumDirective.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/PreprocessorDirectives/PragmaChecksumDirective.cs new file mode 100644 index 00000000000..dff901fa826 --- /dev/null +++ b/csharp/extractor/Semmle.Extraction.CSharp/Entities/PreprocessorDirectives/PragmaChecksumDirective.cs @@ -0,0 +1,19 @@ +using Microsoft.CodeAnalysis.CSharp.Syntax; +using System.IO; + +namespace Semmle.Extraction.CSharp.Entities +{ + internal class PragmaChecksumDirective : PreprocessorDirective + { + public PragmaChecksumDirective(Context cx, PragmaChecksumDirectiveTriviaSyntax trivia) + : base(cx, trivia) + { + } + + protected override void PopulatePreprocessor(TextWriter trapFile) + { + var file = Extraction.Entities.File.Create(cx, trivia.File.ValueText); + trapFile.pragma_checksums(this, file, trivia.Guid.ToString(), trivia.Bytes.ToString()); + } + } +} diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/PreprocessorDirectives/PragmaWarningDirective.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/PreprocessorDirectives/PragmaWarningDirective.cs new file mode 100644 index 00000000000..4502fa4a87a --- /dev/null +++ b/csharp/extractor/Semmle.Extraction.CSharp/Entities/PreprocessorDirectives/PragmaWarningDirective.cs @@ -0,0 +1,26 @@ +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CSharp; +using Microsoft.CodeAnalysis.CSharp.Syntax; +using System.IO; + +namespace Semmle.Extraction.CSharp.Entities +{ + internal class PragmaWarningDirective : PreprocessorDirective + { + public PragmaWarningDirective(Context cx, PragmaWarningDirectiveTriviaSyntax trivia) + : base(cx, trivia) + { + } + + protected override void PopulatePreprocessor(TextWriter trapFile) + { + trapFile.pragma_warnings(this, trivia.DisableOrRestoreKeyword.IsKind(SyntaxKind.DisableKeyword) ? 0 : 1); + + var childIndex = 0; + foreach (var code in trivia.ErrorCodes) + { + trapFile.pragma_warning_error_codes(this, code.ToString(), childIndex++); + } + } + } +} diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/PreprocessorDirectives/PreprocessorDirective.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/PreprocessorDirectives/PreprocessorDirective.cs new file mode 100644 index 00000000000..4575dd8b8dc --- /dev/null +++ b/csharp/extractor/Semmle.Extraction.CSharp/Entities/PreprocessorDirectives/PreprocessorDirective.cs @@ -0,0 +1,41 @@ +using Microsoft.CodeAnalysis.CSharp.Syntax; +using Semmle.Extraction.Entities; +using System.IO; + +namespace Semmle.Extraction.CSharp.Entities +{ + internal abstract class PreprocessorDirective : FreshEntity where TDirective : DirectiveTriviaSyntax + { + protected readonly TDirective trivia; + + protected PreprocessorDirective(Context cx, TDirective trivia, bool populateFromBase = true) + : base(cx) + { + this.trivia = trivia; + if (populateFromBase) + { + TryPopulate(); + } + } + + protected sealed override void Populate(TextWriter trapFile) + { + PopulatePreprocessor(trapFile); + + trapFile.preprocessor_directive_active(this, trivia.IsActive); + trapFile.preprocessor_directive_location(this, cx.CreateLocation(ReportingLocation)); + + if (!cx.Extractor.Standalone) + { + var compilation = Compilation.Create(cx); + trapFile.preprocessor_directive_compilation(this, compilation); + } + } + + protected abstract void PopulatePreprocessor(TextWriter trapFile); + + public sealed override Microsoft.CodeAnalysis.Location ReportingLocation => trivia.GetLocation(); + + public override TrapStackBehaviour TrapStackBehaviour => TrapStackBehaviour.OptionalLabel; + } +} diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/PreprocessorDirectives/RegionDirective.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/PreprocessorDirectives/RegionDirective.cs new file mode 100644 index 00000000000..b2f017688a3 --- /dev/null +++ b/csharp/extractor/Semmle.Extraction.CSharp/Entities/PreprocessorDirectives/RegionDirective.cs @@ -0,0 +1,19 @@ +using Microsoft.CodeAnalysis.CSharp.Syntax; +using System; +using System.IO; + +namespace Semmle.Extraction.CSharp.Entities +{ + internal class RegionDirective : PreprocessorDirective + { + public RegionDirective(Context cx, RegionDirectiveTriviaSyntax trivia) + : base(cx, trivia) + { + } + + protected override void PopulatePreprocessor(TextWriter trapFile) + { + trapFile.directive_regions(this, trivia.EndOfDirectiveToken.LeadingTrivia.ToString()); + } + } +} diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/PreprocessorDirectives/UndefineDirective.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/PreprocessorDirectives/UndefineDirective.cs new file mode 100644 index 00000000000..d4b976d50c0 --- /dev/null +++ b/csharp/extractor/Semmle.Extraction.CSharp/Entities/PreprocessorDirectives/UndefineDirective.cs @@ -0,0 +1,18 @@ +using Microsoft.CodeAnalysis.CSharp.Syntax; +using System.IO; + +namespace Semmle.Extraction.CSharp.Entities +{ + internal class UndefineDirective : PreprocessorDirective + { + public UndefineDirective(Context cx, UndefDirectiveTriviaSyntax trivia) + : base(cx, trivia) + { + } + + protected override void PopulatePreprocessor(TextWriter trapFile) + { + trapFile.directive_undefines(this, trivia.Name.ToString()); + } + } +} diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/PreprocessorDirectives/WarningDirective.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/PreprocessorDirectives/WarningDirective.cs new file mode 100644 index 00000000000..1511be8d28c --- /dev/null +++ b/csharp/extractor/Semmle.Extraction.CSharp/Entities/PreprocessorDirectives/WarningDirective.cs @@ -0,0 +1,18 @@ +using Microsoft.CodeAnalysis.CSharp.Syntax; +using System.IO; + +namespace Semmle.Extraction.CSharp.Entities +{ + internal class WarningDirective : PreprocessorDirective + { + public WarningDirective(Context cx, WarningDirectiveTriviaSyntax trivia) + : base(cx, trivia) + { + } + + protected override void PopulatePreprocessor(TextWriter trapFile) + { + trapFile.directive_warnings(this, trivia.EndOfDirectiveToken.LeadingTrivia.ToString()); + } + } +} diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Property.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Property.cs index 739708138ad..6795c4a12df 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Property.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Property.cs @@ -84,15 +84,15 @@ namespace Semmle.Extraction.CSharp.Entities { Context.PopulateLater(() => { - var loc = Context.Create(initializer.GetLocation()); - var annotatedType = new AnnotatedType(type, NullableAnnotation.None); + var loc = Context.CreateLocation(initializer.GetLocation()); + var annotatedType = AnnotatedTypeSymbol.CreateNotAnnotated(symbol.Type); var simpleAssignExpr = new Expression(new ExpressionInfo(Context, annotatedType, loc, ExprKind.SIMPLE_ASSIGN, this, child++, false, null)); Expression.CreateFromNode(new ExpressionNodeInfo(Context, initializer.Value, simpleAssignExpr, 0)); var access = new Expression(new ExpressionInfo(Context, annotatedType, Location, ExprKind.PROPERTY_ACCESS, simpleAssignExpr, 1, false, null)); trapFile.expr_access(access, this); if (!symbol.IsStatic) { - This.CreateImplicit(Context, Type.Create(Context, symbol.ContainingType), Location, access, -1); + This.CreateImplicit(Context, symbol.ContainingType, Location, access, -1); } }); } diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Statement.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Statement.cs index 44bd7f80583..94ab9a7ce61 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Statement.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Statement.cs @@ -1,24 +1,41 @@ using Microsoft.CodeAnalysis.CSharp.Syntax; -using Semmle.Extraction.CSharp.Populators; using Microsoft.CodeAnalysis.CSharp; -using Semmle.Extraction.Entities; using System.IO; namespace Semmle.Extraction.CSharp.Entities { - /// - /// Whether this entity is the parent of a top-level statement. - /// - public interface IStatementParentEntity : IEntity - { - bool IsTopLevelParent { get; } - } - internal abstract class Statement : FreshEntity, IExpressionParentEntity, IStatementParentEntity { - protected Statement(Context cx) : base(cx) { } + private readonly int child; + private readonly Kinds.StmtKind kind; + private readonly IStatementParentEntity parent; - public static Statement Create(Context cx, StatementSyntax node, Statement parent, int child) => + protected Statement(Context cx, Kinds.StmtKind kind, IStatementParentEntity parent, int child) + : base(cx) + { + this.kind = kind; + this.parent = parent; + this.child = child; + } + + protected override void Populate(TextWriter trapFile) + { + trapFile.statements(this, kind); + if (parent.IsTopLevelParent) + { + trapFile.stmt_parent_top_level(this, child, parent); + } + else + { + trapFile.stmt_parent(this, child, parent); + } + + PopulateStatement(trapFile); + } + + protected abstract void PopulateStatement(TextWriter trapFile); + + public static Statement Create(Context cx, StatementSyntax node, IStatementParentEntity parent, int child) => Statements.Factory.Create(cx, node, parent, child); /// @@ -27,54 +44,10 @@ namespace Semmle.Extraction.CSharp.Entities /// public virtual int NumberOfStatements => 1; - public override Microsoft.CodeAnalysis.Location ReportingLocation => GetStatementSyntax().GetLocation(); - bool IExpressionParentEntity.IsTopLevelParent => false; bool IStatementParentEntity.IsTopLevelParent => false; - protected abstract CSharpSyntaxNode GetStatementSyntax(); - public override TrapStackBehaviour TrapStackBehaviour => TrapStackBehaviour.NeedsLabel; } - - internal abstract class Statement : Statement where TSyntax : CSharpSyntaxNode - { - protected readonly TSyntax Stmt; - private readonly int child; - private readonly Kinds.StmtKind kind; - private readonly IStatementParentEntity parent; - private readonly Location location; - - protected override CSharpSyntaxNode GetStatementSyntax() => Stmt; - - protected Statement(Context cx, TSyntax stmt, Kinds.StmtKind kind, IStatementParentEntity parent, int child, Location location) - : base(cx) - { - Stmt = stmt; - this.parent = parent; - this.child = child; - this.location = location; - this.kind = kind; - cx.BindComments(this, location.symbol); - } - - protected sealed override void Populate(TextWriter trapFile) - { - trapFile.statements(this, kind); - if (parent.IsTopLevelParent) - trapFile.stmt_parent_top_level(this, child, parent); - else - trapFile.stmt_parent(this, child, parent); - trapFile.stmt_location(this, location); - PopulateStatement(trapFile); - } - - protected abstract void PopulateStatement(TextWriter trapFile); - - protected Statement(Context cx, TSyntax stmt, Kinds.StmtKind kind, IStatementParentEntity parent, int child) - : this(cx, stmt, kind, parent, child, cx.Create(stmt.FixedLocation())) { } - - public override string ToString() => Label.ToString(); - } } diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Statement`1.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Statement`1.cs new file mode 100644 index 00000000000..8ea6650d4f7 --- /dev/null +++ b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Statement`1.cs @@ -0,0 +1,35 @@ +using Semmle.Extraction.CSharp.Populators; +using Microsoft.CodeAnalysis.CSharp; +using Semmle.Extraction.Entities; +using System.IO; + +namespace Semmle.Extraction.CSharp.Entities +{ + internal abstract class Statement : Statement where TSyntax : CSharpSyntaxNode + { + protected readonly TSyntax Stmt; + private readonly Location location; + + protected Statement(Context cx, TSyntax stmt, Kinds.StmtKind kind, IStatementParentEntity parent, int child, Location location) + : base(cx, kind, parent, child) + { + Stmt = stmt; + this.location = location; + cx.BindComments(this, location.symbol); + } + + protected Statement(Context cx, TSyntax stmt, Kinds.StmtKind kind, IStatementParentEntity parent, int child) + : this(cx, stmt, kind, parent, child, cx.CreateLocation(stmt.FixedLocation())) { } + + protected sealed override void Populate(TextWriter trapFile) + { + base.Populate(trapFile); + + trapFile.stmt_location(this, location); + } + + public override Microsoft.CodeAnalysis.Location ReportingLocation => Stmt.GetLocation(); + + public override string ToString() => Label.ToString(); + } +} diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Statements/Case.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Statements/Case.cs index e2a712c006b..8046bdb6e26 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Statements/Case.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Statements/Case.cs @@ -10,7 +10,7 @@ namespace Semmle.Extraction.CSharp.Entities.Statements internal abstract class Case : Statement where TSyntax : SwitchLabelSyntax { protected Case(Context cx, TSyntax node, Switch parent, int child) - : base(cx, node, StmtKind.CASE, parent, child, cx.Create(node.GetLocation())) { } + : base(cx, node, StmtKind.CASE, parent, child, cx.CreateLocation(node.GetLocation())) { } public static Statement Create(Context cx, SwitchLabelSyntax node, Switch parent, int child) { diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Statements/Catch.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Statements/Catch.cs index 13cc39f7fea..b9bddab82e2 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Statements/Catch.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Statements/Catch.cs @@ -10,7 +10,7 @@ namespace Semmle.Extraction.CSharp.Entities.Statements private static readonly string systemExceptionName = typeof(System.Exception).ToString(); private Catch(Context cx, CatchClauseSyntax node, Try parent, int child) - : base(cx, node, StmtKind.CATCH, parent, child, cx.Create(node.GetLocation())) { } + : base(cx, node, StmtKind.CATCH, parent, child, cx.CreateLocation(node.GetLocation())) { } protected override void PopulateStatement(TextWriter trapFile) { @@ -20,11 +20,11 @@ namespace Semmle.Extraction.CSharp.Entities.Statements if (hasVariableDeclaration) // A catch clause of the form 'catch(Ex ex) { ... }' { var decl = Expressions.VariableDeclaration.Create(cx, Stmt.Declaration, false, this, 0); - trapFile.catch_type(this, decl.Type.Type.TypeRef, true); + trapFile.catch_type(this, Type.Create(cx, decl.Type).TypeRef, true); } else if (isSpecificCatchClause) // A catch clause of the form 'catch(Ex) { ... }' { - trapFile.catch_type(this, Type.Create(cx, cx.GetType(Stmt.Declaration.Type)).Type.TypeRef, true); + trapFile.catch_type(this, Type.Create(cx, cx.GetType(Stmt.Declaration.Type)).TypeRef, true); } else // A catch clause of the form 'catch { ... }' { diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Statements/Do.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Statements/Do.cs index a0cd9da7372..7cdcfb1f57b 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Statements/Do.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Statements/Do.cs @@ -8,7 +8,7 @@ namespace Semmle.Extraction.CSharp.Entities.Statements internal class Do : Statement { private Do(Context cx, DoStatementSyntax node, IStatementParentEntity parent, int child) - : base(cx, node, StmtKind.DO, parent, child, cx.Create(node.GetLocation())) { } + : base(cx, node, StmtKind.DO, parent, child, cx.CreateLocation(node.GetLocation())) { } public static Do Create(Context cx, DoStatementSyntax node, IStatementParentEntity parent, int child) { diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Statements/Factory.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Statements/Factory.cs index 69ebdca1c16..2960982061e 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Statements/Factory.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Statements/Factory.cs @@ -5,7 +5,7 @@ namespace Semmle.Extraction.CSharp.Entities.Statements { internal static class Factory { - internal static Statement Create(Context cx, StatementSyntax node, Statement parent, int child) + internal static Statement Create(Context cx, StatementSyntax node, IStatementParentEntity parent, int child) { switch (node.Kind()) { diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Statements/ForEach.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Statements/ForEach.cs index 653ed384e7b..e7bb987574e 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Statements/ForEach.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Statements/ForEach.cs @@ -8,6 +8,15 @@ namespace Semmle.Extraction.CSharp.Entities.Statements { internal class ForEach : Statement { + internal enum ForeachSymbolType + { + GetEnumeratorMethod = 1, + CurrentProperty, + MoveNextMethod, + DisposeMethod, + ElementType + } + private ForEach(Context cx, ForEachStatementSyntax stmt, IStatementParentEntity parent, int child) : base(cx, stmt, StmtKind.FOREACH, parent, child) { } @@ -18,18 +27,59 @@ namespace Semmle.Extraction.CSharp.Entities.Statements return ret; } - protected override void PopulateStatement(TextWriter _) + protected override void PopulateStatement(TextWriter trapFile) { Expression.Create(cx, Stmt.Expression, this, 1); - var typeSymbol = cx.GetModel(Stmt).GetDeclaredSymbol(Stmt); - var type = Type.Create(cx, typeSymbol.GetAnnotatedType()); + var semanticModel = cx.GetModel(Stmt); + var typeSymbol = semanticModel.GetDeclaredSymbol(Stmt); + var type = typeSymbol.GetAnnotatedType(); - var location = cx.Create(Stmt.Identifier.GetLocation()); + var location = cx.CreateLocation(Stmt.Identifier.GetLocation()); Expressions.VariableDeclaration.Create(cx, typeSymbol, type, Stmt.Type, location, Stmt.Type.IsVar, this, 0); Statement.Create(cx, Stmt.Statement, this, 2); + + var info = semanticModel.GetForEachStatementInfo(Stmt); + + if (info.Equals(default)) + { + cx.ExtractionError("Could not get foreach statement info", null, cx.CreateLocation(this.ReportingLocation), severity: Util.Logging.Severity.Info); + return; + } + + trapFile.foreach_stmt_info(this, info.IsAsynchronous); + + if (info.GetEnumeratorMethod != null) + { + var m = Method.Create(cx, info.GetEnumeratorMethod); + trapFile.foreach_stmt_desugar(this, m, ForeachSymbolType.GetEnumeratorMethod); + } + + if (info.MoveNextMethod != null) + { + var m = Method.Create(cx, info.MoveNextMethod); + trapFile.foreach_stmt_desugar(this, m, ForeachSymbolType.MoveNextMethod); + } + + if (info.DisposeMethod != null) + { + var m = Method.Create(cx, info.DisposeMethod); + trapFile.foreach_stmt_desugar(this, m, ForeachSymbolType.DisposeMethod); + } + + if (info.CurrentProperty != null) + { + var p = Property.Create(cx, info.CurrentProperty); + trapFile.foreach_stmt_desugar(this, p, ForeachSymbolType.CurrentProperty); + } + + if (info.ElementType != null) + { + var t = Type.Create(cx, info.ElementType); + trapFile.foreach_stmt_desugar(this, t, ForeachSymbolType.ElementType); + } } } diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Statements/GlobalStatementsBlock.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Statements/GlobalStatementsBlock.cs new file mode 100644 index 00000000000..062a09e3fae --- /dev/null +++ b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Statements/GlobalStatementsBlock.cs @@ -0,0 +1,42 @@ +using Semmle.Extraction.Kinds; +using System.Linq; +using System.IO; +using Semmle.Extraction.Entities; + +namespace Semmle.Extraction.CSharp.Entities.Statements +{ + internal class GlobalStatementsBlock : Statement + { + private readonly Method parent; + + private GlobalStatementsBlock(Context cx, Method parent) + : base(cx, StmtKind.BLOCK, parent, 0) + { + this.parent = parent; + } + + public override Microsoft.CodeAnalysis.Location ReportingLocation + { + get + { + return parent.symbol + ?.DeclaringSyntaxReferences + .FirstOrDefault() + ?.GetSyntax() + .GetLocation(); + } + } + + public static GlobalStatementsBlock Create(Context cx, Method parent) + { + var ret = new GlobalStatementsBlock(cx, parent); + ret.TryPopulate(); + return ret; + } + + protected override void PopulateStatement(TextWriter trapFile) + { + trapFile.stmt_location(this, cx.CreateLocation(ReportingLocation)); + } + } +} diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Statements/Labeled.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Statements/Labeled.cs index 1fce622b347..fe69af917ba 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Statements/Labeled.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Statements/Labeled.cs @@ -6,17 +6,18 @@ namespace Semmle.Extraction.CSharp.Entities.Statements { internal class Labeled : Statement { - private readonly Statement parent; + private readonly IStatementParentEntity parent; private readonly int child; + private Statement labelledStmt; - private Labeled(Context cx, LabeledStatementSyntax stmt, Statement parent, int child) + private Labeled(Context cx, LabeledStatementSyntax stmt, IStatementParentEntity parent, int child) : base(cx, stmt, StmtKind.LABEL, parent, child) { this.parent = parent; this.child = child; } - public static Labeled Create(Context cx, LabeledStatementSyntax node, Statement parent, int child) + public static Labeled Create(Context cx, LabeledStatementSyntax node, IStatementParentEntity parent, int child) { var ret = new Labeled(cx, node, parent, child); ret.TryPopulate(); @@ -27,13 +28,11 @@ namespace Semmle.Extraction.CSharp.Entities.Statements { trapFile.exprorstmt_name(this, Stmt.Identifier.ToString()); - // For compatilibty with the Mono extractor, make insert the labelled statement into the same block + // For compatibility with the Mono extractor, make insert the labelled statement into the same block // as this one. The parent MUST be a block statement. labelledStmt = Statement.Create(cx, Stmt.Statement, parent, child + 1); } - private Statement labelledStmt; - public override int NumberOfStatements => 1 + labelledStmt.NumberOfStatements; } } diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Statements/LocalFunction.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Statements/LocalFunction.cs index eb81f27cb3a..5e417fd8885 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Statements/LocalFunction.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Statements/LocalFunction.cs @@ -10,7 +10,7 @@ namespace Semmle.Extraction.CSharp.Entities.Statements internal class LocalFunction : Statement { private LocalFunction(Context cx, LocalFunctionStatementSyntax node, IStatementParentEntity parent, int child) - : base(cx, node, StmtKind.LOCAL_FUNCTION, parent, child, cx.Create(node.GetLocation())) { } + : base(cx, node, StmtKind.LOCAL_FUNCTION, parent, child, cx.CreateLocation(node.GetLocation())) { } public static LocalFunction Create(Context cx, LocalFunctionStatementSyntax node, IStatementParentEntity parent, int child) { diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Symbol.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Symbol.cs index 5e0850ba8c8..f7a493af78e 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Symbol.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Symbol.cs @@ -78,7 +78,7 @@ namespace Semmle.Extraction.CSharp.Entities if (loc != null) { // Some built in operators lack locations, so loc is null. - yield return Context.Create(ReportingLocation); + yield return Context.CreateLocation(ReportingLocation); if (Context.Extractor.OutputPath != null && loc.Kind == LocationKind.SourceFile) yield return Assembly.CreateOutputAssembly(Context); } @@ -124,7 +124,7 @@ namespace Semmle.Extraction.CSharp.Entities public override bool NeedsPopulation => Context.Defines(symbol); - public Extraction.Entities.Location Location => Context.Create(ReportingLocation); + public Extraction.Entities.Location Location => Context.CreateLocation(ReportingLocation); protected void PopulateMetadataHandle(TextWriter trapFile) { diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/TypeMention.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/TypeMention.cs index 4f1e166b8dc..e05c2d0c102 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp/Entities/TypeMention.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp/Entities/TypeMention.cs @@ -47,7 +47,7 @@ namespace Semmle.Extraction.CSharp.Entities switch (type) { case ArrayType at: - return GetArrayElementType(at.ElementType.Type); + return GetArrayElementType(at.ElementType); case NamedType nt when nt.symbol.IsBoundSpan() || nt.symbol.IsBoundReadOnlySpan(): return nt.TypeArguments.Single(); @@ -118,7 +118,7 @@ namespace Semmle.Extraction.CSharp.Entities private void Emit(TextWriter trapFile, Microsoft.CodeAnalysis.Location loc, IEntity parent, Type type) { trapFile.type_mention(this, type.TypeRef, parent); - trapFile.type_mention_location(this, cx.Create(loc)); + trapFile.type_mention_location(this, cx.CreateLocation(loc)); } public static TypeMention Create(Context cx, TypeSyntax syntax, IEntity parent, Type type, Microsoft.CodeAnalysis.Location loc = null) @@ -128,8 +128,8 @@ namespace Semmle.Extraction.CSharp.Entities return ret; } - public static TypeMention Create(Context cx, TypeSyntax syntax, IEntity parent, AnnotatedType type, Microsoft.CodeAnalysis.Location loc = null) => - Create(cx, syntax, parent, type.Type, loc); + public static TypeMention Create(Context cx, TypeSyntax syntax, IEntity parent, AnnotatedTypeSymbol? type, Microsoft.CodeAnalysis.Location loc = null) => + Create(cx, syntax, parent, Type.Create(cx, type?.Symbol), loc); public override TrapStackBehaviour TrapStackBehaviour => TrapStackBehaviour.OptionalLabel; } diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Types/ArrayType.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Types/ArrayType.cs index 2c617158219..4ec1db558e5 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Types/ArrayType.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Types/ArrayType.cs @@ -1,3 +1,4 @@ +using System; using System.IO; using Microsoft.CodeAnalysis; @@ -8,16 +9,16 @@ namespace Semmle.Extraction.CSharp.Entities private ArrayType(Context cx, IArrayTypeSymbol init) : base(cx, init) { - element = Create(cx, symbol.GetAnnotatedElementType()); + elementLazy = new Lazy(() => Create(cx, symbol.ElementType)); } - private readonly AnnotatedType element; + private readonly Lazy elementLazy; public int Rank => symbol.Rank; - public override AnnotatedType ElementType => element; + public Type ElementType => elementLazy.Value; - public override int Dimension => 1 + element.Type.Dimension; + public override int Dimension => 1 + ElementType.Dimension; // All array types are extracted because they won't // be extracted in their defining assembly. @@ -25,18 +26,19 @@ namespace Semmle.Extraction.CSharp.Entities public override void Populate(TextWriter trapFile) { - trapFile.array_element_type(this, Dimension, Rank, element.Type.TypeRef); + trapFile.array_element_type(this, Dimension, Rank, ElementType.TypeRef); PopulateType(trapFile); } public override void WriteId(TextWriter trapFile) { - trapFile.WriteSubId(element.Type); + trapFile.WriteSubId(ElementType); symbol.BuildArraySuffix(trapFile); trapFile.Write(";type"); } - public static ArrayType Create(Context cx, IArrayTypeSymbol symbol) => ArrayTypeFactory.Instance.CreateEntityFromSymbol(cx, symbol); + public static ArrayType Create(Context cx, IArrayTypeSymbol symbol) => + ArrayTypeFactory.Instance.CreateEntityFromSymbol(cx, symbol); private class ArrayTypeFactory : ICachedEntityFactory { diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Types/FunctionPointerType.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Types/FunctionPointerType.cs new file mode 100644 index 00000000000..1bf68a4c3c2 --- /dev/null +++ b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Types/FunctionPointerType.cs @@ -0,0 +1,42 @@ +using System.IO; +using System.Linq; +using Microsoft.CodeAnalysis; + +namespace Semmle.Extraction.CSharp.Entities +{ + internal class FunctionPointerType : Type + { + private FunctionPointerType(Context cx, IFunctionPointerTypeSymbol init) + : base(cx, init) + { + } + + public override void WriteId(TextWriter trapFile) + { + symbol.BuildTypeId(Context, trapFile, symbol); + trapFile.Write(";functionpointertype"); + } + + public override bool NeedsPopulation => true; + + public override void Populate(TextWriter trapFile) + { + trapFile.function_pointer_calling_conventions(this, (int)symbol.Signature.CallingConvention); + foreach (var (conv, i) in symbol.Signature.UnmanagedCallingConventionTypes.Select((nt, i) => (Create(Context, nt), i))) + { + trapFile.has_unmanaged_calling_conventions(this, i, conv.TypeRef); + } + + PopulateType(trapFile); + } + + public static FunctionPointerType Create(Context cx, IFunctionPointerTypeSymbol symbol) => FunctionPointerTypeFactory.Instance.CreateEntityFromSymbol(cx, symbol); + + private class FunctionPointerTypeFactory : ICachedEntityFactory + { + public static FunctionPointerTypeFactory Instance { get; } = new FunctionPointerTypeFactory(); + + public FunctionPointerType Create(Context cx, IFunctionPointerTypeSymbol init) => new FunctionPointerType(cx, init); + } + } +} diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Types/NamedType.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Types/NamedType.cs index 5812c4a9303..0d95d776592 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Types/NamedType.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Types/NamedType.cs @@ -87,6 +87,11 @@ namespace Semmle.Extraction.CSharp.Entities foreach (var l in Locations) trapFile.type_location(this, l); } + + if (symbol.IsAnonymousType) + { + trapFile.anonymous_types(this); + } } private readonly Lazy typeArgumentsLazy; @@ -101,7 +106,7 @@ namespace Semmle.Extraction.CSharp.Entities get { foreach (var l in GetLocations(symbol)) - yield return Context.Create(l); + yield return Context.CreateLocation(l); if (Context.Extractor.OutputPath != null && symbol.DeclaringSyntaxReferences.Any()) yield return Assembly.CreateOutputAssembly(Context); @@ -144,36 +149,6 @@ namespace Semmle.Extraction.CSharp.Entities base.WriteQuotedId(trapFile); } - /// - /// Returns the element type in an Enumerable/IEnumerable - /// - /// Extraction context. - /// The enumerable type. - /// The element type, or null. - private static AnnotatedTypeSymbol GetElementType(Context cx, INamedTypeSymbol type) - { - var et = GetEnumerableType(cx, type); - if (et.Symbol != null) - return et; - - return type.AllInterfaces - .Where(i => i.OriginalDefinition.SpecialType == SpecialType.System_Collections_Generic_IEnumerable_T) - .Concat(type.AllInterfaces.Where(i => i.SpecialType == SpecialType.System_Collections_IEnumerable)) - .Select(i => GetEnumerableType(cx, i)) - .FirstOrDefault(); - } - - private static AnnotatedTypeSymbol GetEnumerableType(Context cx, INamedTypeSymbol type) - { - return type.SpecialType == SpecialType.System_Collections_IEnumerable - ? cx.Compilation.ObjectType.WithAnnotation(NullableAnnotation.NotAnnotated) - : type.OriginalDefinition.SpecialType == SpecialType.System_Collections_Generic_IEnumerable_T - ? type.GetAnnotatedTypeArguments().First() - : default(AnnotatedTypeSymbol); - } - - public override AnnotatedType ElementType => Type.Create(Context, GetElementType(Context, symbol)); - private class NamedTypeFactory : ICachedEntityFactory { public static NamedTypeFactory Instance { get; } = new NamedTypeFactory(); @@ -230,5 +205,5 @@ namespace Semmle.Extraction.CSharp.Entities { trapFile.typerefs(this, symbol.Name); } - }; + } } diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Types/NullType.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Types/NullType.cs index 2822e346384..33f7c44d21f 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Types/NullType.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Types/NullType.cs @@ -27,7 +27,7 @@ namespace Semmle.Extraction.CSharp.Entities return obj != null && obj.GetType() == typeof(NullType); } - public static AnnotatedType Create(Context cx) => new AnnotatedType(NullTypeFactory.Instance.CreateEntity(cx, typeof(NullType), null), NullableAnnotation.None); + public static Type Create(Context cx) => NullTypeFactory.Instance.CreateEntity(cx, typeof(NullType), null); private class NullTypeFactory : ICachedEntityFactory { diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Types/TupleType.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Types/TupleType.cs index af9c4bf4fa6..6f6ff85cf77 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Types/TupleType.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Types/TupleType.cs @@ -53,12 +53,12 @@ namespace Semmle.Extraction.CSharp.Entities // about what locations are available for a tuple type. // Sometimes it's the source code, and sometimes it's empty. foreach (var l in symbol.Locations) - trapFile.type_location(this, Context.Create(l)); + trapFile.type_location(this, Context.CreateLocation(l)); } private readonly Lazy tupleElementsLazy; public Field[] TupleElements => tupleElementsLazy.Value; - public override IEnumerable TypeMentions => TupleElements.Select(e => e.Type.Type); + public override IEnumerable TypeMentions => TupleElements.Select(e => e.Type); } } diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Types/Type.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Types/Type.cs index 1b1d205b3d7..8c96a334565 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Types/Type.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Types/Type.cs @@ -1,42 +1,18 @@ using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp.Syntax; using Semmle.Util; +using System; using System.Collections.Generic; using System.IO; using System.Linq; namespace Semmle.Extraction.CSharp.Entities { - /// - /// Represents an annotated type consisting of a type entity and nullability information. - /// - public struct AnnotatedType - { - public AnnotatedType(Type t, NullableAnnotation n) - { - Type = t; - annotation = n; - } - - /// - /// The underlying type. - /// - public Type Type { get; private set; } - - private readonly NullableAnnotation annotation; - - /// - /// Gets the annotated type symbol of this annotated type. - /// - public AnnotatedTypeSymbol Symbol => new AnnotatedTypeSymbol(Type.symbol, annotation); - } - public abstract class Type : CachedSymbol { protected Type(Context cx, ITypeSymbol init) : base(cx, init) { } - public virtual AnnotatedType ElementType => default(AnnotatedType); public override bool NeedsPopulation => base.NeedsPopulation || symbol.TypeKind == TypeKind.Dynamic || symbol.TypeKind == TypeKind.TypeParameter; @@ -82,6 +58,7 @@ namespace Semmle.Extraction.CSharp.Entities case TypeKind.Enum: return Kinds.TypeKind.ENUM; case TypeKind.Delegate: return Kinds.TypeKind.DELEGATE; case TypeKind.Pointer: return Kinds.TypeKind.POINTER; + case TypeKind.FunctionPointer: return Kinds.TypeKind.FUNCTION_POINTER; case TypeKind.Error: return Kinds.TypeKind.UNKNOWN; default: cx.ModelError(t, $"Unhandled type kind '{t.TypeKind}'"); @@ -156,23 +133,14 @@ namespace Semmle.Extraction.CSharp.Entities // This is a delegate. // The method "Invoke" has the return type. var invokeMethod = ((INamedTypeSymbol)symbol).DelegateInvokeMethod; + ExtractParametersForDelegateLikeType(trapFile, invokeMethod, + t => trapFile.delegate_return_type(this, t)); + } - // Copy the parameters from the "Invoke" method to the delegate type - for (var i = 0; i < invokeMethod.Parameters.Length; ++i) - { - var param = invokeMethod.Parameters[i]; - var originalParam = invokeMethod.OriginalDefinition.Parameters[i]; - var originalParamEntity = SymbolEqualityComparer.Default.Equals(param, originalParam) ? null : - DelegateTypeParameter.Create(Context, originalParam, Create(Context, ((INamedTypeSymbol)symbol).OriginalDefinition)); - DelegateTypeParameter.Create(Context, param, this, originalParamEntity); - } - - var returnKey = Create(Context, invokeMethod.ReturnType); - trapFile.delegate_return_type(this, returnKey.TypeRef); - if (invokeMethod.ReturnsByRef) - trapFile.type_annotation(this, Kinds.TypeAnnotation.Ref); - if (invokeMethod.ReturnsByRefReadonly) - trapFile.type_annotation(this, Kinds.TypeAnnotation.ReadonlyRef); + if (symbol is IFunctionPointerTypeSymbol functionPointer) + { + ExtractParametersForDelegateLikeType(trapFile, functionPointer.Signature, + t => trapFile.function_pointer_return_type(this, t)); } Modifier.ExtractModifiers(Context, trapFile, this, symbol); @@ -195,6 +163,23 @@ namespace Semmle.Extraction.CSharp.Entities } } + private void ExtractParametersForDelegateLikeType(TextWriter trapFile, IMethodSymbol invokeMethod, Action storeReturnType) + { + for (var i = 0; i < invokeMethod.Parameters.Length; ++i) + { + var param = invokeMethod.Parameters[i]; + var originalParam = invokeMethod.OriginalDefinition.Parameters[i]; + var originalParamEntity = SymbolEqualityComparer.Default.Equals(param, originalParam) + ? null + : DelegateTypeParameter.Create(Context, originalParam, Create(Context, ((INamedTypeSymbol)symbol).OriginalDefinition)); + DelegateTypeParameter.Create(Context, param, this, originalParamEntity); + } + + var returnKey = Create(Context, invokeMethod.ReturnType); + storeReturnType(returnKey.TypeRef); + Method.ExtractRefReturn(trapFile, invokeMethod, this); + } + /// /// Called to extract all members and nested types. /// This is called on each member of a namespace, @@ -277,12 +262,12 @@ namespace Semmle.Extraction.CSharp.Entities { type = type.DisambiguateType(); return type == null - ? NullType.Create(cx).Type + ? NullType.Create(cx) : (Type)cx.CreateEntity(type); } - public static AnnotatedType Create(Context cx, AnnotatedTypeSymbol type) => - new AnnotatedType(Create(cx, type.Symbol), type.Nullability); + public static Type Create(Context cx, AnnotatedTypeSymbol? type) => + Create(cx, type?.Symbol); public virtual int Dimension => 0; @@ -290,8 +275,7 @@ namespace Semmle.Extraction.CSharp.Entities symbol != null && symbol.TypeKind == TypeKind.Delegate; /// - /// A copy of a delegate "Invoke" method parameter used for the delgate - /// type. + /// A copy of a delegate "Invoke" method or function pointer parameter. /// private class DelegateTypeParameter : Parameter { @@ -331,10 +315,10 @@ namespace Semmle.Extraction.CSharp.Entities public override bool Equals(object obj) { var other = obj as Type; - return other?.GetType() == GetType() && SymbolEqualityComparer.IncludeNullability.Equals(other.symbol, symbol); + return other?.GetType() == GetType() && SymbolEqualityComparer.Default.Equals(other.symbol, symbol); } - public override int GetHashCode() => SymbolEqualityComparer.IncludeNullability.GetHashCode(symbol); + public override int GetHashCode() => SymbolEqualityComparer.Default.GetHashCode(symbol); } internal abstract class Type : Type where T : ITypeSymbol diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Types/TypeParameter.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Types/TypeParameter.cs index b4d35f7b506..e92a3891704 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Types/TypeParameter.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Types/TypeParameter.cs @@ -54,7 +54,7 @@ namespace Semmle.Extraction.CSharp.Entities foreach (var l in symbol.Locations) { - trapFile.type_location(this, Context.Create(l)); + trapFile.type_location(this, Context.CreateLocation(l)); } if (IsSourceDeclaration) diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/UsingDirective.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/UsingDirective.cs index caa12ab0082..d08a1320ba2 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp/Entities/UsingDirective.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp/Entities/UsingDirective.cs @@ -30,7 +30,7 @@ namespace Semmle.Extraction.CSharp.Entities { var ns = Namespace.Create(cx, namespaceSymbol); trapFile.using_namespace_directives(this, ns); - trapFile.using_directive_location(this, cx.Create(ReportingLocation)); + trapFile.using_directive_location(this, cx.CreateLocation(ReportingLocation)); } else { @@ -44,7 +44,7 @@ namespace Semmle.Extraction.CSharp.Entities // A "using static" var m = Type.Create(cx, (ITypeSymbol)info.Symbol); trapFile.using_static_directives(this, m.TypeRef); - trapFile.using_directive_location(this, cx.Create(ReportingLocation)); + trapFile.using_directive_location(this, cx.CreateLocation(ReportingLocation)); } if (parent != null) diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Extractor.cs b/csharp/extractor/Semmle.Extraction.CSharp/Extractor.cs index cf991e0930a..2f979863dd0 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp/Extractor.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp/Extractor.cs @@ -68,7 +68,10 @@ namespace Semmle.Extraction.CSharp { var stopwatch = new Stopwatch(); stopwatch.Start(); - var commandLineArguments = Options.CreateWithEnvironment(args); + + Entities.Compilation.Settings = (Directory.GetCurrentDirectory(), args); + + var commandLineArguments = Options.CreateWithEnvironment(Entities.Compilation.Settings.Args); var fileLogger = new FileLogger(commandLineArguments.Verbosity, GetCSharpLogPath()); using var logger = commandLineArguments.Console ? new CombinedLogger(new ConsoleLogger(commandLineArguments.Verbosity), fileLogger) @@ -95,10 +98,9 @@ namespace Semmle.Extraction.CSharp return ExitCode.Ok; } - var cwd = Directory.GetCurrentDirectory(); var compilerArguments = CSharpCommandLineParser.Default.Parse( compilerVersion.ArgsWithResponse, - cwd, + Entities.Compilation.Settings.Cwd, compilerVersion.FrameworkPath, compilerVersion.AdditionalReferenceDirectories ); @@ -106,7 +108,7 @@ namespace Semmle.Extraction.CSharp if (compilerArguments == null) { var sb = new StringBuilder(); - sb.Append(" Failed to parse command line: ").AppendList(" ", args); + sb.Append(" Failed to parse command line: ").AppendList(" ", Entities.Compilation.Settings.Args); logger.Log(Severity.Error, sb.ToString()); ++analyser.CompilationErrors; return ExitCode.Failed; @@ -159,7 +161,7 @@ namespace Semmle.Extraction.CSharp ); analyser.EndInitialize(compilerArguments, commandLineArguments, compilation); - analyser.AnalyseCompilation(cwd, args); + analyser.AnalyseCompilation(); analyser.AnalyseReferences(); foreach (var tree in compilation.SyntaxTrees) diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Kinds/ExprKind.cs b/csharp/extractor/Semmle.Extraction.CSharp/Kinds/ExprKind.cs index f46ed47ff5f..292e8c47d98 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp/Kinds/ExprKind.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp/Kinds/ExprKind.cs @@ -115,6 +115,16 @@ namespace Semmle.Extraction.Kinds SWITCH_CASE = 118, ASSIGN_COALESCE = 119, SUPPRESS_NULLABLE_WARNING = 120, - NAMESPACE_ACCESS = 121 + NAMESPACE_ACCESS = 121, + LT_PATTERN = 122, + GT_PATTERN = 123, + LE_PATTERN = 124, + GE_PATTERN = 125, + NOT_PATTERN = 126, + AND_PATTERN = 127, + OR_PATTERN = 128, + FUNCTION_POINTER_INVOCATION = 129, + + DEFINE_SYMBOL = 999 } } diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Kinds/TypeKind.cs b/csharp/extractor/Semmle.Extraction.CSharp/Kinds/TypeKind.cs index fb205a6646e..01fad60e003 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp/Kinds/TypeKind.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp/Kinds/TypeKind.cs @@ -34,6 +34,7 @@ namespace Semmle.Extraction.Kinds // lgtm[cs/similar-file] DYNAMIC = 29, ARGLIST = 30, UNKNOWN = 31, - TUPLE = 32 + TUPLE = 32, + FUNCTION_POINTER = 33 } } diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Populators/Ast.cs b/csharp/extractor/Semmle.Extraction.CSharp/Populators/Ast.cs deleted file mode 100644 index 866d436bda1..00000000000 --- a/csharp/extractor/Semmle.Extraction.CSharp/Populators/Ast.cs +++ /dev/null @@ -1,63 +0,0 @@ -using Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.CSharp; -using Microsoft.CodeAnalysis.CSharp.Syntax; -using Semmle.Extraction.CSharp.Entities; - -namespace Semmle.Extraction.CSharp.Populators -{ - internal class Ast : CSharpSyntaxVisitor - { - private readonly Context cx; - private readonly IExpressionParentEntity parent; - private readonly int child; - - public Ast(Context cx, IExpressionParentEntity parent, int child) - { - this.cx = cx; - this.parent = parent; - this.child = child; - } - - public override void DefaultVisit(SyntaxNode node) - { - cx.ModelError(node, $"Unhandled syntax node {node.Kind()}"); - } - - public override void VisitArgumentList(ArgumentListSyntax node) - { - var c = 0; - foreach (var m in node.Arguments) - { - cx.Extract(m, parent, c++); - } - } - - public override void VisitArgument(ArgumentSyntax node) - { - Expression.Create(cx, node.Expression, parent, child); - } - } - - public static class AstExtensions - { - public static void Extract(this Context cx, CSharpSyntaxNode node, IExpressionParentEntity parent, int child) - { - using (cx.StackGuard) - { - try - { - node.Accept(new Ast(cx, parent, child)); - } - catch (System.Exception ex) // lgtm[cs/catch-of-all-exceptions] - { - cx.ModelError(node, $"Exception processing syntax node of type {node.Kind()}: {ex.Message}"); - } - } - } - - public static void Extract(this Context cx, SyntaxNode node, IEntity parent, int child) - { - cx.Extract(((CSharpSyntaxNode)node), parent, child); - } - } -} diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Populators/AstLineCounter.cs b/csharp/extractor/Semmle.Extraction.CSharp/Populators/AstLineCounter.cs new file mode 100644 index 00000000000..a185675ee27 --- /dev/null +++ b/csharp/extractor/Semmle.Extraction.CSharp/Populators/AstLineCounter.cs @@ -0,0 +1,48 @@ +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CSharp; +using Microsoft.CodeAnalysis.CSharp.Syntax; +using Semmle.Util; + +namespace Semmle.Extraction.CSharp.Populators +{ + internal class AstLineCounter : CSharpSyntaxVisitor + { + public override LineCounts DefaultVisit(SyntaxNode node) + { + var text = node.SyntaxTree.GetText().GetSubText(node.GetLocation().SourceSpan).ToString(); + return LineCounter.ComputeLineCounts(text); + } + + public override LineCounts VisitMethodDeclaration(MethodDeclarationSyntax method) + { + return Visit(method.Identifier, method.Body ?? (SyntaxNode)method.ExpressionBody); + } + + public static LineCounts Visit(SyntaxToken identifier, SyntaxNode body) + { + var start = identifier.GetLocation().SourceSpan.Start; + var end = body.GetLocation().SourceSpan.End - 1; + + var textSpan = new Microsoft.CodeAnalysis.Text.TextSpan(start, end - start); + + var text = body.SyntaxTree.GetText().GetSubText(textSpan) + "\r\n"; + return LineCounter.ComputeLineCounts(text); + } + + public override LineCounts VisitConstructorDeclaration(ConstructorDeclarationSyntax method) + { + return Visit(method.Identifier, (SyntaxNode)method.Body ?? method.ExpressionBody); + } + + public override LineCounts VisitDestructorDeclaration(DestructorDeclarationSyntax method) + { + return Visit(method.Identifier, (SyntaxNode)method.Body ?? method.ExpressionBody); + } + + public override LineCounts VisitOperatorDeclaration(OperatorDeclarationSyntax node) + { + return Visit(node.OperatorToken, node.Body ?? (SyntaxNode)node.ExpressionBody); + } + } + +} diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Populators/CommentPopulator.cs b/csharp/extractor/Semmle.Extraction.CSharp/Populators/CommentPopulator.cs new file mode 100644 index 00000000000..325746274ff --- /dev/null +++ b/csharp/extractor/Semmle.Extraction.CSharp/Populators/CommentPopulator.cs @@ -0,0 +1,123 @@ +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CSharp; +using Semmle.Extraction.CommentProcessing; +using Semmle.Extraction.CSharp.Entities; +using System; + +namespace Semmle.Extraction.CSharp.Populators +{ + /// + /// Populators for comments. + /// + public static class CommentPopulator + { + public static void ExtractCommentBlocks(Context cx, ICommentGenerator gen) + { + cx.Try(null, null, () => + { + gen.GenerateBindings((entity, duplicationGuardKey, block, binding) => + { + var commentBlock = Entities.CommentBlock.Create(cx, block); + Action a = () => + { + commentBlock.BindTo(entity, binding); + }; + // When the duplication guard key exists, it means that the entity is guarded against + // trap duplication (). + // We must therefore also guard comment construction. + if (duplicationGuardKey != null) + cx.WithDuplicationGuard(duplicationGuardKey, a); + else + a(); + }); + }); + } + + public static void ExtractComment(Context cx, SyntaxTrivia trivia) + { + switch (trivia.Kind()) + { + case SyntaxKind.SingleLineDocumentationCommentTrivia: + /* + This is actually a multi-line comment consisting of /// lines. + So split it up. + */ + + var text = trivia.ToFullString(); + + var split = text.Split('\n'); + var currentLocation = trivia.GetLocation().SourceSpan.Start - 3; + + for (var line = 0; line < split.Length - 1; ++line) + { + var fullLine = split[line]; + var nextLineLocation = currentLocation + fullLine.Length + 1; + fullLine = fullLine.TrimEnd('\r'); + var trimmedLine = fullLine; + + var leadingSpaces = trimmedLine.IndexOf('/'); + if (leadingSpaces != -1) + { + fullLine = fullLine.Substring(leadingSpaces); + currentLocation += leadingSpaces; + trimmedLine = trimmedLine.Substring(leadingSpaces + 3); // Remove leading spaces and the "///" + trimmedLine = trimmedLine.Trim(); + + var span = Microsoft.CodeAnalysis.Text.TextSpan.FromBounds(currentLocation, currentLocation + fullLine.Length); + var location = Microsoft.CodeAnalysis.Location.Create(trivia.SyntaxTree, span); + var commentType = CommentLineType.XmlDoc; + cx.CommentGenerator.AddComment(CommentLine.Create(cx, location, commentType, trimmedLine, fullLine)); + } + else + { + cx.ModelError("Unexpected comment format"); + } + currentLocation = nextLineLocation; + } + break; + + case SyntaxKind.SingleLineCommentTrivia: + { + var contents = trivia.ToString().Substring(2); + var commentType = CommentLineType.Singleline; + if (contents.Length > 0 && contents[0] == '/') + { + commentType = CommentLineType.XmlDoc; + contents = contents.Substring(1); // An XML comment. + } + cx.CommentGenerator.AddComment(CommentLine.Create(cx, trivia.GetLocation(), commentType, contents.Trim(), trivia.ToFullString())); + } + break; + case SyntaxKind.MultiLineDocumentationCommentTrivia: + case SyntaxKind.MultiLineCommentTrivia: + /* We receive a single SyntaxTrivia for a multiline block spanning several lines. + So we split it into separate lines + */ + text = trivia.ToFullString(); + + split = text.Split('\n'); + currentLocation = trivia.GetLocation().SourceSpan.Start; + + for (var line = 0; line < split.Length; ++line) + { + var fullLine = split[line]; + var nextLineLocation = currentLocation + fullLine.Length + 1; + fullLine = fullLine.TrimEnd('\r'); + var trimmedLine = fullLine; + if (line == 0) + trimmedLine = trimmedLine.Substring(2); + if (line == split.Length - 1) + trimmedLine = trimmedLine.Substring(0, trimmedLine.Length - 2); + trimmedLine = trimmedLine.Trim(); + + var span = Microsoft.CodeAnalysis.Text.TextSpan.FromBounds(currentLocation, currentLocation + fullLine.Length); + var location = Microsoft.CodeAnalysis.Location.Create(trivia.SyntaxTree, span); + var commentType = line == 0 ? CommentLineType.Multiline : CommentLineType.MultilineContinuation; + cx.CommentGenerator.AddComment(CommentLine.Create(cx, location, commentType, trimmedLine, fullLine)); + currentLocation = nextLineLocation; + } + break; + } + } + } +} diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Populators/Comments.cs b/csharp/extractor/Semmle.Extraction.CSharp/Populators/Comments.cs deleted file mode 100644 index 8f6bb6f5206..00000000000 --- a/csharp/extractor/Semmle.Extraction.CSharp/Populators/Comments.cs +++ /dev/null @@ -1,33 +0,0 @@ -using Semmle.Extraction.CommentProcessing; -using System; - -namespace Semmle.Extraction.CSharp.Populators -{ - /// - /// Populators for comments. - /// - public static class Comments - { - public static void ExtractComments(this Context cx, ICommentGenerator gen) - { - cx.Try(null, null, () => - { - gen.GenerateBindings((entity, duplicationGuardKey, block, binding) => - { - var commentBlock = Entities.CommentBlock.Create(cx, block); - Action a = () => - { - commentBlock.BindTo(entity, binding); - }; - // When the duplication guard key exists, it means that the entity is guarded against - // trap duplication (). - // We must therefore also guard comment construction. - if (duplicationGuardKey != null) - cx.WithDuplicationGuard(duplicationGuardKey, a); - else - a(); - }); - }); - } - } -} diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Populators/CompilationUnit.cs b/csharp/extractor/Semmle.Extraction.CSharp/Populators/CompilationUnit.cs deleted file mode 100644 index 69814bf197a..00000000000 --- a/csharp/extractor/Semmle.Extraction.CSharp/Populators/CompilationUnit.cs +++ /dev/null @@ -1,150 +0,0 @@ -using Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.CSharp; -using Microsoft.CodeAnalysis.CSharp.Syntax; -using Semmle.Extraction.CSharp.Entities; -using Semmle.Extraction.Entities; -using Semmle.Util; -using Semmle.Util.Logging; -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; - -namespace Semmle.Extraction.CSharp.Populators -{ - public class TypeContainerVisitor : CSharpSyntaxVisitor - { - protected Context cx { get; } - protected IEntity parent { get; } - protected TextWriter trapFile { get; } - private readonly Lazy> attributeLookup; - - public TypeContainerVisitor(Context cx, TextWriter trapFile, IEntity parent) - { - this.cx = cx; - this.parent = parent; - this.trapFile = trapFile; - attributeLookup = new Lazy>(() => - { - var dict = new Dictionary(); - foreach (var attributeData in cx.Compilation.Assembly.GetAttributes().Concat(cx.Compilation.Assembly.Modules.SelectMany(m => m.GetAttributes()))) - { - if (attributeData.ApplicationSyntaxReference?.GetSyntax() is SyntaxNode syntax) - dict.Add(syntax, attributeData); - } - return dict.GetValueOrDefault; - }); - } - - public override void DefaultVisit(SyntaxNode node) - { - throw new InternalError(node, "Unhandled top-level syntax node"); - } - - public override void VisitDelegateDeclaration(DelegateDeclarationSyntax node) - { - Entities.NamedType.Create(cx, cx.GetModel(node).GetDeclaredSymbol(node)).ExtractRecursive(trapFile, parent); - } - - public override void VisitClassDeclaration(ClassDeclarationSyntax classDecl) - { - Entities.Type.Create(cx, cx.GetModel(classDecl).GetDeclaredSymbol(classDecl)).ExtractRecursive(trapFile, parent); - } - - public override void VisitStructDeclaration(StructDeclarationSyntax node) - { - Entities.Type.Create(cx, cx.GetModel(node).GetDeclaredSymbol(node)).ExtractRecursive(trapFile, parent); - } - - public override void VisitEnumDeclaration(EnumDeclarationSyntax node) - { - Entities.Type.Create(cx, cx.GetModel(node).GetDeclaredSymbol(node)).ExtractRecursive(trapFile, parent); - } - - public override void VisitInterfaceDeclaration(InterfaceDeclarationSyntax node) - { - Entities.Type.Create(cx, cx.GetModel(node).GetDeclaredSymbol(node)).ExtractRecursive(trapFile, parent); - } - - public override void VisitAttributeList(AttributeListSyntax node) - { - if (cx.Extractor.Standalone) - return; - - var outputAssembly = Assembly.CreateOutputAssembly(cx); - foreach (var attribute in node.Attributes) - { - if (attributeLookup.Value(attribute) is AttributeData attributeData) - { - var ae = Semmle.Extraction.CSharp.Entities.Attribute.Create(cx, attributeData, outputAssembly); - cx.BindComments(ae, attribute.GetLocation()); - } - } - } - } - - internal class TypeOrNamespaceVisitor : TypeContainerVisitor - { - public TypeOrNamespaceVisitor(Context cx, TextWriter trapFile, IEntity parent) - : base(cx, trapFile, parent) { } - - public override void VisitUsingDirective(UsingDirectiveSyntax usingDirective) - { - // Only deal with "using namespace" not "using X = Y" - if (usingDirective.Alias == null) - new UsingDirective(cx, usingDirective, (NamespaceDeclaration)parent); - } - - public override void VisitNamespaceDeclaration(NamespaceDeclarationSyntax node) - { - NamespaceDeclaration.Create(cx, node, (NamespaceDeclaration)parent); - } - } - - internal class CompilationUnitVisitor : TypeOrNamespaceVisitor - { - public CompilationUnitVisitor(Context cx) - : base(cx, cx.TrapWriter.Writer, null) { } - - public override void VisitExternAliasDirective(ExternAliasDirectiveSyntax node) - { - // This information is not yet extracted. - cx.ExtractionError("Not implemented extern alias directive", node.ToFullString(), Extraction.Entities.Location.Create(cx, node.GetLocation()), "", Severity.Info); - } - - public override void VisitCompilationUnit(CompilationUnitSyntax compilationUnit) - { - foreach (var m in compilationUnit.ChildNodes()) - { - cx.Try(m, null, () => ((CSharpSyntaxNode)m).Accept(this)); - } - - // Gather comments: - foreach (var trivia in compilationUnit.DescendantTrivia(compilationUnit.Span)) - { - CommentLine.Extract(cx, trivia); - } - - foreach (var trivia in compilationUnit.GetLeadingTrivia()) - { - CommentLine.Extract(cx, trivia); - } - - foreach (var trivia in compilationUnit.GetTrailingTrivia()) - { - CommentLine.Extract(cx, trivia); - } - } - } - - public class CompilationUnit - { - public static void Extract(Context cx, SyntaxNode unit) - { - // Ensure that the file itself is populated in case the source file is totally empty - Semmle.Extraction.Entities.File.Create(cx, unit.SyntaxTree.FilePath); - - ((CSharpSyntaxNode)unit).Accept(new CompilationUnitVisitor(cx)); - } - } -} diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Populators/CompilationUnitVisitor.cs b/csharp/extractor/Semmle.Extraction.CSharp/Populators/CompilationUnitVisitor.cs new file mode 100644 index 00000000000..58e5404ccd7 --- /dev/null +++ b/csharp/extractor/Semmle.Extraction.CSharp/Populators/CompilationUnitVisitor.cs @@ -0,0 +1,73 @@ +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CSharp; +using Microsoft.CodeAnalysis.CSharp.Syntax; +using Semmle.Util.Logging; +using Semmle.Extraction.CSharp.Entities; +using Semmle.Extraction.CSharp.Entities.Statements; +using System.Linq; + +namespace Semmle.Extraction.CSharp.Populators +{ + internal class CompilationUnitVisitor : TypeOrNamespaceVisitor + { + public CompilationUnitVisitor(Context cx) + : base(cx, cx.TrapWriter.Writer, null) { } + + public override void VisitExternAliasDirective(ExternAliasDirectiveSyntax node) + { + // This information is not yet extracted. + Cx.ExtractionError("Not implemented extern alias directive", node.ToFullString(), Cx.CreateLocation(node.GetLocation()), "", Severity.Info); + } + + public override void VisitCompilationUnit(CompilationUnitSyntax compilationUnit) + { + foreach (var m in compilationUnit.ChildNodes()) + { + Cx.Try(m, null, () => ((CSharpSyntaxNode)m).Accept(this)); + } + + ExtractGlobalStatements(compilationUnit); + + // Gather comments: + foreach (var trivia in compilationUnit.DescendantTrivia(compilationUnit.Span, descendIntoTrivia: true)) + { + CommentPopulator.ExtractComment(Cx, trivia); + } + + foreach (var trivia in compilationUnit.GetLeadingTrivia()) + { + CommentPopulator.ExtractComment(Cx, trivia); + } + + foreach (var trivia in compilationUnit.GetTrailingTrivia()) + { + CommentPopulator.ExtractComment(Cx, trivia); + } + } + + private void ExtractGlobalStatements(CompilationUnitSyntax compilationUnit) + { + var globalStatements = compilationUnit + .ChildNodes() + .OfType() + .ToList(); + + if (!globalStatements.Any()) + { + return; + } + + var entryPoint = Cx.Compilation.GetEntryPoint(System.Threading.CancellationToken.None); + var entryMethod = Method.Create(Cx, entryPoint); + var block = GlobalStatementsBlock.Create(Cx, entryMethod); + + for (var i = 0; i < globalStatements.Count; i++) + { + if (globalStatements[i].Statement is object) + { + Statement.Create(Cx, globalStatements[i].Statement, block, i); + } + } + } + } +} diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Populators/DirectiveVisitor.cs b/csharp/extractor/Semmle.Extraction.CSharp/Populators/DirectiveVisitor.cs new file mode 100644 index 00000000000..0c400728554 --- /dev/null +++ b/csharp/extractor/Semmle.Extraction.CSharp/Populators/DirectiveVisitor.cs @@ -0,0 +1,137 @@ +using System.Collections.Generic; +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CSharp; +using Microsoft.CodeAnalysis.CSharp.Syntax; + +namespace Semmle.Extraction.CSharp.Populators +{ + internal class DirectiveVisitor : CSharpSyntaxWalker + { + private readonly Context cx; + + public DirectiveVisitor(Context cx) : base(SyntaxWalkerDepth.StructuredTrivia) + { + this.cx = cx; + } + + public override void VisitPragmaWarningDirectiveTrivia(PragmaWarningDirectiveTriviaSyntax node) + { + new Entities.PragmaWarningDirective(cx, node); + } + + public override void VisitPragmaChecksumDirectiveTrivia(PragmaChecksumDirectiveTriviaSyntax node) + { + new Entities.PragmaChecksumDirective(cx, node); + } + + public override void VisitDefineDirectiveTrivia(DefineDirectiveTriviaSyntax node) + { + new Entities.DefineDirective(cx, node); + } + + public override void VisitUndefDirectiveTrivia(UndefDirectiveTriviaSyntax node) + { + new Entities.UndefineDirective(cx, node); + } + + public override void VisitWarningDirectiveTrivia(WarningDirectiveTriviaSyntax node) + { + new Entities.WarningDirective(cx, node); + } + + public override void VisitErrorDirectiveTrivia(ErrorDirectiveTriviaSyntax node) + { + new Entities.ErrorDirective(cx, node); + } + + public override void VisitNullableDirectiveTrivia(NullableDirectiveTriviaSyntax node) + { + new Entities.NullableDirective(cx, node); + } + + public override void VisitLineDirectiveTrivia(LineDirectiveTriviaSyntax node) + { + new Entities.LineDirective(cx, node); + } + + private readonly Stack regionStarts = new Stack(); + + public override void VisitRegionDirectiveTrivia(RegionDirectiveTriviaSyntax node) + { + var region = new Entities.RegionDirective(cx, node); + regionStarts.Push(region); + } + + public override void VisitEndRegionDirectiveTrivia(EndRegionDirectiveTriviaSyntax node) + { + if (regionStarts.Count == 0) + { + cx.ExtractionError("Couldn't find start region", null, + cx.CreateLocation(node.GetLocation()), null, Util.Logging.Severity.Warning); + return; + } + + var start = regionStarts.Pop(); + new Entities.EndRegionDirective(cx, node, start); + } + + private class IfDirectiveStackElement + { + public Entities.IfDirective Entity { get; } + public int SiblingCount { get; set; } + + + public IfDirectiveStackElement(Entities.IfDirective entity) + { + Entity = entity; + } + } + + private readonly Stack ifStarts = new Stack(); + + public override void VisitIfDirectiveTrivia(IfDirectiveTriviaSyntax node) + { + var ifStart = new Entities.IfDirective(cx, node); + ifStarts.Push(new IfDirectiveStackElement(ifStart)); + } + + public override void VisitEndIfDirectiveTrivia(EndIfDirectiveTriviaSyntax node) + { + if (ifStarts.Count == 0) + { + cx.ExtractionError("Couldn't find start if", null, + cx.CreateLocation(node.GetLocation()), null, Util.Logging.Severity.Warning); + return; + } + + var start = ifStarts.Pop(); + new Entities.EndIfDirective(cx, node, start.Entity); + } + + public override void VisitElifDirectiveTrivia(ElifDirectiveTriviaSyntax node) + { + if (ifStarts.Count == 0) + { + cx.ExtractionError("Couldn't find start if", null, + cx.CreateLocation(node.GetLocation()), null, Util.Logging.Severity.Warning); + return; + } + + var start = ifStarts.Peek(); + new Entities.ElifDirective(cx, node, start.Entity, start.SiblingCount++); + } + + public override void VisitElseDirectiveTrivia(ElseDirectiveTriviaSyntax node) + { + if (ifStarts.Count == 0) + { + cx.ExtractionError("Couldn't find start if", null, + cx.CreateLocation(node.GetLocation()), null, Util.Logging.Severity.Warning); + return; + } + + var start = ifStarts.Peek(); + new Entities.ElseDirective(cx, node, start.Entity, start.SiblingCount++); + } + } +} diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Populators/Methods.cs b/csharp/extractor/Semmle.Extraction.CSharp/Populators/Methods.cs deleted file mode 100644 index 148160b8815..00000000000 --- a/csharp/extractor/Semmle.Extraction.CSharp/Populators/Methods.cs +++ /dev/null @@ -1,65 +0,0 @@ -using Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.CSharp; -using Microsoft.CodeAnalysis.CSharp.Syntax; -using Semmle.Util; -using System.IO; - -namespace Semmle.Extraction.CSharp.Populators -{ - public static class MethodExtensions - { - private class AstLineCounter : CSharpSyntaxVisitor - { - public override LineCounts DefaultVisit(SyntaxNode node) - { - var text = node.SyntaxTree.GetText().GetSubText(node.GetLocation().SourceSpan).ToString(); - return Semmle.Util.LineCounter.ComputeLineCounts(text); - } - - public override LineCounts VisitMethodDeclaration(MethodDeclarationSyntax method) - { - return Visit(method.Identifier, method.Body ?? (SyntaxNode)method.ExpressionBody); - } - - public static LineCounts Visit(SyntaxToken identifier, SyntaxNode body) - { - var start = identifier.GetLocation().SourceSpan.Start; - var end = body.GetLocation().SourceSpan.End - 1; - - var textSpan = new Microsoft.CodeAnalysis.Text.TextSpan(start, end - start); - - var text = body.SyntaxTree.GetText().GetSubText(textSpan) + "\r\n"; - return Semmle.Util.LineCounter.ComputeLineCounts(text); - } - - public override LineCounts VisitConstructorDeclaration(ConstructorDeclarationSyntax method) - { - return Visit(method.Identifier, (SyntaxNode)method.Body ?? method.ExpressionBody); - } - - public override LineCounts VisitDestructorDeclaration(DestructorDeclarationSyntax method) - { - return Visit(method.Identifier, (SyntaxNode)method.Body ?? method.ExpressionBody); - } - - public override LineCounts VisitOperatorDeclaration(OperatorDeclarationSyntax node) - { - return Visit(node.OperatorToken, node.Body ?? (SyntaxNode)node.ExpressionBody); - } - } - - public static void NumberOfLines(this Context cx, TextWriter trapFile, ISymbol symbol, IEntity callable) - { - foreach (var decl in symbol.DeclaringSyntaxReferences) - { - cx.NumberOfLines(trapFile, (CSharpSyntaxNode)decl.GetSyntax(), callable); - } - } - - public static void NumberOfLines(this Context cx, TextWriter trapFile, CSharpSyntaxNode node, IEntity callable) - { - var lineCounts = node.Accept(new AstLineCounter()); - trapFile.numlines(callable, lineCounts); - } - } -} diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Populators/Symbols.cs b/csharp/extractor/Semmle.Extraction.CSharp/Populators/Symbols.cs index ddf64257cbe..a4a06fd6ba2 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp/Populators/Symbols.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp/Populators/Symbols.cs @@ -38,6 +38,8 @@ namespace Semmle.Extraction.CSharp.Populators public override IEntity VisitPointerType(IPointerTypeSymbol symbol) => PointerType.Create(cx, symbol); + public override IEntity VisitFunctionPointerType(IFunctionPointerTypeSymbol symbol) => FunctionPointerType.Create(cx, symbol); + public override IEntity VisitDynamicType(IDynamicTypeSymbol symbol) => DynamicType.Create(cx, symbol); } } diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Populators/TypeContainerVisitor.cs b/csharp/extractor/Semmle.Extraction.CSharp/Populators/TypeContainerVisitor.cs new file mode 100644 index 00000000000..ededf2978b9 --- /dev/null +++ b/csharp/extractor/Semmle.Extraction.CSharp/Populators/TypeContainerVisitor.cs @@ -0,0 +1,99 @@ +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CSharp; +using Microsoft.CodeAnalysis.CSharp.Syntax; +using Semmle.Extraction.Entities; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; + +namespace Semmle.Extraction.CSharp.Populators +{ + public class TypeContainerVisitor : CSharpSyntaxVisitor + { + protected Context Cx { get; } + protected IEntity Parent { get; } + protected TextWriter TrapFile { get; } + private readonly Lazy> attributeLookup; + + public TypeContainerVisitor(Context cx, TextWriter trapFile, IEntity parent) + { + Cx = cx; + Parent = parent; + TrapFile = trapFile; + + attributeLookup = new Lazy>(() => + { + var dict = new Dictionary(); + foreach (var attributeData in cx.Compilation.Assembly.GetAttributes().Concat(cx.Compilation.Assembly.Modules.SelectMany(m => m.GetAttributes()))) + { + if (attributeData.ApplicationSyntaxReference?.GetSyntax() is SyntaxNode syntax) + dict.Add(syntax, attributeData); + } + return dict.GetValueOrDefault; + }); + } + + public override void DefaultVisit(SyntaxNode node) + { + throw new InternalError(node, "Unhandled top-level syntax node"); + } + + public override void VisitGlobalStatement(GlobalStatementSyntax node) + { + // Intentionally left empty. + // Global statements are handled in CompilationUnitVisitor + } + + public override void VisitDelegateDeclaration(DelegateDeclarationSyntax node) + { + Entities.NamedType.Create(Cx, Cx.GetModel(node).GetDeclaredSymbol(node)).ExtractRecursive(TrapFile, Parent); + } + + public override void VisitRecordDeclaration(RecordDeclarationSyntax node) + { + ExtractTypeDeclaration(node); + } + + public override void VisitClassDeclaration(ClassDeclarationSyntax node) + { + ExtractTypeDeclaration(node); + } + + public override void VisitStructDeclaration(StructDeclarationSyntax node) + { + ExtractTypeDeclaration(node); + } + + public override void VisitEnumDeclaration(EnumDeclarationSyntax node) + { + ExtractTypeDeclaration(node); + } + + public override void VisitInterfaceDeclaration(InterfaceDeclarationSyntax node) + { + ExtractTypeDeclaration(node); + } + + private void ExtractTypeDeclaration(BaseTypeDeclarationSyntax node) + { + Entities.Type.Create(Cx, Cx.GetModel(node).GetDeclaredSymbol(node)).ExtractRecursive(TrapFile, Parent); + } + + public override void VisitAttributeList(AttributeListSyntax node) + { + if (Cx.Extractor.Standalone) + return; + + var outputAssembly = Assembly.CreateOutputAssembly(Cx); + foreach (var attribute in node.Attributes) + { + if (attributeLookup.Value(attribute) is AttributeData attributeData) + { + var ae = Entities.Attribute.Create(Cx, attributeData, outputAssembly); + Cx.BindComments(ae, attribute.GetLocation()); + } + } + } + } +} diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Populators/TypeOrNamespaceVisitor.cs b/csharp/extractor/Semmle.Extraction.CSharp/Populators/TypeOrNamespaceVisitor.cs new file mode 100644 index 00000000000..a3daae08a60 --- /dev/null +++ b/csharp/extractor/Semmle.Extraction.CSharp/Populators/TypeOrNamespaceVisitor.cs @@ -0,0 +1,24 @@ +using Microsoft.CodeAnalysis.CSharp.Syntax; +using Semmle.Extraction.CSharp.Entities; +using System.IO; + +namespace Semmle.Extraction.CSharp.Populators +{ + internal class TypeOrNamespaceVisitor : TypeContainerVisitor + { + public TypeOrNamespaceVisitor(Context cx, TextWriter trapFile, IEntity parent) + : base(cx, trapFile, parent) { } + + public override void VisitUsingDirective(UsingDirectiveSyntax usingDirective) + { + // Only deal with "using namespace" not "using X = Y" + if (usingDirective.Alias == null) + new UsingDirective(Cx, usingDirective, (NamespaceDeclaration)Parent); + } + + public override void VisitNamespaceDeclaration(NamespaceDeclarationSyntax node) + { + NamespaceDeclaration.Create(Cx, node, (NamespaceDeclaration)Parent); + } + } +} diff --git a/csharp/extractor/Semmle.Extraction.CSharp/SymbolExtensions.cs b/csharp/extractor/Semmle.Extraction.CSharp/SymbolExtensions.cs index 530a30d8a51..77e27a00be5 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp/SymbolExtensions.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp/SymbolExtensions.cs @@ -23,6 +23,9 @@ namespace Semmle.Extraction.CSharp Symbol = symbol; Nullability = nullability; } + + public static AnnotatedTypeSymbol? CreateNotAnnotated(ITypeSymbol symbol) => + symbol is null ? (AnnotatedTypeSymbol?)null : new AnnotatedTypeSymbol(symbol, NullableAnnotation.None); } internal static class SymbolExtensions @@ -131,6 +134,13 @@ namespace Semmle.Extraction.CSharp return tp.ContainingSymbol is ITypeSymbol cont ? IdDependsOnImpl(cont) : SymbolEqualityComparer.Default.Equals(tp.ContainingSymbol, symbol); + case TypeKind.FunctionPointer: + var funptr = (IFunctionPointerTypeSymbol)type; + if (funptr.Signature.Parameters.Any(p => IdDependsOnImpl(p.Type))) + { + return true; + } + return IdDependsOnImpl(funptr.Signature.ReturnType); default: return false; } @@ -187,6 +197,10 @@ namespace Semmle.Extraction.CSharp case TypeKind.Dynamic: trapFile.Write("dynamic"); return; + case TypeKind.FunctionPointer: + var funptr = (IFunctionPointerTypeSymbol)type; + funptr.BuildFunctionPointerTypeId(cx, trapFile, symbolBeingDefined); + return; default: throw new InternalError(type, $"Unhandled type kind '{type.TypeKind}'"); } @@ -262,6 +276,11 @@ namespace Semmle.Extraction.CSharp trapFile.Write("::"); } + private static void BuildFunctionPointerTypeId(this IFunctionPointerTypeSymbol funptr, Context cx, TextWriter trapFile, ISymbol symbolBeingDefined) + { + BuildFunctionPointerSignature(funptr, trapFile, (s, tw) => s.BuildOrWriteId(cx, tw, symbolBeingDefined)); + } + private static void BuildNamedTypeId(this INamedTypeSymbol named, Context cx, TextWriter trapFile, ISymbol symbolBeingDefined, bool addBaseClass, bool constructUnderlyingTupleType) { if (!constructUnderlyingTupleType && named.IsTupleType) @@ -391,6 +410,10 @@ namespace Semmle.Extraction.CSharp ptr.PointedAtType.BuildDisplayName(cx, trapFile); trapFile.Write('*'); return; + case TypeKind.FunctionPointer: + var funptr = (IFunctionPointerTypeSymbol)type; + funptr.BuildFunctionPointerTypeDisplayName(cx, trapFile); + return; case TypeKind.TypeParameter: trapFile.Write(type.Name); return; @@ -403,31 +426,93 @@ namespace Semmle.Extraction.CSharp } } - public static void BuildNamedTypeDisplayName(this INamedTypeSymbol namedType, Context cx, TextWriter trapFile, bool constructUnderlyingTupleType) + public static void BuildFunctionPointerSignature(IFunctionPointerTypeSymbol funptr, TextWriter trapFile, + Action buildNested) + { + trapFile.Write("delegate* "); + trapFile.Write(funptr.Signature.CallingConvention.ToString().ToLowerInvariant()); + + if (funptr.Signature.UnmanagedCallingConventionTypes.Any()) + { + trapFile.Write('['); + trapFile.BuildList(",", funptr.Signature.UnmanagedCallingConventionTypes, buildNested); + trapFile.Write("]"); + } + + trapFile.Write('<'); + trapFile.BuildList(",", funptr.Signature.Parameters, + (p, trap) => + { + buildNested(p.Type, trap); + switch (p.RefKind) + { + case RefKind.Out: + trap.Write(" out"); + break; + case RefKind.In: + trap.Write(" in"); + break; + case RefKind.Ref: + trap.Write(" ref"); + break; + } + }); + + if (funptr.Signature.Parameters.Any()) + { + trapFile.Write(","); + } + + buildNested(funptr.Signature.ReturnType, trapFile); + + if (funptr.Signature.ReturnsByRef) + trapFile.Write(" ref"); + if (funptr.Signature.ReturnsByRefReadonly) + trapFile.Write(" ref readonly"); + + trapFile.Write('>'); + } + + private static void BuildFunctionPointerTypeDisplayName(this IFunctionPointerTypeSymbol funptr, Context cx, TextWriter trapFile) + { + BuildFunctionPointerSignature(funptr, trapFile, (s, tw) => s.BuildDisplayName(cx, tw)); + } + + private static void BuildNamedTypeDisplayName(this INamedTypeSymbol namedType, Context cx, TextWriter trapFile, bool constructUnderlyingTupleType) { if (!constructUnderlyingTupleType && namedType.IsTupleType) { trapFile.Write('('); - trapFile.BuildList(",", namedType.TupleElements.Select(f => f.Type), - (t, tb0) => t.BuildDisplayName(cx, tb0) - ); - + trapFile.BuildList( + ",", + namedType.TupleElements.Select(f => f.Type), + (t, tb0) => t.BuildDisplayName(cx, tb0)); trapFile.Write(")"); return; } if (namedType.IsAnonymousType) + { namedType.BuildAnonymousName(cx, trapFile); + } else + { trapFile.Write(namedType.Name); + } + if (namedType.IsGenericType && namedType.TypeKind != TypeKind.Error && namedType.TypeArguments.Any()) { trapFile.Write('<'); - trapFile.BuildList(",", namedType.TypeArguments, (p, tb0) => - { - if (IsReallyBound(namedType)) - p.BuildDisplayName(cx, tb0); - }); + trapFile.BuildList( + ",", + namedType.TypeArguments, + (p, tb0) => + { + if (IsReallyBound(namedType)) + { + p.BuildDisplayName(cx, tb0); + } + }); trapFile.Write('>'); } } diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Tuples.cs b/csharp/extractor/Semmle.Extraction.CSharp/Tuples.cs index 4123cc1808d..df39d6a836c 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp/Tuples.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp/Tuples.cs @@ -1,5 +1,7 @@ +using Microsoft.CodeAnalysis.CSharp.Syntax; using Semmle.Extraction.CommentProcessing; using Semmle.Extraction.CSharp.Entities; +using Semmle.Extraction.CSharp.Entities.Expressions; using Semmle.Extraction.Entities; using Semmle.Extraction.Kinds; using Semmle.Util; @@ -26,6 +28,11 @@ namespace Semmle.Extraction.CSharp trapFile.WriteTuple("accessors", accessorKey, kind, name, propKey, unboundAccessor); } + internal static void init_only_accessors(this TextWriter trapFile, Accessor accessorKey) + { + trapFile.WriteTuple("init_only_accessors", accessorKey); + } + internal static void array_element_type(this TextWriter trapFile, ArrayType array, int dimension, int rank, Type elementType) { trapFile.WriteTuple("array_element_type", array, dimension, rank, elementType); @@ -46,6 +53,17 @@ namespace Semmle.Extraction.CSharp trapFile.WriteTuple("catch_type", @catch, type, explicityCaught ? 1 : 2); } + internal static void foreach_stmt_info(this TextWriter trapFile, Entities.Statements.ForEach @foreach, bool isAsync) + { + trapFile.WriteTuple("foreach_stmt_info", @foreach, isAsync ? 2 : 1); + } + + internal static void foreach_stmt_desugar(this TextWriter trapFile, Entities.Statements.ForEach @foreach, IEntity entity, + Entities.Statements.ForEach.ForeachSymbolType type) + { + trapFile.WriteTuple("foreach_stmt_desugar", @foreach, entity, (int)type); + } + internal static void commentblock(this TextWriter trapFile, CommentBlock k) { trapFile.WriteTuple("commentblock", k); @@ -106,6 +124,11 @@ namespace Semmle.Extraction.CSharp trapFile.WriteTuple("compilations", compilation, cwd); } + internal static void compilation_assembly(this TextWriter trapFile, Compilation compilation, Assembly assembly) + { + trapFile.WriteTuple("compilation_assembly", compilation, assembly); + } + internal static void compiler_generated(this TextWriter trapFile, IEntity entity) { trapFile.WriteTuple("compiler_generated", entity); @@ -141,6 +164,11 @@ namespace Semmle.Extraction.CSharp trapFile.WriteTuple("delegate_return_type", delegateKey, returnType); } + internal static void function_pointer_return_type(this TextWriter trapFile, Type functionPointer, Type returnType) + { + trapFile.WriteTuple("function_pointer_return_type", functionPointer, returnType); + } + internal static void destructor_location(this TextWriter trapFile, Destructor destructor, Location location) { trapFile.WriteTuple("destructor_location", destructor, location); @@ -266,6 +294,11 @@ namespace Semmle.Extraction.CSharp trapFile.WriteTuple("extend", type, super); } + internal static void anonymous_types(this TextWriter trapFile, Type type) + { + trapFile.WriteTuple("anonymous_types", type); + } + internal static void field_location(this TextWriter trapFile, Field field, Location location) { trapFile.WriteTuple("field_location", field, location); @@ -296,6 +329,11 @@ namespace Semmle.Extraction.CSharp trapFile.WriteTuple("implicitly_typed_array_creation", array); } + internal static void implicitly_typed_object_creation(this TextWriter trapFile, Expression expression) + { + trapFile.WriteTuple("implicitly_typed_object_creation", expression); + } + internal static void indexer_location(this TextWriter trapFile, Indexer indexer, Location location) { trapFile.WriteTuple("indexer_location", indexer, location); @@ -456,6 +494,16 @@ namespace Semmle.Extraction.CSharp trapFile.WriteTuple("specific_type_parameter_nullability", constraints, baseType, nullability); } + internal static void function_pointer_calling_conventions(this TextWriter trapFile, FunctionPointerType type, int kind) + { + trapFile.WriteTuple("function_pointer_calling_conventions", type, kind); + } + + internal static void has_unmanaged_calling_conventions(this TextWriter trapFile, FunctionPointerType type, int index, Type convention) + { + trapFile.WriteTuple("has_unmanaged_calling_conventions", type, index, convention); + } + internal static void stackalloc_array_creation(this TextWriter trapFile, Expression array) { trapFile.WriteTuple("stackalloc_array_creation", array); @@ -555,5 +603,123 @@ namespace Semmle.Extraction.CSharp { trapFile.WriteTuple("using_static_directives", @using, type); } + + internal static void preprocessor_directive_location(this TextWriter trapFile, + PreprocessorDirective directive, Location location) + where TDirective : DirectiveTriviaSyntax + { + trapFile.WriteTuple("preprocessor_directive_location", directive, location); + } + + internal static void preprocessor_directive_compilation(this TextWriter trapFile, + PreprocessorDirective directive, Compilation compilation) + where TDirective : DirectiveTriviaSyntax + { + trapFile.WriteTuple("preprocessor_directive_compilation", directive, compilation); + } + + internal static void preprocessor_directive_active(this TextWriter trapFile, + PreprocessorDirective directive, bool isActive) + where TDirective : DirectiveTriviaSyntax + { + trapFile.WriteTuple("preprocessor_directive_active", directive, isActive ? 1 : 0); + } + + internal static void pragma_warnings(this TextWriter trapFile, PragmaWarningDirective pragma, int kind) + { + trapFile.WriteTuple("pragma_warnings", pragma, kind); + } + + internal static void pragma_warning_error_codes(this TextWriter trapFile, PragmaWarningDirective pragma, string errorCode, int child) + { + trapFile.WriteTuple("pragma_warning_error_codes", pragma, errorCode, child); + } + + internal static void pragma_checksums(this TextWriter trapFile, PragmaChecksumDirective pragma, Extraction.Entities.File file, string guid, string bytes) + { + trapFile.WriteTuple("pragma_checksums", pragma, file, guid, bytes); + } + + internal static void directive_defines(this TextWriter trapFile, DefineDirective directive, string name) + { + trapFile.WriteTuple("directive_defines", directive, name); + } + + internal static void directive_undefines(this TextWriter trapFile, UndefineDirective directive, string name) + { + trapFile.WriteTuple("directive_undefines", directive, name); + } + + internal static void directive_warnings(this TextWriter trapFile, WarningDirective directive, string message) + { + trapFile.WriteTuple("directive_warnings", directive, message); + } + + internal static void directive_errors(this TextWriter trapFile, ErrorDirective directive, string message) + { + trapFile.WriteTuple("directive_errors", directive, message); + } + + internal static void directive_nullables(this TextWriter trapFile, NullableDirective directive, int setting, int target) + { + trapFile.WriteTuple("directive_nullables", directive, setting, target); + } + + internal static void directive_lines(this TextWriter trapFile, LineDirective directive, int kind) + { + trapFile.WriteTuple("directive_lines", directive, kind); + } + + internal static void directive_line_value(this TextWriter trapFile, LineDirective directive, int line) + { + trapFile.WriteTuple("directive_line_value", directive, line); + } + + internal static void directive_line_file(this TextWriter trapFile, LineDirective directive, Extraction.Entities.File file) + { + trapFile.WriteTuple("directive_line_file", directive, file); + } + + internal static void directive_regions(this TextWriter trapFile, RegionDirective directive, string name) + { + trapFile.WriteTuple("directive_regions", directive, name); + } + + internal static void directive_endregions(this TextWriter trapFile, EndRegionDirective directive, RegionDirective start) + { + trapFile.WriteTuple("directive_endregions", directive, start); + } + + internal static void regions(this TextWriter trapFile, RegionDirective start, EndRegionDirective end) + { + trapFile.WriteTuple("regions", start, end); + } + + internal static void directive_ifs(this TextWriter trapFile, IfDirective directive, bool branchTaken, bool conditionValue) + { + trapFile.WriteTuple("directive_ifs", directive, branchTaken ? 1 : 0, conditionValue ? 1 : 0); + } + + internal static void directive_elifs(this TextWriter trapFile, ElifDirective directive, bool branchTaken, bool conditionValue, + IfDirective start, int index) + { + trapFile.WriteTuple("directive_elifs", directive, branchTaken ? 1 : 0, conditionValue ? 1 : 0, start, index); + } + + internal static void directive_elses(this TextWriter trapFile, ElseDirective directive, bool branchTaken, + IfDirective start, int index) + { + trapFile.WriteTuple("directive_elses", directive, branchTaken ? 1 : 0, start, index); + } + + internal static void directive_endifs(this TextWriter trapFile, EndIfDirective directive, IfDirective start) + { + trapFile.WriteTuple("directive_endifs", directive, start); + } + + internal static void directive_define_symbols(this TextWriter trapFile, DefineSymbol symb, string name) + { + trapFile.WriteTuple("directive_define_symbols", symb, name); + } } } diff --git a/csharp/extractor/Semmle.Extraction/AssemblyScope.cs b/csharp/extractor/Semmle.Extraction/AssemblyScope.cs new file mode 100644 index 00000000000..27c9377bb30 --- /dev/null +++ b/csharp/extractor/Semmle.Extraction/AssemblyScope.cs @@ -0,0 +1,25 @@ +using Microsoft.CodeAnalysis; + +namespace Semmle.Extraction +{ + /// + /// The scope of symbols in an assembly. + /// + public class AssemblyScope : IExtractionScope + { + private readonly IAssemblySymbol assembly; + private readonly string filepath; + + public AssemblyScope(IAssemblySymbol symbol, string path) + { + assembly = symbol; + filepath = path; + } + + public bool InFileScope(string path) => path == filepath; + + public bool InScope(ISymbol symbol) => + SymbolEqualityComparer.Default.Equals(symbol.ContainingAssembly, assembly) || + SymbolEqualityComparer.Default.Equals(symbol, assembly); + } +} diff --git a/csharp/extractor/Semmle.Extraction/CommentProcessing.cs b/csharp/extractor/Semmle.Extraction/CommentProcessing.cs index f407f5703fe..201ac705136 100644 --- a/csharp/extractor/Semmle.Extraction/CommentProcessing.cs +++ b/csharp/extractor/Semmle.Extraction/CommentProcessing.cs @@ -53,7 +53,7 @@ namespace Semmle.Extraction.CommentProcessing if (l2 == null) return 1; - var diff = l1.SourceTree == l2.SourceTree ? 0 : l1.SourceTree.FilePath.CompareTo(l2.SourceTree.FilePath); + var diff = l1.SourceTree == l2.SourceTree ? 0 : l1.SourceTree!.FilePath.CompareTo(l2.SourceTree!.FilePath); if (diff != 0) return diff; diff = l1.SourceSpan.Start - l2.SourceSpan.Start; @@ -384,9 +384,12 @@ namespace Semmle.Extraction.CommentProcessing /// The line to add. public void AddCommentLine(ICommentLine line) { - Location = !lines.Any() ? - line.Location : - Location.Create(line.Location.SourceTree, new TextSpan(Location.SourceSpan.Start, line.Location.SourceSpan.End - Location.SourceSpan.Start)); + Location = !lines.Any() + ? line.Location + : Location.Create( + line.Location.SourceTree!, + new TextSpan(Location.SourceSpan.Start, line.Location.SourceSpan.End - Location.SourceSpan.Start)); + lines.Add(line); } } diff --git a/csharp/extractor/Semmle.Extraction/Context.cs b/csharp/extractor/Semmle.Extraction/Context.cs index d6b67bb9af1..7f5ef6b1110 100644 --- a/csharp/extractor/Semmle.Extraction/Context.cs +++ b/csharp/extractor/Semmle.Extraction/Context.cs @@ -18,7 +18,7 @@ namespace Semmle.Extraction /// /// Access various extraction functions, e.g. logger, trap writer. /// - public IExtractor Extractor { get; } + public Extractor Extractor { get; } /// /// The program database provided by Roslyn. @@ -51,7 +51,7 @@ namespace Semmle.Extraction // A recursion guard against writing to the trap file whilst writing an id to the trap file. private bool writingLabel = false; - public void DefineLabel(IEntity entity, TextWriter trapFile, IExtractor extractor) + public void DefineLabel(IEntity entity, TextWriter trapFile, Extractor extractor) { if (writingLabel) { @@ -77,7 +77,7 @@ namespace Semmle.Extraction { if (idLabelCache.ContainsKey(id)) { - this.Extractor.Message(new Message("Label collision for " + id, entity.Label.ToString(), Entities.Location.Create(this, entity.ReportingLocation), "", Severity.Warning)); + this.Extractor.Message(new Message("Label collision for " + id, entity.Label.ToString(), CreateLocation(entity.ReportingLocation), "", Severity.Warning)); } else { @@ -169,7 +169,7 @@ namespace Semmle.Extraction #endif private readonly IDictionary objectEntityCache = new Dictionary(); - private readonly IDictionary symbolEntityCache = new Dictionary(10000, SymbolEqualityComparer.IncludeNullability); + private readonly IDictionary symbolEntityCache = new Dictionary(10000, SymbolEqualityComparer.Default); private readonly HashSet - /// The context. /// Optional syntax node for error reporting. /// Optional symbol for error reporting. /// The action to perform. - public static void Try(this Context context, SyntaxNode? node, ISymbol? symbol, Action a) + public void Try(SyntaxNode? node, ISymbol? symbol, Action a) { try { @@ -522,26 +508,49 @@ namespace Semmle.Extraction Message message; if (node != null) - message = Message.Create(context, ex.Message, node, ex.StackTrace); + { + message = Message.Create(this, ex.Message, node, ex.StackTrace); + } else if (symbol != null) - message = Message.Create(context, ex.Message, symbol, ex.StackTrace); + { + message = Message.Create(this, ex.Message, symbol, ex.StackTrace); + } else if (ex is InternalError ie) - message = new Message(ie.Text, ie.EntityText, Entities.Location.Create(context, ie.Location), ex.StackTrace); + { + message = new Message(ie.Text, ie.EntityText, CreateLocation(ie.Location), ex.StackTrace); + } else - message = new Message("Uncaught exception", ex.Message, GeneratedLocation.Create(context), ex.StackTrace); + { + message = new Message($"Uncaught exception. {ex.Message}", null, CreateLocation(), ex.StackTrace); + } - context.ExtractionError(message); + ExtractionError(message); } } /// /// Write the given tuple to the trap file. /// - /// Extractor context. /// Tuple to write. - public static void Emit(this Context cx, Tuple tuple) + public void Emit(Tuple tuple) { - cx.TrapWriter.Emit(tuple); + TrapWriter.Emit(tuple); + } + + public Entities.Location CreateLocation() + { + return SourceTree == null + ? GeneratedLocation.Create(this) + : CreateLocation(Microsoft.CodeAnalysis.Location.Create(SourceTree, Microsoft.CodeAnalysis.Text.TextSpan.FromBounds(0, 0))); + } + + public Entities.Location CreateLocation(Microsoft.CodeAnalysis.Location? location) + { + return (location == null || location.Kind == LocationKind.None) + ? GeneratedLocation.Create(this) + : location.IsInSource + ? NonGeneratedSourceLocation.Create(this, location) + : Assembly.Create(this, location); } } } diff --git a/csharp/extractor/Semmle.Extraction/Entities/Assembly.cs b/csharp/extractor/Semmle.Extraction/Entities/Assembly.cs index 35055541371..e8b1e2cb46b 100644 --- a/csharp/extractor/Semmle.Extraction/Entities/Assembly.cs +++ b/csharp/extractor/Semmle.Extraction/Entities/Assembly.cs @@ -19,7 +19,7 @@ namespace Semmle.Extraction.Entities } else { - assembly = init.MetadataModule.ContainingAssembly; + assembly = init.MetadataModule!.ContainingAssembly; var identity = assembly.Identity; var idString = identity.Name + " " + identity.Version; assemblyPath = cx.Extractor.GetAssemblyFile(idString); @@ -35,8 +35,7 @@ namespace Semmle.Extraction.Entities } } - public override bool NeedsPopulation => - !SymbolEqualityComparer.Default.Equals(assembly, Context.Compilation.Assembly) || !Context.IsGlobalContext; + public override bool NeedsPopulation => true; public override int GetHashCode() => symbol == null ? 91187354 : symbol.GetHashCode(); @@ -49,7 +48,7 @@ namespace Semmle.Extraction.Entities return false; } - public static new Location Create(Context cx, Microsoft.CodeAnalysis.Location loc) => AssemblyConstructorFactory.Instance.CreateEntity(cx, loc, loc); + public static Location Create(Context cx, Microsoft.CodeAnalysis.Location loc) => AssemblyConstructorFactory.Instance.CreateEntity(cx, loc, loc); private class AssemblyConstructorFactory : ICachedEntityFactory { @@ -59,7 +58,8 @@ namespace Semmle.Extraction.Entities } private static readonly object outputAssemblyCacheKey = new object(); - public static Location CreateOutputAssembly(Context cx) + + public static Assembly CreateOutputAssembly(Context cx) { if (cx.Extractor.OutputPath == null) throw new InternalError("Attempting to create the output assembly in standalone extraction mode"); diff --git a/csharp/extractor/Semmle.Extraction/Entities/ExtractionError.cs b/csharp/extractor/Semmle.Extraction/Entities/ExtractionError.cs index 74bc41fa957..96aabb57f8e 100644 --- a/csharp/extractor/Semmle.Extraction/Entities/ExtractionError.cs +++ b/csharp/extractor/Semmle.Extraction/Entities/ExtractionError.cs @@ -14,7 +14,8 @@ namespace Semmle.Extraction.Entities protected override void Populate(TextWriter trapFile) { - trapFile.extractor_messages(this, msg.Severity, "C# extractor", msg.Text, msg.EntityText, msg.Location ?? GeneratedLocation.Create(cx), msg.StackTrace); + trapFile.extractor_messages(this, msg.Severity, "C# extractor", msg.Text, msg.EntityText ?? string.Empty, + msg.Location ?? cx.CreateLocation(), msg.StackTrace ?? string.Empty); } public override TrapStackBehaviour TrapStackBehaviour => TrapStackBehaviour.NoLabel; diff --git a/csharp/extractor/Semmle.Extraction/Entities/File.cs b/csharp/extractor/Semmle.Extraction/Entities/File.cs index 80bc3ad0533..9ad618512a4 100644 --- a/csharp/extractor/Semmle.Extraction/Entities/File.cs +++ b/csharp/extractor/Semmle.Extraction/Entities/File.cs @@ -18,7 +18,7 @@ namespace Semmle.Extraction.Entities private readonly Lazy transformedPathLazy; private PathTransformer.ITransformedPath TransformedPath => transformedPathLazy.Value; - public override bool NeedsPopulation => Context.DefinesFile(originalPath) || originalPath == Context.Extractor.OutputPath; + public override bool NeedsPopulation => true; public override void Populate(TextWriter trapFile) { @@ -27,12 +27,11 @@ namespace Semmle.Extraction.Entities if (TransformedPath.ParentDirectory is PathTransformer.ITransformedPath dir) trapFile.containerparent(Folder.Create(Context, dir), this); - var fromSource = TransformedPath.Extension.ToLowerInvariant().Equals("cs"); - if (fromSource) + var trees = Context.Compilation.SyntaxTrees.Where(t => t.FilePath == originalPath); + + if (trees.Any()) { - foreach (var text in Context.Compilation.SyntaxTrees - .Where(t => t.FilePath == originalPath) - .Select(tree => tree.GetText())) + foreach (var text in trees.Select(tree => tree.GetText())) { var rawText = text.ToString() ?? ""; var lineCounts = LineCounter.ComputeLineCounts(rawText); @@ -43,10 +42,39 @@ namespace Semmle.Extraction.Entities Context.TrapWriter.Archive(originalPath, TransformedPath, text.Encoding ?? System.Text.Encoding.Default); } } + else if (IsPossiblyTextFile()) + { + try + { + System.Text.Encoding encoding; + var lineCount = 0; + using (var sr = new StreamReader(originalPath, detectEncodingFromByteOrderMarks: true)) + { + while (sr.ReadLine() != null) + { + lineCount++; + } + encoding = sr.CurrentEncoding; + } + + trapFile.numlines(this, new LineCounts() { Total = lineCount, Code = 0, Comment = 0 }); + Context.TrapWriter.Archive(originalPath, TransformedPath, encoding ?? System.Text.Encoding.Default); + } + catch (Exception exc) + { + Context.ExtractionError($"Couldn't read file: {originalPath}. {exc.Message}", null, null, exc.StackTrace); + } + } trapFile.file_extraction_mode(this, Context.Extractor.Standalone ? 1 : 0); } + private bool IsPossiblyTextFile() + { + var extension = TransformedPath.Extension.ToLowerInvariant(); + return !extension.Equals("dll") && !extension.Equals("exe"); + } + public override void WriteId(System.IO.TextWriter trapFile) { trapFile.Write(TransformedPath.DatabaseId); diff --git a/csharp/extractor/Semmle.Extraction/Entities/Location.cs b/csharp/extractor/Semmle.Extraction/Entities/Location.cs index 354caaa65d9..cdd3c9a50dc 100644 --- a/csharp/extractor/Semmle.Extraction/Entities/Location.cs +++ b/csharp/extractor/Semmle.Extraction/Entities/Location.cs @@ -1,4 +1,6 @@ +using Microsoft.CodeAnalysis.Text; + namespace Semmle.Extraction.Entities { public abstract class Location : CachedEntity @@ -6,27 +8,8 @@ namespace Semmle.Extraction.Entities protected Location(Context cx, Microsoft.CodeAnalysis.Location? init) : base(cx, init) { } - public static Location Create(Context cx, Microsoft.CodeAnalysis.Location? loc) => - (loc == null || loc.Kind == Microsoft.CodeAnalysis.LocationKind.None) - ? GeneratedLocation.Create(cx) - : loc.IsInSource - ? NonGeneratedSourceLocation.Create(cx, loc) - : Assembly.Create(cx, loc); - public override Microsoft.CodeAnalysis.Location? ReportingLocation => symbol; public override TrapStackBehaviour TrapStackBehaviour => TrapStackBehaviour.OptionalLabel; } - - public static class LocationExtensions - { - /// - /// Creates a Location entity. - /// - /// The extraction context. - /// The CodeAnalysis location. - /// The Location entity. - public static Location Create(this Context cx, Microsoft.CodeAnalysis.Location? location) => - Location.Create(cx, location); - } } diff --git a/csharp/extractor/Semmle.Extraction/Entities/SourceLocation.cs b/csharp/extractor/Semmle.Extraction/Entities/SourceLocation.cs index 2697049dce2..ae69f95449a 100644 --- a/csharp/extractor/Semmle.Extraction/Entities/SourceLocation.cs +++ b/csharp/extractor/Semmle.Extraction/Entities/SourceLocation.cs @@ -15,21 +15,28 @@ namespace Semmle.Extraction.Entities public class NonGeneratedSourceLocation : SourceLocation { - protected NonGeneratedSourceLocation(Context cx, Microsoft.CodeAnalysis.Location? init) + protected NonGeneratedSourceLocation(Context cx, Microsoft.CodeAnalysis.Location init) : base(cx, init) { - if (init is null) - throw new ArgumentException("Location may not be null", nameof(init)); Position = init.GetLineSpan(); FileEntity = File.Create(Context, Position.Path); } - public static new Location Create(Context cx, Microsoft.CodeAnalysis.Location loc) => SourceLocationFactory.Instance.CreateEntity(cx, loc, loc); + public static Location Create(Context cx, Microsoft.CodeAnalysis.Location loc) => SourceLocationFactory.Instance.CreateEntity(cx, loc, loc); public override void Populate(TextWriter trapFile) { - trapFile.locations_default(this, FileEntity, Position.Span.Start.Line + 1, Position.Span.Start.Character + 1, - Position.Span.End.Line + 1, Position.Span.End.Character); + trapFile.locations_default(this, FileEntity, + Position.Span.Start.Line + 1, Position.Span.Start.Character + 1, + Position.Span.End.Line + 1, Position.Span.End.Character); + + var mapped = symbol!.GetMappedLineSpan(); + if (mapped.HasMappedPath && mapped.IsValid) + { + var mappedLoc = Create(Context, Microsoft.CodeAnalysis.Location.Create(mapped.Path, default, mapped.Span)); + + trapFile.locations_mapped(this, mappedLoc); + } } public FileLinePositionSpan Position diff --git a/csharp/extractor/Semmle.Extraction/Entity.cs b/csharp/extractor/Semmle.Extraction/Entity.cs index 5479c93fee9..8839b6ede2a 100644 --- a/csharp/extractor/Semmle.Extraction/Entity.cs +++ b/csharp/extractor/Semmle.Extraction/Entity.cs @@ -137,7 +137,7 @@ namespace Semmle.Extraction where TSymbol : ISymbol where TEntity : ICachedEntity => cx.CreateEntityFromSymbol(factory, init); - public static void DefineLabel(this IEntity entity, TextWriter trapFile, IExtractor extractor) + public static void DefineLabel(this IEntity entity, TextWriter trapFile, Extractor extractor) { trapFile.WriteLabel(entity); trapFile.Write("="); diff --git a/csharp/extractor/Semmle.Extraction/ExtractionScope.cs b/csharp/extractor/Semmle.Extraction/ExtractionScope.cs deleted file mode 100644 index 7f70284c278..00000000000 --- a/csharp/extractor/Semmle.Extraction/ExtractionScope.cs +++ /dev/null @@ -1,78 +0,0 @@ -using Microsoft.CodeAnalysis; -using System.Linq; - -namespace Semmle.Extraction -{ - /// - /// Defines which entities belong in the trap file - /// for the currently extracted entity. This is used to ensure that - /// trap files do not contain redundant information. Generally a symbol - /// should have an affinity with exactly one trap file, except for constructed - /// symbols. - /// - public interface IExtractionScope - { - /// - /// Whether the given symbol belongs in the trap file. - /// - /// The symbol to populate. - bool InScope(ISymbol symbol); - - /// - /// Whether the given file belongs in the trap file. - /// - /// The path to populate. - bool InFileScope(string path); - - bool IsGlobalScope { get; } - - bool FromSource { get; } - } - - /// - /// The scope of symbols in an assembly. - /// - public class AssemblyScope : IExtractionScope - { - private readonly IAssemblySymbol assembly; - private readonly string filepath; - - public AssemblyScope(IAssemblySymbol symbol, string path, bool isOutput) - { - assembly = symbol; - filepath = path; - IsGlobalScope = isOutput; - } - - public bool IsGlobalScope { get; } - - public bool InFileScope(string path) => path == filepath; - - public bool InScope(ISymbol symbol) => - SymbolEqualityComparer.Default.Equals(symbol.ContainingAssembly, assembly) || - SymbolEqualityComparer.Default.Equals(symbol, assembly); - - public bool FromSource => false; - } - - /// - /// The scope of symbols in a source file. - /// - public class SourceScope : IExtractionScope - { - private readonly SyntaxTree sourceTree; - - public SourceScope(SyntaxTree tree) - { - sourceTree = tree; - } - - public bool IsGlobalScope => false; - - public bool InFileScope(string path) => path == sourceTree.FilePath; - - public bool InScope(ISymbol symbol) => symbol.Locations.Any(loc => loc.SourceTree == sourceTree); - - public bool FromSource => true; - } -} diff --git a/csharp/extractor/Semmle.Extraction/Extractor.cs b/csharp/extractor/Semmle.Extraction/Extractor.cs index 1931aeeeb33..6e031fbca52 100644 --- a/csharp/extractor/Semmle.Extraction/Extractor.cs +++ b/csharp/extractor/Semmle.Extraction/Extractor.cs @@ -1,105 +1,13 @@ -using System; using System.Collections.Generic; using Microsoft.CodeAnalysis; using Semmle.Util.Logging; namespace Semmle.Extraction { - /// - /// Provides common extraction functions for use during extraction. - /// - /// - /// - /// This is held in the passed to each entity. - /// - public interface IExtractor - { - /// - /// Logs a message (to csharp.log). - /// Increases the error count if msg.severity is Error. - /// - /// The message to log. - void Message(Message msg); - - /// - /// Cache assembly names. - /// - /// The assembly name. - /// The file defining the assembly. - void SetAssemblyFile(string assembly, string file); - - /// - /// Maps assembly names to file names. - /// - /// The assembly name - /// The file defining the assmebly. - string GetAssemblyFile(string assembly); - - /// - /// How many errors encountered during extraction? - /// - int Errors { get; } - - /// - /// The extraction is standalone - meaning there will be a lot of errors. - /// - bool Standalone { get; } - - /// - /// Record a new error type. - /// - /// The display name of the type, qualified where possible. - /// If the missing type was referenced from a source file. - void MissingType(string fqn, bool fromSource); - - /// - /// Record an unresolved `using namespace` directive. - /// - /// The full name of the namespace. - /// If the missing namespace was referenced from a source file. - void MissingNamespace(string fqn, bool fromSource); - - /// - /// The list of missing types. - /// - IEnumerable MissingTypes { get; } - - /// - /// The list of missing namespaces. - /// - IEnumerable MissingNamespaces { get; } - - /// - /// The full path of the generated DLL/EXE. - /// null if not specified. - /// - string OutputPath { get; } - - /// - /// The object used for logging. - /// - ILogger Logger { get; } - - /// - /// The path transformer to apply. - /// - PathTransformer PathTransformer { get; } - - /// - /// Creates a new context. - /// - /// The C# compilation. - /// The trap writer. - /// The extraction scope (what to include in this trap file). - /// Whether to add assembly prefixes to TRAP labels. - /// - Context CreateContext(Compilation c, TrapWriter trapWriter, IExtractionScope scope, bool addAssemblyTrapPrefix); - } - /// /// Implementation of the main extractor state. /// - public class Extractor : IExtractor + public class Extractor { public bool Standalone { @@ -190,11 +98,6 @@ namespace Semmle.Extraction } } - public Context CreateContext(Compilation c, TrapWriter trapWriter, IExtractionScope scope, bool addAssemblyTrapPrefix) - { - return new Context(this, c, trapWriter, scope, addAssemblyTrapPrefix); - } - public IEnumerable MissingTypes => missingTypes; public IEnumerable MissingNamespaces => missingNamespaces; diff --git a/csharp/extractor/Semmle.Extraction/IExtractionScope.cs b/csharp/extractor/Semmle.Extraction/IExtractionScope.cs new file mode 100644 index 00000000000..f12823b3f96 --- /dev/null +++ b/csharp/extractor/Semmle.Extraction/IExtractionScope.cs @@ -0,0 +1,26 @@ +using Microsoft.CodeAnalysis; + +namespace Semmle.Extraction +{ + /// + /// Defines which entities belong in the trap file + /// for the currently extracted entity. This is used to ensure that + /// trap files do not contain redundant information. Generally a symbol + /// should have an affinity with exactly one trap file, except for constructed + /// symbols. + /// + public interface IExtractionScope + { + /// + /// Whether the given symbol belongs in the trap file. + /// + /// The symbol to populate. + bool InScope(ISymbol symbol); + + /// + /// Whether the given file belongs in the trap file. + /// + /// The path to populate. + bool InFileScope(string path); + } +} diff --git a/csharp/extractor/Semmle.Extraction/Message.cs b/csharp/extractor/Semmle.Extraction/Message.cs index fbe91fb95e6..a100a69a285 100644 --- a/csharp/extractor/Semmle.Extraction/Message.cs +++ b/csharp/extractor/Semmle.Extraction/Message.cs @@ -13,27 +13,27 @@ namespace Semmle.Extraction { public Severity Severity { get; } public string Text { get; } - public string StackTrace { get; } - public string EntityText { get; } + public string? StackTrace { get; } + public string? EntityText { get; } public Entities.Location? Location { get; } - public Message(string text, string entityText, Entities.Location? location, string? stackTrace = null, Severity severity = Severity.Error) + public Message(string text, string? entityText, Entities.Location? location, string? stackTrace = null, Severity severity = Severity.Error) { Severity = severity; Text = text; - StackTrace = stackTrace ?? ""; + StackTrace = stackTrace; EntityText = entityText; Location = location; } public static Message Create(Context cx, string text, ISymbol symbol, string? stackTrace = null, Severity severity = Severity.Error) { - return new Message(text, symbol.ToString() ?? "", Entities.Location.Create(cx, symbol.Locations.FirstOrDefault()), stackTrace, severity); + return new Message(text, symbol.ToString(), cx.CreateLocation(symbol.Locations.FirstOrDefault()), stackTrace, severity); } public static Message Create(Context cx, string text, SyntaxNode node, string? stackTrace = null, Severity severity = Severity.Error) { - return new Message(text, node.ToString(), Entities.Location.Create(cx, node.GetLocation()), stackTrace, severity); + return new Message(text, node.ToString(), cx.CreateLocation(node.GetLocation()), stackTrace, severity); } public override string ToString() => Text; diff --git a/csharp/extractor/Semmle.Extraction/SourceScope.cs b/csharp/extractor/Semmle.Extraction/SourceScope.cs new file mode 100644 index 00000000000..fba816f6363 --- /dev/null +++ b/csharp/extractor/Semmle.Extraction/SourceScope.cs @@ -0,0 +1,23 @@ +using Microsoft.CodeAnalysis; +using System.Linq; + +namespace Semmle.Extraction +{ + + /// + /// The scope of symbols in a source file. + /// + public class SourceScope : IExtractionScope + { + public SyntaxTree SourceTree { get; } + + public SourceScope(SyntaxTree tree) + { + SourceTree = tree; + } + + public bool InFileScope(string path) => path == SourceTree.FilePath; + + public bool InScope(ISymbol symbol) => symbol.Locations.Any(loc => loc.SourceTree == SourceTree); + } +} diff --git a/csharp/extractor/Semmle.Extraction/Symbol.cs b/csharp/extractor/Semmle.Extraction/Symbol.cs index 4366cff7f06..2585ffd037f 100644 --- a/csharp/extractor/Semmle.Extraction/Symbol.cs +++ b/csharp/extractor/Semmle.Extraction/Symbol.cs @@ -79,7 +79,7 @@ namespace Semmle.Extraction /// A class used to wrap an `ISymbol` object, which uses `SymbolEqualityComparer.Default` /// for comparison. /// - public sealed class SymbolEqualityWrapper + public struct SymbolEqualityWrapper { public ISymbol Symbol { get; } @@ -88,6 +88,6 @@ namespace Semmle.Extraction public override bool Equals(object? other) => other is SymbolEqualityWrapper sew && SymbolEqualityComparer.Default.Equals(Symbol, sew.Symbol); - public override int GetHashCode() => 11 * Symbol.GetHashCode(); + public override int GetHashCode() => 11 * SymbolEqualityComparer.Default.GetHashCode(Symbol); } } diff --git a/csharp/extractor/Semmle.Extraction/Tuples.cs b/csharp/extractor/Semmle.Extraction/Tuples.cs index 0a71ba6b3d9..8e9016cb6b6 100644 --- a/csharp/extractor/Semmle.Extraction/Tuples.cs +++ b/csharp/extractor/Semmle.Extraction/Tuples.cs @@ -43,6 +43,11 @@ namespace Semmle.Extraction trapFile.WriteTuple("locations_default", label, file, startLine, startCol, endLine, endCol); } + public static void locations_mapped(this System.IO.TextWriter trapFile, SourceLocation l1, Location l2) + { + trapFile.WriteTuple("locations_mapped", l1, l2); + } + public static void numlines(this System.IO.TextWriter trapFile, IEntity label, LineCounts lineCounts) { trapFile.WriteTuple("numlines", label, lineCounts.Total, lineCounts.Code, lineCounts.Comment); diff --git a/csharp/extractor/Semmle.Util/StringExtensions.cs b/csharp/extractor/Semmle.Util/StringExtensions.cs new file mode 100644 index 00000000000..d5d6c8cf27d --- /dev/null +++ b/csharp/extractor/Semmle.Util/StringExtensions.cs @@ -0,0 +1,41 @@ +using System.Collections.Generic; +using System.Linq; + +namespace Semmle.Util +{ + public static class StringExtensions + { + public static (string, string) Split(this string self, int index0) + { + var split = self.Split(new[] { index0 }); + return (split[0], split[1]); + } + + public static (string, string, string) Split(this string self, int index0, int index1) + { + var split = self.Split(new[] { index0, index1 }); + return (split[0], split[1], split[2]); + } + + public static (string, string, string, string) Split(this string self, int index0, int index1, int index2) + { + var split = self.Split(new[] { index0, index1, index2 }); + return (split[0], split[1], split[2], split[4]); + } + + private static List Split(this string self, params int[] indices) + { + var ret = new List(); + var previousIndex = 0; + foreach (var index in indices.OrderBy(i => i)) + { + ret.Add(self.Substring(previousIndex, index - previousIndex)); + previousIndex = index; + } + + ret.Add(self.Substring(previousIndex)); + + return ret; + } + } +} diff --git a/csharp/extractor/Semmle.Util/Win32.cs b/csharp/extractor/Semmle.Util/Win32.cs index fe198b9612a..046a0957e87 100644 --- a/csharp/extractor/Semmle.Util/Win32.cs +++ b/csharp/extractor/Semmle.Util/Win32.cs @@ -8,7 +8,7 @@ namespace Semmle.Util /// /// Holder for various Win32 functions. /// - public class Win32 + public static class Win32 { [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)] public static extern int GetFinalPathNameByHandle( // lgtm[cs/unmanaged-code] diff --git a/csharp/ql/src/API Abuse/FormatInvalid.qhelp b/csharp/ql/src/API Abuse/FormatInvalid.qhelp index e4ef9b0ca2c..868c43ffc14 100644 --- a/csharp/ql/src/API Abuse/FormatInvalid.qhelp +++ b/csharp/ql/src/API Abuse/FormatInvalid.qhelp @@ -4,28 +4,46 @@

    -The format string supplied to formatting methods (such as string.Format()) -must be formatted correctly, otherwise the exception System.FormatException -will be thrown. +When using string formatting methods (such as string.Format()), the following +should be taken into account:

    +
      +
    1. + The formatting string must be formatted correctly, otherwise the exception + System.FormatException will be thrown. +
    2. +
    3. + All passed arguments should be used by the formatting string, otherwise such + arguments will be ignored. +
    4. +
    5. + Missing arguments will result in a System.FormatException exception + being thrown. +
    6. +
    -

    -Change the format string so that it is correctly formatted. Ensure that each -format item adheres to the syntax: -

    - -
    -

    {index[,alignment][:formatString]}

    -
    - -

    -When literals { or } are required, replace them with {{ and -}}, respectively, or supply them as arguments. -

    +
      +
    1. + Change the format string so that it is correctly formatted. Ensure that each + format item adheres to the syntax: +
      +

      {index[,alignment][:formatString]}

      +
      + When literals { or } are required, replace them with {{ and + }}, respectively, or supply them as arguments. +
    2. +
    3. + Change the format string to use the highlighted argument, or remove the unnecessary argument. +
    4. +
    5. + Supply the correct number of arguments to the format method, or change the format string + to use the correct arguments. +
    6. +
    @@ -40,8 +58,39 @@ literals are not properly escaped. In the revised example, the literals are properly escaped.

    - + + +

    +Here are three examples where the format string does not use all the arguments. +

    + +
      +
    • On line 7, the second argument (ex.HResult) is not logged.
    • +
    • On line 8, the first argument (ex) is not logged but the second + argument (ex.HResult) is logged twice.
    • +
    • On line 9, a C-style format string is used, which is incorrect, and neither + argument will be logged.
    • +
    +
    + + +

    +Here are two examples where the call to String.Format() is missing arguments. +

    + +
      +
    • On line 7, the second argument (last) is not supplied.
    • +
    • On line 8, the format items are numbered {1} and {2}, + instead of {0} and {1} as they should be.
    • +
    + +

    +In the revised example, both arguments are supplied. +

    + +
    +
  • MSDN: String.Format Method.
  • Microsoft: Composite Formatting.
  • diff --git a/csharp/ql/src/API Abuse/FormatInvalid.ql b/csharp/ql/src/API Abuse/FormatInvalid.ql index 979af415936..ef16359de09 100644 --- a/csharp/ql/src/API Abuse/FormatInvalid.ql +++ b/csharp/ql/src/API Abuse/FormatInvalid.ql @@ -1,18 +1,86 @@ /** - * @name Invalid format string - * @description Using a format string with an incorrect format causes a 'System.FormatException'. + * @name Invalid string formatting + * @description Calling 'string.Format()' with either an invalid format string or incorrect + * number of arguments may result in dropped arguments or a 'System.FormatException'. * @kind path-problem * @problem.severity error * @precision high - * @id cs/invalid-format-string + * @id cs/invalid-string-formatting * @tags reliability * maintainability */ import csharp import semmle.code.csharp.frameworks.Format -import FormatFlow +import DataFlow::PathGraph -from FormatCall s, InvalidFormatString src, PathNode source, PathNode sink -where hasFlowPath(src, source, s, sink) -select src, source, sink, "Invalid format string used in $@ formatting call.", s, "this" +private class FormatConfiguration extends DataFlow::Configuration { + FormatConfiguration() { this = "format" } + + override predicate isSource(DataFlow::Node n) { n.asExpr() instanceof StringLiteral } + + override predicate isSink(DataFlow::Node n) { + exists(FormatCall c | n.asExpr() = c.getFormatExpr()) + } +} + +private predicate invalidFormatString( + InvalidFormatString src, DataFlow::PathNode source, DataFlow::PathNode sink, string msg, + FormatCall call, string callString +) { + source.getNode().asExpr() = src and + sink.getNode().asExpr() = call.getFormatExpr() and + any(FormatConfiguration conf).hasFlowPath(source, sink) and + call.hasInsertions() and + msg = "Invalid format string used in $@ formatting call." and + callString = "this" +} + +private predicate unusedArgument( + FormatCall call, DataFlow::PathNode source, DataFlow::PathNode sink, string msg, + ValidFormatString src, string srcString, Expr unusedExpr, string unusedString +) { + exists(int unused | + source.getNode().asExpr() = src and + sink.getNode().asExpr() = call.getFormatExpr() and + any(FormatConfiguration conf).hasFlowPath(source, sink) and + unused = call.getASuppliedArgument() and + not unused = src.getAnInsert() and + not src.getValue() = "" and + msg = "The $@ ignores $@." and + srcString = "format string" and + unusedExpr = call.getSuppliedExpr(unused) and + unusedString = "this supplied value" + ) +} + +private predicate missingArgument( + FormatCall call, DataFlow::PathNode source, DataFlow::PathNode sink, string msg, + ValidFormatString src, string srcString +) { + exists(int used, int supplied | + source.getNode().asExpr() = src and + sink.getNode().asExpr() = call.getFormatExpr() and + any(FormatConfiguration conf).hasFlowPath(source, sink) and + used = src.getAnInsert() and + supplied = call.getSuppliedArguments() and + used >= supplied and + msg = "Argument '{" + used + "}' has not been supplied to $@ format string." and + srcString = "this" + ) +} + +from + Element alert, DataFlow::PathNode source, DataFlow::PathNode sink, string msg, Element extra1, + string extra1String, Element extra2, string extra2String +where + invalidFormatString(alert, source, sink, msg, extra1, extra1String) and + extra2 = extra1 and + extra2String = extra1String + or + unusedArgument(alert, source, sink, msg, extra1, extra1String, extra2, extra2String) + or + missingArgument(alert, source, sink, msg, extra1, extra1String) and + extra2 = extra1 and + extra2String = extra1String +select alert, source, sink, msg, extra1, extra1String, extra2, extra2String diff --git a/csharp/ql/src/API Abuse/FormatInvalidBad.cs b/csharp/ql/src/API Abuse/FormatInvalidBad.cs index 7f7faad5bdc..ec3df72655d 100644 --- a/csharp/ql/src/API Abuse/FormatInvalidBad.cs +++ b/csharp/ql/src/API Abuse/FormatInvalidBad.cs @@ -1,9 +1,9 @@ using System; -class Bad +class Bad1 { string GenerateEmptyClass(string c) { - return string.Format("class {0} { }"); + return string.Format("class {0} { }", "C"); } } diff --git a/csharp/ql/src/API Abuse/FormatInvalidGood.cs b/csharp/ql/src/API Abuse/FormatInvalidGood.cs index 2060501541d..efc62a07391 100644 --- a/csharp/ql/src/API Abuse/FormatInvalidGood.cs +++ b/csharp/ql/src/API Abuse/FormatInvalidGood.cs @@ -1,9 +1,9 @@ using System; -class Good +class Good1 { string GenerateEmptyClass(string c) { - return string.Format("class {0} {{ }}"); + return string.Format("class {0} {{ }}", "C"); } } diff --git a/csharp/ql/src/API Abuse/FormatMissingArgument.qhelp b/csharp/ql/src/API Abuse/FormatMissingArgument.qhelp deleted file mode 100644 index ddab9a65a04..00000000000 --- a/csharp/ql/src/API Abuse/FormatMissingArgument.qhelp +++ /dev/null @@ -1,41 +0,0 @@ - - - -

    -Formatting methods (such as String.Format()) that are missing arguments will -throw the exception System.FormatException. This is caused by the format -string not matching the actual arguments supplied or an incorrect format string. -

    -
    - - -

    -Supply the correct number of arguments to the format method, or change the format string -to use the correct arguments. -

    -
    - - -

    -Here are two examples where the call to String.Format() is missing arguments. -

    - -
      -
    • On line 5, the second argument (last) is not supplied.
    • -
    • On line 6, the format items are numbered {1} and {2}, - instead of {0} and {1} as they should be.
    • -
    - -

    -In the revised example, both arguments are supplied. -

    - -
    - - -
  • MSDN: String.Format Method.
  • -
  • Microsoft: Composite Formatting.
  • -
    -
    \ No newline at end of file diff --git a/csharp/ql/src/API Abuse/FormatMissingArgument.ql b/csharp/ql/src/API Abuse/FormatMissingArgument.ql deleted file mode 100644 index 58385d4a295..00000000000 --- a/csharp/ql/src/API Abuse/FormatMissingArgument.ql +++ /dev/null @@ -1,24 +0,0 @@ -/** - * @name Missing format argument - * @description Supplying too few arguments to a format string causes a 'System.FormatException'. - * @kind path-problem - * @problem.severity error - * @precision high - * @id cs/format-argument-missing - * @tags reliability - * maintainability - */ - -import csharp -import semmle.code.csharp.frameworks.Format -import FormatFlow - -from - FormatCall format, ValidFormatString src, int used, int supplied, PathNode source, PathNode sink -where - hasFlowPath(src, source, format, sink) and - used = src.getAnInsert() and - supplied = format.getSuppliedArguments() and - used >= supplied -select format, source, sink, "Argument '{" + used + "}' has not been supplied to $@ format string.", - src, "this" diff --git a/csharp/ql/src/API Abuse/FormatMissingArgumentBad.cs b/csharp/ql/src/API Abuse/FormatMissingArgumentBad.cs index 0fc5b21f1ae..a66eea4cf32 100644 --- a/csharp/ql/src/API Abuse/FormatMissingArgumentBad.cs +++ b/csharp/ql/src/API Abuse/FormatMissingArgumentBad.cs @@ -1,6 +1,6 @@ using System; -class Bad +class Bad3 { void Hello(string first, string last) { diff --git a/csharp/ql/src/API Abuse/FormatMissingArgumentGood.cs b/csharp/ql/src/API Abuse/FormatMissingArgumentGood.cs index 36fbe2de8a7..817da4d8336 100644 --- a/csharp/ql/src/API Abuse/FormatMissingArgumentGood.cs +++ b/csharp/ql/src/API Abuse/FormatMissingArgumentGood.cs @@ -1,6 +1,6 @@ using System; -class Good +class Good3 { void Hello(string first, string last) { diff --git a/csharp/ql/src/API Abuse/FormatUnusedArgument.qhelp b/csharp/ql/src/API Abuse/FormatUnusedArgument.qhelp deleted file mode 100644 index fc280f1c3b3..00000000000 --- a/csharp/ql/src/API Abuse/FormatUnusedArgument.qhelp +++ /dev/null @@ -1,37 +0,0 @@ - - - -

    -Arguments which are passed to formatting methods (such as String.Format()) -but are not used, are either unnecessary or mean that the format string is incorrect. The result -is that the argument will be ignored, which may not be the intended behavior. -

    -
    - - -

    -Change the format string to use the highlighted argument, or remove the unnecessary argument. -

    -
    - - -

    -Here are three examples where the format string does not use all the arguments. -

    - -
      -
    • On line 5, the second argument (ex.HResult) is not logged.
    • -
    • On line 6, the first argument (ex) is not logged but the second - argument (ex.HResult) is logged twice.
    • -
    • On line 4, a C-style format string is used, which is incorrect, and neither - argument will be logged.
    • -
    -
    - - -
  • MSDN: String.Format Method.
  • -
  • Microsoft: Composite Formatting.
  • -
    -
    \ No newline at end of file diff --git a/csharp/ql/src/API Abuse/FormatUnusedArgument.ql b/csharp/ql/src/API Abuse/FormatUnusedArgument.ql deleted file mode 100644 index 226330d7dbf..00000000000 --- a/csharp/ql/src/API Abuse/FormatUnusedArgument.ql +++ /dev/null @@ -1,22 +0,0 @@ -/** - * @name Unused format argument - * @description Supplying more arguments than are required for a format string may indicate an error in the format string. - * @kind path-problem - * @problem.severity warning - * @precision high - * @id cs/format-argument-unused - * @tags reliability - * maintainability - */ - -import csharp -import semmle.code.csharp.frameworks.Format -import FormatFlow - -from FormatCall format, int unused, ValidFormatString src, PathNode source, PathNode sink -where - hasFlowPath(src, source, format, sink) and - unused = format.getAnUnusedArgument(src) and - not src.getValue() = "" -select format, source, sink, "The $@ ignores $@.", src, "format string", - format.getSuppliedExpr(unused), "this supplied value" diff --git a/csharp/ql/src/API Abuse/FormatUnusedArgumentBad.cs b/csharp/ql/src/API Abuse/FormatUnusedArgumentBad.cs index 838c1f27944..25bce1a742e 100644 --- a/csharp/ql/src/API Abuse/FormatUnusedArgumentBad.cs +++ b/csharp/ql/src/API Abuse/FormatUnusedArgumentBad.cs @@ -1,6 +1,6 @@ using System; -class Bad +class Bad2 { void M(Exception ex) { diff --git a/csharp/ql/src/Dead Code/DeadCode.qll b/csharp/ql/src/Dead Code/DeadCode.qll index e3584eaa1a4..dd0f6104e31 100644 --- a/csharp/ql/src/Dead Code/DeadCode.qll +++ b/csharp/ql/src/Dead Code/DeadCode.qll @@ -43,6 +43,8 @@ Expr getAMethodAccess(Method m) { predicate potentiallyAccessedByForEach(Method m) { m.hasName("GetEnumerator") and m.getDeclaringType().getABaseType+().hasQualifiedName("System.Collections.IEnumerable") + or + foreach_stmt_desugar(_, m, 1) } predicate isRecursivelyLiveExpression(Expr e) { diff --git a/csharp/ql/src/Dead Code/DeadStoreOfLocal.ql b/csharp/ql/src/Dead Code/DeadStoreOfLocal.ql index 2e8d1b92e02..4e214c6f6d0 100644 --- a/csharp/ql/src/Dead Code/DeadStoreOfLocal.ql +++ b/csharp/ql/src/Dead Code/DeadStoreOfLocal.ql @@ -63,7 +63,7 @@ predicate mayEscape(LocalVariable v) { exists(Callable c, Expr e, Expr succ | c = getACapturingCallableAncestor(v) | e = getADelegateExpr(c) and DataFlow::localExprFlow(e, succ) and - not succ = any(DelegateCall dc).getDelegateExpr() and + not succ = any(DelegateCall dc).getExpr() and not succ = any(Cast cast).getExpr() and not succ = any(Call call | nonEscapingCall(call)).getAnArgument() and not succ = any(AssignableDefinition ad | ad.getTarget() instanceof LocalVariable).getSource() diff --git a/csharp/ql/src/Likely Bugs/NestedLoopsSameVariable.ql b/csharp/ql/src/Likely Bugs/NestedLoopsSameVariable.ql index 3e89dc89e9d..f0eb93926c0 100644 --- a/csharp/ql/src/Likely Bugs/NestedLoopsSameVariable.ql +++ b/csharp/ql/src/Likely Bugs/NestedLoopsSameVariable.ql @@ -27,6 +27,13 @@ class NestedForConditions extends SC::StructuralComparisonConfiguration { } } +private predicate hasChild(Stmt outer, Element child) { + outer = child.getParent() and + (outer instanceof ForStmt or outer = any(ForStmt f).getBody()) + or + hasChild(outer, child.getParent()) +} + /** A nested `for` statement that shares the same iteration variable as an outer `for` statement. */ class NestedForLoopSameVariable extends ForStmt { ForStmt outer; @@ -35,7 +42,7 @@ class NestedForLoopSameVariable extends ForStmt { MutatorOperation outerUpdate; NestedForLoopSameVariable() { - outer = this.getParent+() and + hasChild(outer, this) and innerUpdate = this.getAnUpdate() and outerUpdate = outer.getAnUpdate() and innerUpdate.getOperand() = iteration.getAnAccess() and @@ -88,7 +95,7 @@ class NestedForLoopSameVariable extends ForStmt { /** Finds elements inside the outer loop that are no longer guarded by the loop invariant. */ private ControlFlow::Node getAnUnguardedNode() { - result.getElement().getParent+() = getOuterForStmt().getBody() and + hasChild(getOuterForStmt().getBody(), result.getElement()) and ( result = this.getCondition().(ControlFlowElement).getAControlFlowExitNode().getAFalseSuccessor() diff --git a/csharp/ql/src/Likely Bugs/UncheckedCastInEquals.ql b/csharp/ql/src/Likely Bugs/UncheckedCastInEquals.ql index 5d2ef55cd1f..7c93d25d646 100644 --- a/csharp/ql/src/Likely Bugs/UncheckedCastInEquals.ql +++ b/csharp/ql/src/Likely Bugs/UncheckedCastInEquals.ql @@ -12,12 +12,18 @@ import csharp import semmle.code.csharp.frameworks.System +private predicate equalsMethodChild(EqualsMethod equals, Element child) { + child = equals + or + equalsMethodChild(equals, child.getParent()) +} + predicate nodeBeforeParameterAccess(ControlFlow::Node node) { exists(EqualsMethod equals | equals.getBody() = node.getElement()) or exists(EqualsMethod equals, Parameter param, ControlFlow::Node mid | equals.getParameter(0) = param and - equals.getAChild*() = mid.getElement() and + equalsMethodChild(equals, mid.getElement()) and nodeBeforeParameterAccess(mid) and not param.getAnAccess() = mid.getElement() and mid.getASuccessor() = node diff --git a/csharp/ql/src/Security Features/CWE-134/UncontrolledFormatString.ql b/csharp/ql/src/Security Features/CWE-134/UncontrolledFormatString.ql index 3b9d6af7d14..a22c13bbb97 100644 --- a/csharp/ql/src/Security Features/CWE-134/UncontrolledFormatString.ql +++ b/csharp/ql/src/Security Features/CWE-134/UncontrolledFormatString.ql @@ -27,7 +27,7 @@ class FormatStringConfiguration extends TaintTracking::Configuration { } override predicate isSink(DataFlow::Node sink) { - sink.asExpr() = any(FormatCall call).getFormatExpr() + sink.asExpr() = any(FormatCall call | call.hasInsertions()).getFormatExpr() } } diff --git a/csharp/ql/src/Useless code/DefaultToString.qll b/csharp/ql/src/Useless code/DefaultToString.qll index 810e815950b..9ba8be009da 100644 --- a/csharp/ql/src/Useless code/DefaultToString.qll +++ b/csharp/ql/src/Useless code/DefaultToString.qll @@ -20,9 +20,15 @@ predicate invokesToString(Expr e, ValueOrRefType t) { // Implicit invocation via forwarder method t = e.stripCasts().getType() and not t instanceof StringType and - exists(AssignableDefinitions::ImplicitParameterDefinition def, Parameter p, ParameterRead pr | + exists(Parameter p | + alwaysInvokesToStringOnParameter(p) and e = p.getAnAssignedArgument() - | + ) +} + +pragma[noinline] +private predicate alwaysInvokesToStringOnParameter(Parameter p) { + exists(AssignableDefinitions::ImplicitParameterDefinition def, ParameterRead pr | def.getParameter() = p and pr = def.getAReachableRead() and pr.getAControlFlowNode().postDominates(p.getCallable().getEntryPoint()) and diff --git a/csharp/ql/src/csharp.qll b/csharp/ql/src/csharp.qll index 2a44f6e864a..3c821c9a443 100644 --- a/csharp/ql/src/csharp.qll +++ b/csharp/ql/src/csharp.qll @@ -19,6 +19,7 @@ import semmle.code.csharp.Type import semmle.code.csharp.Using import semmle.code.csharp.Variable import semmle.code.csharp.XML +import semmle.code.csharp.Preprocessor import semmle.code.csharp.exprs.Access import semmle.code.csharp.exprs.ArithmeticOperation import semmle.code.csharp.exprs.Assignment diff --git a/csharp/ql/src/experimental/ir/implementation/IRType.qll b/csharp/ql/src/experimental/ir/implementation/IRType.qll index 3bf3bf2e276..e0bccafae6b 100644 --- a/csharp/ql/src/experimental/ir/implementation/IRType.qll +++ b/csharp/ql/src/experimental/ir/implementation/IRType.qll @@ -341,7 +341,7 @@ module IRTypeConsistency { query predicate multipleIRTypes(Language::LanguageType type, string message) { strictcount(type.getIRType()) > 1 and message = - "`LanguageType` " + type.getAQlClass() + " has multiple `IRType`s: " + + "`LanguageType` " + type + " has multiple `IRType`s: " + concat(type.getIRType().toString(), ", ") } diff --git a/csharp/ql/src/experimental/ir/implementation/raw/internal/desugar/Delegate.qll b/csharp/ql/src/experimental/ir/implementation/raw/internal/desugar/Delegate.qll index 939f14ba8fe..f7c80e497fa 100644 --- a/csharp/ql/src/experimental/ir/implementation/raw/internal/desugar/Delegate.qll +++ b/csharp/ql/src/experimental/ir/implementation/raw/internal/desugar/Delegate.qll @@ -97,9 +97,7 @@ private class TranslatedDelegateInvokeCall extends TranslatedCompilerGeneratedCa ) } - override TranslatedExprBase getQualifier() { - result = getTranslatedExpr(generatedBy.getDelegateExpr()) - } + override TranslatedExprBase getQualifier() { result = getTranslatedExpr(generatedBy.getExpr()) } override Instruction getQualifierResult() { result = getQualifier().getResult() } diff --git a/csharp/ql/src/experimental/ir/implementation/raw/internal/desugar/Foreach.qll b/csharp/ql/src/experimental/ir/implementation/raw/internal/desugar/Foreach.qll index 9dee8221235..a526ec5bdcd 100644 --- a/csharp/ql/src/experimental/ir/implementation/raw/internal/desugar/Foreach.qll +++ b/csharp/ql/src/experimental/ir/implementation/raw/internal/desugar/Foreach.qll @@ -171,11 +171,7 @@ private class TranslatedForeachMoveNext extends TranslatedCompilerGeneratedCall, override Callable getInstructionFunction(InstructionTag tag) { tag = CallTargetTag() and - exists(Callable internal | - internal.getName() = "MoveNext" and - internal.getReturnType() instanceof BoolType and - result = internal - ) + result = generatedBy.getMoveNext() } override Type getCallResultType() { result instanceof BoolType } @@ -205,28 +201,9 @@ private class TranslatedForeachGetEnumerator extends TranslatedCompilerGenerated result = getInstructionFunction(CallTargetTag()).getReturnType() } - private Callable getEnumeratorCallable() { - if exists(generatedBy.getIterableExpr().getType().(ValueOrRefType).getAMember("GetEnumerator")) - then - result = generatedBy.getIterableExpr().getType().(ValueOrRefType).getAMember("GetEnumerator") - else - exists(Interface inter | - inter = - generatedBy - .getIterableExpr() - .getType() - .(ValueOrRefType) - // There could be some abstract base types until we reach `IEnumerable` (eg. `Array`) - .getABaseType*() - .getABaseInterface() and - inter.getName() = "IEnumerable" and - result = inter.getAMember("GetEnumerator") - ) - } - override Callable getInstructionFunction(InstructionTag tag) { tag = CallTargetTag() and - result = getEnumeratorCallable() + result = generatedBy.getGetEnumerator() } override TranslatedExpr getArgument(int id) { none() } @@ -247,7 +224,7 @@ private class TranslatedForeachCurrent extends TranslatedCompilerGeneratedCall, TranslatedForeachCurrent() { this = TTranslatedCompilerGeneratedElement(generatedBy, 5) } - override Type getCallResultType() { result = generatedBy.getAVariable().getType() } + override Type getCallResultType() { result = generatedBy.getElementType() } override TranslatedExpr getArgument(int id) { none() } @@ -262,10 +239,7 @@ private class TranslatedForeachCurrent extends TranslatedCompilerGeneratedCall, override Callable getInstructionFunction(InstructionTag tag) { tag = CallTargetTag() and - exists(Property prop | - prop.getName() = "Current" and - result = prop.getGetter() - ) + result = generatedBy.getCurrent().getGetter() } } @@ -280,10 +254,7 @@ private class TranslatedForeachDispose extends TranslatedCompilerGeneratedCall, override Callable getInstructionFunction(InstructionTag tag) { tag = CallTargetTag() and - exists(Callable dispose | - dispose.getName() = "Dispose" and - result = dispose - ) + result = generatedBy.getDispose() } final override Type getCallResultType() { result instanceof VoidType } diff --git a/csharp/ql/src/semmle/code/cil/Access.qll b/csharp/ql/src/semmle/code/cil/Access.qll index e42a883a2e5..6d72a48ff1b 100644 --- a/csharp/ql/src/semmle/code/cil/Access.qll +++ b/csharp/ql/src/semmle/code/cil/Access.qll @@ -37,7 +37,7 @@ class WriteAccess extends VariableAccess, @cil_write_access { /** An instruction that accesses a parameter. */ class ParameterAccess extends StackVariableAccess, @cil_arg_access { - override Parameter getTarget() { result = StackVariableAccess.super.getTarget() } + override MethodParameter getTarget() { result = StackVariableAccess.super.getTarget() } } /** An instruction that reads a parameter. */ diff --git a/csharp/ql/src/semmle/code/cil/CIL.qll b/csharp/ql/src/semmle/code/cil/CIL.qll index 1e61c798c54..1e77d98fd29 100644 --- a/csharp/ql/src/semmle/code/cil/CIL.qll +++ b/csharp/ql/src/semmle/code/cil/CIL.qll @@ -18,3 +18,5 @@ import ControlFlow import DataFlow import Attribute import Stubs +import CustomModifierReceiver +import Parameterizable diff --git a/csharp/ql/src/semmle/code/cil/ConsistencyChecks.qll b/csharp/ql/src/semmle/code/cil/ConsistencyChecks.qll index f5ebe9a5103..bd6a1bc8885 100644 --- a/csharp/ql/src/semmle/code/cil/ConsistencyChecks.qll +++ b/csharp/ql/src/semmle/code/cil/ConsistencyChecks.qll @@ -473,7 +473,7 @@ class InvalidOverride extends MethodViolation { InvalidOverride() { base = getMethod().getOverriddenMethod() and not getMethod().getDeclaringType().getABaseType+() = base.getDeclaringType() and - base.getDeclaringType().isSourceDeclaration() // Bases classes of constructed types aren't extracted properly. + base.getDeclaringType().isUnboundDeclaration() // Bases classes of constructed types aren't extracted properly. } override string getMessage() { @@ -664,7 +664,7 @@ class MissingCilDeclaration extends ConsistencyViolation, MissingCSharpCheck { override string getMessage() { result = "Cannot locate CIL for " + getDeclaration().toStringWithTypes() + " of class " + - getDeclaration().getAQlClass() + getDeclaration().getAPrimaryQlClass() } override string toString() { result = getDeclaration().toStringWithTypes() } @@ -753,7 +753,7 @@ class DeclarationWithMultipleLabels extends DeclarationViolation { class DeclarationWithoutLabel extends DeclarationViolation { DeclarationWithoutLabel() { exists(Declaration d | this = DeclarationCheck(d) | - d.isSourceDeclaration() and + d.isUnboundDeclaration() and not d instanceof TypeParameter and not exists(d.getLabel()) and (d instanceof Callable or d instanceof Type) diff --git a/csharp/ql/src/semmle/code/cil/CustomModifierReceiver.qll b/csharp/ql/src/semmle/code/cil/CustomModifierReceiver.qll new file mode 100644 index 00000000000..40e121416c7 --- /dev/null +++ b/csharp/ql/src/semmle/code/cil/CustomModifierReceiver.qll @@ -0,0 +1,21 @@ +/** + * Provides a class to represent `modopt` and `modreq` declarations. + */ + +private import CIL +private import dotnet + +/** + * A class to represent entities that can receive custom modifiers. Custom modifiers can be attached to + * - the type of a `Field`, + * - the return type of a `Method` or `Property`, + * - the type of parameters. + * A `CustomModifierReceiver` is therefore either a `Field`, `Property`, `Method`, or `Parameter`. + */ +class CustomModifierReceiver extends Declaration, @cil_custom_modifier_receiver { + /** Holds if this targeted type has `modifier` applied as `modreq`. */ + predicate hasRequiredCustomModifier(Type modifier) { cil_custom_modifiers(this, modifier, 1) } + + /** Holds if this targeted type has `modifier` applied as `modopt`. */ + predicate hasOptionalCustomModifier(Type modifier) { cil_custom_modifiers(this, modifier, 0) } +} diff --git a/csharp/ql/src/semmle/code/cil/DataFlow.qll b/csharp/ql/src/semmle/code/cil/DataFlow.qll index 7316a06b2de..6991658ea3a 100644 --- a/csharp/ql/src/semmle/code/cil/DataFlow.qll +++ b/csharp/ql/src/semmle/code/cil/DataFlow.qll @@ -74,7 +74,7 @@ private predicate localExactStep(DataFlowNode src, DataFlowNode sink) { or src = sink.(ConditionalBranch).getAnOperand() or - src = sink.(Parameter).getAWrite() + src = sink.(MethodParameter).getAWrite() or exists(VariableUpdate update | update.getVariable().(Parameter) = sink and src = update.getSource() diff --git a/csharp/ql/src/semmle/code/cil/Declaration.qll b/csharp/ql/src/semmle/code/cil/Declaration.qll index 170cc576c9b..a747d4a6d80 100644 --- a/csharp/ql/src/semmle/code/cil/Declaration.qll +++ b/csharp/ql/src/semmle/code/cil/Declaration.qll @@ -24,9 +24,6 @@ class Declaration extends DotNet::Declaration, Element, @cil_declaration { override Declaration getUnboundDeclaration() { result = this } - /** Holds if this declaration is a source declaration. */ - final predicate isUnboundDeclaration() { this = getUnboundDeclaration() } - /** * DEPRECATED: Use `isUnboundDeclaration()` instead. * @@ -54,35 +51,28 @@ private predicate toCSharpTypeParameterJoin(TypeParameter tp, int i, CS::Unbound * A member of a type. Either a type (`Type`), a method (`Method`), a property (`Property`), or an event (`Event`). */ class Member extends DotNet::Member, Declaration, @cil_member { - /** Holds if this member is declared `public`. */ - predicate isPublic() { cil_public(this) } + override predicate isPublic() { cil_public(this) } - /** Holds if this member is declared `protected.` */ - predicate isProtected() { cil_protected(this) } + override predicate isProtected() { cil_protected(this) } - /** Holds if this member is `private`. */ - predicate isPrivate() { cil_private(this) } + override predicate isPrivate() { cil_private(this) } - /** Holds if this member is `internal`. */ - predicate isInternal() { cil_internal(this) } + override predicate isInternal() { cil_internal(this) } - /** Holds if this member is `sealed`. */ - predicate isSealed() { cil_sealed(this) } + override predicate isSealed() { cil_sealed(this) } - /** Holds if this member is `abstract`. */ - predicate isAbstract() { cil_abstract(this) } + override predicate isAbstract() { cil_abstract(this) } + + override predicate isStatic() { cil_static(this) } /** Holds if this member has a security attribute. */ predicate hasSecurity() { cil_security(this) } - /** Holds if this member is `static`. */ - predicate isStatic() { cil_static(this) } - override Location getLocation() { result = getDeclaringType().getLocation() } } /** A property. */ -class Property extends DotNet::Property, Member, @cil_property { +class Property extends DotNet::Property, Member, CustomModifierReceiver, @cil_property { override string getName() { cil_property(this, _, result, _) } /** Gets the type of this property. */ diff --git a/csharp/ql/src/semmle/code/cil/Instructions.qll b/csharp/ql/src/semmle/code/cil/Instructions.qll index 438c16518f8..bc79e15d4e4 100644 --- a/csharp/ql/src/semmle/code/cil/Instructions.qll +++ b/csharp/ql/src/semmle/code/cil/Instructions.qll @@ -626,35 +626,43 @@ module Opcodes { class Ldarg_0 extends ParameterReadAccess, @cil_ldarg_0 { override string getOpcodeName() { result = "ldarg.0" } - override Parameter getTarget() { result = getImplementation().getMethod().getRawParameter(0) } + override MethodParameter getTarget() { + result = getImplementation().getMethod().getRawParameter(0) + } } /** An `ldarg.1` instruction. */ class Ldarg_1 extends ParameterReadAccess, @cil_ldarg_1 { override string getOpcodeName() { result = "ldarg.1" } - override Parameter getTarget() { result = getImplementation().getMethod().getRawParameter(1) } + override MethodParameter getTarget() { + result = getImplementation().getMethod().getRawParameter(1) + } } /** An `ldarg.2` instruction. */ class Ldarg_2 extends ParameterReadAccess, @cil_ldarg_2 { override string getOpcodeName() { result = "ldarg.2" } - override Parameter getTarget() { result = getImplementation().getMethod().getRawParameter(2) } + override MethodParameter getTarget() { + result = getImplementation().getMethod().getRawParameter(2) + } } /** An `ldarg.3` instruction. */ class Ldarg_3 extends ParameterReadAccess, @cil_ldarg_3 { override string getOpcodeName() { result = "ldarg.3" } - override Parameter getTarget() { result = getImplementation().getMethod().getRawParameter(3) } + override MethodParameter getTarget() { + result = getImplementation().getMethod().getRawParameter(3) + } } /** An `ldarg.s` instruction. */ class Ldarg_s extends ParameterReadAccess, @cil_ldarg_s { override string getOpcodeName() { result = "ldarg.s" } - override Parameter getTarget() { cil_access(this, result) } + override MethodParameter getTarget() { cil_access(this, result) } override string getExtra() { result = this.getTarget().getIndex().toString() } } @@ -663,21 +671,21 @@ module Opcodes { class Ldarg extends ParameterReadAccess, @cil_ldarg { override string getOpcodeName() { result = "ldarg" } - override Parameter getTarget() { cil_access(this, result) } + override MethodParameter getTarget() { cil_access(this, result) } } /** An `ldarga.s` instruction. */ class Ldarga_s extends ParameterReadAccess, ReadRefAccess, @cil_ldarga_s { override string getOpcodeName() { result = "ldarga.s" } - override Parameter getTarget() { cil_access(this, result) } + override MethodParameter getTarget() { cil_access(this, result) } } /** An `starg.s` instruction. */ class Starg_s extends ParameterWriteAccess, @cil_starg_s { override string getOpcodeName() { result = "starg.s" } - override Parameter getTarget() { cil_access(this, result) } + override MethodParameter getTarget() { cil_access(this, result) } } /** An `ldfld` instruction. */ diff --git a/csharp/ql/src/semmle/code/cil/Method.qll b/csharp/ql/src/semmle/code/cil/Method.qll index 69ecad20bdf..5ef282e582a 100644 --- a/csharp/ql/src/semmle/code/cil/Method.qll +++ b/csharp/ql/src/semmle/code/cil/Method.qll @@ -66,7 +66,8 @@ class MethodImplementation extends EntryPoint, @cil_method_implementation { * A method, which corresponds to any callable in C#, including constructors, * destructors, operators, accessors and so on. */ -class Method extends DotNet::Callable, Element, Member, TypeContainer, DataFlowNode, @cil_method { +class Method extends DotNet::Callable, Element, Member, TypeContainer, DataFlowNode, + CustomModifierReceiver, Parameterizable, @cil_method { /** * Gets a method implementation, if any. Note that there can * be several implementations in different assemblies. @@ -88,9 +89,7 @@ class Method extends DotNet::Callable, Element, Member, TypeContainer, DataFlowN override Location getALocation() { cil_method_location(this.getUnboundDeclaration(), result) } - override Parameter getRawParameter(int n) { cil_parameter(result, this, n, _) } - - override Parameter getParameter(int n) { + override MethodParameter getParameter(int n) { if isStatic() then result = getRawParameter(n) else (result = getRawParameter(n + 1) and n >= 0) } @@ -246,6 +245,13 @@ class Setter extends Accessor { Setter() { cil_setter(_, this) } override Property getProperty() { cil_setter(result, this) } + + /** Holds if this setter is an `init` accessor. */ + predicate isInitOnly() { + exists(Type t | t.getQualifiedName() = "System.Runtime.CompilerServices.IsExternalInit" | + this.hasRequiredCustomModifier(t) + ) + } } /** diff --git a/csharp/ql/src/semmle/code/cil/Parameterizable.qll b/csharp/ql/src/semmle/code/cil/Parameterizable.qll new file mode 100644 index 00000000000..77b16aba025 --- /dev/null +++ b/csharp/ql/src/semmle/code/cil/Parameterizable.qll @@ -0,0 +1,15 @@ +/** + * Provides `Parameterizable` class. + */ + +private import CIL +private import dotnet + +/** + * A parameterizable entity, such as `FunctionPointerType` or `Method`. + */ +class Parameterizable extends DotNet::Parameterizable, Element, @cil_parameterizable { + override Parameter getRawParameter(int n) { cil_parameter(result, this, n, _) } + + override Parameter getParameter(int n) { cil_parameter(result, this, n, _) } +} diff --git a/csharp/ql/src/semmle/code/cil/Type.qll b/csharp/ql/src/semmle/code/cil/Type.qll index a69b5392e06..d4a7161b772 100644 --- a/csharp/ql/src/semmle/code/cil/Type.qll +++ b/csharp/ql/src/semmle/code/cil/Type.qll @@ -79,7 +79,7 @@ class Type extends DotNet::Type, Declaration, TypeContainer, @cil_type { } /** Holds if this type is an `enum`. */ - predicate isEnum() { this.getBaseClass*().isSystemType("Enum") } + predicate isEnum() { this.getBaseClass().isSystemType("Enum") } /** Holds if this type is public. */ predicate isPublic() { cil_public(this) } diff --git a/csharp/ql/src/semmle/code/cil/Types.qll b/csharp/ql/src/semmle/code/cil/Types.qll index 118acfbfa4b..1bc74767d6b 100644 --- a/csharp/ql/src/semmle/code/cil/Types.qll +++ b/csharp/ql/src/semmle/code/cil/Types.qll @@ -47,8 +47,12 @@ class ValueOrRefType extends DotNet::ValueOrRefType, Type, @cil_valueorreftype { class Enum extends ValueOrRefType { Enum() { this.isEnum() } - // Note that we don't actually use the proper internal representation yet. - override IntType getUnderlyingType() { any() } + override IntegralType getUnderlyingType() { + cil_enum_underlying_type(this, result) + or + not cil_enum_underlying_type(this, _) and + result instanceof IntType + } } /** A `class`. */ @@ -56,6 +60,11 @@ class Class extends ValueOrRefType { Class() { this.isClass() } } +/** A `record`. */ +class Record extends Class { + Record() { this.isRecord() } +} + /** An `interface`. */ class Interface extends ValueOrRefType { Interface() { this.isInterface() } @@ -284,3 +293,21 @@ class CharType extends IntegralType { class SystemType extends ValueOrRefType { SystemType() { this.isSystemType("Type") } } + +/** + * A function pointer type, for example + * + * ```csharp + * delegate* + * ``` + */ +class FunctionPointerType extends Type, CustomModifierReceiver, Parameterizable, + @cil_function_pointer_type { + /** Gets the return type of this function pointer. */ + Type getReturnType() { cil_function_pointer_return_type(this, result) } + + /** Gets the calling convention. */ + int getCallingConvention() { cil_function_pointer_calling_conventions(this, result) } + + override string toString() { result = Type.super.toString() } +} diff --git a/csharp/ql/src/semmle/code/cil/Variable.qll b/csharp/ql/src/semmle/code/cil/Variable.qll index b8aee2cbe28..3a247e1f0d1 100644 --- a/csharp/ql/src/semmle/code/cil/Variable.qll +++ b/csharp/ql/src/semmle/code/cil/Variable.qll @@ -56,17 +56,16 @@ class LocalVariable extends StackVariable, @cil_local_variable { override Method getMethod() { result = getImplementation().getMethod() } } -/** A method parameter. */ -class Parameter extends DotNet::Parameter, StackVariable, @cil_parameter { - /** Gets the method declaring this parameter. */ - override Method getMethod() { this = result.getARawParameter() } - - override Method getCallable() { result = getMethod() } +/** A parameter of a `Method` or `FunctionPointerType`. */ +class Parameter extends DotNet::Parameter, CustomModifierReceiver, @cil_parameter { + override Parameterizable getDeclaringElement() { cil_parameter(this, result, _, _) } /** Gets the index of this parameter. */ int getIndex() { cil_parameter(this, _, result, _) } - override string toString() { result = "Parameter " + getIndex() + " of " + getMethod().getName() } + override string toString() { + result = "Parameter " + getIndex() + " of " + getDeclaringElement().getName() + } override Type getType() { cil_parameter(this, _, _, result) } @@ -99,22 +98,36 @@ class Parameter extends DotNet::Parameter, StackVariable, @cil_parameter { else result = "" } - override Location getLocation() { result = getMethod().getLocation() } + override Location getLocation() { result = getDeclaringElement().getLocation() } +} + +/** A method parameter. */ +class MethodParameter extends Parameter, StackVariable { + /** Gets the method declaring this parameter. */ + override Method getMethod() { this = result.getARawParameter() } override ParameterAccess getAnAccess() { result.getTarget() = this } /** Gets a parameter in an overridden method. */ - Parameter getOverriddenParameter() { + MethodParameter getOverriddenParameter() { result = getMethod().getOverriddenMethod().getRawParameter(getRawPosition()) } - override Parameter getUnboundDeclaration() { + override MethodParameter getUnboundDeclaration() { result = getMethod().getUnboundDeclaration().getRawParameter(getRawPosition()) } + + override string toString() { result = Parameter.super.toString() } + + override string toStringWithTypes() { result = Parameter.super.toStringWithTypes() } + + override Type getType() { result = Parameter.super.getType() } + + override Location getLocation() { result = Parameter.super.getLocation() } } /** A parameter corresponding to `this`. */ -class ThisParameter extends Parameter { +class ThisParameter extends MethodParameter { ThisParameter() { not this.getMethod().isStatic() and this.getIndex() = 0 @@ -122,7 +135,7 @@ class ThisParameter extends Parameter { } /** A field. */ -class Field extends DotNet::Field, Variable, Member, @cil_field { +class Field extends DotNet::Field, Variable, Member, CustomModifierReceiver, @cil_field { override string toString() { result = getName() } override string toStringWithTypes() { diff --git a/csharp/ql/src/semmle/code/csharp/AnnotatedType.qll b/csharp/ql/src/semmle/code/csharp/AnnotatedType.qll index 0e5c512057a..6a6274821d7 100644 --- a/csharp/ql/src/semmle/code/csharp/AnnotatedType.qll +++ b/csharp/ql/src/semmle/code/csharp/AnnotatedType.qll @@ -231,6 +231,8 @@ private module Annotations { type = element.(Expr).getType() or type = element.(DelegateType).getReturnType() + or + type = element.(FunctionPointerType).getReturnType() ) } } diff --git a/csharp/ql/src/semmle/code/csharp/Assignable.qll b/csharp/ql/src/semmle/code/csharp/Assignable.qll index f0d82f1dbce..ef00211188c 100644 --- a/csharp/ql/src/semmle/code/csharp/Assignable.qll +++ b/csharp/ql/src/semmle/code/csharp/Assignable.qll @@ -3,6 +3,7 @@ */ import csharp +private import semmle.code.csharp.dataflow.internal.SsaImpl as SsaImpl /** * An assignable, that is, an element that can be assigned to. Either a @@ -83,7 +84,7 @@ class AssignableRead extends AssignableAccess { pragma[noinline] private ControlFlow::Node getAnAdjacentReadSameVar() { - Ssa::Internal::adjacentReadPairSameVar(_, this.getAControlFlowNode(), result) + SsaImpl::adjacentReadPairSameVar(_, this.getAControlFlowNode(), result) } /** diff --git a/csharp/ql/src/semmle/code/csharp/Element.qll b/csharp/ql/src/semmle/code/csharp/Element.qll index f9ebbc5bef9..521138db1b5 100644 --- a/csharp/ql/src/semmle/code/csharp/Element.qll +++ b/csharp/ql/src/semmle/code/csharp/Element.qll @@ -48,17 +48,4 @@ class Element extends DotNet::Element, @element { * other children (zero-based). */ int getIndex() { exists(Element parent | parent.getChild(result) = this) } - - /** - * Gets the name of a primary CodeQL class to which this element belongs. - * - * For most elements, this is simply the most precise syntactic category to - * which they belong; for example, `AddExpr` is a primary class, but - * `BinaryOperation` is not. - * - * This predicate always has a result. If no primary class can be - * determined, the result is `"???"`. If multiple primary classes match, - * this predicate can have multiple results. - */ - string getAPrimaryQlClass() { result = "???" } } diff --git a/csharp/ql/src/semmle/code/csharp/ExprOrStmtParent.qll b/csharp/ql/src/semmle/code/csharp/ExprOrStmtParent.qll index 80029612a7c..c7c7bfe00e8 100644 --- a/csharp/ql/src/semmle/code/csharp/ExprOrStmtParent.qll +++ b/csharp/ql/src/semmle/code/csharp/ExprOrStmtParent.qll @@ -57,7 +57,10 @@ cached private module Cached { cached Location bestLocation(Element e) { - result = e.getALocation().(SourceLocation) + result = e.getALocation().(SourceLocation) and + not exists(e.getALocation().(SourceLocation).getMappedLocation()) + or + result = e.getALocation().(SourceLocation).getMappedLocation() or hasNoSourceLocation(e) and result = min(Location l | l = e.getALocation() | l order by l.getFile().toString()) diff --git a/csharp/ql/src/semmle/code/csharp/Location.qll b/csharp/ql/src/semmle/code/csharp/Location.qll index 99df294ae63..97f9302c474 100644 --- a/csharp/ql/src/semmle/code/csharp/Location.qll +++ b/csharp/ql/src/semmle/code/csharp/Location.qll @@ -14,6 +14,7 @@ import File private import Attribute +private import semmle.code.csharp.commons.Compilation /** * A location of a program element. @@ -61,6 +62,12 @@ class EmptyLocation extends Location { * within the file. */ class SourceLocation extends Location, @location_default { + /** Gets the location that takes into account `#line` directives, if any. */ + Location getMappedLocation() { + locations_mapped(this, result) and + not exists(LineDirective l | l.getALocation() = this) + } + override File getFile() { locations_default(this, result, _, _, _, _) } override predicate hasLocationInfo( @@ -171,6 +178,9 @@ class Assembly extends Location, Attributable, @assembly { /** Gets the version of this assembly. */ Version getVersion() { assemblies(this, _, _, _, result) } + /** Gets the compilation producing this assembly, if any. */ + Compilation getCompilation() { compilation_assembly(result, this) } + override File getFile() { assemblies(this, result, _, _, _) } override string toString() { result = this.getFullName() } diff --git a/csharp/ql/src/semmle/code/csharp/Member.qll b/csharp/ql/src/semmle/code/csharp/Member.qll index 0b3e06c2e5e..520df43cfb8 100644 --- a/csharp/ql/src/semmle/code/csharp/Member.qll +++ b/csharp/ql/src/semmle/code/csharp/Member.qll @@ -16,9 +16,6 @@ private import TypeRef class Declaration extends DotNet::Declaration, Element, @declaration { override ValueOrRefType getDeclaringType() { none() } - /** Holds if this declaration is unbound. */ - final predicate isUnboundDeclaration() { this = this.getUnboundDeclaration() } - /** Holds if this declaration is unconstructed and in source code. */ final predicate isSourceDeclaration() { this.fromSource() and this.isUnboundDeclaration() } @@ -123,6 +120,20 @@ class Modifiable extends Declaration, @modifiable { class Member extends DotNet::Member, Modifiable, @member { /** Gets an access to this member. */ MemberAccess getAnAccess() { result.getTarget() = this } + + override predicate isPublic() { Modifiable.super.isPublic() } + + override predicate isProtected() { Modifiable.super.isProtected() } + + override predicate isPrivate() { Modifiable.super.isPrivate() } + + override predicate isInternal() { Modifiable.super.isInternal() } + + override predicate isSealed() { Modifiable.super.isSealed() } + + override predicate isAbstract() { Modifiable.super.isAbstract() } + + override predicate isStatic() { Modifiable.super.isStatic() } } /** @@ -316,18 +327,10 @@ class Virtualizable extends Member, @virtualizable { * A parameterizable declaration. Either a callable (`Callable`), a delegate * type (`DelegateType`), or an indexer (`Indexer`). */ -class Parameterizable extends Declaration, @parameterizable { - /** Gets a parameter of this declaration, if any. */ - Parameter getAParameter() { result = getParameter(_) } +class Parameterizable extends DotNet::Parameterizable, Declaration, @parameterizable { + override Parameter getRawParameter(int i) { params(result, _, _, i, _, this, _) } - /** Gets the `i`th parameter of this declaration. */ - Parameter getParameter(int i) { params(result, _, _, i, _, this, _) } - - /** Gets the number of parameters of this declaration. */ - int getNumberOfParameters() { result = count(this.getAParameter()) } - - /** Holds if this declaration has no parameters. */ - predicate hasNoParameters() { not exists(this.getAParameter()) } + override Parameter getParameter(int i) { params(result, _, _, i, _, this, _) } /** * Gets the name of this parameter followed by its type, possibly prefixed diff --git a/csharp/ql/src/semmle/code/csharp/Preprocessor.qll b/csharp/ql/src/semmle/code/csharp/Preprocessor.qll new file mode 100644 index 00000000000..daf4978da53 --- /dev/null +++ b/csharp/ql/src/semmle/code/csharp/Preprocessor.qll @@ -0,0 +1,347 @@ +/** + * Provides all preprocessor directive classes. + */ + +import Element +private import semmle.code.csharp.commons.Compilation + +/** + * A preprocessor directive, such as `PragmaWarningDirective`, `PragmaChecksumDirective`, + * `DefineDirective`, `UndefineDirective`, `WarningDirective`, `ErrorDirective`, + * `NullableDirective`, `LineDirective`, `RegionDirective`, `EndRegionDirective`, + * `BranchDirective`, or `EndifDirective`. + */ +class PreprocessorDirective extends Element, @preprocessor_directive { + /** + * Holds if this directive is processed by the preprocessor, such as any directive + * that is not inside a not taken `BranchDirective`. + */ + predicate isActive() { preprocessor_directive_active(this, 1) } + + override Location getALocation() { preprocessor_directive_location(this, result) } + + /** Gets the compilation this directive belongs to, if any. */ + Compilation getCompilation() { preprocessor_directive_compilation(this, result) } +} + +/** + * A `#pragma warning` directive. + */ +class PragmaWarningDirective extends PreprocessorDirective, @pragma_warning { + /** Holds if this is a `#pragma warning restore` directive. */ + predicate isRestore() { pragma_warnings(this, 1) } + + /** Holds if this is a `#pragma warning disable` directive. */ + predicate isDisable() { pragma_warnings(this, 0) } + + /** Holds if this directive specifies error codes. */ + predicate hasErrorCodes() { pragma_warning_error_codes(this, _, _) } + + /** Gets a specified error code from this directive. */ + string getAnErrorCode() { pragma_warning_error_codes(this, result, _) } + + override string toString() { result = "#pragma warning ..." } + + override string getAPrimaryQlClass() { result = "PragmaWarningDirective" } +} + +/** + * A `#pragma checksum` directive. + */ +class PragmaChecksumDirective extends PreprocessorDirective, @pragma_checksum { + /** Gets the file name of this directive. */ + File getReferencedFile() { pragma_checksums(this, result, _, _) } + + /** Gets the GUID of this directive. */ + string getGuid() { pragma_checksums(this, _, result, _) } + + /** Gets the checksum bytes of this directive. */ + string getBytes() { pragma_checksums(this, _, _, result) } + + override string toString() { result = "#pragma checksum ..." } + + override string getAPrimaryQlClass() { result = "PragmaChecksumDirective" } +} + +/** + * A `#define` directive. + */ +class DefineDirective extends PreprocessorDirective, @directive_define { + /** Gets the name of the preprocessor symbol that is being set by this directive. */ + string getName() { directive_defines(this, result) } + + override string toString() { result = "#define ..." } + + override string getAPrimaryQlClass() { result = "DefineDirective" } +} + +/** + * An `#undef` directive. + */ +class UndefineDirective extends PreprocessorDirective, @directive_undefine { + /** Gets the name of the preprocessor symbol that is being unset by this directive. */ + string getName() { directive_undefines(this, result) } + + override string toString() { result = "#undef ..." } + + override string getAPrimaryQlClass() { result = "UndefineDirective" } +} + +/** + * A `#warning` directive. + */ +class WarningDirective extends PreprocessorDirective, @directive_warning { + /** Gets the text of the warning. */ + string getMessage() { directive_warnings(this, result) } + + override string toString() { result = "#warning ..." } + + override string getAPrimaryQlClass() { result = "WarningDirective" } +} + +/** + * An `#error` directive. + */ +class ErrorDirective extends PreprocessorDirective, @directive_error { + /** Gets the text of the error. */ + string getMessage() { directive_errors(this, result) } + + override string toString() { result = "#error ..." } + + override string getAPrimaryQlClass() { result = "ErrorDirective" } +} + +/** + * A `#nullable` directive. + */ +class NullableDirective extends PreprocessorDirective, @directive_nullable { + /** Holds if this is a `#nullable disable` directive. */ + predicate isDisable() { directive_nullables(this, 0, _) } + + /** Holds if this is a `#nullable enable` directive. */ + predicate isEnable() { directive_nullables(this, 1, _) } + + /** Holds if this is a `#nullable restore` directive. */ + predicate isRestore() { directive_nullables(this, 2, _) } + + /** Holds if this directive targets all nullable contexts. */ + predicate targetsAll() { directive_nullables(this, _, 0) } + + /** Holds if this directive targets nullable annotation context. */ + predicate targetsAnnotations() { directive_nullables(this, _, 1) } + + /** Holds if this directive targets nullable warning context. */ + predicate targetsWarnings() { directive_nullables(this, _, 2) } + + /** Gets the succeeding `#nullable` directive in the file, if any. */ + NullableDirective getSuccNullableDirective() { + result = + min(NullableDirective next | + next.getFile() = this.getFile() and + next.getLocation().getStartLine() > this.getLocation().getStartLine() + | + next order by next.getLocation().getStartLine() + ) + } + + /** Holds if there is a succeeding `#nullable` directive in the file. */ + predicate hasSuccNullableDirective() { + exists(NullableDirective other | + other.getFile() = this.getFile() and + other.getLocation().getStartLine() > this.getLocation().getStartLine() + ) + } + + override string toString() { result = "#nullable ..." } + + override string getAPrimaryQlClass() { result = "NullableDirective" } +} + +/** + * A `#line` directive, such as `#line default`, `#line hidden`, or `#line` + * directive with line number. + */ +class LineDirective extends PreprocessorDirective, @directive_line { + /** Gets the succeeding `#line` directive in the file, if any. */ + LineDirective getSuccLineDirective() { + result = + min(LineDirective next | + next.getFile() = this.getFile() and + next.getLocation().getStartLine() > this.getLocation().getStartLine() + | + next order by next.getLocation().getStartLine() + ) + } + + /** Holds if there is a succeeding `#line` directive in the file. */ + predicate hasSuccLineDirective() { + exists(LineDirective other | + other.getFile() = this.getFile() and + other.getLocation().getStartLine() > this.getLocation().getStartLine() + ) + } + + override string toString() { result = "#line ..." } + + override string getAPrimaryQlClass() { result = "LineDirective" } +} + +/** + * A `#line default` directive. + */ +class DefaultLineDirective extends LineDirective { + DefaultLineDirective() { directive_lines(this, 0) } + + override string toString() { result = "#line default" } + + override string getAPrimaryQlClass() { result = "DefaultLineDirective" } +} + +/** + * A `#line hidden` directive. + */ +class HiddenLineDirective extends LineDirective { + HiddenLineDirective() { directive_lines(this, 1) } + + override string toString() { result = "#line hidden" } + + override string getAPrimaryQlClass() { result = "HiddenLineDirective" } +} + +/** + * A numeric `#line` directive, such as `#line 200 file` + */ +class NumericLineDirective extends LineDirective { + NumericLineDirective() { directive_lines(this, 2) } + + /** Gets the line number of this directive. */ + int getLine() { directive_line_value(this, result) } + + /** Gets the referenced file of this directive. */ + File getReferencedFile() { directive_line_file(this, result) } + + override string getAPrimaryQlClass() { result = "NumericLineDirective" } +} + +/** + * A `#region` directive. + */ +class RegionDirective extends PreprocessorDirective, @directive_region { + /** Gets the name of this region. */ + string getName() { directive_regions(this, result) } + + /** Gets the closing `#endregion` directive. */ + EndRegionDirective getEnd() { directive_endregions(result, this) } + + override string toString() { result = "#region ..." } + + override string getAPrimaryQlClass() { result = "RegionDirective" } +} + +/** + * An `#endregion` directive. + */ +class EndRegionDirective extends PreprocessorDirective, @directive_endregion { + /** Gets the opening `#region` directive. */ + RegionDirective getStart() { result.getEnd() = this } + + override string toString() { result = "#endregion" } + + override string getAPrimaryQlClass() { result = "EndRegionDirective" } +} + +/** + * A branching preprocessor directive, such as `IfDirective`, `ElifDirective`, or + * `ElseDirective`. + */ +class BranchDirective extends PreprocessorDirective, @branch_directive { + /** Holds if the branch is taken by the preprocessor. */ + predicate branchTaken() { none() } +} + +/** + * A preprocessor directive with a branching condition, such as `IfDirective` or + * `ElifDirective`. + */ +class ConditionalDirective extends BranchDirective, @conditional_directive { + /** Gets the condition. */ + Expr getCondition() { result = this.getChild(0) } + + /** Holds if the condition is matched. */ + predicate conditionMatched() { none() } +} + +/** + * An `#if` preprocessor directive. + */ +class IfDirective extends ConditionalDirective, @directive_if { + override predicate branchTaken() { directive_ifs(this, 1, _) } + + override predicate conditionMatched() { directive_ifs(this, _, 1) } + + /** Gets the closing `#endif` preprocessor directive. */ + EndifDirective getEndifDirective() { directive_endifs(result, this) } + + /** Gets the sibling `#elif` or `#else` preprocessor directive at index `sibling`. */ + BranchDirective getSiblingDirective(int sibling) { + directive_elifs(result, _, _, this, sibling) or + directive_elses(result, _, this, sibling) + } + + /** Gets a sibling `#elif` or `#else` preprocessor directive. */ + BranchDirective getASiblingDirective() { result = getSiblingDirective(_) } + + override string toString() { result = "#if ..." } + + override string getAPrimaryQlClass() { result = "IfDirective" } +} + +/** + * An `#elif` preprocessor directive. + */ +class ElifDirective extends ConditionalDirective, @directive_elif { + override predicate branchTaken() { directive_elifs(this, 1, _, _, _) } + + override predicate conditionMatched() { directive_elifs(this, _, 1, _, _) } + + /** Gets the opening `#if` preprocessor directive. */ + IfDirective getIfDirective() { directive_elifs(this, _, _, result, _) } + + /** Gets the successive branching preprocessor directive (`#elif` or `#else`), if any. */ + BranchDirective getSuccSiblingDirective() { + exists(IfDirective i, int index | + this = i.getSiblingDirective(index) and + result = i.getSiblingDirective(index + 1) + ) + } + + override string toString() { result = "#elif ..." } + + override string getAPrimaryQlClass() { result = "ElifDirective" } +} + +/** + * An `#else` preprocessor directive. + */ +class ElseDirective extends BranchDirective, @directive_else { + /** Gets the opening `#if` preprocessor directive. */ + IfDirective getIfDirective() { directive_elses(this, _, result, _) } + + override predicate branchTaken() { directive_elses(this, 1, _, _) } + + override string toString() { result = "#else" } + + override string getAPrimaryQlClass() { result = "ElseDirective" } +} + +/** + * An `#endif` preprocessor directive. + */ +class EndifDirective extends PreprocessorDirective, @directive_endif { + /** Gets the opening `#if` preprocessor directive. */ + IfDirective getIfDirective() { directive_endifs(this, result) } + + override string toString() { result = "#endif" } + + override string getAPrimaryQlClass() { result = "EndifDirective" } +} diff --git a/csharp/ql/src/semmle/code/csharp/PrintAst.qll b/csharp/ql/src/semmle/code/csharp/PrintAst.qll index 63ff928f9fc..1cac4a5f238 100644 --- a/csharp/ql/src/semmle/code/csharp/PrintAst.qll +++ b/csharp/ql/src/semmle/code/csharp/PrintAst.qll @@ -48,6 +48,8 @@ private predicate isNotNeeded(Element e) { or e instanceof TupleType or + e instanceof ConditionalDirective + or isNotNeeded(e.(Declaration).getDeclaringType()) or isNotNeeded(e.(Parameter).getDeclaringElement()) @@ -100,15 +102,16 @@ private ValueOrRefType getAnInterestingBaseType(ValueOrRefType type) { not type instanceof ArrayType and not type instanceof NullableType and result = type.getABaseType() and - isInterestingBaseType(result) + isInterestingBaseType(type, result) } -private predicate isInterestingBaseType(ValueOrRefType base) { +private predicate isInterestingBaseType(ValueOrRefType type, ValueOrRefType base) { not base instanceof ObjectType and not base.getQualifiedName() = "System.ValueType" and not base.getQualifiedName() = "System.Delegate" and not base.getQualifiedName() = "System.MulticastDelegate" and - not base.getQualifiedName() = "System.Enum" + not base.getQualifiedName() = "System.Enum" and + exists(TypeMention tm | tm.getTarget() = type and tm.getType() = base) } /** @@ -131,7 +134,8 @@ private newtype TPrintAstNode = TParametersNode(Parameterizable parameterizable) { shouldPrint(parameterizable, _) and parameterizable.getNumberOfParameters() > 0 and - not isNotNeeded(parameterizable) + not isNotNeeded(parameterizable) and + exists(Parameter p | p.getDeclaringElement() = parameterizable and shouldPrint(p, _)) } or TAttributesNode(Attributable attributable) { shouldPrint(attributable, _) and @@ -568,11 +572,12 @@ final class TypeNode extends ElementNode { result.(BaseTypesNode).getValueOrRefType() = type or result.(ElementNode).getElement() = - rank[childIndex - 3](Member m, string file, int line, int column | + rank[childIndex - 3](Member m, string file, int line, int column, string name | m = type.getAMember() and + name = m.getName() and locationSortKeys(m, file, line, column) | - m order by file, line, column + m order by file, line, column, name ) } } diff --git a/csharp/ql/src/semmle/code/csharp/Property.qll b/csharp/ql/src/semmle/code/csharp/Property.qll index 3607f1fa06e..23179b7725a 100644 --- a/csharp/ql/src/semmle/code/csharp/Property.qll +++ b/csharp/ql/src/semmle/code/csharp/Property.qll @@ -472,6 +472,9 @@ class Setter extends Accessor, @setter { result = Accessor.super.getDeclaration() } + /** Holds if this setter is an `init`-only accessor. */ + predicate isInitOnly() { init_only_accessors(this) } + override string getAPrimaryQlClass() { result = "Setter" } } @@ -563,6 +566,4 @@ class IndexerProperty extends Property { // ``` result.getIndexer() = i } - - override string getAPrimaryQlClass() { result = "IndexerProperty" } } diff --git a/csharp/ql/src/semmle/code/csharp/Stmt.qll b/csharp/ql/src/semmle/code/csharp/Stmt.qll index 8fadbc1267b..375e698d1cb 100644 --- a/csharp/ql/src/semmle/code/csharp/Stmt.qll +++ b/csharp/ql/src/semmle/code/csharp/Stmt.qll @@ -33,6 +33,9 @@ class Stmt extends ControlFlowElement, @stmt { override Location getALocation() { stmt_location(this, result) } + /** Holds if this statement is a global statement. */ + predicate isGlobal() { this.getParent().(BlockStmt).isGlobalStatementContainer() } + /** * Gets the singleton statement contained in this statement, by removing * enclosing block statements. @@ -70,6 +73,11 @@ class BlockStmt extends Stmt, @block_stmt { /** Holds if this block is an empty block with no statements. */ predicate isEmpty() { not exists(this.getAStmt()) } + /** Holds if this block is the container of the global statements. */ + predicate isGlobalStatementContainer() { + this.getEnclosingCallable().hasQualifiedName("$.
    $") + } + override Stmt stripSingletonBlocks() { if getNumberOfStmts() = 1 then result = getAChildStmt().stripSingletonBlocks() @@ -582,6 +590,27 @@ class ForeachStmt extends LoopStmt, @foreach_stmt { */ Expr getIterableExpr() { result = this.getChild(1) } + /** Gets the called `GetEnumerator` method. */ + Method getGetEnumerator() { foreach_stmt_desugar(this, result, 1) } + + /** Gets the called `MoveNext` or `MoveNextAsync` method. */ + Method getMoveNext() { foreach_stmt_desugar(this, result, 3) } + + /** Gets the called `Dispose` or `DisposeAsync` method, if any. */ + Method getDispose() { foreach_stmt_desugar(this, result, 4) } + + /** Gets the called `Current` property. */ + Property getCurrent() { foreach_stmt_desugar(this, result, 2) } + + /** + * Gets the intermediate type to which the `Current` property is converted before + * being converted to the iteration variable type. + */ + Type getElementType() { foreach_stmt_desugar(this, result, 5) } + + /** Holds if this `foreach` statement is asynchronous. */ + predicate isAsync() { foreach_stmt_info(this, 2) } + override string toString() { result = "foreach (... ... in ...) ..." } override string getAPrimaryQlClass() { result = "ForeachStmt" } diff --git a/csharp/ql/src/semmle/code/csharp/Type.qll b/csharp/ql/src/semmle/code/csharp/Type.qll index c86d936189a..c9e89da9943 100644 --- a/csharp/ql/src/semmle/code/csharp/Type.qll +++ b/csharp/ql/src/semmle/code/csharp/Type.qll @@ -736,6 +736,21 @@ class Class extends RefType, @class_type { override string getAPrimaryQlClass() { result = "Class" } } +/** + * A `record`, for example + * + * ```csharp + * record R(object Prop) { + * ... + * } + * ``` + */ +class Record extends Class { + Record() { this.isRecord() } + + override string getAPrimaryQlClass() { result = "Record" } +} + /** * A class generated by the compiler from an anonymous object creation. * @@ -746,7 +761,7 @@ class Class extends RefType, @class_type { * ``` */ class AnonymousClass extends Class { - AnonymousClass() { this.getName().matches("<%") } + AnonymousClass() { anonymous_types(this) } } /** @@ -797,6 +812,95 @@ class DelegateType extends RefType, Parameterizable, @delegate_type { override string getAPrimaryQlClass() { result = "DelegateType" } } +private newtype TCallingConvention = + MkCallingConvention(int i) { function_pointer_calling_conventions(_, i) } + +/** + * Represents a signature calling convention. Specifies how arguments in a given + * signature are passed from the caller to the callee. + */ +class CallingConvention extends TCallingConvention { + /** Gets a textual representation of this calling convention. */ + string toString() { result = "CallingConvention" } +} + +/** Managed calling convention with fixed-length argument list. */ +class DefaultCallingConvention extends CallingConvention { + DefaultCallingConvention() { this = MkCallingConvention(0) } + + override string toString() { result = "DefaultCallingConvention" } +} + +/** Unmanaged C/C++-style calling convention where the call stack is cleaned by the caller. */ +class CDeclCallingConvention extends CallingConvention { + CDeclCallingConvention() { this = MkCallingConvention(1) } + + override string toString() { result = "CDeclCallingConvention" } +} + +/** Unmanaged calling convention where call stack is cleaned up by the callee. */ +class StdCallCallingConvention extends CallingConvention { + StdCallCallingConvention() { this = MkCallingConvention(2) } + + override string toString() { result = "StdCallCallingConvention" } +} + +/** + * Unmanaged C++-style calling convention for calling instance member functions + * with a fixed argument list. + */ +class ThisCallCallingConvention extends CallingConvention { + ThisCallCallingConvention() { this = MkCallingConvention(3) } + + override string toString() { result = "ThisCallCallingConvention" } +} + +/** Unmanaged calling convention where arguments are passed in registers when possible. */ +class FastCallCallingConvention extends CallingConvention { + FastCallCallingConvention() { this = MkCallingConvention(4) } + + override string toString() { result = "FastCallCallingConvention" } +} + +/** Managed calling convention for passing extra arguments. */ +class VarArgsCallingConvention extends CallingConvention { + VarArgsCallingConvention() { this = MkCallingConvention(5) } + + override string toString() { result = "VarArgsCallingConvention" } +} + +/** + * A function pointer type, for example + * + * ```csharp + * delegate* + * ``` + */ +class FunctionPointerType extends Type, Parameterizable, @function_pointer_type { + /** Gets the return type of this function pointer. */ + Type getReturnType() { function_pointer_return_type(this, getTypeRef(result)) } + + /** Gets the calling convention. */ + CallingConvention getCallingConvention() { + exists(int i | + function_pointer_calling_conventions(this, i) and result = MkCallingConvention(i) + ) + } + + /** Gets the unmanaged calling convention at index `i`. */ + Type getUnmanagedCallingConvention(int i) { + has_unmanaged_calling_conventions(this, i, getTypeRef(result)) + } + + /** Gets an unmanaged calling convention. */ + Type getAnUnmanagedCallingConvention() { result = getUnmanagedCallingConvention(_) } + + /** Gets the annotated return type of this function pointer type. */ + AnnotatedType getAnnotatedReturnType() { result.appliesTo(this) } + + override string getAPrimaryQlClass() { result = "FunctionPointerType" } +} + /** * The `null` type. The type of the `null` literal. */ diff --git a/csharp/ql/src/semmle/code/csharp/Variable.qll b/csharp/ql/src/semmle/code/csharp/Variable.qll index 6756ca6e533..a13175dfeb0 100644 --- a/csharp/ql/src/semmle/code/csharp/Variable.qll +++ b/csharp/ql/src/semmle/code/csharp/Variable.qll @@ -177,7 +177,7 @@ class Parameter extends DotNet::Parameter, LocalScopeVariable, Attributable, Top predicate hasExtensionMethodModifier() { params(this, _, _, _, 4, _, _) } /** Gets the declaring element of this parameter. */ - Parameterizable getDeclaringElement() { params(this, _, _, _, _, result, _) } + override Parameterizable getDeclaringElement() { params(this, _, _, _, _, result, _) } override Parameter getUnboundDeclaration() { params(this, _, _, _, _, _, result) } @@ -213,7 +213,7 @@ class Parameter extends DotNet::Parameter, LocalScopeVariable, Attributable, Top predicate hasDefaultValue() { exists(getDefaultValue()) } /** Gets the callable to which this parameter belongs, if any. */ - override Callable getCallable() { result.getAParameter() = this } + override Callable getCallable() { result = this.getDeclaringElement() } /** * Gets an argument which is assigned to this parameter in a call to the diff --git a/csharp/ql/src/semmle/code/csharp/commons/Compilation.qll b/csharp/ql/src/semmle/code/csharp/commons/Compilation.qll index c1eb3362c47..6af0af0e8a9 100644 --- a/csharp/ql/src/semmle/code/csharp/commons/Compilation.qll +++ b/csharp/ql/src/semmle/code/csharp/commons/Compilation.qll @@ -9,6 +9,9 @@ class Compilation extends @compilation { /** Gets the directory in which this compilation was run, as a string. */ string getDirectoryString() { compilations(this, result) } + /** Gets the output assembly. */ + Assembly getOutputAssembly() { compilation_assembly(this, result) } + /** Gets the folder in which this compilation was run. */ Folder getFolder() { result.getAbsolutePath() = getDirectoryString() } diff --git a/csharp/ql/src/semmle/code/csharp/commons/ConsistencyChecks.qll b/csharp/ql/src/semmle/code/csharp/commons/ConsistencyChecks.qll index aabdc030274..79ff7107129 100644 --- a/csharp/ql/src/semmle/code/csharp/commons/ConsistencyChecks.qll +++ b/csharp/ql/src/semmle/code/csharp/commons/ConsistencyChecks.qll @@ -46,10 +46,13 @@ module SsaChecks { } predicate notDominatedByDef(AssignableRead read, string m) { - exists(Definition def, BasicBlock bb, ControlFlow::Node rnode, ControlFlow::Node dnode, int i | + exists( + Definition def, ControlFlow::BasicBlock bb, ControlFlow::Node rnode, ControlFlow::Node dnode, + int i + | def.getAReadAtNode(rnode) = read | - def.definesAt(bb, i) and + def.definesAt(_, bb, i) and dnode = bb.getNode(max(int j | j = i or j = 0)) and not dnode.dominates(rnode) ) and diff --git a/csharp/ql/src/semmle/code/csharp/commons/Util.qll b/csharp/ql/src/semmle/code/csharp/commons/Util.qll index 203d84cbef6..d1b9b3b7894 100644 --- a/csharp/ql/src/semmle/code/csharp/commons/Util.qll +++ b/csharp/ql/src/semmle/code/csharp/commons/Util.qll @@ -5,7 +5,11 @@ import csharp /** A `Main` method. */ class MainMethod extends Method { MainMethod() { - this.hasName("Main") and + ( + this.hasName("Main") + or + this.hasQualifiedName("$", "
    $") + ) and this.isStatic() and (this.getReturnType() instanceof VoidType or this.getReturnType() instanceof IntType) and if this.getNumberOfParameters() = 1 diff --git a/csharp/ql/src/semmle/code/csharp/controlflow/BasicBlocks.qll b/csharp/ql/src/semmle/code/csharp/controlflow/BasicBlocks.qll index 341e72eafa5..8b20ccb3c22 100644 --- a/csharp/ql/src/semmle/code/csharp/controlflow/BasicBlocks.qll +++ b/csharp/ql/src/semmle/code/csharp/controlflow/BasicBlocks.qll @@ -377,7 +377,17 @@ private predicate entryBB(BasicBlock bb) { * an annotated exit node. */ class AnnotatedExitBasicBlock extends BasicBlock { - AnnotatedExitBasicBlock() { this.getANode() instanceof ControlFlow::Nodes::AnnotatedExitNode } + private boolean isNormal; + + AnnotatedExitBasicBlock() { + this.getANode() = + any(ControlFlow::Nodes::AnnotatedExitNode n | + if n.isNormal() then isNormal = true else isNormal = false + ) + } + + /** Holds if this block represents a normal exit. */ + predicate isNormal() { isNormal = true } } /** @@ -390,19 +400,14 @@ class ExitBasicBlock extends BasicBlock { private module JoinBlockPredecessors { private import ControlFlow::Nodes - - private class CallableOrCFE extends Element { - CallableOrCFE() { this instanceof Callable or this instanceof ControlFlowElement } - } - - private predicate id(CallableOrCFE x, CallableOrCFE y) { x = y } - - private predicate idOf(CallableOrCFE x, int y) = equivalenceRelation(id/2)(x, y) + private import semmle.code.csharp.controlflow.internal.ControlFlowGraphImpl int getId(JoinBlockPredecessor jbp) { - idOf(jbp.getFirstNode().(ElementNode).getElement(), result) - or - idOf(jbp.(EntryBasicBlock).getCallable(), result) + exists(ControlFlowTree::Range t | ControlFlowTree::idOf(t, result) | + t = jbp.getFirstNode().getElement() + or + t = jbp.(EntryBasicBlock).getCallable() + ) } string getSplitString(JoinBlockPredecessor jbp) { diff --git a/csharp/ql/src/semmle/code/csharp/controlflow/ControlFlowGraph.qll b/csharp/ql/src/semmle/code/csharp/controlflow/ControlFlowGraph.qll index 9f4eda99838..061b7674810 100644 --- a/csharp/ql/src/semmle/code/csharp/controlflow/ControlFlowGraph.qll +++ b/csharp/ql/src/semmle/code/csharp/controlflow/ControlFlowGraph.qll @@ -270,7 +270,7 @@ module ControlFlow { /** Gets the callable that this exit applies to. */ Callable getCallable() { result = c } - /** Holds if this node represent a normal exit. */ + /** Holds if this node represents a normal exit. */ predicate isNormal() { normal = true } override BasicBlocks::AnnotatedExitBlock getBasicBlock() { diff --git a/csharp/ql/src/semmle/code/csharp/controlflow/Guards.qll b/csharp/ql/src/semmle/code/csharp/controlflow/Guards.qll index 7cad1dff909..396fb52a85d 100644 --- a/csharp/ql/src/semmle/code/csharp/controlflow/Guards.qll +++ b/csharp/ql/src/semmle/code/csharp/controlflow/Guards.qll @@ -621,8 +621,7 @@ private Ssa::Definition getAnSsaQualifier(Expr e, ControlFlow::Node cfn) { } private AssignableAccess getATrackedAccess(Ssa::Definition def, ControlFlow::Node cfn) { - result = def.getAReadAtNode(cfn) and - not def instanceof Ssa::ImplicitUntrackedDefinition + result = def.getAReadAtNode(cfn) or result = def.(Ssa::ExplicitDefinition).getADefinition().getTargetAccess() and cfn = def.getControlFlowNode() @@ -1724,6 +1723,7 @@ module Internal { cached private module Cached { private import semmle.code.csharp.Caching + private import semmle.code.csharp.dataflow.internal.SsaImpl as SsaImpl /** * Holds if basic block `bb` only is reached when guard `g` has abstract value `v`. @@ -1776,9 +1776,9 @@ module Internal { private predicate adjacentReadPairSameVarUniquePredecessor( Ssa::Definition def, ControlFlow::Node cfn1, ControlFlow::Node cfn2 ) { - Ssa::Internal::adjacentReadPairSameVar(def, cfn1, cfn2) and + SsaImpl::adjacentReadPairSameVar(def, cfn1, cfn2) and not exists(ControlFlow::Node other | - Ssa::Internal::adjacentReadPairSameVar(def, other, cfn2) and + SsaImpl::adjacentReadPairSameVar(def, other, cfn2) and other != cfn1 and other != cfn2 ) @@ -1832,7 +1832,7 @@ module Internal { private predicate firstReadUniquePredecessor(Ssa::ExplicitDefinition def, ControlFlow::Node cfn) { exists(def.getAFirstReadAtNode(cfn)) and not exists(ControlFlow::Node other | - Ssa::Internal::adjacentReadPairSameVar(def, other, cfn) and + SsaImpl::adjacentReadPairSameVar(def, other, cfn) and other != cfn ) } diff --git a/csharp/ql/src/semmle/code/csharp/controlflow/internal/Completion.qll b/csharp/ql/src/semmle/code/csharp/controlflow/internal/Completion.qll index 1db2329043b..089339ba1b8 100644 --- a/csharp/ql/src/semmle/code/csharp/controlflow/internal/Completion.qll +++ b/csharp/ql/src/semmle/code/csharp/controlflow/internal/Completion.qll @@ -23,11 +23,11 @@ import csharp private import semmle.code.csharp.commons.Assertions private import semmle.code.csharp.commons.Constants private import semmle.code.csharp.frameworks.System +private import ControlFlowGraphImpl private import NonReturning private import SuccessorType private import SuccessorTypes -// Internal representation of completions private newtype TCompletion = TSimpleCompletion() or TBooleanCompletion(boolean b) { b = true or b = false } or @@ -40,26 +40,33 @@ private newtype TCompletion = TGotoCompletion(string label) { label = any(GotoStmt gs).getLabel() } or TThrowCompletion(ExceptionClass ec) or TExitCompletion() or - TNestedCompletion(Completion inner, Completion outer) { - inner instanceof NormalCompletion and - ( - outer = TReturnCompletion() - or - outer = TBreakCompletion() - or - outer = TContinueCompletion() - or - outer = TGotoCompletion(_) - or - outer = TThrowCompletion(_) - or - outer = TExitCompletion() - ) - or + TNestedCompletion(Completion inner, Completion outer, int nestLevel) { inner = TBreakCompletion() and - outer instanceof NonNestedNormalCompletion + outer instanceof NonNestedNormalCompletion and + nestLevel = 0 + or + inner instanceof NormalCompletion and + nestedFinallyCompletion(outer, nestLevel) } +pragma[noinline] +private predicate nestedFinallyCompletion(Completion outer, int nestLevel) { + ( + outer = TReturnCompletion() + or + outer = TBreakCompletion() + or + outer = TContinueCompletion() + or + outer = TGotoCompletion(_) + or + outer = TThrowCompletion(_) + or + outer = TExitCompletion() + ) and + nestLevel = any(Statements::TryStmtTree t).nestLevel() +} + pragma[noinline] private predicate completionIsValidForStmt(Stmt s, Completion c) { s instanceof BreakStmt and @@ -225,36 +232,57 @@ private Expr getQualifier(QualifiableExpr e) { result = e.getChildExpr(-1) } +pragma[noinline] +private predicate typePatternMustHaveMatchingCompletion( + TypePatternExpr tpe, Type t, Type strippedType +) { + exists(Expr e, Expr stripped | mustHaveMatchingCompletion(e, tpe) | + stripped = e.stripCasts() and + t = tpe.getCheckedType() and + strippedType = stripped.getType() and + not t.containsTypeParameters() and + not strippedType.containsTypeParameters() + ) +} + +pragma[noinline] +private Type typePatternCommonSubTypeLeft(Type t) { + typePatternMustHaveMatchingCompletion(_, t, _) and + result.isImplicitlyConvertibleTo(t) and + not result instanceof DynamicType +} + +pragma[noinline] +private Type typePatternCommonSubTypeRight(Type strippedType) { + typePatternMustHaveMatchingCompletion(_, _, strippedType) and + result.isImplicitlyConvertibleTo(strippedType) and + not result instanceof DynamicType +} + +pragma[noinline] +private predicate typePatternCommonSubType(Type t, Type strippedType) { + typePatternCommonSubTypeLeft(t) = typePatternCommonSubTypeRight(strippedType) +} + /** - * Holds if expression `e` constantly matches (`value = true`) or constantly - * non-matches (`value = false`). + * Holds if pattern expression `pe` constantly matches (`value = true`) or + * constantly non-matches (`value = false`). */ -private predicate isMatchingConstant(Expr e, boolean value) { - exists(Switch s | mustHaveMatchingCompletion(s, e) | - exists(Expr stripped | stripped = s.getExpr().stripCasts() | - exists(Case c, string strippedValue | - c = s.getACase() and - e = c.getPattern() and - strippedValue = stripped.getValue() - | - if strippedValue = e.getValue() then value = true else value = false - ) - or - exists(Case c, TypePatternExpr tpe, Type t, Type strippedType | c = s.getACase() | - tpe = c.getPattern() and - e = tpe and - t = tpe.getCheckedType() and - strippedType = stripped.getType() and - not t.isImplicitlyConvertibleTo(strippedType) and - not t instanceof Interface and - not t.containsTypeParameters() and - not strippedType.containsTypeParameters() and - value = false - ) - ) - or - e instanceof DiscardPatternExpr and - value = true +private predicate isMatchingConstant(PatternExpr pe, boolean value) { + exists(Expr e, string exprValue, string patternValue | + mustHaveMatchingCompletion(e, pe) and + exprValue = e.stripCasts().getValue() and + patternValue = pe.getValue() and + if exprValue = patternValue then value = true else value = false + ) + or + pe instanceof DiscardPatternExpr and + value = true + or + exists(Type t, Type strippedType | + typePatternMustHaveMatchingCompletion(pe, t, strippedType) and + not typePatternCommonSubType(t, strippedType) and + value = false ) } @@ -347,9 +375,6 @@ private class TriedControlFlowElement extends ControlFlowElement { or this instanceof DynamicExpr and result instanceof SystemExceptionClass - or - this instanceof StringLiteral and - result instanceof SystemOutOfMemoryExceptionClass } private CoreLib getCoreLibFromACatchClause() { @@ -514,16 +539,48 @@ predicate switchMatching(Switch s, Case c, PatternExpr pe) { pe = c.getPattern() } -private predicate mustHaveMatchingCompletion(Switch s, PatternExpr pe) { switchMatching(s, _, pe) } - /** * Holds if a normal completion of `cfe` must be a matching completion. Thats is, - * whether `cfe` determines a match in a `switch` statement or `catch` clause. + * whether `cfe` determines a match in a `switch/if` statement or `catch` clause. */ private predicate mustHaveMatchingCompletion(ControlFlowElement cfe) { - mustHaveMatchingCompletion(_, cfe) + switchMatching(_, _, cfe) or cfe instanceof SpecificCatchClause + or + cfe = any(IsExpr ie | inBooleanContext(ie)).getPattern() + or + cfe = any(RecursivePatternExpr rpe).getAChildExpr() + or + cfe = any(PositionalPatternExpr ppe).getPattern(_) + or + cfe = any(PropertyPatternExpr ppe).getPattern(_) + or + cfe = any(UnaryPatternExpr upe | mustHaveMatchingCompletion(upe)).getPattern() + or + cfe = any(BinaryPatternExpr bpe).getAnOperand() +} + +/** + * Holds if `pe` must have a matching completion, and `e` is the expression + * that is being matched. + */ +private predicate mustHaveMatchingCompletion(Expr e, PatternExpr pe) { + exists(Switch s | + switchMatching(s, _, pe) and + e = s.getExpr() + ) + or + e = any(IsExpr ie | pe = ie.getPattern()).getExpr() and + mustHaveMatchingCompletion(pe) + or + exists(PatternExpr mid | mustHaveMatchingCompletion(e, mid) | + pe = mid.(UnaryPatternExpr).getPattern() + or + pe = mid.(RecursivePatternExpr).getAChildExpr() + or + pe = mid.(BinaryPatternExpr).getAnOperand() + ) } /** @@ -561,7 +618,13 @@ class SimpleCompletion extends NonNestedNormalCompletion, TSimpleCompletion { * completion (`NullnessCompletion`), a matching completion (`MatchingCompletion`), * or an emptiness completion (`EmptinessCompletion`). */ -abstract class ConditionalCompletion extends NonNestedNormalCompletion { } +abstract class ConditionalCompletion extends NonNestedNormalCompletion { + /** Gets the Boolean value of this completion. */ + abstract boolean getValue(); + + /** Gets the dual completion. */ + abstract ConditionalCompletion getDual(); +} /** * A completion that represents evaluation of an expression @@ -572,10 +635,9 @@ class BooleanCompletion extends ConditionalCompletion { BooleanCompletion() { this = TBooleanCompletion(value) } - /** Gets the Boolean value of this completion. */ - boolean getValue() { result = value } + override boolean getValue() { result = value } - BooleanCompletion getDual() { result = TBooleanCompletion(value.booleanNot()) } + override BooleanCompletion getDual() { result = TBooleanCompletion(value.booleanNot()) } override BooleanSuccessor getAMatchingSuccessorType() { result.getValue() = value } @@ -607,6 +669,10 @@ class NullnessCompletion extends ConditionalCompletion, TNullnessCompletion { /** Holds if the last sub expression of this expression evaluates to a non-`null` value. */ predicate isNonNull() { value = false } + override boolean getValue() { result = value } + + override NullnessCompletion getDual() { result = TNullnessCompletion(value.booleanNot()) } + override NullnessSuccessor getAMatchingSuccessorType() { result.getValue() = value } override string toString() { if this.isNull() then result = "null" else result = "non-null" } @@ -627,6 +693,10 @@ class MatchingCompletion extends ConditionalCompletion, TMatchingCompletion { /** Holds if there is not a match. */ predicate isNonMatch() { value = false } + override boolean getValue() { result = value } + + override MatchingCompletion getDual() { result = TMatchingCompletion(value.booleanNot()) } + override MatchingSuccessor getAMatchingSuccessorType() { result.getValue() = value } override string toString() { if this.isMatch() then result = "match" else result = "no-match" } @@ -644,6 +714,10 @@ class EmptinessCompletion extends ConditionalCompletion, TEmptinessCompletion { /** Holds if the emptiness test evaluates to `true`. */ predicate isEmpty() { value = true } + override boolean getValue() { result = value } + + override EmptinessCompletion getDual() { result = TEmptinessCompletion(value.booleanNot()) } + override EmptinessSuccessor getAMatchingSuccessorType() { result.getValue() = value } override string toString() { if this.isEmpty() then result = "empty" else result = "non-empty" } @@ -674,21 +748,25 @@ class EmptinessCompletion extends ConditionalCompletion, TEmptinessCompletion { class NestedCompletion extends Completion, TNestedCompletion { Completion inner; Completion outer; + int nestLevel; - NestedCompletion() { this = TNestedCompletion(inner, outer) } + NestedCompletion() { this = TNestedCompletion(inner, outer, nestLevel) } /** Gets a completion that is compatible with the inner completion. */ Completion getAnInnerCompatibleCompletion() { result.getOuterCompletion() = this.getInnerCompletion() } + /** Gets the level of this nested completion. */ + int getNestLevel() { result = nestLevel } + override Completion getInnerCompletion() { result = inner } override Completion getOuterCompletion() { result = outer } override SuccessorType getAMatchingSuccessorType() { none() } - override string toString() { result = outer + " [" + inner + "]" } + override string toString() { result = outer + " [" + inner + "] (" + nestLevel + ")" } } /** @@ -725,13 +803,13 @@ class NestedBreakCompletion extends NormalCompletion, NestedCompletion { override BreakCompletion getInnerCompletion() { result = inner } - override SimpleCompletion getOuterCompletion() { result = outer } + override NonNestedNormalCompletion getOuterCompletion() { result = outer } override Completion getAnInnerCompatibleCompletion() { result = inner and outer = TSimpleCompletion() or - result = TNestedCompletion(outer, inner) + result = TNestedCompletion(outer, inner, _) } override SuccessorType getAMatchingSuccessorType() { @@ -749,7 +827,7 @@ class NestedBreakCompletion extends NormalCompletion, NestedCompletion { class ReturnCompletion extends Completion { ReturnCompletion() { this = TReturnCompletion() or - this = TNestedCompletion(_, TReturnCompletion()) + this = TNestedCompletion(_, TReturnCompletion(), _) } override ReturnSuccessor getAMatchingSuccessorType() { any() } @@ -768,7 +846,7 @@ class ReturnCompletion extends Completion { class BreakCompletion extends Completion { BreakCompletion() { this = TBreakCompletion() or - this = TNestedCompletion(_, TBreakCompletion()) + this = TNestedCompletion(_, TBreakCompletion(), _) } override BreakSuccessor getAMatchingSuccessorType() { any() } @@ -787,7 +865,7 @@ class BreakCompletion extends Completion { class ContinueCompletion extends Completion { ContinueCompletion() { this = TContinueCompletion() or - this = TNestedCompletion(_, TContinueCompletion()) + this = TNestedCompletion(_, TContinueCompletion(), _) } override ContinueSuccessor getAMatchingSuccessorType() { any() } @@ -807,7 +885,7 @@ class GotoCompletion extends Completion { GotoCompletion() { this = TGotoCompletion(label) or - this = TNestedCompletion(_, TGotoCompletion(label)) + this = TNestedCompletion(_, TGotoCompletion(label), _) } /** Gets the label of the `goto` completion. */ @@ -830,7 +908,7 @@ class ThrowCompletion extends Completion { ThrowCompletion() { this = TThrowCompletion(ec) or - this = TNestedCompletion(_, TThrowCompletion(ec)) + this = TNestedCompletion(_, TThrowCompletion(ec), _) } /** Gets the type of the exception being thrown. */ @@ -856,7 +934,7 @@ class ThrowCompletion extends Completion { class ExitCompletion extends Completion { ExitCompletion() { this = TExitCompletion() or - this = TNestedCompletion(_, TExitCompletion()) + this = TNestedCompletion(_, TExitCompletion(), _) } override ExitSuccessor getAMatchingSuccessorType() { any() } diff --git a/csharp/ql/src/semmle/code/csharp/controlflow/internal/ControlFlowGraphImpl.qll b/csharp/ql/src/semmle/code/csharp/controlflow/internal/ControlFlowGraphImpl.qll index 3a6c8e57725..a0c0784c010 100644 --- a/csharp/ql/src/semmle/code/csharp/controlflow/internal/ControlFlowGraphImpl.qll +++ b/csharp/ql/src/semmle/code/csharp/controlflow/internal/ControlFlowGraphImpl.qll @@ -50,7 +50,29 @@ private import SuccessorTypes private import Splitting private import semmle.code.csharp.ExprOrStmtParent -abstract private class ControlFlowTree extends ControlFlowElement { +/** An element that defines a new CFG scope. */ +class CfgScope extends Element, @top_level_exprorstmt_parent { + CfgScope() { not this instanceof Attribute } +} + +module ControlFlowTree { + private class Range_ = @callable or @control_flow_element; + + class Range extends Element, Range_ { + Range() { this = getAChild*(any(CfgScope scope)) } + } + + Element getAChild(Element p) { + result = p.getAChild() or + result = p.(AssignOperation).getExpandedAssignment() + } + + private predicate id(Range x, Range y) { x = y } + + predicate idOf(Range x, int y) = equivalenceRelation(id/2)(x, y) +} + +abstract private class ControlFlowTree extends ControlFlowTree::Range { /** * Holds if `first` is the first element executed within this control * flow element. @@ -96,23 +118,6 @@ predicate last(ControlFlowTree cft, ControlFlowElement last, Completion c) { ) } -pragma[noinline] -private LabeledStmt getLabledStmt(string label, Callable c) { - result.getEnclosingCallable() = c and - label = result.getLabel() -} - -pragma[nomagic] -private predicate goto(ControlFlowElement cfe, GotoCompletion gc, string label, Callable enclosing) { - last(_, cfe, gc) and - // Special case: when a `goto` happens inside a `try` statement with a - // `finally` block, flow does not go directly to the target, but instead - // to the `finally` block (and from there possibly to the target) - not cfe = any(Statements::TryStmtTree t | t.hasFinally()).getBlockOrCatchFinallyPred(_) and - label = gc.getLabel() and - enclosing = cfe.getEnclosingCallable() -} - /** * Holds if `succ` is a control flow successor for `pred`, given that `pred` * finishes with completion `c`. @@ -120,33 +125,10 @@ private predicate goto(ControlFlowElement cfe, GotoCompletion gc, string label, pragma[nomagic] predicate succ(ControlFlowElement pred, ControlFlowElement succ, Completion c) { any(ControlFlowTree cft).succ(pred, succ, c) - or - exists(Constructor con, InitializerSplitting::InitializedInstanceMember m, int i | - last(m.getInitializer(), pred, c) and - c instanceof NormalCompletion and - InitializerSplitting::constructorInitializeOrder(con, m, i) - | - // Flow from one member initializer to the next - exists(InitializerSplitting::InitializedInstanceMember next | - InitializerSplitting::constructorInitializeOrder(con, next, i + 1) and - first(next.getInitializer(), succ) - ) - or - // Flow from last member initializer to constructor body - m = InitializerSplitting::lastConstructorInitializer(con) and - first(con.getBody(), succ) - ) - or - // Flow from element with `goto` completion to first element of relevant - // target - exists(string label, Callable enclosing | - goto(pred, c, label, enclosing) and - first(getLabledStmt(label, enclosing), succ) - ) } /** Holds if `first` is first executed when entering `scope`. */ -predicate succEntry(@top_level_exprorstmt_parent scope, ControlFlowElement first) { +predicate scopeFirst(CfgScope scope, ControlFlowElement first) { scope = any(Callable c | if exists(c.(Constructor).getInitializer()) @@ -166,7 +148,7 @@ predicate succEntry(@top_level_exprorstmt_parent scope, ControlFlowElement first } /** Holds if `scope` is exited when `last` finishes with completion `c`. */ -predicate succExit(ControlFlowElement last, Callable scope, Completion c) { +predicate scopeLast(Callable scope, ControlFlowElement last, Completion c) { last(scope.getBody(), last, c) and not c instanceof GotoCompletion or @@ -177,6 +159,33 @@ predicate succExit(ControlFlowElement last, Callable scope, Completion c) { ) } +private class CallableTree extends ControlFlowTree, Callable { + final override predicate propagatesAbnormal(ControlFlowElement child) { none() } + + final override predicate first(ControlFlowElement first) { none() } + + final override predicate last(ControlFlowElement last, Completion c) { none() } + + final override predicate succ(ControlFlowElement pred, ControlFlowElement succ, Completion c) { + exists(Constructor con, InitializerSplitting::InitializedInstanceMember m, int i | + this = con and + last(m.getInitializer(), pred, c) and + c instanceof NormalCompletion and + InitializerSplitting::constructorInitializeOrder(con, m, i) + | + // Flow from one member initializer to the next + exists(InitializerSplitting::InitializedInstanceMember next | + InitializerSplitting::constructorInitializeOrder(con, next, i + 1) and + first(next.getInitializer(), succ) + ) + or + // Flow from last member initializer to constructor body + m = InitializerSplitting::lastConstructorInitializer(con) and + first(con.getBody(), succ) + ) + } +} + /** * A control flow element where the children are evaluated following a * standard left-to-right evaluation. The actual evaluation order is @@ -225,15 +234,11 @@ abstract private class PostOrderTree extends ControlFlowTree { } abstract private class SwitchTree extends ControlFlowTree, Switch { - Expr expr; - - SwitchTree() { expr = this.getExpr() } - - override predicate propagatesAbnormal(ControlFlowElement child) { child = expr } + override predicate propagatesAbnormal(ControlFlowElement child) { child = this.getExpr() } override predicate succ(ControlFlowElement pred, ControlFlowElement succ, Completion c) { // Flow from last element of switch expression to first element of first case - last(expr, pred, c) and + last(this.getExpr(), pred, c) and c instanceof NormalCompletion and first(this.getCase(0), succ) or @@ -254,17 +259,12 @@ abstract private class SwitchTree extends ControlFlowTree, Switch { } abstract private class CaseTree extends ControlFlowTree, Case { - PatternExpr pattern; - ControlFlowElement body; - - CaseTree() { pattern = this.getPattern() and body = this.getBody() } - final override predicate propagatesAbnormal(ControlFlowElement child) { - child in [pattern, this.getCondition().(ControlFlowElement), body] + child in [this.getPattern(), this.getCondition().(ControlFlowElement), this.getBody()] } override predicate succ(ControlFlowElement pred, ControlFlowElement succ, Completion c) { - last(pattern, pred, c) and + last(this.getPattern(), pred, c) and c.(MatchingCompletion).isMatch() and ( if exists(this.getCondition()) @@ -273,13 +273,13 @@ abstract private class CaseTree extends ControlFlowTree, Case { first(this.getCondition(), succ) else // Flow from last element of pattern to first element of body - first(body, succ) + first(this.getBody(), succ) ) or // Flow from last element of condition to first element of body last(this.getCondition(), pred, c) and c instanceof TrueCompletion and - first(body, succ) + first(this.getBody(), succ) } } @@ -290,7 +290,7 @@ module Expressions { private class SimpleNoNodeExpr extends NoNodeExpr { SimpleNoNodeExpr() { this instanceof TypeAccess and - not this = any(PatternMatch pm).getPattern() + not this instanceof TypeAccessPatternExpr } } @@ -368,10 +368,16 @@ module Expressions { not this instanceof NoNodeExpr and not this instanceof SwitchExpr and not this instanceof SwitchCaseExpr and - not this instanceof ConstructorInitializer + not this instanceof ConstructorInitializer and + not this instanceof NotPatternExpr and + not this instanceof OrPatternExpr and + not this instanceof AndPatternExpr and + not this instanceof RecursivePatternExpr and + not this instanceof PositionalPatternExpr and + not this instanceof PropertyPatternExpr } - final override ControlFlowTree getChildElement(int i) { result = getExprChild(this, i) } + final override ControlFlowElement getChildElement(int i) { result = getExprChild(this, i) } final override predicate first(ControlFlowElement first) { first(this.getFirstChild(), first) @@ -426,13 +432,11 @@ module Expressions { } } + private class StatOrDynAccessorCall_ = + @dynamic_member_access_expr or @dynamic_element_access_expr or @call_access_expr; + /** A normal or a (potential) dynamic call to an accessor. */ - private class StatOrDynAccessorCall extends Expr { - StatOrDynAccessorCall() { - this instanceof AccessorCall or - this instanceof DynamicAccess - } - } + private class StatOrDynAccessorCall extends Expr, StatOrDynAccessorCall_ { } /** * An expression that writes via an accessor call, for example `x.Prop = 0`, @@ -515,138 +519,113 @@ module Expressions { LogicalNotExprTree() { operand = this.getOperand() } - final override predicate propagatesAbnormal(ControlFlowElement child) { - child = this.getOperand() - } + final override predicate propagatesAbnormal(ControlFlowElement child) { child = operand } final override predicate first(ControlFlowElement first) { first(operand, first) } final override predicate succ(ControlFlowElement pred, ControlFlowElement succ, Completion c) { succ = this and - ( - last(operand, pred, c.(BooleanCompletion).getDual()) - or - last(operand, pred, c) and - c instanceof SimpleCompletion - ) + last(operand, pred, c) and + c instanceof NormalCompletion } } private class LogicalAndExprTree extends PostOrderTree, LogicalAndExpr { - private Expr left; - private Expr right; + final override predicate propagatesAbnormal(ControlFlowElement child) { + child in [this.getLeftOperand(), this.getRightOperand()] + } - LogicalAndExprTree() { left = this.getLeftOperand() and right = this.getRightOperand() } - - final override predicate propagatesAbnormal(ControlFlowElement child) { child in [left, right] } - - final override predicate first(ControlFlowElement first) { first(left, first) } + final override predicate first(ControlFlowElement first) { first(this.getLeftOperand(), first) } final override predicate succ(ControlFlowElement pred, ControlFlowElement succ, Completion c) { // Flow from last element of left operand to first element of right operand - last(left, pred, c) and + last(this.getLeftOperand(), pred, c) and c instanceof TrueCompletion and - first(right, succ) + first(this.getRightOperand(), succ) or // Post-order: flow from last element of left operand to element itself - last(left, pred, c) and + last(this.getLeftOperand(), pred, c) and c instanceof FalseCompletion and succ = this or // Post-order: flow from last element of right operand to element itself - last(right, pred, c) and + last(this.getRightOperand(), pred, c) and c instanceof NormalCompletion and succ = this } } private class LogicalOrExprTree extends PostOrderTree, LogicalOrExpr { - private Expr left; - private Expr right; + final override predicate propagatesAbnormal(ControlFlowElement child) { + child in [this.getLeftOperand(), this.getRightOperand()] + } - LogicalOrExprTree() { left = this.getLeftOperand() and right = this.getRightOperand() } - - final override predicate propagatesAbnormal(ControlFlowElement child) { child in [left, right] } - - final override predicate first(ControlFlowElement first) { first(left, first) } + final override predicate first(ControlFlowElement first) { first(this.getLeftOperand(), first) } final override predicate succ(ControlFlowElement pred, ControlFlowElement succ, Completion c) { // Flow from last element of left operand to first element of right operand - last(left, pred, c) and + last(this.getLeftOperand(), pred, c) and c instanceof FalseCompletion and - first(right, succ) + first(this.getRightOperand(), succ) or // Post-order: flow from last element of left operand to element itself - last(left, pred, c) and + last(this.getLeftOperand(), pred, c) and c instanceof TrueCompletion and succ = this or // Post-order: flow from last element of right operand to element itself - last(right, pred, c) and + last(this.getRightOperand(), pred, c) and c instanceof NormalCompletion and succ = this } } private class NullCoalescingExprTree extends PostOrderTree, NullCoalescingExpr { - private Expr left; - private Expr right; + final override predicate propagatesAbnormal(ControlFlowElement child) { + child in [this.getLeftOperand(), this.getRightOperand()] + } - NullCoalescingExprTree() { left = this.getLeftOperand() and right = this.getRightOperand() } - - final override predicate propagatesAbnormal(ControlFlowElement child) { child in [left, right] } - - final override predicate first(ControlFlowElement first) { first(left, first) } + final override predicate first(ControlFlowElement first) { first(this.getLeftOperand(), first) } final override predicate succ(ControlFlowElement pred, ControlFlowElement succ, Completion c) { // Flow from last element of left operand to first element of right operand - last(left, pred, c) and + last(this.getLeftOperand(), pred, c) and c.(NullnessCompletion).isNull() and - first(right, succ) + first(getRightOperand(), succ) or // Post-order: flow from last element of left operand to element itself - last(left, pred, c) and + last(this.getLeftOperand(), pred, c) and succ = this and c instanceof NormalCompletion and not c.(NullnessCompletion).isNull() or // Post-order: flow from last element of right operand to element itself - last(right, pred, c) and + last(getRightOperand(), pred, c) and c instanceof NormalCompletion and succ = this } } private class ConditionalExprTree extends PostOrderTree, ConditionalExpr { - private Expr condition; - private Expr thenBranch; - private Expr elseBranch; - - ConditionalExprTree() { - condition = this.getCondition() and - thenBranch = this.getThen() and - elseBranch = this.getElse() - } - final override predicate propagatesAbnormal(ControlFlowElement child) { - child in [condition, thenBranch, elseBranch] + child in [this.getCondition(), this.getThen(), this.getElse()] } - final override predicate first(ControlFlowElement first) { first(condition, first) } + final override predicate first(ControlFlowElement first) { first(this.getCondition(), first) } final override predicate succ(ControlFlowElement pred, ControlFlowElement succ, Completion c) { // Flow from last element of condition to first element of then branch - last(condition, pred, c) and + last(this.getCondition(), pred, c) and c instanceof TrueCompletion and - first(thenBranch, succ) + first(this.getThen(), succ) or // Flow from last element of condition to first element of else branch - last(condition, pred, c) and + last(this.getCondition(), pred, c) and c instanceof FalseCompletion and - first(elseBranch, succ) + first(this.getElse(), succ) or // Post-order: flow from last element of a branch to element itself - last([thenBranch, elseBranch], pred, c) and + last([this.getThen(), this.getElse()], pred, c) and c instanceof NormalCompletion and succ = this } @@ -664,10 +643,7 @@ module Expressions { final override predicate first(ControlFlowElement first) { first(expanded, first) } - final override predicate last(ControlFlowElement last, Completion c) { - last = expanded and - last(expanded, last, c) - } + final override predicate last(ControlFlowElement last, Completion c) { last(expanded, last, c) } final override predicate propagatesAbnormal(ControlFlowElement child) { none() } @@ -716,16 +692,12 @@ module Expressions { } private class ThrowExprTree extends PostOrderTree, ThrowExpr { - private Expr expr; + final override predicate propagatesAbnormal(ControlFlowElement child) { child = this.getExpr() } - ThrowExprTree() { expr = this.getExpr() } - - final override predicate propagatesAbnormal(ControlFlowElement child) { child = expr } - - final override predicate first(ControlFlowElement first) { first(expr, first) } + final override predicate first(ControlFlowElement first) { first(this.getExpr(), first) } final override predicate succ(ControlFlowElement pred, ControlFlowElement succ, Completion c) { - last(expr, pred, c) and + last(this.getExpr(), pred, c) and c instanceof NormalCompletion and succ = this } @@ -832,7 +804,7 @@ module Expressions { child = this.getACase() } - final override predicate first(ControlFlowElement first) { first(expr, first) } + final override predicate first(ControlFlowElement first) { first(this.getExpr(), first) } final override predicate succ(ControlFlowElement pred, ControlFlowElement succ, Completion c) { SwitchTree.super.succ(pred, succ, c) @@ -844,7 +816,13 @@ module Expressions { } private class SwitchCaseExprTree extends PostOrderTree, CaseTree, SwitchCaseExpr { - final override predicate first(ControlFlowElement first) { first(pattern, first) } + final override predicate first(ControlFlowElement first) { first(this.getPattern(), first) } + + pragma[noinline] + private predicate lastNoMatch(ControlFlowElement last, ConditionalCompletion cc) { + last([this.getPattern(), this.getCondition()], last, cc) and + (cc.(MatchingCompletion).isNonMatch() or cc instanceof FalseCompletion) + } final override predicate last(ControlFlowElement last, Completion c) { PostOrderTree.super.last(last, c) @@ -854,10 +832,10 @@ module Expressions { this = se.getCase(i) and not this.matchesAll() and not exists(se.getCase(i + 1)) and - last([pattern, this.getCondition()], last, cc) and - (cc.(MatchingCompletion).isNonMatch() or cc instanceof FalseCompletion) and + this.lastNoMatch(last, cc) and c = any(NestedCompletion nc | + nc.getNestLevel() = 0 and nc.getInnerCompletion() = cc and nc.getOuterCompletion() .(ThrowCompletion) @@ -870,7 +848,7 @@ module Expressions { final override predicate succ(ControlFlowElement pred, ControlFlowElement succ, Completion c) { CaseTree.super.succ(pred, succ, c) or - last(body, pred, c) and + last(this.getBody(), pred, c) and succ = this and c instanceof NormalCompletion } @@ -924,6 +902,181 @@ module Expressions { ) } } + + private class NotPatternExprTree extends PostOrderTree, NotPatternExpr { + final override predicate propagatesAbnormal(ControlFlowElement child) { + child = this.getPattern() + } + + final override predicate first(ControlFlowElement first) { first(this.getPattern(), first) } + + final override predicate succ(ControlFlowElement pred, ControlFlowElement succ, Completion c) { + succ = this and + last(this.getPattern(), pred, c) and + c instanceof NormalCompletion + } + } + + private class AndPatternExprTree extends PostOrderTree, AndPatternExpr { + final override predicate propagatesAbnormal(ControlFlowElement child) { + child = this.getAnOperand() + } + + final override predicate first(ControlFlowElement first) { first(this.getLeftOperand(), first) } + + final override predicate succ(ControlFlowElement pred, ControlFlowElement succ, Completion c) { + // Flow from last element of left operand to first element of right operand + last(this.getLeftOperand(), pred, c) and + c.(MatchingCompletion).getValue() = true and + first(this.getRightOperand(), succ) + or + // Post-order: flow from last element of left operand to element itself + last(this.getLeftOperand(), pred, c) and + c.(MatchingCompletion).getValue() = false and + succ = this + or + // Post-order: flow from last element of right operand to element itself + last(this.getRightOperand(), pred, c) and + c instanceof MatchingCompletion and + succ = this + } + } + + private class OrPatternExprTree extends PostOrderTree, OrPatternExpr { + final override predicate propagatesAbnormal(ControlFlowElement child) { + child = this.getAnOperand() + } + + final override predicate first(ControlFlowElement first) { first(this.getLeftOperand(), first) } + + final override predicate succ(ControlFlowElement pred, ControlFlowElement succ, Completion c) { + // Flow from last element of left operand to first element of right operand + last(this.getLeftOperand(), pred, c) and + c.(MatchingCompletion).getValue() = false and + first(this.getRightOperand(), succ) + or + // Post-order: flow from last element of left operand to element itself + last(this.getLeftOperand(), pred, c) and + c.(MatchingCompletion).getValue() = true and + succ = this + or + // Post-order: flow from last element of right operand to element itself + last(this.getRightOperand(), pred, c) and + c instanceof MatchingCompletion and + succ = this + } + } +} + +private class RecursivePatternExprTree extends PostOrderTree, RecursivePatternExpr { + private Expr getTypeExpr() { + result = this.getVariableDeclExpr() + or + not exists(this.getVariableDeclExpr()) and + result = this.getTypeAccess() + } + + private PatternExpr getChildPattern() { + result = this.getPositionalPatterns() + or + result = this.getPropertyPatterns() + } + + final override predicate propagatesAbnormal(ControlFlowElement child) { + child = this.getChildPattern() + } + + final override predicate first(ControlFlowElement first) { + first(this.getTypeExpr(), first) + or + not exists(this.getTypeExpr()) and + first(this.getChildPattern(), first) + } + + final override predicate succ(ControlFlowElement pred, ControlFlowElement succ, Completion c) { + // Flow from type test to child pattern + last(this.getTypeExpr(), pred, c) and + first(this.getChildPattern(), succ) and + c.(MatchingCompletion).getValue() = true + or + // Flow from type test to self + last(this.getTypeExpr(), pred, c) and + succ = this and + c.(MatchingCompletion).getValue() = false + or + // Flow from child pattern to self + last(this.getChildPattern(), pred, c) and + succ = this and + c instanceof MatchingCompletion + } +} + +private class PositionalPatternExprTree extends PreOrderTree, PositionalPatternExpr { + final override predicate propagatesAbnormal(ControlFlowElement child) { + child = this.getPattern(_) + } + + final override predicate last(ControlFlowElement last, Completion c) { + last = this and + c.(MatchingCompletion).getValue() = false + or + last(this.getPattern(_), last, c) and + c.(MatchingCompletion).getValue() = false + or + exists(int lst | + last(this.getPattern(lst), last, c) and + not exists(this.getPattern(lst + 1)) + ) + } + + final override predicate succ(ControlFlowElement pred, ControlFlowElement succ, Completion c) { + // Flow from self to first pattern + pred = this and + c.(MatchingCompletion).getValue() = true and + first(this.getPattern(0), succ) + or + // Flow from one pattern to the next + exists(int i | + last(this.getPattern(i), pred, c) and + c.(MatchingCompletion).getValue() = true and + first(this.getPattern(i + 1), succ) + ) + } +} + +private class PropertyPatternExprExprTree extends PostOrderTree, PropertyPatternExpr { + final override predicate propagatesAbnormal(ControlFlowElement child) { + child = this.getPattern(_) + } + + final override predicate first(ControlFlowElement first) { + first(this.getPattern(0), first) + or + not exists(this.getPattern(0)) and + first = this + } + + final override predicate succ(ControlFlowElement pred, ControlFlowElement succ, Completion c) { + // Flow from one pattern to the next + exists(int i | + last(this.getPattern(i), pred, c) and + c.(MatchingCompletion).getValue() = true and + first(this.getPattern(i + 1), succ) + ) + or + // Post-order: flow from last element of failing pattern to element itself + last(this.getPattern(_), pred, c) and + c.(MatchingCompletion).getValue() = false and + succ = this + or + // Post-order: flow from last element of last pattern to element itself + exists(int last | + last(this.getPattern(last), pred, c) and + not exists(this.getPattern(last + 1)) and + c instanceof MatchingCompletion and + succ = this + ) + } } module Statements { @@ -932,18 +1085,18 @@ module Statements { // The following statements need special treatment not this instanceof IfStmt and not this instanceof SwitchStmt and - (this instanceof DefaultCase or not this instanceof CaseStmt) and + not this instanceof CaseStmt and not this instanceof LoopStmt and not this instanceof TryStmt and not this instanceof SpecificCatchClause and - not this instanceof JumpStmt + not this instanceof JumpStmt and + not this instanceof LabeledStmt } private ControlFlowTree getChildElement0(int i) { not this instanceof GeneralCatchClause and not this instanceof FixedStmt and not this instanceof UsingBlockStmt and - not this instanceof DefaultCase and result = this.getChild(i) or this = any(GeneralCatchClause gcc | i = 0 and result = gcc.getBlock()) @@ -966,12 +1119,9 @@ module Statements { result = us.getBody() and i = max([1, count(us.getVariableDeclExpr(_))]) ) - or - result = this.(DefaultCase).getStmt() and - i = 0 } - final override ControlFlowTree getChildElement(int i) { + final override ControlFlowElement getChildElement(int i) { result = rank[i + 1](ControlFlowElement cfe, int j | cfe = this.getChildElement0(j) | cfe order by j) } @@ -994,15 +1144,13 @@ module Statements { } private class IfStmtTree extends PreOrderTree, IfStmt { - private Expr condition; - - IfStmtTree() { condition = this.getCondition() } - - final override predicate propagatesAbnormal(ControlFlowElement child) { child = condition } + final override predicate propagatesAbnormal(ControlFlowElement child) { + child = this.getCondition() + } final override predicate last(ControlFlowElement last, Completion c) { // Condition exits with a false completion and there is no `else` branch - last(condition, last, c) and + last(this.getCondition(), last, c) and c instanceof FalseCompletion and not exists(this.getElse()) or @@ -1016,10 +1164,10 @@ module Statements { final override predicate succ(ControlFlowElement pred, ControlFlowElement succ, Completion c) { // Pre-order: flow from statement itself to first element of condition pred = this and - first(condition, succ) and + first(this.getCondition(), succ) and c instanceof SimpleCompletion or - last(condition, pred, c) and + last(this.getCondition(), pred, c) and ( // Flow from last element of condition to first element of then branch c instanceof TrueCompletion and first(this.getThen(), succ) @@ -1034,7 +1182,7 @@ module Statements { final override predicate last(ControlFlowElement last, Completion c) { // Switch expression exits normally and there are no cases not exists(this.getACase()) and - last(expr, last, c) and + last(this.getExpr(), last, c) and c instanceof NormalCompletion or // A statement exits with a `break` completion @@ -1044,8 +1192,9 @@ module Statements { last(this.getStmt(_), last, c) and not c instanceof BreakCompletion and not c instanceof NormalCompletion and - not getLabledStmt(c.(GotoCompletion).getLabel(), this.getEnclosingCallable()) instanceof - CaseStmt + not any(LabeledStmtTree t | + t.hasLabelInCallable(c.(GotoCompletion).getLabel(), this.getEnclosingCallable()) + ) instanceof CaseStmt or // Last case exits with a non-match exists(CaseStmt cs, int last_ | @@ -1065,7 +1214,7 @@ module Statements { or // Pre-order: flow from statement itself to first switch expression pred = this and - first(expr, succ) and + first(this.getExpr(), succ) and c instanceof SimpleCompletion or // Flow from last element of non-`case` statement `i` to first element of statement `i+1` @@ -1090,27 +1239,23 @@ module Statements { c instanceof FalseCompletion or // Case pattern exits with a non-match - last(pattern, last, c) and + last(this.getPattern(), last, c) and not c.(MatchingCompletion).isMatch() or // Case body exits with any completion - last(body, last, c) + last(this.getBody(), last, c) } final override predicate succ(ControlFlowElement pred, ControlFlowElement succ, Completion c) { CaseTree.super.succ(pred, succ, c) or pred = this and - first(pattern, succ) and + first(this.getPattern(), succ) and c instanceof SimpleCompletion } } abstract private class LoopStmtTree extends PreOrderTree, LoopStmt { - Stmt body; - - LoopStmtTree() { body = this.getBody() } - final override predicate propagatesAbnormal(ControlFlowElement child) { child = this.getCondition() } @@ -1121,10 +1266,10 @@ module Statements { c instanceof FalseCompletion or // Body exits with a break completion - last(body, last, c.(NestedBreakCompletion).getAnInnerCompatibleCompletion()) + last(this.getBody(), last, c.(NestedBreakCompletion).getAnInnerCompatibleCompletion()) or // Body exits with a completion that does not continue the loop - last(body, last, c) and + last(this.getBody(), last, c) and not c instanceof BreakCompletion and not c.continuesLoop() } @@ -1133,11 +1278,11 @@ module Statements { // Flow from last element of condition to first element of loop body last(this.getCondition(), pred, c) and c instanceof TrueCompletion and - first(body, succ) + first(this.getBody(), succ) or // Flow from last element of loop body back to first element of condition not this instanceof ForStmt and - last(body, pred, c) and + last(this.getBody(), pred, c) and c.continuesLoop() and first(this.getCondition(), succ) } @@ -1158,7 +1303,7 @@ module Statements { LoopStmtTree.super.succ(pred, succ, c) or pred = this and - first(body, succ) and + first(this.getBody(), succ) and c instanceof SimpleCompletion } } @@ -1169,7 +1314,7 @@ module Statements { result = this.getCondition() or not exists(this.getCondition()) and - result = body + result = this.getBody() } final override predicate succ(ControlFlowElement pred, ControlFlowElement succ, Completion c) { @@ -1204,11 +1349,11 @@ module Statements { // Flow from last element of condition into first element of loop body last(this.getCondition(), pred, c) and c instanceof TrueCompletion and - first(body, succ) + first(this.getBody(), succ) or // Flow from last element of loop body to first element of update/condition/self exists(ControlFlowElement next | - last(body, pred, c) and + last(this.getBody(), pred, c) and c.continuesLoop() and first(next, succ) and if exists(this.getUpdate(0)) @@ -1300,13 +1445,51 @@ module Statements { last(cc.getBlock(), result, c) } - class TryStmtTree extends PreOrderTree, TryStmt { - ControlFlowTree body; + /** Gets a child of `cfe` that is in CFG scope `scope`. */ + pragma[noinline] + private ControlFlowElement getAChildInScope(ControlFlowElement cfe, Callable scope) { + result = ControlFlowTree::getAChild(cfe) and + scope = result.getEnclosingCallable() + } + class TryStmtTree extends PreOrderTree, TryStmt { final override predicate propagatesAbnormal(ControlFlowElement child) { child = this.getFinally() } + /** + * Gets a descendant that belongs to the `finally` block of this try statement. + */ + ControlFlowElement getAFinallyDescendant() { + result = this.getFinally() + or + exists(ControlFlowElement mid | + mid = this.getAFinallyDescendant() and + result = getAChildInScope(mid, mid.getEnclosingCallable()) and + not exists(TryStmtTree nestedTry | + result = nestedTry.getFinally() and + nestedTry != this + ) + ) + } + + /** + * Holds if `innerTry` has a `finally` block and is immediately nested inside the + * `finally` block of this `try` statement. + */ + private predicate nestedFinally(TryStmtTree innerTry) { + exists(ControlFlowElement innerFinally | + innerFinally = getAChildInScope(this.getAFinallyDescendant(), this.getEnclosingCallable()) and + innerFinally = innerTry.getFinally() + ) + } + + /** + * Gets the `finally`-nesting level of this `try` statement. That is, the number of + * `finally` blocks that this `try` statement is nested under. + */ + int nestLevel() { result = count(TryStmtTree outer | outer.nestedFinally+(this)) } + /** Holds if `last` is a last element of the block of this `try` statement. */ pragma[nomagic] predicate lastBlock(ControlFlowElement last, Completion c) { last(this.getBlock(), last, c) } @@ -1314,26 +1497,30 @@ module Statements { /** * Gets a last element from a `try` or `catch` block of this `try` statement * that may finish with completion `c`, such that control may be transferred - * to the `finally` block (if it exists). + * to the `finally` block (if it exists), but only if `finalizable = true`. */ pragma[nomagic] - ControlFlowElement getBlockOrCatchFinallyPred(Completion c) { - this.lastBlock(result, c) and + ControlFlowElement getAFinallyPredecessor(Completion c, boolean finalizable) { + // Exit completions skip the `finally` block + (if c instanceof ExitCompletion then finalizable = false else finalizable = true) and ( - // Any non-throw completion from the `try` block will always continue directly - // to the `finally` block - not c instanceof ThrowCompletion + this.lastBlock(result, c) and + ( + // Any non-throw completion from the `try` block will always continue directly + // to the `finally` block + not c instanceof ThrowCompletion + or + // Any completion from the `try` block will continue to the `finally` block + // when there are no catch clauses + not exists(this.getACatchClause()) + ) or - // Any completion from the `try` block will continue to the `finally` block - // when there are no catch clauses - not exists(this.getACatchClause()) + // Last element from any of the `catch` clause blocks continues to the `finally` block + result = lastCatchClauseBlock(this.getACatchClause(), c) + or + // Last element of last `catch` clause continues to the `finally` block + result = lastLastCatchClause(this.getACatchClause(), c) ) - or - // Last element from any of the `catch` clause blocks continues to the `finally` block - result = lastCatchClauseBlock(this.getACatchClause(), c) - or - // Last element of last `catch` clause continues to the `finally` block - result = lastLastCatchClause(this.getACatchClause(), c) } pragma[nomagic] @@ -1343,31 +1530,38 @@ module Statements { pragma[nomagic] private predicate lastFinally( - ControlFlowElement last, NormalCompletion finally, Completion outer + ControlFlowElement last, NormalCompletion finally, Completion outer, int nestLevel ) { this.lastFinally0(last, finally) and - exists(this.getBlockOrCatchFinallyPred(any(Completion c0 | outer = c0.getOuterCompletion()))) + exists( + this.getAFinallyPredecessor(any(Completion c0 | outer = c0.getOuterCompletion()), true) + ) and + nestLevel = this.nestLevel() } final override predicate last(ControlFlowElement last, Completion c) { - last = this.getBlockOrCatchFinallyPred(c) and - ( + exists(boolean finalizable | last = this.getAFinallyPredecessor(c, finalizable) | // If there is no `finally` block, last elements are from the body, from // the blocks of one of the `catch` clauses, or from the last `catch` clause not this.hasFinally() or - // Exit completions ignore the `finally` block - c instanceof ExitCompletion + finalizable = false ) or - this.lastFinally(last, c, any(NormalCompletion nc)) + this.lastFinally(last, c, any(NormalCompletion nc), _) or // If the `finally` block completes normally, it inherits any non-normal // completion that was current before the `finally` block was entered - c = - any(NestedCompletion nc | - this.lastFinally(last, nc.getAnInnerCompatibleCompletion(), nc.getOuterCompletion()) - ) + exists(int nestLevel | + c = + any(NestedCompletion nc | + this.lastFinally(last, nc.getAnInnerCompatibleCompletion(), nc.getOuterCompletion(), + nestLevel) and + // unbind + nc.getNestLevel() >= nestLevel and + nc.getNestLevel() <= nestLevel + ) + ) } /** @@ -1390,43 +1584,22 @@ module Statements { first(this.getCatchClause(0), succ) or exists(CatchClause cc, int i | cc = this.getCatchClause(i) | + // Flow from one `catch` clause to the next pred = cc and last(this.getCatchClause(i), cc, c) and - ( - // Flow from one `catch` clause to the next - first(this.getCatchClause(i + 1), succ) and - c = any(MatchingCompletion mc | not mc.isMatch()) - or - // Flow from last `catch` clause to first element of `finally` block - this.getCatchClause(i).isLast() and - first(this.getFinally(), succ) and - c instanceof ThrowCompletion // inherited from `try` block - ) + first(this.getCatchClause(i + 1), succ) and + c = any(MatchingCompletion mc | not mc.isMatch()) or + // Flow from last element of `catch` clause filter to next `catch` clause last(this.getCatchClause(i), pred, c) and last(cc.getFilterClause(), pred, _) and - ( - // Flow from last element of `catch` clause filter to next `catch` clause - first(this.getCatchClause(i + 1), succ) and - c instanceof FalseCompletion - or - // Flow from last element of `catch` clause filter, of last clause, to first - // element of `finally` block - this.getCatchClause(i).isLast() and - first(this.getFinally(), succ) and - c instanceof ThrowCompletion // inherited from `try` block - ) - or - // Flow from last element of a `catch` block to first element of `finally` block - pred = lastCatchClauseBlock(cc, c) and - first(this.getFinally(), succ) + first(this.getCatchClause(i + 1), succ) and + c instanceof FalseCompletion ) or - // Flow from last element of `try` block to first element of `finally` block - this.lastBlock(pred, c) and - first(this.getFinally(), succ) and - not c instanceof ExitCompletion and - (c instanceof ThrowCompletion implies not exists(this.getACatchClause())) + // Flow into `finally` block + pred = getAFinallyPredecessor(c, true) and + first(this.getFinally(), succ) } } @@ -1481,6 +1654,7 @@ module Statements { this.isLast() and c = any(NestedCompletion nc | + nc.getNestLevel() = 0 and this.throwMayBeUncaught(nc.getOuterCompletion().(ThrowCompletion)) and ( // Incompatible exception type: clause itself @@ -1543,6 +1717,51 @@ module Statements { c instanceof NormalCompletion } } + + pragma[nomagic] + private predicate goto(ControlFlowElement cfe, GotoCompletion gc, string label, Callable enclosing) { + last(_, cfe, gc) and + // Special case: when a `goto` happens inside a `try` statement with a + // `finally` block, flow does not go directly to the target, but instead + // to the `finally` block (and from there possibly to the target) + not cfe = any(Statements::TryStmtTree t | t.hasFinally()).getAFinallyPredecessor(_, true) and + label = gc.getLabel() and + enclosing = cfe.getEnclosingCallable() + } + + private class LabeledStmtTree extends PreOrderTree, LabeledStmt { + final override predicate propagatesAbnormal(ControlFlowElement child) { none() } + + final override predicate last(ControlFlowElement last, Completion c) { + if this instanceof DefaultCase + then last(this.getStmt(), last, c) + else ( + not this instanceof CaseStmt and + last = this and + c.isValidFor(this) + ) + } + + pragma[noinline] + predicate hasLabelInCallable(string label, Callable c) { + this.getEnclosingCallable() = c and + label = this.getLabel() + } + + final override predicate succ(ControlFlowElement pred, ControlFlowElement succ, Completion c) { + this instanceof DefaultCase and + pred = this and + first(this.getStmt(), succ) and + c instanceof SimpleCompletion + or + // Flow from element with matching `goto` completion to this statement + exists(string label, Callable enclosing | + goto(pred, c, label, enclosing) and + this.hasLabelInCallable(label, enclosing) and + succ = this + ) + } + } } cached diff --git a/csharp/ql/src/semmle/code/csharp/controlflow/internal/NonReturning.qll b/csharp/ql/src/semmle/code/csharp/controlflow/internal/NonReturning.qll index a3f80938ad8..6d075d031f5 100644 --- a/csharp/ql/src/semmle/code/csharp/controlflow/internal/NonReturning.qll +++ b/csharp/ql/src/semmle/code/csharp/controlflow/internal/NonReturning.qll @@ -45,6 +45,18 @@ private class ThrowingCall extends NonReturningCall { c.getExceptionClass().matchesHandle(ex) and not m.isVirtual() ) + or + this = + any(MethodCall mc | + mc.getTarget() + .hasQualifiedName("System.Runtime.ExceptionServices.ExceptionDispatchInfo", "Throw") and + ( + mc.hasNoArguments() and + c.getExceptionClass() instanceof SystemExceptionClass + or + c.getExceptionClass() = mc.getArgument(0).getType() + ) + ) ) } diff --git a/csharp/ql/src/semmle/code/csharp/controlflow/internal/PreBasicBlocks.qll b/csharp/ql/src/semmle/code/csharp/controlflow/internal/PreBasicBlocks.qll index 54b1aedc568..d1398719c15 100644 --- a/csharp/ql/src/semmle/code/csharp/controlflow/internal/PreBasicBlocks.qll +++ b/csharp/ql/src/semmle/code/csharp/controlflow/internal/PreBasicBlocks.qll @@ -19,7 +19,7 @@ private predicate startsBB(ControlFlowElement cfe) { ( succ(cfe, _, _) or - succExit(cfe, _, _) + scopeLast(_, cfe, _) ) or strictcount(ControlFlowElement pred, Completion c | succ(pred, cfe, c)) > 1 @@ -33,7 +33,7 @@ private predicate startsBB(ControlFlowElement cfe) { i > 1 or i = 1 and - succExit(pred, _, _) + scopeLast(_, pred, _) ) } @@ -47,7 +47,7 @@ private predicate bbIndex(ControlFlowElement bbStart, ControlFlowElement cfe, in private predicate succBB(PreBasicBlock pred, PreBasicBlock succ) { succ = pred.getASuccessor() } -private predicate entryBB(PreBasicBlock bb) { succEntry(_, bb) } +private predicate entryBB(PreBasicBlock bb) { scopeFirst(_, bb) } private predicate bbIDominates(PreBasicBlock dom, PreBasicBlock bb) = idominance(entryBB/1, succBB/2)(_, dom, bb) @@ -100,7 +100,7 @@ class ConditionBlock extends PreBasicBlock { exists(Completion c | c = getConditionalCompletion(_) | succ(this.getLastElement(), _, c) or - succExit(this.getLastElement(), _, c) + scopeLast(_, this.getLastElement(), c) ) } diff --git a/csharp/ql/src/semmle/code/csharp/controlflow/internal/PreSsa.qll b/csharp/ql/src/semmle/code/csharp/controlflow/internal/PreSsa.qll index 1599de3f6b6..8243520aaf1 100644 --- a/csharp/ql/src/semmle/code/csharp/controlflow/internal/PreSsa.qll +++ b/csharp/ql/src/semmle/code/csharp/controlflow/internal/PreSsa.qll @@ -140,7 +140,7 @@ class Definition extends TPreSsaDef { predicate implicitEntryDef(Callable c, PreBasicBlock bb, SimpleAssignable a) { not a instanceof LocalScopeVariable and c = a.getACallable() and - succEntry(c, bb) + scopeFirst(c, bb) } private predicate assignableDefAt( @@ -157,7 +157,7 @@ private predicate assignableDefAt( or def.(ImplicitParameterDefinition).getParameter() = a and exists(Callable c | a = c.getAParameter() | - succEntry(c, bb) and + scopeFirst(c, bb) and i = -1 ) } @@ -169,7 +169,7 @@ private predicate readAt(PreBasicBlock bb, int i, AssignableRead read, SimpleAss pragma[noinline] private predicate exitBlock(PreBasicBlock bb, Callable c) { - succExit(bb.getLastElement(), _, _) and + scopeLast(c, bb.getLastElement(), _) and c = bb.getEnclosingCallable() } diff --git a/csharp/ql/src/semmle/code/csharp/controlflow/internal/Splitting.qll b/csharp/ql/src/semmle/code/csharp/controlflow/internal/Splitting.qll index 55f9ed81f85..c69f313c17b 100644 --- a/csharp/ql/src/semmle/code/csharp/controlflow/internal/Splitting.qll +++ b/csharp/ql/src/semmle/code/csharp/controlflow/internal/Splitting.qll @@ -29,7 +29,7 @@ private module Cached { TInitializerSplitKind() or TConditionalCompletionSplitKind() or TAssertionSplitKind() or - TFinallySplitKind(int nestLevel) { nestLevel = FinallySplitting::nestLevel(_) } or + TFinallySplitKind(int nestLevel) { nestLevel = any(Statements::TryStmtTree t).nestLevel() } or TExceptionHandlerSplitKind() or TBooleanSplitKind(BooleanSplitting::BooleanSplitSubKind kind) { kind.startsSplit(_) } or TLoopSplitKind(LoopSplitting::AnalyzableLoopStmt loop) @@ -43,7 +43,7 @@ private module Cached { success in [false, true] } or TFinallySplit(FinallySplitting::FinallySplitType type, int nestLevel) { - nestLevel = FinallySplitting::nestLevel(_) + nestLevel = any(Statements::TryStmtTree t).nestLevel() } or TExceptionHandlerSplit(ExceptionClass ec) or TBooleanSplit(BooleanSplitting::BooleanSplitSubKind kind, boolean branch) { @@ -173,9 +173,9 @@ abstract class SplitImpl extends Split { * Holds if this split is entered when control passes from `scope` to the entry point * `first`. * - * Invariant: `hasEntryScope(scope, first) implies succEntry(scope, first)`. + * Invariant: `hasEntryScope(scope, first) implies scopeFirst(scope, first)`. */ - abstract predicate hasEntryScope(Callable scope, ControlFlowElement first); + abstract predicate hasEntryScope(CfgScope scope, ControlFlowElement first); /** * Holds if this split is left when control passes from `pred` to `succ` with @@ -189,9 +189,9 @@ abstract class SplitImpl extends Split { * Holds if this split is left when control passes from `last` out of the enclosing * scope `scope` with completion `c`. * - * Invariant: `hasExitScope(last, scope, c) implies succExit(last, scope, c)` + * Invariant: `hasExitScope(last, scope, c) implies scopeLast(scope, last, c)` */ - abstract predicate hasExitScope(ControlFlowElement last, Callable scope, Completion c); + abstract predicate hasExitScope(ControlFlowElement last, CfgScope scope, Completion c); /** * Holds if this split is maintained when control passes from `pred` to `succ` with @@ -364,8 +364,8 @@ module InitializerSplitting { ) } - override predicate hasEntryScope(Callable scope, ControlFlowElement first) { - succEntry(scope, first) and + override predicate hasEntryScope(CfgScope scope, ControlFlowElement first) { + scopeFirst(scope, first) and scope = this.getConstructor() and first = any(InitializedInstanceMember m).getAnInitializerDescendant() } @@ -377,9 +377,9 @@ module InitializerSplitting { succ.getEnclosingCallable() = this.getConstructor() } - override predicate hasExitScope(ControlFlowElement last, Callable scope, Completion c) { + override predicate hasExitScope(ControlFlowElement last, CfgScope scope, Completion c) { this.appliesTo(last) and - succExit(last, scope, c) and + scopeLast(scope, last, c) and scope = this.getConstructor() } @@ -465,10 +465,28 @@ module ConditionalCompletionSplitting { or last(succ.(SwitchCaseExpr).getBody(), pred, c) and completion = c + or + last(succ.(NotPatternExpr).getPattern(), pred, c) and + completion.(MatchingCompletion).getDual() = c + or + last(succ.(IsExpr).getPattern(), pred, c) and + completion.(BooleanCompletion).getValue() = c.(MatchingCompletion).getValue() + or + last(succ.(AndPatternExpr).getAnOperand(), pred, c) and + completion = c + or + last(succ.(OrPatternExpr).getAnOperand(), pred, c) and + completion = c + or + last(succ.(RecursivePatternExpr).getAChildExpr(), pred, c) and + completion = c + or + last(succ.(PropertyPatternExpr).getPattern(_), pred, c) and + completion = c ) } - override predicate hasEntryScope(Callable scope, ControlFlowElement first) { none() } + override predicate hasEntryScope(CfgScope scope, ControlFlowElement first) { none() } override predicate hasExit(ControlFlowElement pred, ControlFlowElement succ, Completion c) { this.appliesTo(pred) and @@ -476,9 +494,9 @@ module ConditionalCompletionSplitting { if c instanceof ConditionalCompletion then completion = c else any() } - override predicate hasExitScope(ControlFlowElement last, Callable scope, Completion c) { + override predicate hasExitScope(ControlFlowElement last, CfgScope scope, Completion c) { this.appliesTo(last) and - succExit(last, scope, c) and + scopeLast(scope, last, c) and if c instanceof ConditionalCompletion then completion = c else any() } @@ -574,7 +592,7 @@ module AssertionSplitting { ) } - override predicate hasEntryScope(Callable scope, ControlFlowElement first) { none() } + override predicate hasEntryScope(CfgScope scope, ControlFlowElement first) { none() } override predicate hasExit(ControlFlowElement pred, ControlFlowElement succ, Completion c) { this.appliesTo(pred) and @@ -589,10 +607,10 @@ module AssertionSplitting { ) } - override predicate hasExitScope(ControlFlowElement last, Callable scope, Completion c) { + override predicate hasExitScope(ControlFlowElement last, CfgScope scope, Completion c) { this.appliesTo(last) and last = a and - succExit(last, scope, c) and + scopeLast(scope, last, c) and ( success = true and c instanceof NormalCompletion @@ -610,12 +628,6 @@ module AssertionSplitting { } } -pragma[noinline] -private ControlFlowElement getAChild(ControlFlowElement cfe, Callable c) { - result = cfe.getAChild() and - c = result.getEnclosingCallable() -} - module FinallySplitting { /** * The type of a split `finally` node. @@ -639,45 +651,14 @@ module FinallySplitting { } } - /** - * Gets a descendant that belongs to the `finally` block of try statement - * `try`. - */ - ControlFlowElement getAFinallyDescendant(TryStmt try) { - result = try.getFinally() - or - exists(ControlFlowElement mid | - mid = getAFinallyDescendant(try) and - result = getAChild(mid, mid.getEnclosingCallable()) and - not exists(TryStmt nestedTry | - result = nestedTry.getFinally() and - nestedTry != try - ) - ) - } - - /** - * Holds if `innerTry` has a `finally` block and is immediately nested inside the - * `finally` block of `outerTry`. - */ - private predicate nestedFinally(TryStmt outerTry, TryStmt innerTry) { - exists(ControlFlowElement innerFinally | - innerFinally = getAChild(getAFinallyDescendant(outerTry), outerTry.getEnclosingCallable()) and - innerFinally = innerTry.getFinally() - ) - } - - /** Gets the nesting level of the `finally` block for `try`. */ - int nestLevel(TryStmt try) { result = strictcount(TryStmt outer | nestedFinally*(outer, try)) } - /** A control flow element that belongs to a `finally` block. */ private class FinallyControlFlowElement extends ControlFlowElement { - private TryStmt try; + private Statements::TryStmtTree try; - FinallyControlFlowElement() { this = getAFinallyDescendant(try) } + FinallyControlFlowElement() { this = try.getAFinallyDescendant() } /** Gets the immediate `try` block that this node belongs to. */ - TryStmt getTryStmt() { result = try } + Statements::TryStmtTree getTryStmt() { result = try } /** Holds if this node is the entry node in the `finally` block it belongs to. */ predicate isEntryNode() { first(try.getFinally(), this) } @@ -685,7 +666,9 @@ module FinallySplitting { /** A control flow element that does not belong to a `finally` block. */ private class NonFinallyControlFlowElement extends ControlFlowElement { - NonFinallyControlFlowElement() { not this = getAFinallyDescendant(_) } + NonFinallyControlFlowElement() { + not this = any(Statements::TryStmtTree t).getAFinallyDescendant() + } } /** @@ -727,7 +710,7 @@ module FinallySplitting { if type instanceof NormalSuccessor then result = "" else - if nestLevel > 1 + if nestLevel > 0 then result = "finally(" + nestLevel + "): " + type.toString() else result = "finally: " + type.toString() } @@ -738,7 +721,7 @@ module FinallySplitting { } int getNextListOrder() { - result = max(int i | i = getListOrder(_) + 1 or i = AssertionSplitting::getNextListOrder()) + result = max([getListOrder(_) + 1, AssertionSplitting::getNextListOrder()]) } private class FinallySplitKind extends SplitKind, TFinallySplitKind { @@ -759,7 +742,7 @@ module FinallySplitting { ControlFlowElement pred, FinallyControlFlowElement succ, int nestLevel, Completion c ) { succ.isEntryNode() and - nestLevel = nestLevel(succ.getTryStmt()) and + nestLevel = succ.getTryStmt().nestLevel() and succ(pred, succ, c) } @@ -771,7 +754,7 @@ module FinallySplitting { this.getType().isSplitForEntryCompletion(c) } - override predicate hasEntryScope(Callable scope, ControlFlowElement first) { none() } + override predicate hasEntryScope(CfgScope scope, ControlFlowElement first) { none() } /** * Holds if this split applies to control flow element `pred`, where `pred` @@ -779,13 +762,15 @@ module FinallySplitting { */ private predicate appliesToPredecessor(ControlFlowElement pred) { this.appliesTo(pred) and - (succ(pred, _, _) or succExit(pred, _, _)) + (succ(pred, _, _) or scopeLast(_, pred, _)) } pragma[noinline] - private predicate exit0(ControlFlowElement pred, TryStmt try, int nestLevel, Completion c) { + private predicate exit0( + ControlFlowElement pred, Statements::TryStmtTree try, int nestLevel, Completion c + ) { this.appliesToPredecessor(pred) and - nestLevel = nestLevel(try) and + nestLevel = try.nestLevel() and last(try, pred, c) } @@ -821,7 +806,7 @@ module FinallySplitting { ) ) or - // If this split is normal, and an outer split can exit based on a inherited + // If this split is normal, and an outer split can exit based on an inherited // completion, we need to exit this split as well. For example, in // // ```csharp @@ -864,8 +849,8 @@ module FinallySplitting { ) } - override predicate hasExitScope(ControlFlowElement last, Callable scope, Completion c) { - succExit(last, scope, c) and + override predicate hasExitScope(ControlFlowElement last, CfgScope scope, Completion c) { + scopeLast(scope, last, c) and ( exit(last, c, _) or @@ -881,10 +866,10 @@ module FinallySplitting { if fcfe.isEntryNode() then // entering a nested `finally` block - nestLevel(fcfe.getTryStmt()) > this.getNestLevel() + fcfe.getTryStmt().nestLevel() > this.getNestLevel() else // staying in the same (possibly nested) `finally` block as `pred` - nestLevel(fcfe.getTryStmt()) >= this.getNestLevel() + fcfe.getTryStmt().nestLevel() >= this.getNestLevel() ) } } @@ -963,7 +948,7 @@ module ExceptionHandlerSplitting { ) } - override predicate hasEntryScope(Callable scope, ControlFlowElement first) { none() } + override predicate hasEntryScope(CfgScope scope, ControlFlowElement first) { none() } /** * Holds if this split applies to catch clause `scc`. The parameter `match` @@ -991,7 +976,7 @@ module ExceptionHandlerSplitting { */ private predicate appliesToPredecessor(ControlFlowElement pred, Completion c) { this.appliesTo(pred) and - (succ(pred, _, c) or succExit(pred, _, c)) and + (succ(pred, _, c) or scopeLast(_, pred, c)) and ( pred instanceof SpecificCatchClause implies @@ -1045,10 +1030,10 @@ module ExceptionHandlerSplitting { ) } - override predicate hasExitScope(ControlFlowElement last, Callable scope, Completion c) { + override predicate hasExitScope(ControlFlowElement last, CfgScope scope, Completion c) { // Exit out from last `catch` clause (no catch clauses match) this.hasLastExit(last, c) and - succExit(last, scope, c) + scopeLast(scope, last, c) } override predicate hasSuccessor(ControlFlowElement pred, ControlFlowElement succ, Completion c) { @@ -1242,8 +1227,7 @@ module BooleanSplitting { } int getNextListOrder() { - result = - max(int i | i = getListOrder(_) + 1 or i = ExceptionHandlerSplitting::getNextListOrder()) + result = max([getListOrder(_) + 1, ExceptionHandlerSplitting::getNextListOrder()]) } private class BooleanSplitKind extends SplitKind, TBooleanSplitKind { @@ -1276,7 +1260,7 @@ module BooleanSplitting { hasEntry0(pred, succ, this.getSubKind(), this.getBranch(), c) } - override predicate hasEntryScope(Callable scope, ControlFlowElement first) { none() } + override predicate hasEntryScope(CfgScope scope, ControlFlowElement first) { none() } private ConditionBlock getACorrelatedCondition(boolean inverted) { this.getSubKind().correlatesConditions(_, result, inverted) @@ -1289,7 +1273,7 @@ module BooleanSplitting { private predicate appliesToBlock(PreBasicBlock bb, Completion c) { this.appliesTo(bb) and exists(ControlFlowElement last | last = bb.getLastElement() | - (succ(last, _, c) or succExit(last, _, c)) and + (succ(last, _, c) or scopeLast(_, last, c)) and // Respect the value recorded in this split for all correlated conditions forall(boolean inverted | bb = this.getACorrelatedCondition(inverted) | c.getInnerCompletion() instanceof BooleanCompletion @@ -1309,10 +1293,10 @@ module BooleanSplitting { ) } - override predicate hasExitScope(ControlFlowElement last, Callable scope, Completion c) { + override predicate hasExitScope(ControlFlowElement last, CfgScope scope, Completion c) { exists(PreBasicBlock bb | this.appliesToBlock(bb, c) | last = bb.getLastElement() and - succExit(last, scope, c) + scopeLast(scope, last, c) ) } @@ -1466,7 +1450,7 @@ module LoopSplitting { } int getNextListOrder() { - result = max(int i | i = getListOrder(_) + 1 or i = BooleanSplitting::getNextListOrder()) + result = max([getListOrder(_) + 1, BooleanSplitting::getNextListOrder()]) } private class LoopSplitKind extends SplitKind, TLoopSplitKind { @@ -1486,7 +1470,7 @@ module LoopSplitting { loop.start(pred, succ, c) } - override predicate hasEntryScope(Callable scope, ControlFlowElement first) { none() } + override predicate hasEntryScope(CfgScope scope, ControlFlowElement first) { none() } /** * Holds if this split applies to control flow element `pred`, where `pred` @@ -1494,7 +1478,7 @@ module LoopSplitting { */ private predicate appliesToPredecessor(ControlFlowElement pred, Completion c) { this.appliesTo(pred) and - (succ(pred, _, c) or succExit(pred, _, c)) and + (succ(pred, _, c) or scopeLast(_, pred, c)) and not loop.pruneLoopCondition(pred, c) } @@ -1503,9 +1487,9 @@ module LoopSplitting { loop.stop(pred, succ, c) } - override predicate hasExitScope(ControlFlowElement last, Callable scope, Completion c) { + override predicate hasExitScope(ControlFlowElement last, CfgScope scope, Completion c) { this.appliesToPredecessor(last, c) and - succExit(last, scope, c) + scopeLast(scope, last, c) } override predicate hasSuccessor(ControlFlowElement pred, ControlFlowElement succ, Completion c) { @@ -1535,10 +1519,10 @@ class Splits extends TSplits { } private predicate succEntrySplitsFromRank( - @top_level_exprorstmt_parent pred, ControlFlowElement succ, Splits splits, int rnk + CfgScope pred, ControlFlowElement succ, Splits splits, int rnk ) { splits = TSplitsNil() and - succEntry(pred, succ) and + scopeFirst(pred, succ) and rnk = 0 or exists(SplitImpl head, Splits tail | succEntrySplitsCons(pred, succ, head, tail, rnk) | @@ -1559,17 +1543,11 @@ private predicate succEntrySplitsCons( * when entering callable `pred`. */ pragma[noinline] -predicate succEntrySplits( - @top_level_exprorstmt_parent pred, ControlFlowElement succ, Splits succSplits, SuccessorType t -) { +predicate succEntrySplits(CfgScope pred, ControlFlowElement succ, Splits succSplits, SuccessorType t) { exists(int rnk | - succEntry(pred, succ) and + scopeFirst(pred, succ) and t instanceof NormalSuccessor and - succEntrySplitsFromRank(pred, succ, succSplits, rnk) and - // Attribute arguments in assemblies are represented as expressions, even though - // they are not from source. We are not interested in constructing a CFG for such - // expressions. - succ.fromSource() + succEntrySplitsFromRank(pred, succ, succSplits, rnk) | rnk = 0 and not any(SplitImpl split).hasEntryScope(pred, succ) @@ -1582,11 +1560,11 @@ predicate succEntrySplits( * Holds if `pred` with splits `predSplits` can exit the enclosing callable * `succ` with type `t`. */ -predicate succExitSplits(ControlFlowElement pred, Splits predSplits, Callable succ, SuccessorType t) { +predicate succExitSplits(ControlFlowElement pred, Splits predSplits, CfgScope succ, SuccessorType t) { exists(Reachability::SameSplitsBlock b, Completion c | pred = b.getAnElement() | b.isReachable(predSplits) and t = c.getAMatchingSuccessorType() and - succExit(pred, succ, c) and + scopeLast(succ, pred, c) and forall(SplitImpl predSplit | predSplit = predSplits.getASplit() | predSplit.hasExitScope(pred, succ, c) ) @@ -1923,7 +1901,7 @@ module Reachability { * That is, `cfe` starts a new block of elements with the same set of splits. */ private predicate startsSplits(ControlFlowElement cfe) { - succEntry(_, cfe) + scopeFirst(_, cfe) or exists(SplitImpl s | s.hasEntry(_, cfe, _) diff --git a/csharp/ql/src/semmle/code/csharp/dataflow/CallContext.qll b/csharp/ql/src/semmle/code/csharp/dataflow/CallContext.qll index b0a6d9d98ed..8be2fc0939f 100755 --- a/csharp/ql/src/semmle/code/csharp/dataflow/CallContext.qll +++ b/csharp/ql/src/semmle/code/csharp/dataflow/CallContext.qll @@ -11,7 +11,8 @@ cached private newtype TCallContext = TEmptyCallContext() or TArgNonDelegateCallContext(Expr arg) { exists(DispatchCall dc | arg = dc.getArgument(_)) } or - TArgDelegateCallContext(DelegateCall dc, int i) { exists(dc.getArgument(i)) } + TArgDelegateCallContext(DelegateCall dc, int i) { exists(dc.getArgument(i)) } or + TArgFunctionPointerCallContext(FunctionPointerCall fptrc, int i) { exists(fptrc.getArgument(i)) } /** * A call context. @@ -60,12 +61,14 @@ class NonDelegateCallArgumentCallContext extends ArgumentCallContext, TArgNonDel override Location getLocation() { result = arg.getLocation() } } -/** An argument of a delegate call. */ -class DelegateCallArgumentCallContext extends ArgumentCallContext, TArgDelegateCallContext { - DelegateCall dc; +/** An argument of a delegate or function pointer call. */ +class DelegateLikeCallArgumentCallContext extends ArgumentCallContext { + DelegateLikeCall dc; int arg; - DelegateCallArgumentCallContext() { this = TArgDelegateCallContext(dc, arg) } + DelegateLikeCallArgumentCallContext() { + this = TArgDelegateCallContext(dc, arg) or this = TArgFunctionPointerCallContext(dc, arg) + } override predicate isArgument(Expr call, int i) { call = dc and @@ -76,3 +79,11 @@ class DelegateCallArgumentCallContext extends ArgumentCallContext, TArgDelegateC override Location getLocation() { result = dc.getArgument(arg).getLocation() } } + +/** An argument of a delegate call. */ +class DelegateCallArgumentCallContext extends DelegateLikeCallArgumentCallContext, + TArgDelegateCallContext { } + +/** An argument of a function pointer call. */ +class FunctionPointerCallArgumentCallContext extends DelegateLikeCallArgumentCallContext, + TArgFunctionPointerCallContext { } diff --git a/csharp/ql/src/semmle/code/csharp/dataflow/Nullness.qll b/csharp/ql/src/semmle/code/csharp/dataflow/Nullness.qll index 33e1b7f24f9..15133668d00 100644 --- a/csharp/ql/src/semmle/code/csharp/dataflow/Nullness.qll +++ b/csharp/ql/src/semmle/code/csharp/dataflow/Nullness.qll @@ -23,6 +23,7 @@ private import internal.CallableReturns private import semmle.code.csharp.commons.Assertions private import semmle.code.csharp.controlflow.Guards as G private import semmle.code.csharp.controlflow.Guards::AbstractValues +private import semmle.code.csharp.dataflow.internal.SsaImpl as SsaImpl private import semmle.code.csharp.frameworks.System private import semmle.code.csharp.frameworks.Test @@ -177,7 +178,7 @@ private predicate defMaybeNull(Ssa::Definition def, string msg, Element reason) exists(G::DereferenceableExpr de | de = def.getARead() | reason = de.getANullCheck(_, true) and msg = "as suggested by $@ null check" and - not de = any(Ssa::PseudoDefinition pdef).getARead() and + not de = any(Ssa::PhiNode phi).getARead() and strictcount(Element e | e = any(Ssa::Definition def0 | de = def0.getARead()).getElement()) = 1 and // Don't use a check as reason if there is a `null` assignment // or argument @@ -205,7 +206,7 @@ private predicate defMaybeNull(Ssa::Definition def, string msg, Element reason) // A variable of nullable type may be null exists(Dereference d | dereferenceAt(_, _, def, d) | d.hasNullableType() and - not def instanceof Ssa::PseudoDefinition and + not def instanceof Ssa::PhiNode and reason = def.getSourceVariable().getAssignable() and msg = "because it has a nullable type" ) @@ -236,13 +237,13 @@ private predicate defNullImpliesStep( Ssa::Definition def1, BasicBlock bb1, Ssa::Definition def2, BasicBlock bb2 ) { exists(Ssa::SourceVariable v | defNullImpliesStep0(v, def1, bb1, bb2) | - def2.(Ssa::PseudoDefinition).getAnInput() = def1 and + def2.(Ssa::PhiNode).getAnInput() = def1 and bb2 = def2.getBasicBlock() or def2 = def1 and - not exists(Ssa::PseudoDefinition def | - def.getSourceVariable() = v and - bb2 = def.getBasicBlock() + not exists(Ssa::PhiNode phi | + phi.getSourceVariable() = v and + bb2 = phi.getBasicBlock() ) ) and not exists(SuccessorTypes::ConditionalSuccessor s, NullValue nv | @@ -426,14 +427,14 @@ module PathGraph { } private Ssa::Definition getAPseudoInput(Ssa::Definition def) { - result = def.(Ssa::PseudoDefinition).getAnInput() + result = def.(Ssa::PhiNode).getAnInput() } // `def.getAnUltimateDefinition()` includes inputs into uncertain // definitions, but we only want inputs into pseudo nodes private Ssa::Definition getAnUltimateDefinition(Ssa::Definition def) { result = getAPseudoInput*(def) and - not result instanceof Ssa::PseudoDefinition + not result instanceof Ssa::PhiNode } /** @@ -446,7 +447,7 @@ private predicate defReaches(Ssa::Definition def, ControlFlow::Node cfn, boolean (always = true or always = false) or exists(ControlFlow::Node mid | defReaches(def, mid, always) | - Ssa::Internal::adjacentReadPairSameVar(_, mid, cfn) and + SsaImpl::adjacentReadPairSameVar(_, mid, cfn) and not mid = any(Dereference d | if always = true diff --git a/csharp/ql/src/semmle/code/csharp/dataflow/SSA.qll b/csharp/ql/src/semmle/code/csharp/dataflow/SSA.qll index 713b8fcb3b5..44307d68e1f 100644 --- a/csharp/ql/src/semmle/code/csharp/dataflow/SSA.qll +++ b/csharp/ql/src/semmle/code/csharp/dataflow/SSA.qll @@ -1,368 +1,14 @@ /** - * Provides classes for working with static single assignment (SSA) form. + * Provides the module `Ssa` for working with static single assignment (SSA) form. */ import csharp +/** + * Provides classes for working with static single assignment (SSA) form. + */ module Ssa { - class BasicBlock = ControlFlow::BasicBlock; - - private module SourceVariableImpl { - private import AssignableDefinitions - - /** A field or a property. */ - class FieldOrProp extends Assignable, Modifiable { - FieldOrProp() { - this instanceof Field - or - this instanceof Property - } - } - - /** An instance field or property. */ - class InstanceFieldOrProp extends FieldOrProp { - InstanceFieldOrProp() { not this.isStatic() } - } - - /** An access to a field or a property. */ - class FieldOrPropAccess extends AssignableAccess, QualifiableExpr { - FieldOrPropAccess() { this.getTarget() instanceof FieldOrProp } - } - - /** An access to a field or a property that reads the underlying value. */ - class FieldOrPropRead extends FieldOrPropAccess, AssignableRead { } - - cached - private module Cached { - cached - newtype TSourceVariable = - TLocalVar(Callable c, LocalScopeVariable v) { - c = v.getCallable() - or - // Local scope variables can be captured - c = v.getAnAccess().getEnclosingCallable() - } or - TPlainFieldOrProp(Callable c, FieldOrProp f) { - exists(FieldOrPropRead fr | isPlainFieldOrPropAccess(fr, f, c)) - } or - TQualifiedFieldOrProp(Callable c, SourceVariable q, InstanceFieldOrProp f) { - exists(FieldOrPropRead fr | isQualifiedFieldOrPropAccess(fr, f, c, q)) - } - - /** Gets an access to source variable `v`. */ - cached - AssignableAccess getAnAccess(SourceVariable v) { - exists(Callable c | - exists(LocalScopeVariable lsv | v = TLocalVar(c, lsv) | - result = lsv.getAnAccess() and - result.getEnclosingCallable() = c - ) - or - exists(FieldOrProp fp | v = TPlainFieldOrProp(c, fp) | - isPlainFieldOrPropAccess(result, fp, c) - ) - or - exists(FieldOrProp fp, SourceVariable q | v = TQualifiedFieldOrProp(c, q, fp) | - isQualifiedFieldOrPropAccess(result, fp, c, q) - ) - ) - } - - cached - AssignableDefinition getADefinition(ExplicitDefinition def) { - exists(TrackedVar tv, AssignableDefinition ad | def = TSsaExplicitDef(tv, ad, _, _) | - result = ad or - result = getASameOutRefDefAfter(tv, ad) - ) - } - } - - import Cached - - /** - * Holds if `fpa` is an access inside callable `c` of `this`-qualified or - * static field or property `fp`. - */ - predicate isPlainFieldOrPropAccess(FieldOrPropAccess fpa, FieldOrProp fp, Callable c) { - fieldOrPropAccessInCallable(fpa, fp, c) and - (ownFieldOrPropAccess(fpa) or fp.isStatic()) - } - - /** - * Holds if `fpa` is an access inside callable `c` of instance field or property - * `fp` with qualifier `q`. - */ - predicate isQualifiedFieldOrPropAccess( - FieldOrPropAccess fpa, InstanceFieldOrProp fp, Callable c, SourceVariable q - ) { - fieldOrPropAccessInCallable(fpa, fp, c) and - fpa.getQualifier() = q.getAnAccess() - } - - /** Holds if `fpa` is an access inside callable `c` of field or property `fp`. */ - private predicate fieldOrPropAccessInCallable(FieldOrPropAccess fpa, FieldOrProp fp, Callable c) { - fp = fpa.getTarget() and - c = fpa.getEnclosingCallable() - } - - /** Holds if `fpa` is an access to an instance field or property of `this`. */ - predicate ownFieldOrPropAccess(FieldOrPropAccess fpa) { - fpa.getQualifier() instanceof ThisAccess - } - - /* - * Liveness analysis to restrict the size of the SSA representation - */ - - /** - * Holds if the `i`th node of basic block `bb` is assignable definition `ad` - * targeting source variable `v`. - */ - predicate variableDefinition(BasicBlock bb, int i, SourceVariable v, AssignableDefinition ad) { - ad = v.getADefinition() and - ad.getAControlFlowNode() = bb.getNode(i) and - // In cases like `(x, x) = (0, 1)`, we discard the first (dead) definition of `x` - not exists(TupleAssignmentDefinition first, TupleAssignmentDefinition second | first = ad | - second.getAssignment() = first.getAssignment() and - second.getEvaluationOrder() > first.getEvaluationOrder() and - second = v.getADefinition() - ) and - // In cases like `M(out x, out x)`, there is no inherent evaluation order, so we - // collapse the two definitions of `x`, using the first access as the representative, - // and expose both definitions in `ExplicitDefinition.getADefinition()` - not ad = getASameOutRefDefAfter(v, _) - } - - /** - * Gets an `out`/`ref` definition of the same source variable as the `out`/`ref` - * definition `def`, belonging to the same call, at a position after `def`. - */ - OutRefDefinition getASameOutRefDefAfter(SourceVariable v, OutRefDefinition def) { - def = v.getADefinition() and - result.getCall() = def.getCall() and - result.getIndex() > def.getIndex() and - result = v.getADefinition() - } - - /** - * Holds if the `i`th node of basic block `bb` is a (potential) write to source - * variable `v`. The Boolean `certain` indicates whether the write is certain. - */ - private predicate variableWrite(BasicBlock bb, int i, SourceVariable v, boolean certain) { - exists(AssignableDefinition ad | variableDefinition(bb, i, v, ad) | - if - any(AssignableDefinition ad0 | ad0 = ad or ad0 = getASameOutRefDefAfter(v, ad)) - .isCertain() - then certain = true - else certain = false - ) - or - variableWrite(bb, i, v.(QualifiedFieldOrPropSourceVariable).getQualifier(), certain) - } - - /** - * A classification of variable reads. - */ - newtype ReadKind = - /** An actual read. */ - ActualRead() or - /** - * A pseudo read for a `ref` or `out` variable at the end of the variable's enclosing - * callable. A pseudo read is inserted to make assignments to `out`/`ref` variables - * live, for example line 1 in - * - * ```csharp - * void M(out int i) { - * i = 0; - * } - * ``` - */ - OutRefExitRead() or - /** - * A pseudo read for a captured variable at the end of the capturing - * callable. A write to a captured variable needs to be live for the same reasons - * as a write to a `ref` or `out` variable (see above). - */ - CapturedVarExitRead() or - /** - * A pseudo read for a `ref` variable, just prior to an update of the referenced value. - * A pseudo read is inserted to make assignments to the `ref` variable live, for example - * line 2 in - * - * ```csharp - * void M() { - * ref int i = ref GetRef(); - * i = 0; - * } - * ``` - * - * The pseudo read is inserted at the CFG node `i` on the left-hand side of the - * assignment on line 3. - */ - RefReadBeforeWrite() - - /** - * Holds if the `i`th node `node` of basic block `bb` reads source variable `v`. - * The read at `node` is of kind `rk`. - */ - predicate variableRead( - BasicBlock bb, int i, SourceVariable v, ControlFlow::Node node, ReadKind rk - ) { - v.getAnAccess().(AssignableRead) = node.getElement() and - node = bb.getNode(i) and - rk = ActualRead() - or - outRefExitRead(bb, i, v, node) and - rk = OutRefExitRead() - or - capturedVarExitRead(bb, i, v, node) and - rk = CapturedVarExitRead() - or - refReadBeforeWrite(bb, i, v, node) and - rk = RefReadBeforeWrite() - } - - private predicate outRefExitRead( - ControlFlow::BasicBlocks::ExitBlock ebb, int i, LocalScopeSourceVariable v, - ControlFlow::Nodes::ExitNode node - ) { - exists(LocalScopeVariable lsv | - lsv = v.getAssignable() and - ebb.getNode(i) = node and - node.getCallable() = lsv.getCallable() - | - lsv.isRef() or lsv.(Parameter).isOut() - ) - } - - private predicate capturedVarExitRead( - ControlFlow::BasicBlocks::ExitBlock ebb, int i, LocalScopeSourceVariable v, - ControlFlow::Nodes::ExitNode node - ) { - exists(BasicBlock bb | variableDefinition(bb, _, v, _) | - ebb.getNode(i) = node and - bb.getCallable() = ebb.getCallable() and - bb.getCallable() != v.getAssignable().getCallable() - ) - } - - private predicate refReadBeforeWrite( - BasicBlock bb, int i, LocalScopeSourceVariable v, ControlFlow::Node node - ) { - exists(AssignableDefinitions::AssignmentDefinition def, LocalVariable lv | - def.getTarget() = lv and - lv.isRef() and - lv = v.getAssignable() and - node = def.getAControlFlowNode().getAPredecessor() and - bb.getNode(i) = node - ) - } - - /** - * A classification of variable references into reads (of a given kind) and - * (certain or uncertain) writes. - */ - newtype RefKind = - Read(ReadKind rk) or - Write(boolean certain) { certain = true or certain = false } - - /** - * Holds if the `i`th node of basic block `bb` is a reference to `v`, either a read - * (when `k` is `Read()`) or a write (when `k` is `UncertainWrite()` or `Write()`). - */ - predicate ref(BasicBlock bb, int i, SourceVariable v, RefKind k) { - exists(ReadKind rk | variableRead(bb, i, v, _, rk) | k = Read(rk)) - or - exists(boolean certain | variableWrite(bb, i, v, certain) | k = Write(certain)) - } - - /** - * Gets the (1-based) rank of the reference to `v` at the `i`th node of basic block `bb`, - * which has the given reference kind `k`. - */ - int refRank(BasicBlock bb, int i, SourceVariable v, RefKind k) { - i = rank[result](int j | ref(bb, j, v, _)) and - ref(bb, i, v, k) - } - - private int maxRefRank(BasicBlock bb, SourceVariable v) { - result = refRank(bb, _, v, _) and - not result + 1 = refRank(bb, _, v, _) - } - - /** - * Gets the (1-based) rank of the first reference to `v` inside basic block `bb` - * that is either a read or a certain write. - */ - private int firstReadOrCertainWrite(BasicBlock bb, SourceVariable v) { - result = - min(int r, RefKind k | - r = refRank(bb, _, v, k) and - k != Write(false) - | - r - ) - } - - /** - * Holds if source variable `v` is live at the beginning of basic block `bb`. - * The read that witnesses the liveness of `v` is of kind `rk`. - */ - predicate liveAtEntry(BasicBlock bb, SourceVariable v, ReadKind rk) { - // The first read or certain write to `v` inside `bb` is a read - refRank(bb, _, v, Read(rk)) = firstReadOrCertainWrite(bb, v) - or - // There is no certain write to `v` inside `bb`, but `v` is live at entry - // to a successor basic block of `bb` - not exists(firstReadOrCertainWrite(bb, v)) and - liveAtExit(bb, v, rk) - } - - /** - * Holds if source variable `v` is live at the end of basic block `bb`. - * The read that witnesses the liveness of `v` is of kind `rk`. - */ - predicate liveAtExit(BasicBlock bb, SourceVariable v, ReadKind rk) { - liveAtEntry(bb.getASuccessor(), v, rk) - } - - /** - * Holds if source variable `v` is likely to be live at any node inside basic - * block `bb`. This is an overestimate. - */ - predicate possiblyLiveAtAllNodes(BasicBlock bb, SourceVariable v) { - liveAtExit(bb, v, _) - or - ref(bb, _, v, Read(_)) - } - - /** - * Holds if variable `v` is live in basic block `bb` at index `i`. - * The rank of `i` is `rnk` as defined by `refRank()`. - */ - predicate liveAtRank(BasicBlock bb, int i, SourceVariable v, int rnk, ReadKind rk) { - rnk = refRank(bb, i, v, _) and - ( - rnk = maxRefRank(bb, v) and - liveAtExit(bb, v, rk) - or - ref(bb, i, v, Read(rk)) - or - exists(int j | liveAtRank(bb, j, v, rnk + 1, rk) | not ref(bb, j, v, Write(true))) - ) - } - - /** - * Holds if variable `v` is live after the (certain or uncertain) write at - * index `i` inside basic block `bb`. The read that witnesses the liveness of - * `v` is of kind `rk`. - */ - predicate liveAfterWrite(BasicBlock bb, int i, SourceVariable v, ReadKind rk) { - exists(int rnk | rnk = refRank(bb, i, v, Write(_)) | liveAtRank(bb, i, v, rnk, rk)) - } - } - - private import SourceVariableImpl + private import internal.SsaImpl as SsaImpl /** * A variable that can be SSA converted. @@ -372,7 +18,7 @@ module Ssa { * `q.fp1.fp2....fpn`, where the base qualifier `q` is either `this`, a local * scope variable, or a type in case `fp1` is static. */ - class SourceVariable extends TSourceVariable { + class SourceVariable extends SsaImpl::TSourceVariable { /** * Gets the assignable corresponding to this source variable. Either * a local scope variable, a field, or a property. @@ -380,7 +26,7 @@ module Ssa { Assignable getAssignable() { none() } /** Gets an access to this source variable. */ - AssignableAccess getAnAccess() { result = getAnAccess(this) } + AssignableAccess getAnAccess() { result = SsaImpl::getAnAccess(this) } /** Gets a definition of this source variable. */ AssignableDefinition getADefinition() { @@ -389,7 +35,7 @@ module Ssa { // Local variable declaration without initializer not exists(result.getTargetAccess()) and this = - any(LocalScopeSourceVariable v | + any(SourceVariables::LocalScopeSourceVariable v | result.getTarget() = v.getAssignable() and result.getEnclosingCallable() = v.getEnclosingCallable() ) @@ -425,10 +71,10 @@ module Ssa { /** Provides different types of `SourceVariable`s. */ module SourceVariables { /** A local scope variable. */ - class LocalScopeSourceVariable extends SourceVariable, TLocalVar { - override LocalScopeVariable getAssignable() { this = TLocalVar(_, result) } + class LocalScopeSourceVariable extends SourceVariable, SsaImpl::TLocalVar { + override LocalScopeVariable getAssignable() { this = SsaImpl::TLocalVar(_, result) } - override Callable getEnclosingCallable() { this = TLocalVar(result, _) } + override Callable getEnclosingCallable() { this = SsaImpl::TLocalVar(result, _) } override string toString() { result = getAssignable().getName() } @@ -438,20 +84,20 @@ module Ssa { /** A fully qualified field or property. */ class FieldOrPropSourceVariable extends SourceVariable { FieldOrPropSourceVariable() { - this = TPlainFieldOrProp(_, _) or - this = TQualifiedFieldOrProp(_, _, _) + this = SsaImpl::TPlainFieldOrProp(_, _) or + this = SsaImpl::TQualifiedFieldOrProp(_, _, _) } - override FieldOrProp getAssignable() { - this = TPlainFieldOrProp(_, result) or - this = TQualifiedFieldOrProp(_, _, result) + override Assignable getAssignable() { + this = SsaImpl::TPlainFieldOrProp(_, result) or + this = SsaImpl::TQualifiedFieldOrProp(_, _, result) } /** * Gets the first access to this field or property in terms of source * code location. This is used as the representative location. */ - private FieldOrPropAccess getFirstAccess() { + private AssignableAccess getFirstAccess() { result = min(this.getAnAccess() as a order by @@ -460,1549 +106,41 @@ module Ssa { } override Location getLocation() { result = getFirstAccess().getLocation() } - - /** - * Holds if the this field or any of the fields part of the qualifier - * are volatile. - */ - predicate isVolatile() { - this.getAssignable().(Field).isVolatile() or - this.getQualifier().(FieldOrPropSourceVariable).isVolatile() - } } /** A plain field or property. */ - class PlainFieldOrPropSourceVariable extends FieldOrPropSourceVariable, TPlainFieldOrProp { - override Callable getEnclosingCallable() { this = TPlainFieldOrProp(result, _) } + class PlainFieldOrPropSourceVariable extends FieldOrPropSourceVariable, + SsaImpl::TPlainFieldOrProp { + override Callable getEnclosingCallable() { this = SsaImpl::TPlainFieldOrProp(result, _) } override string toString() { - exists(FieldOrProp f, string prefix | + exists(Assignable f, string prefix | f = getAssignable() and result = prefix + "." + getAssignable() | - if f.isStatic() then prefix = f.getDeclaringType().getQualifiedName() else prefix = "this" + if f.(Modifiable).isStatic() + then prefix = f.getDeclaringType().getQualifiedName() + else prefix = "this" ) } } /** A qualified field or property. */ class QualifiedFieldOrPropSourceVariable extends FieldOrPropSourceVariable, - TQualifiedFieldOrProp { - override Callable getEnclosingCallable() { this = TQualifiedFieldOrProp(result, _, _) } + SsaImpl::TQualifiedFieldOrProp { + override Callable getEnclosingCallable() { + this = SsaImpl::TQualifiedFieldOrProp(result, _, _) + } - override SourceVariable getQualifier() { this = TQualifiedFieldOrProp(_, result, _) } + override SourceVariable getQualifier() { this = SsaImpl::TQualifiedFieldOrProp(_, result, _) } override string toString() { result = getQualifier() + "." + getAssignable() } } } - private import SourceVariables - - private module TrackedVariablesImpl { - /** Gets the number of accesses of field or property `fp`. */ - private int numberOfAccesses(FieldOrPropSourceVariable fp) { - result = strictcount(fp.getAnAccess()) - } - - /** Holds if field or property `fp` is accessed inside a loop. */ - private predicate loopAccessed(FieldOrPropSourceVariable fp) { - exists(FieldOrPropRead fpr | - fpr = fp.getAnAccess() and - fpr.getAControlFlowNode().getBasicBlock().inLoop() - ) - } - - /** Holds if field or property `fp` is accessed more than once or inside a loop. */ - private predicate multiAccessed(FieldOrPropSourceVariable fp) { - loopAccessed(fp) or 1 < numberOfAccesses(fp) - } - - /** - * Holds if `fp` is a field or a property that is interesting as a basis for SSA. - * - * - A field or property that is read twice is interesting as we want to know whether - * the reads refer to the same value. - * - A field or property that is both written and read is interesting as we want to - * know whether the read might get the written value. - * - A field or property that is read in a loop is interesting as we want to know whether - * the value is the same in different iterations (that is, whether the SSA - * definition can be placed outside the loop). - * - A volatile field is never interesting, since all reads must reread from - * memory and we are forced to assume that the value can change at any point. - * - A property is only interesting if it is "field-like", that is, it is a - * non-overridable trivial property. - */ - predicate trackFieldOrProp(FieldOrPropSourceVariable fp) { - multiAccessed(fp) and - not fp.isVolatile() and - exists(Assignable a | a = fp.getAssignable() | - a instanceof Field - or - a = any(TrivialProperty p | not p.isOverridableOrImplementable()) - ) - } - } - - private import TrackedVariablesImpl - - /** - * A source variable that gets a non-trivial SSA construction. - */ - private class TrackedVar extends SourceVariable { - TrackedVar() { - this instanceof LocalScopeSourceVariable or - trackFieldOrProp(this) - } - } - - /** - * A field or property that gets a non-trivial SSA construction. - */ - private class TrackedFieldOrProp extends TrackedVar, FieldOrPropSourceVariable { } - - /** - * A source variable that gets a trivial SSA construction, that is a - * definition prior to every read. - */ - private class UntrackedVar extends SourceVariable { - UntrackedVar() { not this instanceof TrackedVar } - } - - private module SsaDefReaches { - /** A non-trivial SSA definition. */ - private class TrackedDefinition extends Definition { - TrackedDefinition() { - // Same as `not this instanceof ImplicitUntrackedDefinition` but - // avoids negative recursion - this instanceof ExplicitDefinition or - this instanceof ImplicitEntryDefinition or - this instanceof ImplicitCallDefinition or - this instanceof ImplicitQualifierDefinition or - this instanceof PseudoDefinition - } - } - - /** - * A classification of SSA variable references into reads and non-trivial - * SSA definitions. - */ - private newtype SsaRefKind = - SsaRead() or - SsaDef() - - /** - * Holds if the `i`th node of basic block `bb` is a reference to `v`, - * either a read (when `k` is `Read()`) or a non-trivial SSA definition - * (when `k` is `SsaDef()`). - */ - private predicate ssaRef(BasicBlock bb, int i, SourceVariable v, SsaRefKind k) { - exists(ReadKind rk | variableRead(bb, i, v, _, rk) | - not rk instanceof RefReadBeforeWrite and - k = SsaRead() - ) - or - exists(TrackedDefinition def | definesAt(def, bb, i, v)) and - k = SsaDef() - } - - /** - * Gets the (1-based) rank of the reference to `v` at the `i`th node of basic - * block `bb`, which has the given reference kind `k`. - * - * For example, if `bb` is a basic block with a phi node for `v` (considered - * to be at index -1), reads `v` at node 2, and defines it at node 5, we have: - * - * ```ql - * ssaRefRank(bb, -1, v, SsaDef()) = 1 // phi node - * ssaRefRank(bb, 2, v, Read()) = 2 // read at node 2 - * ssaRefRank(bb, 5, v, SsaDef()) = 3 // definition at node 5 - * ``` - */ - private int ssaRefRank(BasicBlock bb, int i, SourceVariable v, SsaRefKind k) { - i = rank[result](int j | ssaRef(bb, j, v, _)) and - ssaRef(bb, i, v, k) - } - - private int maxSsaRefRank(BasicBlock bb, SourceVariable v) { - result = ssaRefRank(bb, _, v, _) and - not result + 1 = ssaRefRank(bb, _, v, _) - } - - /** - * Holds if the non-trivial SSA definition `def` reaches rank index `rankix` - * in its own basic block `bb`. - */ - private predicate ssaDefReachesRank( - BasicBlock bb, TrackedDefinition def, int rankix, TrackedVar v - ) { - exists(int i | - rankix = ssaRefRank(bb, i, v, SsaDef()) and - definesAt(def, bb, i, v) - ) - or - ssaDefReachesRank(bb, def, rankix - 1, v) and - rankix = ssaRefRank(bb, _, v, SsaRead()) - } - - /** - * Holds if the non-trivial SSA definition of `v` at `def` reaches `read` in the - * same basic block without crossing another SSA definition of `v`. - * The read at `node` is of kind `rk`. - */ - private predicate ssaDefReachesReadWithinBlock( - TrackedVar v, TrackedDefinition def, ControlFlow::Node read, ReadKind rk - ) { - exists(BasicBlock bb, int rankix, int i | - ssaDefReachesRank(bb, def, rankix, v) and - rankix = ssaRefRank(bb, i, v, SsaRead()) and - variableRead(bb, i, v, read, rk) - ) - } - - /** - * Holds if the non-trivial SSA definition of `v` at `def` reaches uncertain SSA - * definition `redef` in the same basic block, without crossing another SSA - * definition of `v`. - */ - private predicate ssaDefReachesUncertainDefWithinBlock( - TrackedVar v, TrackedDefinition def, UncertainDefinition redef - ) { - exists(BasicBlock bb, int rankix, int i | - ssaDefReachesRank(bb, def, rankix, v) and - rankix = ssaRefRank(bb, i, v, SsaDef()) - 1 and - definesAt(redef, bb, i, v) - ) - } - - /** - * Same as `ssaRefRank()`, but restricted to actual reads of `def`, or - * `def` itself. - */ - private int ssaDefRank(TrackedDefinition def, TrackedVar v, BasicBlock bb, int i) { - v = def.getSourceVariable() and - result = ssaRefRank(bb, i, v, _) and - ( - ssaDefReachesRead(_, def, bb.getNode(i), ActualRead()) - or - definesAt(def, bb, i, _) - ) - } - - private int maxSsaDefRefRank(BasicBlock bb, TrackedVar v) { - result = ssaDefRank(_, v, bb, _) and - not result + 1 = ssaDefRank(_, v, bb, _) - } - - private predicate varOccursInBlock(TrackedDefinition def, BasicBlock bb, TrackedVar v) { - exists(ssaDefRank(def, v, bb, _)) - } - - pragma[noinline] - private BasicBlock getAMaybeLiveSuccessor(Definition def, BasicBlock bb) { - result = bb.getASuccessor() and - not varOccursInBlock(_, bb, def.getSourceVariable()) and - ssaDefReachesEndOfBlock(bb, def, _) - } - - /** - * Holds if `def` is accessed in basic block `bb1` (either a read or a write), - * `bb2` is a transitive successor of `bb1`, `def` is live at the end of `bb1`, - * and the underlying variable for `def` is neither read nor written in any block - * on the path between `bb1` and `bb2`. - */ - private predicate varBlockReaches(TrackedDefinition def, BasicBlock bb1, BasicBlock bb2) { - varOccursInBlock(def, bb1, _) and - bb2 = bb1.getASuccessor() - or - exists(BasicBlock mid | varBlockReaches(def, bb1, mid) | - bb2 = getAMaybeLiveSuccessor(def, mid) - ) - } - - /** - * Holds if `def` is accessed in basic block `bb1` (either a read or a write), - * `def` is read at `cfn`, `cfn` is in a transitive successor block of `bb1`, - * and `def` is not read in any block on the path between `bb1` and `cfn`. - */ - private predicate varBlockReachesRead( - TrackedDefinition def, BasicBlock bb1, ControlFlow::Node cfn - ) { - exists(BasicBlock bb2, int i2 | - varBlockReaches(def, bb1, bb2) and - ssaRefRank(bb2, i2, def.getSourceVariable(), SsaRead()) = 1 and - variableRead(bb2, i2, _, cfn, _) - ) - } - - /** - * Holds if `def` is accessed at index `i1` in basic block `bb1` (either a read - * or a write), `def` is read at `cfn`, and there is a path between them without - * any read of `def`. - */ - private predicate adjacentVarRead( - TrackedDefinition def, BasicBlock bb1, int i1, ControlFlow::Node cfn - ) { - exists(int rankix, int i2 | - rankix = ssaDefRank(def, _, bb1, i1) and - rankix + 1 = ssaDefRank(def, _, bb1, i2) and - variableRead(bb1, i2, _, cfn, _) - ) - or - exists(SourceVariable v | ssaDefRank(def, v, bb1, i1) = maxSsaDefRefRank(bb1, v)) and - varBlockReachesRead(def, bb1, cfn) - } - - cached - private module Cached { - /** - * Holds if `cfn` is a last read of the non-trivial SSA definition `def`. - * That is, `cfn` can reach the end of the enclosing callable, or another - * SSA definition for the underlying source variable, without passing through - * another read. - */ - cached - predicate lastRead(TrackedDefinition def, ControlFlow::Node cfn) { - exists(BasicBlock bb1, int i1, int rnk, TrackedVar v | - variableRead(bb1, i1, v, cfn, _) and - rnk = ssaDefRank(def, v, bb1, i1) - | - // Next reference to `v` inside `bb1` is a write - rnk + 1 = ssaRefRank(bb1, _, v, SsaDef()) - or - // No more references to `v` inside `bb1` - rnk = maxSsaDefRefRank(bb1, def.getSourceVariable()) and - ( - // Can reach exit directly - bb1 instanceof ControlFlow::BasicBlocks::ExitBlock - or - exists(BasicBlock bb2 | varBlockReaches(def, bb1, bb2) | - // Can reach a write using one or more steps - 1 = ssaRefRank(bb2, _, def.getSourceVariable(), SsaDef()) - or - // Can reach a block using one or more steps, where `def` is no longer live - not varOccursInBlock(def, bb2, _) and - not ssaDefReachesEndOfBlock(bb2, def, _) - ) - ) - ) - } - - pragma[noinline] - private predicate ssaDefReachesEndOfBlockRec( - BasicBlock bb, TrackedDefinition def, TrackedVar v - ) { - exists(BasicBlock idom | ssaDefReachesEndOfBlock(idom, def, v) | - // The construction of SSA form ensures that each read of a variable is - // dominated by its definition. An SSA definition therefore reaches a - // control flow node if it is the _closest_ SSA definition that dominates - // the node. If two definitions dominate a node then one must dominate the - // other, so therefore the definition of _closest_ is given by the dominator - // tree. Thus, reaching definitions can be calculated in terms of dominance. - idom = bb.getImmediateDominator() - ) - } - - /** - * Holds if the non-trivial SSA definition of `v` at `def` reaches the end of a - * basic block `bb`, at which point it is still live, without crossing another - * SSA definition of `v`. - */ - cached - predicate ssaDefReachesEndOfBlock(BasicBlock bb, TrackedDefinition def, TrackedVar v) { - exists(int last | last = maxSsaRefRank(bb, v) | - ssaDefReachesRank(bb, def, last, v) and - liveAtExit(bb, v, _) - ) - or - ssaDefReachesEndOfBlockRec(bb, def, v) and - liveAtExit(bb, v, _) and - not ssaRef(bb, _, v, SsaDef()) - } - - /** - * Holds if the non-trivial SSA definition of `v` at `def` reaches `read` without - * crossing another SSA definition of `v`. - * The read at `node` is of kind `rk`. - */ - cached - predicate ssaDefReachesRead( - TrackedVar v, TrackedDefinition def, ControlFlow::Node read, ReadKind rk - ) { - ssaDefReachesReadWithinBlock(v, def, read, rk) - or - exists(BasicBlock bb | - variableRead(bb, _, v, read, rk) and - ssaDefReachesEndOfBlock(bb.getAPredecessor(), def, v) and - not ssaDefReachesReadWithinBlock(v, _, read, _) - ) - } - - /** - * Holds if the non-trivial SSA definition of `v` at `def` reaches uncertain SSA - * definition `redef` without crossing another SSA definition of `v`. - */ - cached - predicate ssaDefReachesUncertainDef( - TrackedVar v, TrackedDefinition def, UncertainDefinition redef - ) { - ssaDefReachesUncertainDefWithinBlock(v, def, redef) - or - exists(BasicBlock bb | - definesAt(redef, bb, _, v) and - ssaDefReachesEndOfBlock(bb.getAPredecessor(), def, v) and - not ssaDefReachesUncertainDefWithinBlock(v, _, redef) - ) - } - - /** - * Holds if the value defined at non-trivial SSA definition `def` can reach a - * read at `cfn`, without passing through any other read. - */ - cached - predicate firstReadSameVar(TrackedDefinition def, ControlFlow::Node cfn) { - exists(BasicBlock bb1, int i1 | - definesAt(def, bb1, i1, _) and - adjacentVarRead(def, bb1, i1, cfn) - ) - } - - /** - * Holds if the read at `cfn2` is a read of the same SSA definition `def` - * as the read at `cfn1`, and `cfn2` can be reached from `cfn1` without - * passing through another read. - */ - cached - predicate adjacentReadPairSameVar( - TrackedDefinition def, ControlFlow::Node cfn1, ControlFlow::Node cfn2 - ) { - exists(BasicBlock bb1, int i1 | - variableRead(bb1, i1, _, cfn1, _) and - adjacentVarRead(def, bb1, i1, cfn2) - ) - } - } - - import Cached - } - - private import SsaDefReaches - - /** - * The SSA construction for a field or a property `fp` relies on implicit - * update nodes at every call site that conceivably could reach an update - * of the field or property. For example, there is an implicit update of - * `this.Field` on line 7 in - * - * ```csharp - * int Field; - * - * void SetField(int i) { Field = i; } - * - * int M() { - * Field = 0; - * SetField(1); // implicit update of `this.Field` - * return Field; - * } - * ``` - * - * At a first approximation, we need to find update paths of the form: - * - * ``` - * Call --(callEdge)-->* Callable(setter of fp) - * ``` - * - * This can be improved by excluding paths ending in: - * - * ``` - * Constructor --(intraInstanceCallEdge)-->+ Callable(setter of this.fp) - * ``` - * - * as these updates are guaranteed not to alias with the `fp` under - * consideration. - * - * This set of paths can be expressed positively by noting that those - * that set `this.fp`, end in zero or more `intraInstanceCallEdge`s between - * callables, and before those is either the originating `Call`: - * - * ``` - * Call --(intraInstanceCallEdge)-->* Callable(setter of this.fp) - * ``` - * - * or a `crossInstanceCallEdge`: - * - * ``` - * Call --crossInstanceCallEdge--> Callable - * --(intraInstanceCallEdge)-->* Callable(setter of this.fp) - * ``` - */ - private module FieldOrPropsImpl { - private import semmle.code.csharp.dispatch.Dispatch - - /** - * A callable that is neither static nor a constructor. - */ - private class InstanceCallable extends Callable { - InstanceCallable() { - not this.(Modifiable).isStatic() and - not this instanceof Constructor - } - } - - private class FieldOrPropDefinition extends AssignableDefinition { - FieldOrPropDefinition() { this.getTarget() instanceof FieldOrProp } - } - - /** - * Holds if `fpdef` is a definition that is not relevant as an implicit - * SSA update, since it is an initialization and therefore cannot alias. - */ - private predicate init(FieldOrPropDefinition fpdef) { - exists(FieldOrPropAccess access | access = fpdef.getTargetAccess() | - fpdef.getEnclosingCallable() instanceof Constructor and - ownFieldOrPropAccess(access) - or - exists(LocalVariable v | - v.getAnAccess() = access.getQualifier() and - not v.isCaptured() and - forex(AssignableDefinition def | def.getTarget() = v and exists(def.getSource()) | - def.getSource() instanceof ObjectCreation - ) - ) - ) - or - fpdef.(AssignableDefinitions::AssignmentDefinition).getAssignment() instanceof - MemberInitializer - } - - /** - * Holds if `fpdef` is an update of `fp` in `c` that is relevant for SSA construction. - */ - private predicate relevantDefinition(Callable c, FieldOrProp fp, FieldOrPropDefinition fpdef) { - fpdef.getTarget() = fp and - not init(fpdef) and - fpdef.getEnclosingCallable() = c and - exists(TrackedFieldOrProp tf | tf.getAssignable() = fp) - } - - /** - * Holds if callable `c` can change the value of `this.fp` and is relevant - * for SSA construction. - */ - private predicate setsOwnFieldOrProp(InstanceCallable c, FieldOrProp fp) { - exists(FieldOrPropDefinition fpdef | relevantDefinition(c, fp, fpdef) | - ownFieldOrPropAccess(fpdef.getTargetAccess()) - ) - } - - /** - * Holds if callable `c` can change the value of `fp` and is relevant for SSA - * construction excluding those cases covered by `setsOwnFieldOrProp`. - */ - private predicate setsOtherFieldOrProp(Callable c, FieldOrProp fp) { - exists(FieldOrPropDefinition fpdef | relevantDefinition(c, fp, fpdef) | - not ownFieldOrPropAccess(fpdef.getTargetAccess()) - ) - } - - /** - * Holds if `(c1,c2)` is a call edge to a callable that does not change the - * value of `this`. - * - * Constructor-to-constructor calls can also be intra-instance, but are not - * included, as this does not affect whether a call chain ends in - * - * ``` - * Constructor --(intraInstanceCallEdge)-->+ Callable(setter of this.f) - * ``` - */ - private predicate intraInstanceCallEdge(Callable c1, InstanceCallable c2) { - exists(Call c | - c.getEnclosingCallable() = c1 and - c2 = getARuntimeTarget(c, _) and - c.(QualifiableExpr).targetIsLocalInstance() - ) - } - - /** - * Gets a potential run-time target for the call `c`. - * - * This predicate differs from `Call.getARuntimeTarget()` in three ways: - * - * (1) The returned callable is always a source declaration, - * - * (2) a simpler analysis is applied for delegate calls (needed to avoid making - * the SSA library and `Call.getARuntimeTarget()` mutually recursive), and - * - * (3) indirect calls to delegates via calls to library callables are included. - * - * The Boolean `libraryDelegateCall` indicates whether `c` is a call to a library - * method and the result is a delegate passed to `c`. For example, in - * - * ```csharp - * Lazy M1() - * { - * return new Lazy(M2); - * } - * ``` - * - * the constructor call `new Lazy(M2)` includes `M2` as a target. - */ - Callable getARuntimeTarget(Call c, boolean libraryDelegateCall) { - // Non-delegate call: use dispatch library - exists(DispatchCall dc | dc.getCall() = c | - result = dc.getADynamicTarget().getUnboundDeclaration() and - libraryDelegateCall = false - ) - or - // Delegate call: use simple analysis - result = SimpleDelegateAnalysis::getARuntimeDelegateTarget(c, libraryDelegateCall) - } - - private module SimpleDelegateAnalysis { - private import semmle.code.csharp.dataflow.internal.DelegateDataFlow - private import semmle.code.csharp.dataflow.internal.Steps - private import semmle.code.csharp.frameworks.system.linq.Expressions - - /** - * Holds if `c` is a call that (potentially) calls the delegate expression `e`. - * Either `c` is a delegate call and `e` is the qualifier, or `c` is a call to - * a library callable and `e` is a delegate argument. - */ - private predicate delegateCall(Call c, Expr e, boolean libraryDelegateCall) { - c = any(DelegateCall dc | e = dc.getDelegateExpr()) and - libraryDelegateCall = false - or - c.getTarget().fromLibrary() and - e = c.getAnArgument() and - e.getType() instanceof SystemLinqExpressions::DelegateExtType and - libraryDelegateCall = true - } - - /** Holds if expression `e` is a delegate creation for callable `c` of type `t`. */ - private predicate delegateCreation( - Expr e, Callable c, SystemLinqExpressions::DelegateExtType dt - ) { - e = - any(AnonymousFunctionExpr afe | - dt = afe.getType() and - c = afe - ) - or - e = - any(CallableAccess ca | - c = ca.getTarget().getUnboundDeclaration() and - dt = ca.getType() - ) - } - - private predicate delegateFlowStep(Expr pred, Expr succ) { - Steps::stepClosed(pred, succ) - or - exists(Call call, Callable callable | - callable.getUnboundDeclaration().canReturn(pred) and - call = succ - | - callable = call.getTarget() or - callable = call.getTarget().(Method).getAnOverrider+() or - callable = call.getTarget().(Method).getAnUltimateImplementor() or - callable = getARuntimeDelegateTarget(call, false) - ) - or - pred = succ.(DelegateCreation).getArgument() - or - exists(AssignableDefinition def, Assignable a | - a instanceof Field or - a instanceof Property - | - a = def.getTarget() and - succ.(AssignableRead) = a.getAnAccess() and - pred = def.getSource() - ) - or - exists(AddEventExpr ae | succ.(EventAccess).getTarget() = ae.getTarget() | - pred = ae.getRValue() - ) - } - - private predicate reachesDelegateCall(Expr e) { - delegateCall(_, e, _) - or - exists(Expr mid | reachesDelegateCall(mid) | delegateFlowStep(e, mid)) - } - - pragma[nomagic] - private predicate delegateFlowStepReaches(Expr pred, Expr succ) { - delegateFlowStep(pred, succ) and - reachesDelegateCall(succ) - } - - private Expr delegateCallSource(Callable c) { - delegateCreation(result, c, _) - or - delegateFlowStepReaches(delegateCallSource(c), result) - } - - /** Gets a run-time target for the delegate call `c`. */ - Callable getARuntimeDelegateTarget(Call c, boolean libraryDelegateCall) { - delegateCall(c, delegateCallSource(result), libraryDelegateCall) - } - } - - /** Holds if `(c1,c2)` is an edge in the call graph. */ - predicate callEdge(Callable c1, Callable c2) { - exists(Call c | c.getEnclosingCallable() = c1 and c2 = getARuntimeTarget(c, _)) - } - - /** - * Holds if `(c1,c2)` is an edge in the call graph excluding - * `intraInstanceCallEdge`. - */ - private predicate crossInstanceCallEdge(Callable c1, Callable c2) { - callEdge(c1, c2) and - not intraInstanceCallEdge(c1, c2) - } - - /** - * Holds if a call to `x.c` can change the value of `x.fp`. The actual - * update occurs in `setter`. - */ - private predicate setsOwnFieldOrPropTransitive( - InstanceCallable c, FieldOrProp fp, InstanceCallable setter - ) { - setsOwnFieldOrProp(setter, fp) and - // `intraInstanceCallEdge*(c, setter)` applies `fastTC` and therefore misses - // important magic optimization; consequently apply magic manually by explicit - // recursion - c = setter - or - exists(InstanceCallable mid | setsOwnFieldOrPropTransitive(mid, fp, setter) | - intraInstanceCallEdge(c, mid) - ) - } - - /** - * Holds if a call to `c` can change the value of `fp` on some instance. - * The actual update occurs in `setter`. - */ - private predicate generalSetter(Callable c, FieldOrProp fp, Callable setter) { - exists(InstanceCallable ownsetter | - setsOwnFieldOrPropTransitive(ownsetter, fp, setter) and - crossInstanceCallEdge(c, ownsetter) - ) - or - setsOtherFieldOrProp(c, fp) and c = setter - } - - pragma[noinline] - predicate callAt(BasicBlock bb, int i, Call call) { - bb.getNode(i) = call.getAControlFlowNode() and - getARuntimeTarget(call, _).hasBody() - } - - /** - * Holds if `call` occurs in basic block `bb` at index `i`, `fp` has - * an update somewhere, and `fp` is likely to be live in `bb` at index - * `i`. - */ - private predicate updateCandidate(BasicBlock bb, int i, TrackedFieldOrProp fp, Call call) { - possiblyLiveAtAllNodes(bb, fp) and - callAt(bb, i, call) and - relevantDefinition(_, fp.getAssignable(), _) and - not ref(bb, i, fp, _) - } - - /** - * Holds if `c` is a relevant part of the call graph for - * `updatesNamedFieldOrPropPart1` based on following edges in forward direction. - */ - private predicate pruneFromLeft(Callable c) { - exists(Call call, TrackedFieldOrProp f | - updateCandidate(_, _, f, call) and - c = getARuntimeTarget(call, _) and - generalSetter(_, f.getAssignable(), _) - ) - or - exists(Callable mid | pruneFromLeft(mid) | callEdge(mid, c)) - } - - /** - * Holds if `c` is a relevant part of the call graph for - * `updatesNamedFieldOrPropPart1` based on following edges in backward direction. - */ - private predicate pruneFromRight(Callable c) { - relevantDefinition(c, _, _) and - pruneFromLeft(c) - or - exists(Callable mid | pruneFromRight(mid) | - callEdge(c, mid) and - pruneFromLeft(c) - ) - } - - private class PrunedCallable extends Callable { - PrunedCallable() { pruneFromRight(this) } - } - - private predicate callEdgePruned(PrunedCallable c1, PrunedCallable c2) { callEdge(c1, c2) } - - private predicate callEdgePrunedPlus(PrunedCallable c1, PrunedCallable c2) = - fastTC(callEdgePruned/2)(c1, c2) - - pragma[noinline] - private predicate updatesNamedFieldOrPropPart1Prefix0( - Call call, TrackedFieldOrProp tfp, Callable c1, FieldOrProp fp - ) { - updateCandidate(_, _, tfp, call) and - fp = tfp.getAssignable() and - generalSetter(_, fp, _) and - c1 = getARuntimeTarget(call, _) - } - - pragma[noinline] - private predicate relevantDefinitionProj(PrunedCallable c, FieldOrProp fp) { - relevantDefinition(c, fp, _) - } - - pragma[noopt] - predicate updatesNamedFieldOrPropPart1Prefix( - Call call, TrackedFieldOrProp tfp, Callable c1, Callable setter, FieldOrProp fp - ) { - updatesNamedFieldOrPropPart1Prefix0(call, tfp, c1, fp) and - relevantDefinitionProj(setter, fp) and - (c1 = setter or callEdgePrunedPlus(c1, setter)) - } - - /** - * Holds if `call` may change the value of `tfp` on some instance, which may or - * may not alias with `this`. The actual update occurs in `setter`. - */ - pragma[noopt] - private predicate updatesNamedFieldOrPropPart1( - Call call, TrackedFieldOrProp tfp, Callable setter - ) { - exists(Callable c1, Callable c2, FieldOrProp fp | - updatesNamedFieldOrPropPart1Prefix(call, tfp, c1, setter, fp) and - generalSetter(c2, fp, setter) - | - c1 = c2 or callEdgePrunedPlus(c1, c2) - ) - } - - /** - * Holds if `call` may change the value of `tfp` on `this`. The actual update occurs - * in `setter`. - */ - private predicate updatesNamedFieldOrPropPart2( - Call call, TrackedFieldOrProp tfp, Callable setter - ) { - updateCandidate(_, _, tfp, call) and - setsOwnFieldOrPropTransitive(getARuntimeTarget(call, _), tfp.getAssignable(), setter) - } - - private predicate updatesNamedFieldOrPropPossiblyLive( - BasicBlock bb, int i, TrackedFieldOrProp fp, Call call, Callable setter - ) { - updateCandidate(bb, i, fp, call) and - ( - updatesNamedFieldOrPropPart1(call, fp, setter) - or - updatesNamedFieldOrPropPart2(call, fp, setter) - ) - } - - private int firstRefAfterCall(BasicBlock bb, int i, TrackedFieldOrProp fp) { - updatesNamedFieldOrPropPossiblyLive(bb, i, fp, _, _) and - result = min(int k | k > i and ref(bb, k, fp, _)) - } - - /** - * Holds if `call` may change the value of field or property `fp`. The actual - * update occurs in `setter`. - */ - cached - predicate updatesNamedFieldOrProp(Call c, TrackedFieldOrProp fp, Callable setter) { - forceCachingInSameStage() and - exists(BasicBlock bb, int i | updatesNamedFieldOrPropPossiblyLive(bb, i, fp, c, setter) | - not exists(firstRefAfterCall(bb, i, fp)) and - liveAtExit(bb, fp, _) - or - exists(int j | j = firstRefAfterCall(bb, i, fp) | - liveAtRank(bb, j, fp, _, _) and - not ref(bb, j, fp, Write(true)) - ) - ) - } - - /** - * Same as `variableWrite()`, but extended to include implicit call definitions - * for fields and properties. - */ - private predicate variableWriteExt(BasicBlock bb, int i, SourceVariable v) { - ref(bb, i, v, Write(_)) - or - variableWriteExt(bb, i, v.(QualifiedFieldOrPropSourceVariable).getQualifier()) - or - exists(Call c | callAt(bb, i, c) | updatesNamedFieldOrProp(c, v, _)) - } - - private int firstRefAfterQualifiedDef(BasicBlock bb, int i, QualifiedFieldOrPropSourceVariable q) { - variableWriteExt(bb, i, q) and - result = min(int k | k > i and ref(bb, k, q, _)) - } - - /** - * Holds if qualified field or property `q` is live after the (certain or - * uncertain) write at index `i` inside basic block `bb`. - */ - predicate liveAfterWriteQualified(BasicBlock bb, int i, QualifiedFieldOrPropSourceVariable q) { - variableWriteExt(bb, i, q) and - ( - not exists(firstRefAfterQualifiedDef(bb, i, q)) and - liveAtExit(bb, q, _) - or - exists(int j | j = firstRefAfterQualifiedDef(bb, i, q) | - liveAtRank(bb, j, q, _, _) and - not ref(bb, j, q, Write(true)) - ) - ) - } - } - - private import FieldOrPropsImpl - - /** - * As in the SSA construction for fields and properties, SSA construction - * for captured variables relies on implicit update nodes at every call - * site that conceivably could reach an update of the captured variable. - * For example, there is an implicit update of `v` on line 4 in - * - * ```csharp - * int M() { - * int i = 0; - * Action a = () => { i = 1; }; - * a(); // implicit update of `v` - * return i; - * } - * ``` - * - * We find update paths of the form: - * - * ``` - * Call --(callEdge)-->* Callable(update of v) - * ``` - * - * For simplicity, and for performance reasons, we ignore cases where a path - * goes through the callable that introduces `v`; such a path does not - * represent an actual update, as a new copy of `v` is updated. - */ - private module CapturedVariableImpl { - /** - * A local scope variable that is captured, and updated by at least one capturer. - */ - private class CapturedWrittenLocalScopeVariable extends LocalScopeVariable { - CapturedWrittenLocalScopeVariable() { - exists(AssignableDefinition def | def.getTarget() = this | - def.getEnclosingCallable() != this.getCallable() - ) - } - } - - private class CapturedWrittenLocalScopeSourceVariable extends LocalScopeSourceVariable { - CapturedWrittenLocalScopeSourceVariable() { - this.getAssignable() instanceof CapturedWrittenLocalScopeVariable - } - } - - private class CapturedWrittenLocalScopeVariableDefinition extends AssignableDefinition { - CapturedWrittenLocalScopeVariableDefinition() { - this.getTarget() instanceof CapturedWrittenLocalScopeVariable - } - } - - /** - * Holds if `vdef` is an update of captured variable `v` in callable `c` - * that is relevant for SSA construction. - */ - private predicate relevantDefinition( - Callable c, CapturedWrittenLocalScopeVariable v, - CapturedWrittenLocalScopeVariableDefinition vdef - ) { - exists(BasicBlock bb, int i, CapturedWrittenLocalScopeSourceVariable sv | - vdef.getTarget() = v and - vdef.getEnclosingCallable() = c and - liveAfterWrite(bb, i, sv, _) and // only works because `CapturedVarExitRead`s are inserted - sv.getAssignable() = v and - bb.getNode(i) = vdef.getAControlFlowNode() and - c != v.getCallable() - ) - } - - /** - * Holds if `call` occurs in basic block `bb` at index `i`, captured variable - * `v` has an update somewhere, and `v` is likely to be live in `bb` at index - * `i`. - */ - private predicate updateCandidate( - BasicBlock bb, int i, CapturedWrittenLocalScopeSourceVariable v, Call call - ) { - possiblyLiveAtAllNodes(bb, v) and - callAt(bb, i, call) and - exists(Assignable a | - a = v.getAssignable() and - relevantDefinition(_, a, _) and - not exists(AssignableDefinitions::OutRefDefinition def | - def.getCall() = call and - def.getTarget() = a - ) - ) - } - - /** - * Holds if `c` is a relevant part of the call graph for - * `updatesCapturedVariable` based on following edges in forward direction. - */ - private predicate pruneFromLeft(Callable c) { - exists(Call call, CapturedWrittenLocalScopeSourceVariable v | - updateCandidate(_, _, v, call) and - c = getARuntimeTarget(call, _) and - relevantDefinition(_, v.getAssignable(), _) - ) - or - exists(Callable mid | pruneFromLeft(mid) | callEdge(mid, c)) - } - - /** - * Holds if `c` is a relevant part of the call graph for - * `updatesCapturedVariable` based on following edges in backward direction. - */ - private predicate pruneFromRight(Callable c) { - relevantDefinition(c, _, _) and - pruneFromLeft(c) - or - exists(Callable mid | pruneFromRight(mid) | - callEdge(c, mid) and - pruneFromLeft(c) - ) - } - - private class PrunedCallable extends Callable { - PrunedCallable() { pruneFromRight(this) } - } - - private predicate callEdgePruned(PrunedCallable c1, PrunedCallable c2) { callEdge(c1, c2) } - - private predicate callEdgePrunedPlus(PrunedCallable c1, PrunedCallable c2) = - fastTC(callEdgePruned/2)(c1, c2) - - pragma[noinline] - private predicate relevantDefinitionProj(PrunedCallable c, CapturedWrittenLocalScopeVariable v) { - relevantDefinition(c, v, _) - } - - pragma[noinline] - private predicate updatesCapturedVariablePrefix( - Call call, CapturedWrittenLocalScopeSourceVariable v, PrunedCallable c, - CapturedWrittenLocalScopeVariable captured, boolean libraryDelegateCall - ) { - updateCandidate(_, _, v, call) and - captured = v.getAssignable() and - relevantDefinitionProj(_, captured) and - c = getARuntimeTarget(call, libraryDelegateCall) - } - - /** - * Holds if `call` may change the value of captured variable `v`. The actual - * update occurs in `writer`. That is, `writer` can be reached from `call` - * using zero or more additional calls (as indicated by `additionalCalls`). - * One of the intermediate callables may be the callable that introduces `v`, - * in which case `call` is not an actual update. - */ - pragma[noopt] - private predicate updatesCapturedVariableWriter( - Call call, CapturedWrittenLocalScopeSourceVariable v, PrunedCallable writer, - boolean additionalCalls - ) { - exists( - PrunedCallable c, CapturedWrittenLocalScopeVariable captured, boolean libraryDelegateCall - | - updatesCapturedVariablePrefix(call, v, c, captured, libraryDelegateCall) and - relevantDefinitionProj(writer, captured) and - ( - c = writer and additionalCalls = libraryDelegateCall - or - callEdgePrunedPlus(c, writer) and additionalCalls = true - ) - ) - } - - /** - * Holds if `call` may change the value of captured variable `v`. The actual - * update occurs in `def`. - */ - private predicate updatesCapturedVariablePossiblyLive( - BasicBlock bb, int i, Call call, LocalScopeSourceVariable v, AssignableDefinition def, - boolean additionalCalls - ) { - updateCandidate(bb, i, v, call) and - exists(Callable writer | relevantDefinition(writer, v.getAssignable(), def) | - updatesCapturedVariableWriter(call, v, writer, additionalCalls) - ) - } - - private int firstRefAfter(BasicBlock bb, int i, CapturedWrittenLocalScopeSourceVariable v) { - updatesCapturedVariablePossiblyLive(bb, i, _, v, _, _) and - result = min(int k | k > i and ref(bb, k, v, _)) - } - - /** - * Holds if `call` may change the value of captured variable `v`. The actual - * update occurs in `def`. - */ - cached - predicate updatesCapturedVariable( - Call call, LocalScopeSourceVariable v, AssignableDefinition def, boolean additionalCalls - ) { - forceCachingInSameStage() and - exists(BasicBlock bb, int i | - updatesCapturedVariablePossiblyLive(bb, i, call, v, def, additionalCalls) - | - not exists(firstRefAfter(bb, i, v)) and - liveAtExit(bb, v, _) - or - exists(int j | j = firstRefAfter(bb, i, v) | - liveAtRank(bb, j, v, _, _) and - not ref(bb, j, v, Write(true)) - ) - ) - } - } - - private import CapturedVariableImpl - - /** - * Liveness analysis to restrict the size of the SSA representation for - * captured variables. - * - * Example: - * - * ```csharp - * void M() { - * int i = 0; - * void M2() { - * System.Console.WriteLine(i); - * } - * M2(); - * } - * ``` - * - * The definition of `i` on line 2 is live, because of the call to `M2` on - * line 6. However, that call is not a direct read of `i`, so we account - * for that by inserting an implicit read of `i` on line 6. - * - * The predicates in this module follow the same structure as those in - * `CapturedVariableImpl`. - */ - private module CapturedVariableLivenessImpl { - /** - * Holds if `c` is a callable that captures local scope variable `v`, and - * `c` may read the value of the captured variable. - */ - private predicate capturerReads(Callable c, LocalScopeVariable v) { - exists(ControlFlow::BasicBlocks::EntryBlock ebb, LocalScopeSourceVariable lssv | - liveAtEntry(ebb, lssv, _) - | - v = lssv.getAssignable() and - c = ebb.getCallable() and - v.getCallable() != c - ) - } - - /** - * A local scope variable that is captured, and read by at least one capturer. - */ - private class CapturedReadLocalScopeVariable extends LocalScopeVariable { - CapturedReadLocalScopeVariable() { capturerReads(_, this) } - } - - private class CapturedReadLocalScopeSourceVariable extends LocalScopeSourceVariable { - CapturedReadLocalScopeSourceVariable() { - this.getAssignable() instanceof CapturedReadLocalScopeVariable - } - } - - private predicate capturedVariableWrite( - BasicBlock bb, int i, CapturedReadLocalScopeSourceVariable v - ) { - ref(bb, i, v, Write(_)) - } - - /** - * Holds if the write to captured source variable `v` at index `i` in basic - * block `bb` may be read by a callable reachable from the call `c`. - */ - private predicate implicitReadCandidate( - BasicBlock bb, int i, ControlFlow::Nodes::ElementNode c, - CapturedReadLocalScopeSourceVariable v - ) { - c.getElement() instanceof Call and - exists(BasicBlock bb0, int i0 | bb0.getNode(i0) = c | - // `c` is in basic block `bb` - capturedVariableWrite(bb0, i, v) and - i < i0 and - not capturedVariableWrite(bb, any(int j | j in [i + 1 .. i0 - 1]), v) and - bb = bb0 - or - // `c` is in a basic block reachable from `bb` - not capturedVariableWrite(bb0, any(int j | j < i0), v) and - capturedVariableWrite(bb, i, v) and - capturedVariableWriteReachesStartOf(bb, i, bb0, v) - ) - } - - /** - * Holds if the write to captured source variable `v` at index `i` in basic - * block `bb` reaches the start of basic block `r`, without passing through - * another write. - */ - private predicate capturedVariableWriteReachesStartOf( - BasicBlock bb, int i, BasicBlock r, CapturedReadLocalScopeSourceVariable v - ) { - exists(int last | last = max(refRank(bb, _, v, Write(_))) | - last = refRank(bb, i, v, Write(_)) and - capturedVariableWrite(bb, i, v) and - r = bb.getASuccessor() - ) - or - exists(BasicBlock mid | capturedVariableWriteReachesStartOf(bb, i, mid, v) | - r = mid.getASuccessor() and - not capturedVariableWrite(mid, _, v) - ) - } - - /** - * Holds if `c` is a relevant part of the call graph for - * `readsCapturedVariable` based on following edges in forward direction. - */ - private predicate pruneFromLeft(Callable c) { - exists(Call call, CapturedReadLocalScopeSourceVariable v | - implicitReadCandidate(_, _, call.getAControlFlowNode(), v) and - c = getARuntimeTarget(call, _) - ) - or - exists(Callable mid | pruneFromLeft(mid) | callEdge(mid, c)) - } - - /** - * Holds if `c` is a relevant part of the call graph for - * `readsCapturedVariable` based on following edges in backward direction. - */ - private predicate pruneFromRight(Callable c) { - exists(CapturedReadLocalScopeSourceVariable v | - capturerReads(c, v.getAssignable()) and - capturedVariableWrite(_, _, v) and - pruneFromLeft(c) - ) - or - exists(Callable mid | pruneFromRight(mid) | - callEdge(c, mid) and - pruneFromLeft(c) - ) - } - - private class PrunedCallable extends Callable { - PrunedCallable() { pruneFromRight(this) } - } - - private predicate callEdgePruned(PrunedCallable c1, PrunedCallable c2) { callEdge(c1, c2) } - - private predicate callEdgePrunedPlus(PrunedCallable c1, PrunedCallable c2) = - fastTC(callEdgePruned/2)(c1, c2) - - pragma[noinline] - private predicate readsCapturedVariablePrefix( - ControlFlow::Node call, CapturedReadLocalScopeSourceVariable v, PrunedCallable c, - CapturedReadLocalScopeVariable captured, boolean libraryDelegateCall - ) { - implicitReadCandidate(_, _, call, v) and - captured = v.getAssignable() and - capturerReads(_, captured) and - c = getARuntimeTarget(call.getElement(), libraryDelegateCall) - } - - /** - * Holds if `call` may read the value of captured variable `v`. The actual - * read occurs in `reader`. That is, `reader` can be reached from `call` - * using zero or more additional calls (as indicated by `additionalCalls`). - * One of the intermediate callables may be a callable that writes to `v`, - * in which case `call` is not an actual read. - */ - pragma[noopt] - private predicate readsCapturedVariable( - ControlFlow::Nodes::ElementNode call, CapturedReadLocalScopeSourceVariable v, Callable reader, - boolean additionalCalls - ) { - exists( - PrunedCallable c, CapturedReadLocalScopeVariable captured, boolean libraryDelegateCall - | - readsCapturedVariablePrefix(call, v, c, captured, libraryDelegateCall) and - capturerReads(reader, captured) and - ( - c = reader and additionalCalls = libraryDelegateCall - or - callEdgePrunedPlus(c, reader) and additionalCalls = true - ) - ) - } - - /** - * Holds if captured local scope variable `v` is live after the (certain or uncertain) - * write at index `i` inside basic block `bb`. - * - * The write is live because of the implicit call definition `def`, which reaches - * the write using zero or more additional calls (as indicated by `additionalCalls`). - * That is, data can flow from the write at index `i` out to the call `def`. - * - * Example: - * - * ```csharp - * class C { - * void M1() { - * int i = 0; - * void M2() { i = 2; }; - * M2(); - * System.Console.WriteLine(i); - * } - * } - * ``` - * - * The write to `i` inside `M2` on line 4 is live because of the implicit call - * definition on line 5. - */ - predicate liveAfterWriteCapturedOut( - BasicBlock bb, int i, LocalScopeSourceVariable v, ImplicitCallDefinition def, - boolean additionalCalls - ) { - exists(LocalScopeVariable lsv, AssignableDefinition adef | - def.getSourceVariable().getAssignable() = lsv - | - lsv = v.getAssignable() and - bb.getNode(i) = adef.getAControlFlowNode() and - updatesCapturedVariable(def.getCall(), _, adef, additionalCalls) - ) - } - - /** - * Holds if captured local scope variable `v` is live after the (certain or uncertain) - * write at index `i` inside basic block `bb`. - * - * The write is live because of the implicit entry definition `def`, which can be - * reached using one or more calls (as indicated by `additionalCalls`), starting - * from call `c`. That is, data can flow from the write at index `i` into the - * callable containing `def`. - * - * Example: - * - * ```csharp - * class C { - * void M1() { - * int i = 0; - * void M2() => System.Console.WriteLine(i); - * i = 1; - * M2(); - * } - * } - * ``` - * - * The write to `i` on line 5 is live because of the call to `M2` on line 6, which - * reaches the entry definition for `i` in `M2` on line 4. - */ - predicate liveAfterWriteCapturedIn( - BasicBlock bb, int i, LocalScopeSourceVariable v, ImplicitEntryDefinition def, - ControlFlow::Nodes::ElementNode c, boolean additionalCalls - ) { - exists(Callable reader, SourceVariable sv | - implicitReadCandidate(bb, i, c, v) and - readsCapturedVariable(c, v, reader, additionalCalls) and - sv = def.getSourceVariable() and - reader = sv.getEnclosingCallable() and - v.getAssignable() = sv.getAssignable() - ) - } - - /** - * Holds if captured local scope variable `v` is live after the (certain or uncertain) - * write at index `i` inside basic block `bb`. - */ - predicate liveAfterWriteCaptured(BasicBlock bb, int i, LocalScopeSourceVariable v) { - liveAfterWriteCapturedOut(bb, i, v, _, _) or - liveAfterWriteCapturedIn(bb, i, v, _, _, _) - } - } - - private import CapturedVariableLivenessImpl - - cached - private module SsaImpl { - cached - predicate forceCachingInSameStage() { any() } - - /** - * A data type representing SSA definitions. - * - * We distinguish six kinds of SSA definitions: - * - * 1. Explicit definitions wrapping an `AssignableDefinition` node in the CFG. - * 2. Implicit initializations of variables at the entry point of a callable - * (captured variables and relevant fields or properties), represented by - * the callable entry point in the CFG. - * 3. Implicit indirect definitions of variables through calls (fields, - * properties, or captured variables). - * 4. Implicit indirect definitions of variables through qualifier definitions - * (fields or properties). - * 5. Implicit definitions of variables prior to all reads, for variables that - * are not amenable to SSA analysis (`UntrackedVar`). - * 6. Phi nodes. - * - * SSA definitions are only introduced where necessary. That is, dead assignments - * have no associated SSA definitions. - */ - cached - newtype TDefinition = - TSsaExplicitDef(TrackedVar v, AssignableDefinition def, BasicBlock bb, int i) { - variableDefinition(bb, i, v, def) and - ( - exists(ReadKind rk | liveAfterWrite(bb, i, v, rk) | - // A `ref` assignment such as - // ```csharp - // ref int i = ref GetRef(); - // ``` - // is dead when there are no reads of or writes to `i`. - // That is, the read kind `rk` witnessing the liveness of the assignment - // must not be the pseudo read inserted at the end of the enclosing callable - not ( - rk = OutRefExitRead() and - def.(AssignableDefinitions::AssignmentDefinition).getSource() instanceof RefExpr - ) and - rk != CapturedVarExitRead() // Captured variables are handled below - ) - or - liveAfterWriteCaptured(bb, i, v) - ) - } or - TSsaImplicitEntryDef(TrackedVar v, ControlFlow::BasicBlocks::EntryBlock ebb) { - liveAtEntry(ebb, v, _) and - exists(Callable c | - c = ebb.getCallable() and - c = v.getEnclosingCallable() - | - // Captured variable - exists(LocalScopeVariable lsv | - v = any(LocalScopeSourceVariable lv | lsv = lv.getAssignable()) - | - lsv.getCallable() != c - ) - or - // Each tracked field and property has an implicit entry definition - v instanceof TrackedFieldOrProp - ) - } or - TSsaImplicitCallDef(TrackedVar v, Call c, BasicBlock bb, int i) { - bb.getNode(i) = c.getAControlFlowNode() and - ( - // Liveness of `v` after `c` is guaranteed by `updatesNamedFieldOrProp` - updatesNamedFieldOrProp(c, v, _) - or - // Liveness of `v` after `c` is guaranteed by `updatesCapturedVariable` - updatesCapturedVariable(c, v, _, _) - ) - } or - TSsaImplicitQualifierDef(TrackedVar v, Definition qdef) { - exists(BasicBlock bb, int i | - qdef.getSourceVariable() = v.getQualifier() and - qdef.definesAt(bb, i) and - liveAfterWriteQualified(bb, i, v) and - // Eliminate corner case where a call definition can overlap with a - // qualifier definition: if method `M` updates field `F`, then a call - // to `M` is both an update of `x.M` and `x.M.M`, so the former call - // definition should not give rise to an implicit qualifier definition - // for `x.M.M`. - not exists(TSsaImplicitCallDef(v, _, bb, i)) - ) - } or - TSsaImplicitUntrackedDef(UntrackedVar v, BasicBlock bb, int i) { - // Insert a definition prior to every read for untracked variables - bb.getNode(i + 1) = v.getAnAccess().(AssignableRead).getAControlFlowNode() - } or - TPhiNode(TrackedVar v, ControlFlow::BasicBlocks::JoinBlock bb) { - phiNodeMaybeLive(bb, v) and - liveAtEntry(bb, v, _) - } - - pragma[noinline] - private predicate phiNodeMaybeLive(ControlFlow::BasicBlocks::JoinBlock bb, TrackedVar v) { - exists(Definition def, BasicBlock bb1 | definesAt(def, bb1, _, v) | - bb1.inDominanceFrontier(bb) - ) - } - - /** - * Holds if the SSA definition `def` defines source variable `v` at index `i` - * in basic block `bb`. Phi nodes and entry nodes (captured variables and - * fields/properties) are considered to be at index `-1`, while normal variable - * updates are at the index of the control flow node they wrap. - */ - cached - predicate definesAt(Definition def, BasicBlock bb, int i, SourceVariable v) { - def = TSsaExplicitDef(v, _, bb, i) - or - def = TSsaImplicitEntryDef(v, bb) and i = -1 - or - def = TSsaImplicitCallDef(v, _, bb, i) - or - exists(Definition qdef | def = TSsaImplicitQualifierDef(v, qdef) | definesAt(qdef, bb, i, _)) - or - def = TSsaImplicitUntrackedDef(v, bb, i) - or - def = TPhiNode(v, bb) and i = -1 - } - - cached - predicate isCapturedVariableDefinitionFlowIn( - ExplicitDefinition def, ImplicitEntryDefinition edef, ControlFlow::Nodes::ElementNode c, - boolean additionalCalls - ) { - exists(BasicBlock bb, int i, LocalScopeSourceVariable v | definesAt(def, bb, i, v) | - liveAfterWriteCapturedIn(bb, i, v, edef, c, additionalCalls) - ) - } - - /** - * Holds if the SSA definition `def` assigns to captured local scope variable `v`, - * and the variable may remain unchanged throughout the rest of the enclosing - * callable. - */ - private predicate isLiveCapturedVariableDefinition(ExplicitDefinition def) { - exists(Definition def0 | def = def0.getAnUltimateDefinition() | - ssaDefReachesRead(_, def0, _, CapturedVarExitRead()) - ) - } - - cached - predicate isCapturedVariableDefinitionFlowOut( - ExplicitDefinition def, ImplicitCallDefinition cdef, boolean additionalCalls - ) { - exists(BasicBlock bb, int i, LocalScopeSourceVariable v | definesAt(def, bb, i, v) | - liveAfterWriteCapturedOut(bb, i, v, cdef, additionalCalls) and - isLiveCapturedVariableDefinition(def) - ) - } - } - - private import SsaImpl - private string getSplitString(Definition def) { - exists(BasicBlock bb, int i, ControlFlow::Node cfn | - definesAt(def, bb, i, _) and + exists(ControlFlow::BasicBlock bb, int i, ControlFlow::Node cfn | + def.definesAt(_, bb, i) and result = cfn.(ControlFlow::Nodes::ElementNode).getSplitsString() | cfn = bb.getNode(i) @@ -2022,11 +160,31 @@ module Ssa { /** * A static single assignment (SSA) definition. Either an explicit variable * definition (`ExplicitDefinition`), an implicit variable definition - * (`ImplicitDefinition`), or a pseudo definition (`PseudoDefinition`). + * (`ImplicitDefinition`), or a phi node (`PhiNode`). */ - class Definition extends TDefinition { - /** Gets the source variable underlying this SSA definition. */ - SourceVariable getSourceVariable() { definesAt(this, _, _, result) } + class Definition extends SsaImpl::Definition { + final override SourceVariable getSourceVariable() { + result = SsaImpl::Definition.super.getSourceVariable() + } + + /** + * Gets the control flow node of this SSA definition, if any. Phi nodes are + * examples of SSA definitions without a control flow node, as they are + * modelled at index `-1` in the relevant basic block. + */ + final ControlFlow::Node getControlFlowNode() { + exists(ControlFlow::BasicBlock bb, int i | this.definesAt(_, bb, i) | result = bb.getNode(i)) + } + + /** + * Holds is this SSA definition is live at the end of basic block `bb`. + * That is, this definition reaches the end of basic block `bb`, at which + * point it is still live, without crossing another SSA definition of the + * same source variable. + */ + final predicate isLiveAtEndOfBlock(ControlFlow::BasicBlock bb) { + SsaImpl::isLiveAtEndOfBlock(this, bb) + } /** * Gets a read of the source variable underlying this SSA definition that @@ -2055,7 +213,7 @@ module Ssa { * - The reads of `this.Field` on lines 10 and 11 can be reached from the phi * node between lines 9 and 10. */ - AssignableRead getARead() { result = this.getAReadAtNode(_) } + final AssignableRead getARead() { result = this.getAReadAtNode(_) } /** * Gets a read of the source variable underlying this SSA definition at @@ -2084,9 +242,8 @@ module Ssa { * - The reads of `this.Field` on lines 10 and 11 can be reached from the phi * node between lines 9 and 10. */ - AssignableRead getAReadAtNode(ControlFlow::Node cfn) { - ssaDefReachesRead(_, this, cfn, _) and - result.getAControlFlowNode() = cfn + final AssignableRead getAReadAtNode(ControlFlow::Node cfn) { + result = SsaImpl::getAReadAtNode(this, cfn) } /** @@ -2123,7 +280,7 @@ module Ssa { * Subsequent reads can be found by following the steps defined by * `AssignableRead.getANextRead()`. */ - AssignableRead getAFirstRead() { result = this.getAFirstReadAtNode(_) } + final AssignableRead getAFirstRead() { result = this.getAFirstReadAtNode(_) } /** * Gets a read of the source variable underlying this SSA definition at @@ -2159,8 +316,8 @@ module Ssa { * Subsequent reads can be found by following the steps defined by * `AssignableRead.getANextRead()`. */ - AssignableRead getAFirstReadAtNode(ControlFlow::Node cfn) { - firstReadSameVar(this, cfn) and + final AssignableRead getAFirstReadAtNode(ControlFlow::Node cfn) { + SsaImpl::firstReadSameVar(this, cfn) and result.getAControlFlowNode() = cfn } @@ -2192,7 +349,7 @@ module Ssa { * - The read of `this.Field` on line 11 is a last read of the phi node * between lines 9 and 10. */ - AssignableRead getALastRead() { result = this.getALastReadAtNode(_) } + final AssignableRead getALastRead() { result = this.getALastReadAtNode(_) } /** * Gets a last read of the source variable underlying this SSA definition at @@ -2222,14 +379,23 @@ module Ssa { * - The read of `this.Field` on line 11 is a last read of the phi node * between lines 9 and 10. */ - AssignableRead getALastReadAtNode(ControlFlow::Node cfn) { - lastRead(this, cfn) and + final AssignableRead getALastReadAtNode(ControlFlow::Node cfn) { + SsaImpl::lastReadSameVar(this, cfn) and result.getAControlFlowNode() = cfn } + /** + * Gets an SSA definition whose value can flow to this one in one step. This + * includes inputs to phi nodes and the prior definitions of uncertain writes. + */ + private Definition getAPhiInputOrPriorDefinition() { + result = this.(PhiNode).getAnInput() or + result = this.(UncertainDefinition).getPriorDefinition() + } + /** * Gets a definition that ultimately defines this SSA definition and is - * not itself a pseudo node. Example: + * not itself a phi node. Example: * * ```csharp * int Field; @@ -2256,73 +422,36 @@ module Ssa { * definition on line 4, the explicit definition on line 7, and the implicit * definition on line 9. */ - Definition getAnUltimateDefinition() { - result = this.getAPseudoInputOrPriorDefinition*() and - not result instanceof PseudoDefinition + final Definition getAnUltimateDefinition() { + result = this.getAPhiInputOrPriorDefinition*() and + not result instanceof PhiNode } /** - * Gets an SSA definition whose value can flow to this one in one step. This - * includes inputs to pseudo nodes and the prior definition of uncertain updates. + * DEPRECATED: Use `definesAt/3` instead. */ - private Definition getAPseudoInputOrPriorDefinition() { - result = this.(PseudoDefinition).getAnInput() or - result = this.(UncertainDefinition).getPriorDefinition() - } - - /** - * Holds is this SSA definition is live at the end of basic block `bb`. That is, - * this definition reaches the end of basic block `bb`, at which point it is still - * live, without crossing another SSA definition of the same source variable. - */ - predicate isLiveAtEndOfBlock(BasicBlock bb) { ssaDefReachesEndOfBlock(bb, this, _) } - - /** - * Holds if this SSA definition is at index `i` in basic block `bb`. Phi nodes and - * entry nodes (captured variables and fields/properties) are considered to be at - * index `-1`, while normal variable updates are at the index of the control flow - * node they wrap. - */ - predicate definesAt(BasicBlock bb, int i) { definesAt(this, bb, i, _) } - - /** Gets the basic block to which this SSA definition belongs. */ - BasicBlock getBasicBlock() { this.definesAt(result, _) } - - /** - * Gets the control flow node of this SSA definition, if any. Phi nodes are examples - * of SSA definitions without a control flow node, as they are modelled at index - * `-1` in the relevant basic block. - */ - ControlFlow::Node getControlFlowNode() { - exists(BasicBlock bb, int i | this.definesAt(bb, i) | result = bb.getNode(i)) - } + deprecated predicate definesAt(ControlFlow::BasicBlock bb, int i) { this.definesAt(_, bb, i) } /** * Gets the syntax element associated with this SSA definition, if any. * This is either an expression, for example `x = 0`, a parameter, or a - * callable. Pseudo nodes have no associated syntax element. + * callable. Phi nodes have no associated syntax element. */ Element getElement() { result = this.getControlFlowNode().getElement() } /** Gets the callable to which this SSA definition belongs. */ - Callable getEnclosingCallable() { result = this.getSourceVariable().getEnclosingCallable() } + final Callable getEnclosingCallable() { + result = this.getSourceVariable().getEnclosingCallable() + } /** * Holds if this SSA definition assigns to `out`/`ref` parameter `p`, and the * parameter may remain unchanged throughout the rest of the enclosing callable. */ - predicate isLiveOutRefParameterDefinition(Parameter p) { - exists(Definition def, ControlFlow::Node read, SourceVariable v | - this = def.getAnUltimateDefinition() - | - ssaDefReachesRead(v, def, read, OutRefExitRead()) and - v.getAssignable() = p - ) + final predicate isLiveOutRefParameterDefinition(Parameter p) { + SsaImpl::isLiveOutRefParameterDefinition(this, p) } - /** Gets a textual representation of this SSA definition. */ - string toString() { none() } - /** Gets the location of this SSA definition. */ Location getLocation() { none() } } @@ -2330,18 +459,18 @@ module Ssa { /** * An SSA definition that corresponds to an explicit assignable definition. */ - class ExplicitDefinition extends Definition, TSsaExplicitDef { - TrackedVar tv; + class ExplicitDefinition extends Definition, SsaImpl::WriteDefinition { + SourceVariable sv; AssignableDefinition ad; - ExplicitDefinition() { this = TSsaExplicitDef(tv, ad, _, _) } + ExplicitDefinition() { SsaImpl::explicitDefinition(this, sv, ad) } /** * Gets an underlying assignable definition. The result is always unique, * except for pathological `out`/`ref` assignments like `M(out x, out x)`, * where there may be more than one underlying definition. */ - AssignableDefinition getADefinition() { result = getADefinition(this) } + final AssignableDefinition getADefinition() { result = SsaImpl::getADefinition(this) } /** * Holds if this definition updates a captured local scope variable, and the updated @@ -2364,10 +493,10 @@ module Ssa { * If this definition is the update of `i` on line 5, then the value may be read inside * `M2` via the call on line 6. */ - predicate isCapturedVariableDefinitionFlowIn( + final predicate isCapturedVariableDefinitionFlowIn( ImplicitEntryDefinition def, ControlFlow::Nodes::ElementNode c, boolean additionalCalls ) { - isCapturedVariableDefinitionFlowIn(this, def, c, additionalCalls) + SsaImpl::isCapturedVariableDefinitionFlowIn(this, def, c, additionalCalls) } /** @@ -2391,10 +520,10 @@ module Ssa { * If this definition is the update of `i` on line 4, then the value may be read outside * of `M2` via the call on line 5. */ - predicate isCapturedVariableDefinitionFlowOut( + final predicate isCapturedVariableDefinitionFlowOut( ImplicitCallDefinition cdef, boolean additionalCalls ) { - isCapturedVariableDefinitionFlowOut(this, cdef, additionalCalls) + SsaImpl::isCapturedVariableDefinitionFlowOut(this, cdef, additionalCalls) } override Element getElement() { result = ad.getElement() } @@ -2412,16 +541,21 @@ module Ssa { * An SSA definition that does not correspond to an explicit variable definition. * Either an implicit initialization of a variable at the beginning of a callable * (`ImplicitEntryDefinition`), an implicit definition via a call - * (`ImplicitCallDefinition`), an implicit definition where the qualifier is - * updated (`ImplicitQualifierDefinition`), or a definition for a field or - * property that is not amenable to SSA analysis (`ImplicitUntrackedDefinition`). + * (`ImplicitCallDefinition`), or an implicit definition where the qualifier is + * updated (`ImplicitQualifierDefinition`). */ - class ImplicitDefinition extends Definition { + class ImplicitDefinition extends Definition, SsaImpl::WriteDefinition { ImplicitDefinition() { - this = TSsaImplicitEntryDef(_, _) or - this = TSsaImplicitCallDef(_, _, _, _) or - this = TSsaImplicitQualifierDef(_, _) or - this = TSsaImplicitUntrackedDef(_, _, _) + exists(ControlFlow::BasicBlock bb, SourceVariable v, int i | this.definesAt(v, bb, i) | + SsaImpl::implicitEntryDefinition(bb, v) and + i = -1 + or + SsaImpl::updatesNamedFieldOrProp(bb, i, _, v, _) + or + SsaImpl::updatesCapturedVariable(bb, i, _, v, _, _) + or + SsaImpl::variableWriteQualifier(bb, i, v, _) + ) } } @@ -2430,15 +564,17 @@ module Ssa { * at the beginning of a callable. Either the variable is a local scope variable * captured by the callable, or a field or property accessed inside the callable. */ - class ImplicitEntryDefinition extends ImplicitDefinition, TSsaImplicitEntryDef { - /** Gets the callable that this entry definition belongs to. */ - Callable getCallable() { - exists(ControlFlow::BasicBlocks::EntryBlock ebb | - this = TSsaImplicitEntryDef(_, ebb) and - result = ebb.getCallable() + class ImplicitEntryDefinition extends ImplicitDefinition { + ImplicitEntryDefinition() { + exists(ControlFlow::BasicBlock bb, SourceVariable v | + this.definesAt(v, bb, -1) and + SsaImpl::implicitEntryDefinition(bb, v) ) } + /** Gets the callable that this entry definition belongs to. */ + final Callable getCallable() { result = this.getBasicBlock().getCallable() } + override Callable getElement() { result = this.getCallable() } override string toString() { @@ -2454,8 +590,19 @@ module Ssa { * An SSA definition representing the potential definition of a variable * via a call. */ - class ImplicitCallDefinition extends ImplicitDefinition, TSsaImplicitCallDef { - Call getCall() { this = TSsaImplicitCallDef(_, result, _, _) } + class ImplicitCallDefinition extends ImplicitDefinition { + private Call c; + + ImplicitCallDefinition() { + exists(ControlFlow::BasicBlock bb, SourceVariable v, int i | this.definesAt(v, bb, i) | + SsaImpl::updatesNamedFieldOrProp(bb, i, c, v, _) + or + SsaImpl::updatesCapturedVariable(bb, i, c, v, _, _) + ) + } + + /** Gets the underlying call. */ + final Call getCall() { result = c } /** * Gets one of the definitions that may contribute to this implicit @@ -2463,13 +610,13 @@ module Ssa { * the target of this call following zero or more additional calls, * and which targets the same assignable as this SSA definition. */ - AssignableDefinition getAPossibleDefinition() { - exists(Callable setter | updatesNamedFieldOrProp(getCall(), _, setter) | + final AssignableDefinition getAPossibleDefinition() { + exists(Callable setter | SsaImpl::updatesNamedFieldOrProp(_, _, getCall(), _, setter) | result.getEnclosingCallable() = setter and result.getTarget() = this.getSourceVariable().getAssignable() ) or - updatesCapturedVariable(getCall(), _, result, _) and + SsaImpl::updatesCapturedVariable(_, _, getCall(), _, result, _) and result.getTarget() = this.getSourceVariable().getAssignable() } @@ -2484,9 +631,22 @@ module Ssa { * An SSA definition representing the potential definition of a variable * via an SSA definition for the qualifier. */ - class ImplicitQualifierDefinition extends ImplicitDefinition, TSsaImplicitQualifierDef { + class ImplicitQualifierDefinition extends ImplicitDefinition, SsaImpl::WriteDefinition { + private Definition q; + + ImplicitQualifierDefinition() { + exists( + ControlFlow::BasicBlock bb, int i, SourceVariables::QualifiedFieldOrPropSourceVariable v + | + this.definesAt(v, bb, i) + | + SsaImpl::variableWriteQualifier(bb, i, v, _) and + q.definesAt(v.getQualifier(), bb, i) + ) + } + /** Gets the SSA definition for the qualifier. */ - Definition getQualifierDefinition() { this = TSsaImplicitQualifierDef(_, result) } + final Definition getQualifierDefinition() { result = q } override string toString() { result = getToStringPrefix(this) + "SSA qualifier def(" + getSourceVariable() + ")" @@ -2495,46 +655,20 @@ module Ssa { override Location getLocation() { result = getQualifierDefinition().getLocation() } } - /** - * An SSA definition for a variable that is not amenable to SSA analysis. A definition - * is inserted prior to every read. - */ - class ImplicitUntrackedDefinition extends ImplicitDefinition, TSsaImplicitUntrackedDef { - override AssignableRead getARead() { - exists(BasicBlock bb, int i, UntrackedVar v | - this = TSsaImplicitUntrackedDef(v, bb, i) and - result.getAControlFlowNode() = bb.getNode(i + 1) - ) - } - - override string toString() { - result = getToStringPrefix(this) + "SSA untracked def(" + getSourceVariable() + ")" - } - - override Location getLocation() { result = this.getARead().getLocation() } - } - /** * An SSA definition that has no actual semantics, but simply serves to * merge or filter data flow. * * Phi nodes are the canonical (and currently only) example. */ - class PseudoDefinition extends Definition { - PseudoDefinition() { this = TPhiNode(_, _) } - - /** - * Gets an input of this pseudo definition. - */ - Definition getAnInput() { none() } - } + deprecated class PseudoDefinition = PhiNode; /** * An SSA phi node, that is, a pseudo definition for a variable at a point * in the flow graph where otherwise two or more definitions for the variable * would be visible. */ - class PhiNode extends PseudoDefinition, TPhiNode { + class PhiNode extends Definition, SsaImpl::PhiNode { /** * Gets an input of this phi node. Example: * @@ -2557,19 +691,11 @@ module Ssa { * definition on line 4, the explicit definition on line 7, and the implicit * call definition on line 9 as inputs. */ - override Definition getAnInput() { - exists(BasicBlock bb, BasicBlock phiPred, TrackedVar v | - definesAt(this, bb, _, v) and - bb.getAPredecessor() = phiPred and - ssaDefReachesEndOfBlock(phiPred, result, v) - ) - } + final Definition getAnInput() { this.hasInputFromBlock(result, _) } - /** Holds if `inp` is an input to the phi node along the edge originating in `bb`. */ - predicate hasInputFromBlock(Definition inp, BasicBlock bb) { - this.getAnInput() = inp and - this.getBasicBlock().getAPredecessor() = bb and - inp.isLiveAtEndOfBlock(bb) + /** Holds if `inp` is an input to this phi node along the edge originating in `bb`. */ + predicate hasInputFromBlock(Definition inp, ControlFlow::BasicBlock bb) { + inp = SsaImpl::phiHasInputFromBlock(this, bb) } override string toString() { @@ -2584,12 +710,7 @@ module Ssa { * does not exist in the source program. */ - override Location getLocation() { - exists(ControlFlow::BasicBlocks::JoinBlock bb | - this = TPhiNode(_, bb) and - result = bb.getFirstNode().getLocation() - ) - } + override Location getLocation() { result = this.getBasicBlock().getFirstNode().getLocation() } } /** @@ -2598,27 +719,11 @@ module Ssa { * need not be certain), an implicit non-local update via a call, or an * uncertain update of the qualifier. */ - class UncertainDefinition extends Definition { - UncertainDefinition() { - this = - any(ExplicitDefinition def | - forex(AssignableDefinition ad | ad = def.getADefinition() | not ad.isCertain()) - ) - or - this instanceof ImplicitCallDefinition - or - this.(ImplicitQualifierDefinition).getQualifierDefinition() instanceof UncertainDefinition - } - + class UncertainDefinition extends Definition, SsaImpl::UncertainWriteDefinition { /** - * Gets the immediately preceding definition. Since this update is uncertain + * Gets the immediately preceding definition. Since this update is uncertain, * the value from the preceding definition might still be valid. */ - Definition getPriorDefinition() { ssaDefReachesUncertainDef(_, result, this) } - } - - /** INTERNAL: Do not use. */ - module Internal { - import SsaDefReaches + Definition getPriorDefinition() { result = SsaImpl::uncertainWriteDefinitionInput(this) } } } diff --git a/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowDispatch.qll b/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowDispatch.qll index 39a626c6dc1..c68ba38e0b5 100644 --- a/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowDispatch.qll +++ b/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowDispatch.qll @@ -101,7 +101,7 @@ private module Cached { TNonDelegateCall(ControlFlow::Nodes::ElementNode cfn, DispatchCall dc) { cfn.getElement() = dc.getCall() } or - TExplicitDelegateCall(ControlFlow::Nodes::ElementNode cfn, DelegateCall dc) { + TExplicitDelegateLikeCall(ControlFlow::Nodes::ElementNode cfn, DelegateLikeCall dc) { cfn.getElement() = dc } or TTransitiveCapturedCall(ControlFlow::Nodes::ElementNode cfn, Callable target) { @@ -308,12 +308,12 @@ abstract class DelegateDataFlowCall extends DataFlowCall { override DataFlowCallable getARuntimeTarget() { result = this.getARuntimeTarget(_) } } -/** An explicit delegate call relevant for data flow. */ -class ExplicitDelegateDataFlowCall extends DelegateDataFlowCall, TExplicitDelegateCall { +/** An explicit delegate or function pointer call relevant for data flow. */ +class ExplicitDelegateLikeDataFlowCall extends DelegateDataFlowCall, TExplicitDelegateLikeCall { private ControlFlow::Nodes::ElementNode cfn; - private DelegateCall dc; + private DelegateLikeCall dc; - ExplicitDelegateDataFlowCall() { this = TExplicitDelegateCall(cfn, dc) } + ExplicitDelegateLikeDataFlowCall() { this = TExplicitDelegateLikeCall(cfn, dc) } override DataFlowCallable getARuntimeTarget(CallContext::CallContext cc) { result = getCallableForDataFlow(dc.getARuntimeTarget(cc)) @@ -391,7 +391,7 @@ class SummaryDelegateCall extends DelegateDataFlowCall, TSummaryDelegateCall { override DataFlowCallable getARuntimeTarget(CallContext::CallContext cc) { exists(SummaryDelegateParameterSink p | - p = TSummaryParameterNode(c, pos) and + p.isParameterOf(c, pos) and result = p.getARuntimeTarget(cc) ) } diff --git a/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl.qll b/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl.qll index d9f5acdd279..59cc8d529a7 100644 --- a/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl.qll +++ b/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl.qll @@ -3598,6 +3598,7 @@ private module FlowExploration { or exists(PartialPathNodeRev mid | revPartialPathStep(mid, node, sc1, sc2, ap, config) and + not clearsContent(node, ap.getHead()) and not fullBarrier(node, config) and distSink(node.getEnclosingCallable(), config) <= config.explorationLimit() ) @@ -3611,6 +3612,7 @@ private module FlowExploration { exists(PartialPathNodeFwd mid | partialPathStep(mid, node, cc, sc1, sc2, ap, config) and not fullBarrier(node, config) and + not clearsContent(node, ap.getHead().getContent()) and if node instanceof CastingNode then compatibleTypes(getNodeType(node), ap.getType()) else any() diff --git a/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl2.qll b/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl2.qll index d9f5acdd279..59cc8d529a7 100644 --- a/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl2.qll +++ b/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl2.qll @@ -3598,6 +3598,7 @@ private module FlowExploration { or exists(PartialPathNodeRev mid | revPartialPathStep(mid, node, sc1, sc2, ap, config) and + not clearsContent(node, ap.getHead()) and not fullBarrier(node, config) and distSink(node.getEnclosingCallable(), config) <= config.explorationLimit() ) @@ -3611,6 +3612,7 @@ private module FlowExploration { exists(PartialPathNodeFwd mid | partialPathStep(mid, node, cc, sc1, sc2, ap, config) and not fullBarrier(node, config) and + not clearsContent(node, ap.getHead().getContent()) and if node instanceof CastingNode then compatibleTypes(getNodeType(node), ap.getType()) else any() diff --git a/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl3.qll b/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl3.qll index d9f5acdd279..59cc8d529a7 100644 --- a/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl3.qll +++ b/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl3.qll @@ -3598,6 +3598,7 @@ private module FlowExploration { or exists(PartialPathNodeRev mid | revPartialPathStep(mid, node, sc1, sc2, ap, config) and + not clearsContent(node, ap.getHead()) and not fullBarrier(node, config) and distSink(node.getEnclosingCallable(), config) <= config.explorationLimit() ) @@ -3611,6 +3612,7 @@ private module FlowExploration { exists(PartialPathNodeFwd mid | partialPathStep(mid, node, cc, sc1, sc2, ap, config) and not fullBarrier(node, config) and + not clearsContent(node, ap.getHead().getContent()) and if node instanceof CastingNode then compatibleTypes(getNodeType(node), ap.getType()) else any() diff --git a/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl4.qll b/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl4.qll index d9f5acdd279..59cc8d529a7 100644 --- a/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl4.qll +++ b/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl4.qll @@ -3598,6 +3598,7 @@ private module FlowExploration { or exists(PartialPathNodeRev mid | revPartialPathStep(mid, node, sc1, sc2, ap, config) and + not clearsContent(node, ap.getHead()) and not fullBarrier(node, config) and distSink(node.getEnclosingCallable(), config) <= config.explorationLimit() ) @@ -3611,6 +3612,7 @@ private module FlowExploration { exists(PartialPathNodeFwd mid | partialPathStep(mid, node, cc, sc1, sc2, ap, config) and not fullBarrier(node, config) and + not clearsContent(node, ap.getHead().getContent()) and if node instanceof CastingNode then compatibleTypes(getNodeType(node), ap.getType()) else any() diff --git a/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl5.qll b/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl5.qll index d9f5acdd279..59cc8d529a7 100644 --- a/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl5.qll +++ b/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl5.qll @@ -3598,6 +3598,7 @@ private module FlowExploration { or exists(PartialPathNodeRev mid | revPartialPathStep(mid, node, sc1, sc2, ap, config) and + not clearsContent(node, ap.getHead()) and not fullBarrier(node, config) and distSink(node.getEnclosingCallable(), config) <= config.explorationLimit() ) @@ -3611,6 +3612,7 @@ private module FlowExploration { exists(PartialPathNodeFwd mid | partialPathStep(mid, node, cc, sc1, sc2, ap, config) and not fullBarrier(node, config) and + not clearsContent(node, ap.getHead().getContent()) and if node instanceof CastingNode then compatibleTypes(getNodeType(node), ap.getType()) else any() diff --git a/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowPrivate.qll b/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowPrivate.qll index 2974bc6af6a..64452768185 100644 --- a/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowPrivate.qll +++ b/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowPrivate.qll @@ -10,6 +10,7 @@ private import FlowSummaryImpl as FlowSummaryImpl private import semmle.code.csharp.dataflow.FlowSummary private import semmle.code.csharp.Caching private import semmle.code.csharp.Conversion +private import semmle.code.csharp.dataflow.internal.SsaImpl as SsaImpl private import semmle.code.csharp.ExprOrStmtParent private import semmle.code.csharp.Unification private import semmle.code.csharp.controlflow.Guards @@ -265,33 +266,38 @@ module LocalFlow { } /** - * Holds if `nodeFrom` is a last node referencing SSA definition `def`. - * Either an SSA definition node for `def` when there is no read of `def`, - * or a last read of `def`. + * Holds if `nodeFrom` is a last node referencing SSA definition `def`, which + * can reach `next`. */ - private predicate localFlowSsaInput(Node nodeFrom, Ssa::Definition def) { - def = nodeFrom.(SsaDefinitionNode).getDefinition() and - not exists(def.getARead()) - or - exists(AssignableRead read, ControlFlow::Node cfn | read = nodeFrom.asExprAtNode(cfn) | - def.getALastReadAtNode(cfn) = read + private predicate localFlowSsaInput(Node nodeFrom, Ssa::Definition def, Ssa::Definition next) { + exists(ControlFlow::BasicBlock bb, int i | SsaImpl::lastRefBeforeRedef(def, bb, i, next) | + def = nodeFrom.(SsaDefinitionNode).getDefinition() and + def.definesAt(_, bb, i) + or + nodeFrom.asExprAtNode(bb.getNode(i)) instanceof AssignableRead ) } + private Ssa::Definition getSsaDefinition(Node n) { + result = n.(SsaDefinitionNode).getDefinition() + or + result = n.(ExplicitParameterNode).getSsaDefinition() + } + /** * Holds if there is a local flow step from `nodeFrom` to `nodeTo` involving * SSA definition `def. */ predicate localSsaFlowStep(Ssa::Definition def, Node nodeFrom, Node nodeTo) { - // Flow from SSA definition to first read + // Flow from SSA definition/parameter to first read exists(ControlFlow::Node cfn | - def = nodeFrom.(SsaDefinitionNode).getDefinition() and + def = getSsaDefinition(nodeFrom) and nodeTo.asExprAtNode(cfn) = def.getAFirstReadAtNode(cfn) ) or // Flow from read to next read exists(ControlFlow::Node cfnFrom, ControlFlow::Node cfnTo | - Ssa::Internal::adjacentReadPairSameVar(def, cfnFrom, cfnTo) and + SsaImpl::adjacentReadPairSameVar(def, cfnFrom, cfnTo) and nodeTo = TExprNode(cfnTo) | nodeFrom = TExprNode(cfnFrom) @@ -299,16 +305,16 @@ module LocalFlow { cfnFrom = nodeFrom.(PostUpdateNode).getPreUpdateNode().getControlFlowNode() ) or - // Flow into SSA pseudo definition - exists(Ssa::PseudoDefinition pseudo | - localFlowSsaInput(nodeFrom, def) and - pseudo = nodeTo.(SsaDefinitionNode).getDefinition() and - def = pseudo.getAnInput() + // Flow into phi node + exists(Ssa::PhiNode phi | + localFlowSsaInput(nodeFrom, def, phi) and + phi = nodeTo.(SsaDefinitionNode).getDefinition() and + def = phi.getAnInput() ) or // Flow into uncertain SSA definition exists(LocalFlow::UncertainExplicitSsaDefinition uncertain | - localFlowSsaInput(nodeFrom, def) and + localFlowSsaInput(nodeFrom, def, uncertain) and uncertain = nodeTo.(SsaDefinitionNode).getDefinition() and def = uncertain.getPriorDefinition() ) @@ -319,15 +325,14 @@ module LocalFlow { */ predicate usesInstanceField(Ssa::Definition def) { exists(Ssa::SourceVariables::FieldOrPropSourceVariable fp | fp = def.getSourceVariable() | - not fp.getAssignable().isStatic() + not fp.getAssignable().(Modifiable).isStatic() ) } - predicate localFlowCapturedVarStep(SsaDefinitionNode nodeFrom, ImplicitCapturedArgumentNode nodeTo) { + predicate localFlowCapturedVarStep(Node nodeFrom, ImplicitCapturedArgumentNode nodeTo) { // Flow from SSA definition to implicit captured variable argument exists(Ssa::ExplicitDefinition def, ControlFlow::Nodes::ElementNode call | - def = nodeFrom.getDefinition() - | + def = getSsaDefinition(nodeFrom) and def.isCapturedVariableDefinitionFlowIn(_, call, _) and nodeTo = TImplicitCapturedArgumentNode(call, def.getSourceVariable().getAssignable()) ) @@ -569,9 +574,15 @@ private module Cached { Stages::DataFlowStage::forceCachingInSameStage() and cfn.getElement() instanceof Expr } or TCilExprNode(CIL::Expr e) { e.getImplementation() instanceof CIL::BestImplementation } or - TSsaDefinitionNode(Ssa::Definition def) or - TInstanceParameterNode(Callable c) { c.hasBody() and not c.(Modifiable).isStatic() } or - TCilParameterNode(CIL::Parameter p) { p.getMethod().hasBody() } or + TSsaDefinitionNode(Ssa::Definition def) { + // Handled by `TExplicitParameterNode` below + not def.(Ssa::ExplicitDefinition).getADefinition() instanceof + AssignableDefinitions::ImplicitParameterDefinition + } or + TExplicitParameterNode(DotNet::Parameter p) { p.isUnboundDeclaration() } or + TInstanceParameterNode(Callable c) { + c.isUnboundDeclaration() and not c.(Modifiable).isStatic() + } or TYieldReturnNode(ControlFlow::Nodes::ElementNode cfn) { any(Callable c).canYieldReturn(cfn.getElement()) } or @@ -605,18 +616,6 @@ private module Cached { cfn.getElement() = fla.getQualifier() ) } or - TSummaryParameterNode(SummarizedCallable c, int i) { - exists(SummaryInput input | FlowSummaryImpl::Private::summary(c, input, _, _, _, _) | - input = SummaryInput::parameter(i) - or - input = SummaryInput::delegate(i) - ) - or - exists(SummaryOutput output | - FlowSummaryImpl::Private::summary(c, _, _, output, _, _) and - output = SummaryOutput::delegate(i, _) - ) - } or TSummaryInternalNode( SummarizedCallable c, FlowSummaryImpl::Private::SummaryInternalNodeState state ) { @@ -801,12 +800,10 @@ private module Cached { cached predicate isUnreachableInCall(Node n, DataFlowCall call) { exists( - SsaDefinitionNode paramNode, Ssa::ExplicitDefinition param, Guard guard, - ControlFlow::SuccessorTypes::BooleanSuccessor bs + ExplicitParameterNode paramNode, Guard guard, ControlFlow::SuccessorTypes::BooleanSuccessor bs | viableConstantBooleanParamArg(paramNode, bs.getValue().booleanNot(), call) and - paramNode.getDefinition() = param and - param.getARead() = guard and + paramNode.getSsaDefinition().getARead() = guard and guard.controlsBlock(n.getControlFlowNode().getBasicBlock(), bs, _) ) } @@ -867,13 +864,18 @@ private module Cached { cached predicate nodeIsHidden(Node n) { exists(Ssa::Definition def | def = n.(SsaDefinitionNode).getDefinition() | - def instanceof Ssa::PseudoDefinition + def instanceof Ssa::PhiNode or def instanceof Ssa::ImplicitEntryDefinition or def instanceof Ssa::ImplicitCallDefinition ) or + exists(Parameter p | + p = n.(ParameterNode).getParameter() and + not p.fromSource() + ) + or n instanceof YieldReturnNode or n instanceof ImplicitCapturedArgumentNode @@ -905,33 +907,25 @@ class SsaDefinitionNode extends NodeImpl, TSsaDefinitionNode { override Location getLocationImpl() { result = def.getLocation() } - override string toStringImpl() { - not explicitParameterNode(this, _) and - result = def.toString() - } + override string toStringImpl() { result = def.toString() } } private module ParameterNodes { abstract private class ParameterNodeImpl extends ParameterNode, NodeImpl { } - /** - * Holds if definition node `node` is an entry definition for parameter `p`. - */ - predicate explicitParameterNode(AssignableDefinitionNode node, Parameter p) { - p = node.getDefinition().(AssignableDefinitions::ImplicitParameterDefinition).getParameter() - } - /** * The value of an explicit parameter at function entry, viewed as a node in a data * flow graph. */ - class ExplicitParameterNode extends ParameterNodeImpl { + class ExplicitParameterNode extends ParameterNodeImpl, TExplicitParameterNode { private DotNet::Parameter parameter; - ExplicitParameterNode() { - explicitParameterNode(this, parameter) - or - this = TCilParameterNode(parameter) + ExplicitParameterNode() { this = TExplicitParameterNode(parameter) } + + /** Gets the SSA definition corresponding to this parameter, if any. */ + Ssa::ExplicitDefinition getSsaDefinition() { + result.getADefinition().(AssignableDefinitions::ImplicitParameterDefinition).getParameter() = + this.getParameter() } override DotNet::Parameter getParameter() { result = parameter } @@ -1037,46 +1031,6 @@ private module ParameterNodes { c = this.getEnclosingCallable() } } - - /** A parameter node for a callable with a flow summary. */ - class SummaryParameterNode extends ParameterNodeImpl, SummaryNodeImpl, TSummaryParameterNode { - private SummarizedCallable sc; - private int i; - - SummaryParameterNode() { this = TSummaryParameterNode(sc, i) } - - override Parameter getParameter() { result = sc.getParameter(i) } - - override predicate isParameterOf(DataFlowCallable c, int pos) { - c = sc and - pos = i - } - - override Callable getEnclosingCallableImpl() { result = sc } - - override Type getTypeImpl() { - result = sc.getParameter(i).getType() - or - i = -1 and - result = sc.getDeclaringType() - } - - override ControlFlow::Node getControlFlowNodeImpl() { none() } - - override Location getLocationImpl() { - result = sc.getParameter(i).getLocation() - or - i = -1 and - result = sc.getLocation() - } - - override string toStringImpl() { - result = "[summary] " + sc.getParameter(i) - or - i = -1 and - result = "[summary] this" - } - } } import ParameterNodes @@ -1440,7 +1394,7 @@ private module OutNodes { private DataFlowCall csharpCall(Expr e, ControlFlow::Node cfn) { e = any(DispatchCall dc | result = TNonDelegateCall(cfn, dc)).getCall() or - result = TExplicitDelegateCall(cfn, e) + result = TExplicitDelegateLikeCall(cfn, e) } /** A valid return type for a method that uses `yield return`. */ @@ -1691,8 +1645,6 @@ private class FieldOrPropertyRead extends FieldOrPropertyAccess, AssignableRead * SSA updates. */ predicate hasNonlocalValue() { - this = any(Ssa::ImplicitUntrackedDefinition udef).getARead() - or exists(Ssa::Definition def, Ssa::ImplicitDefinition idef | def.getARead() = this and idef = def.getAnUltimateDefinition() @@ -1936,7 +1888,7 @@ private class ConstantBooleanArgumentNode extends ExprNode { pragma[noinline] private predicate viableConstantBooleanParamArg( - SsaDefinitionNode paramNode, boolean b, DataFlowCall call + ParameterNode paramNode, boolean b, DataFlowCall call ) { exists(ConstantBooleanArgumentNode arg | viableParamArg(call, paramNode, arg) and diff --git a/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowPublic.qll b/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowPublic.qll index bf012e53283..13ca7658240 100644 --- a/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowPublic.qll +++ b/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowPublic.qll @@ -119,12 +119,10 @@ class ExprNode extends Node { class ParameterNode extends Node { ParameterNode() { // charpred needed to avoid making `ParameterNode` abstract - explicitParameterNode(this, _) or + this = TExplicitParameterNode(_) or this.(SsaDefinitionNode).getDefinition() instanceof ImplicitCapturedParameterNodeImpl::SsaCapturedEntryDefinition or - this = TInstanceParameterNode(_) or - this = TCilParameterNode(_) or - this = TSummaryParameterNode(_, _) + this = TInstanceParameterNode(_) } /** Gets the parameter corresponding to this node, if any. */ diff --git a/csharp/ql/src/semmle/code/csharp/dataflow/internal/DelegateDataFlow.qll b/csharp/ql/src/semmle/code/csharp/dataflow/internal/DelegateDataFlow.qll index 32d492d8b29..e6b15b95d7f 100755 --- a/csharp/ql/src/semmle/code/csharp/dataflow/internal/DelegateDataFlow.qll +++ b/csharp/ql/src/semmle/code/csharp/dataflow/internal/DelegateDataFlow.qll @@ -10,11 +10,18 @@ private import semmle.code.csharp.dataflow.CallContext private import semmle.code.csharp.dataflow.internal.DataFlowDispatch private import semmle.code.csharp.dataflow.internal.DataFlowPrivate private import semmle.code.csharp.dataflow.internal.DataFlowPublic +private import semmle.code.csharp.dataflow.FlowSummary private import semmle.code.csharp.dispatch.Dispatch private import semmle.code.csharp.frameworks.system.linq.Expressions +/** A source of flow for a delegate or function pointer expression. */ +abstract private class DelegateLikeFlowSource extends DataFlow::ExprNode { + /** Gets the callable that is referenced in this delegate or function pointer flow source. */ + abstract Callable getCallable(); +} + /** A source of flow for a delegate expression. */ -private class DelegateFlowSource extends DataFlow::ExprNode { +private class DelegateFlowSource extends DelegateLikeFlowSource { Callable c; DelegateFlowSource() { @@ -26,11 +33,29 @@ private class DelegateFlowSource extends DataFlow::ExprNode { } /** Gets the callable that is referenced in this delegate flow source. */ - Callable getCallable() { result = c } + override Callable getCallable() { result = c } } -/** A sink of flow for a delegate expression. */ -abstract private class DelegateFlowSink extends DataFlow::Node { +/** A source of flow for a function pointer expression. */ +private class FunctionPointerFlowSource extends DelegateLikeFlowSource { + Callable c; + + FunctionPointerFlowSource() { + c = + this.getExpr() + .(AddressOfExpr) + .getOperand() + .(CallableAccess) + .getTarget() + .getUnboundDeclaration() + } + + /** Gets the callable that is referenced in this function pointer flow source. */ + override Callable getCallable() { result = c } +} + +/** A sink of flow for a delegate or function pointer expression. */ +abstract private class DelegateLikeFlowSink extends DataFlow::Node { /** * Gets an actual run-time target of this delegate call in the given call * context, if any. The call context records the *last* call required to @@ -84,32 +109,33 @@ abstract private class DelegateFlowSink extends DataFlow::Node { */ cached Callable getARuntimeTarget(CallContext context) { - exists(DelegateFlowSource dfs | + exists(DelegateLikeFlowSource dfs | flowsFrom(this, dfs, _, context) and result = dfs.getCallable() ) } } -/** A delegate call expression. */ -class DelegateCallExpr extends DelegateFlowSink, DataFlow::ExprNode { - DelegateCall dc; +/** A delegate or function pointer call expression. */ +class DelegateLikeCallExpr extends DelegateLikeFlowSink, DataFlow::ExprNode { + DelegateLikeCall dc; - DelegateCallExpr() { this.getExpr() = dc.getDelegateExpr() } + DelegateLikeCallExpr() { this.getExpr() = dc.getExpr() } - /** Gets the delegate call that this expression belongs to. */ - DelegateCall getDelegateCall() { result = dc } + /** Gets the delegate or function pointer call that this expression belongs to. */ + DelegateLikeCall getCall() { result = dc } } /** A parameter of delegate type belonging to a callable with a flow summary. */ -class SummaryDelegateParameterSink extends DelegateFlowSink, SummaryParameterNode { +class SummaryDelegateParameterSink extends DelegateLikeFlowSink, ParameterNode { SummaryDelegateParameterSink() { - this.getType() instanceof SystemLinqExpressions::DelegateExtType + this.getType() instanceof SystemLinqExpressions::DelegateExtType and + this.isParameterOf(any(SummarizedCallable c), _) } } /** A delegate expression that is added to an event. */ -class AddEventSource extends DelegateFlowSink, DataFlow::ExprNode { +class AddEventSource extends DelegateLikeFlowSink, DataFlow::ExprNode { AddEventExpr ae; AddEventSource() { this.getExpr() = ae.getRValue() } @@ -148,7 +174,7 @@ private class NormalReturnNode extends Node { * records the last call on the path from `node` to `sink`, if any. */ private predicate flowsFrom( - DelegateFlowSink sink, DataFlow::Node node, boolean isReturned, CallContext lastCall + DelegateLikeFlowSink sink, DataFlow::Node node, boolean isReturned, CallContext lastCall ) { // Base case sink = node and @@ -186,7 +212,8 @@ private predicate flowsFrom( or // Flow into a callable (delegate call) exists( - ParameterNode mid, CallContext prevLastCall, DelegateCall call, Callable c, Parameter p, int i + ParameterNode mid, CallContext prevLastCall, DelegateLikeCall call, Callable c, Parameter p, + int i | flowsFrom(sink, mid, isReturned, prevLastCall) and isReturned = false and @@ -236,14 +263,14 @@ private predicate flowIntoNonDelegateCall(NonDelegateCall call, Expr arg, DotNet } pragma[noinline] -private predicate flowIntoDelegateCall(DelegateCall call, Callable c, Expr arg, int i) { - exists(DelegateFlowSource dfs, DelegateCallExpr dce | +private predicate flowIntoDelegateCall(DelegateLikeCall call, Callable c, Expr arg, int i) { + exists(DelegateLikeFlowSource dfs, DelegateLikeCallExpr dce | // the call context is irrelevant because the delegate call // itself will be the context flowsFrom(dce, dfs, _, _) and arg = call.getArgument(i) and c = dfs.getCallable() and - call = dce.getDelegateCall() + call = dce.getCall() ) } @@ -253,11 +280,13 @@ private predicate flowOutOfNonDelegateCall(NonDelegateCall call, NormalReturnNod } pragma[noinline] -private predicate flowOutOfDelegateCall(DelegateCall dc, NormalReturnNode ret, CallContext lastCall) { - exists(DelegateFlowSource dfs, DelegateCallExpr dce, Callable c | +private predicate flowOutOfDelegateCall( + DelegateLikeCall dc, NormalReturnNode ret, CallContext lastCall +) { + exists(DelegateLikeFlowSource dfs, DelegateLikeCallExpr dce, Callable c | flowsFrom(dce, dfs, _, lastCall) and ret.getEnclosingCallable() = c and c = dfs.getCallable() and - dc = dce.getDelegateCall() + dc = dce.getCall() ) } diff --git a/csharp/ql/src/semmle/code/csharp/dataflow/internal/FlowSummarySpecific.qll b/csharp/ql/src/semmle/code/csharp/dataflow/internal/FlowSummarySpecific.qll index 5a96a77a2e7..2edca6111ed 100644 --- a/csharp/ql/src/semmle/code/csharp/dataflow/internal/FlowSummarySpecific.qll +++ b/csharp/ql/src/semmle/code/csharp/dataflow/internal/FlowSummarySpecific.qll @@ -87,7 +87,7 @@ module Private { NodeImpl inputNode(SummarizableCallable c, SummaryInput input) { exists(int i | input = TParameterSummaryInput(i) and - result = DataFlowPrivate::TSummaryParameterNode(c, i) + result.(ParameterNode).isParameterOf(c, i) ) or exists(int i | diff --git a/csharp/ql/src/semmle/code/csharp/dataflow/internal/SsaImpl.qll b/csharp/ql/src/semmle/code/csharp/dataflow/internal/SsaImpl.qll new file mode 100644 index 00000000000..7f54d3287d1 --- /dev/null +++ b/csharp/ql/src/semmle/code/csharp/dataflow/internal/SsaImpl.qll @@ -0,0 +1,1187 @@ +/** + * Provides classes for working with static single assignment (SSA) form. + */ + +import csharp +import SsaImplCommon + +/** + * Holds if the `i`th node of basic block `bb` reads source variable `v`. + */ +private predicate variableReadActual(ControlFlow::BasicBlock bb, int i, Ssa::SourceVariable v) { + v.getAnAccess().(AssignableRead) = bb.getNode(i).getElement() +} + +private module SourceVariableImpl { + private import AssignableDefinitions + + /** A field or a property. */ + class FieldOrProp extends Assignable, Modifiable { + FieldOrProp() { + this instanceof Field + or + this instanceof Property + } + + /** Holds if this is a volatile field. */ + predicate isVolatile() { this.(Field).isVolatile() } + } + + /** An instance field or property. */ + class InstanceFieldOrProp extends FieldOrProp { + InstanceFieldOrProp() { not this.isStatic() } + } + + /** An access to a field or a property. */ + class FieldOrPropAccess extends AssignableAccess, QualifiableExpr { + FieldOrPropAccess() { this.getTarget() instanceof FieldOrProp } + } + + /** An access to a field or a property that reads the underlying value. */ + class FieldOrPropRead extends FieldOrPropAccess, AssignableRead { } + + /** + * Holds if `fpa` is an access inside callable `c` of `this`-qualified or + * static field or property `fp`. + */ + predicate isPlainFieldOrPropAccess(FieldOrPropAccess fpa, FieldOrProp fp, Callable c) { + fieldOrPropAccessInCallable(fpa, fp, c) and + (ownFieldOrPropAccess(fpa) or fp.isStatic()) + } + + /** + * Holds if `fpa` is an access inside callable `c` of instance field or property + * `fp` with qualifier `q`. + */ + predicate isQualifiedFieldOrPropAccess( + FieldOrPropAccess fpa, InstanceFieldOrProp fp, Callable c, Ssa::SourceVariable q + ) { + fieldOrPropAccessInCallable(fpa, fp, c) and + fpa.getQualifier() = q.getAnAccess() + } + + /** Holds if `fpa` is an access inside callable `c` of field or property `fp`. */ + private predicate fieldOrPropAccessInCallable(FieldOrPropAccess fpa, FieldOrProp fp, Callable c) { + fp = fpa.getTarget() and + c = fpa.getEnclosingCallable() + } + + /** Holds if `fpa` is an access to an instance field or property of `this`. */ + predicate ownFieldOrPropAccess(FieldOrPropAccess fpa) { fpa.getQualifier() instanceof ThisAccess } + + /** + * Holds if the `i`th node of basic block `bb` is assignable definition `ad` + * targeting source variable `v`. + */ + predicate variableDefinition( + ControlFlow::BasicBlock bb, int i, Ssa::SourceVariable v, AssignableDefinition ad + ) { + ad = v.getADefinition() and + ad.getAControlFlowNode() = bb.getNode(i) and + // In cases like `(x, x) = (0, 1)`, we discard the first (dead) definition of `x` + not exists(TupleAssignmentDefinition first, TupleAssignmentDefinition second | first = ad | + second.getAssignment() = first.getAssignment() and + second.getEvaluationOrder() > first.getEvaluationOrder() and + second = v.getADefinition() + ) and + // In cases like `M(out x, out x)`, there is no inherent evaluation order, so we + // collapse the two definitions of `x`, using the first access as the representative, + // and expose both definitions in `ExplicitDefinition.getADefinition()` + not ad = getASameOutRefDefAfter(v, _) + } + + /** + * Gets an `out`/`ref` definition of the same source variable as the `out`/`ref` + * definition `def`, belonging to the same call, at a position after `def`. + */ + OutRefDefinition getASameOutRefDefAfter(Ssa::SourceVariable v, OutRefDefinition def) { + def = v.getADefinition() and + result.getCall() = def.getCall() and + result.getIndex() > def.getIndex() and + result = v.getADefinition() + } + + /** + * Holds if the `i`th node of basic block `bb` is a (potential) write to source + * variable `v`. The Boolean `certain` indicates whether the write is certain. + * + * This excludes implicit writes via calls. + */ + predicate variableWriteDirect( + ControlFlow::BasicBlock bb, int i, Ssa::SourceVariable v, boolean certain + ) { + exists(AssignableDefinition ad | variableDefinition(bb, i, v, ad) | + if any(AssignableDefinition ad0 | ad0 = ad or ad0 = getASameOutRefDefAfter(v, ad)).isCertain() + then certain = true + else certain = false + ) + or + variableWriteDirect(bb, i, v.(QualifiedFieldOrPropSourceVariable).getQualifier(), certain) + or + implicitEntryDefinition(bb, v) and + i = -1 and + certain = true + } + + /** + * Holds if a pseudo read for `ref` or `out` variable `v` happens at index `i` + * in basic block `bb`. A pseudo read is inserted to make assignments to + * `out`/`ref` variables live, for example line 1 in + * + * ```csharp + * void M(out int i) { + * i = 0; + * } + * ``` + */ + predicate outRefExitRead(ControlFlow::BasicBlock bb, int i, LocalScopeSourceVariable v) { + exists(ControlFlow::Nodes::AnnotatedExitNode exit | + exit.isNormal() and + exists(LocalScopeVariable lsv | + lsv = v.getAssignable() and + bb.getNode(i) = exit and + exit.getCallable() = lsv.getCallable() + | + lsv.(Parameter).isOutOrRef() + or + lsv.isRef() and + strictcount(v.getAnAccess()) > 1 + ) + ) + } + + /** + * Holds if a pseudo read for `ref` variable `v` happens at index `i` in basic + * block `bb`, just prior to an update of the referenced value. A pseudo read + * is inserted to make assignments to the `ref` variable live, for example + * line 2 in + * + * ```csharp + * void M() { + * ref int i = ref GetRef(); + * i = 0; + * } + * ``` + * + * The pseudo read is inserted at the CFG node `i` on the left-hand side of the + * assignment on line 3. + */ + predicate refReadBeforeWrite(ControlFlow::BasicBlock bb, int i, LocalScopeSourceVariable v) { + exists(AssignableDefinitions::AssignmentDefinition def, LocalVariable lv | + def.getTarget() = lv and + lv.isRef() and + lv = v.getAssignable() and + bb.getNode(i) = def.getAControlFlowNode() + ) + } + + /** + * Holds if `fp` is a field or a property that is interesting as a basis for SSA. + * + * - A volatile field is never interesting, since all reads must reread from + * memory and we are forced to assume that the value can change at any point. + * - A property is only interesting if it is "field-like", that is, it is a + * non-overridable trivial property. + */ + predicate trackFieldOrProp(FieldOrProp fp) { + not fp.isVolatile() and + ( + fp instanceof Field + or + fp = any(TrivialProperty p | not p.isOverridableOrImplementable()) + ) + } +} + +private import SourceVariableImpl +private import Ssa::SourceVariables + +private module CallGraph { + private import semmle.code.csharp.dispatch.Dispatch + + /** + * Gets a potential run-time target for the call `c`. + * + * This predicate differs from `Call.getARuntimeTarget()` in three ways: + * + * (1) The returned callable is always a source declaration, + * + * (2) a simpler analysis is applied for delegate calls (needed to avoid making + * the SSA library and `Call.getARuntimeTarget()` mutually recursive), and + * + * (3) indirect calls to delegates via calls to library callables are included. + * + * The Boolean `libraryDelegateCall` indicates whether `c` is a call to a library + * method and the result is a delegate passed to `c`. For example, in + * + * ```csharp + * Lazy M1() + * { + * return new Lazy(M2); + * } + * ``` + * + * the constructor call `new Lazy(M2)` includes `M2` as a target. + */ + Callable getARuntimeTarget(Call c, boolean libraryDelegateCall) { + // Non-delegate call: use dispatch library + exists(DispatchCall dc | dc.getCall() = c | + result = dc.getADynamicTarget().getUnboundDeclaration() and + libraryDelegateCall = false + ) + or + // Delegate call: use simple analysis + result = SimpleDelegateAnalysis::getARuntimeDelegateTarget(c, libraryDelegateCall) + } + + private module SimpleDelegateAnalysis { + private import semmle.code.csharp.dataflow.internal.DelegateDataFlow + private import semmle.code.csharp.dataflow.internal.Steps + private import semmle.code.csharp.frameworks.system.linq.Expressions + + /** + * Holds if `c` is a call that (potentially) calls the delegate expression `e`. + * Either `c` is a delegate call and `e` is the qualifier, or `c` is a call to + * a library callable and `e` is a delegate argument. + */ + private predicate delegateCall(Call c, Expr e, boolean libraryDelegateCall) { + c = any(DelegateCall dc | e = dc.getExpr()) and + libraryDelegateCall = false + or + c.getTarget().fromLibrary() and + e = c.getAnArgument() and + e.getType() instanceof SystemLinqExpressions::DelegateExtType and + libraryDelegateCall = true + } + + /** Holds if expression `e` is a delegate creation for callable `c` of type `t`. */ + private predicate delegateCreation(Expr e, Callable c, SystemLinqExpressions::DelegateExtType dt) { + e = + any(AnonymousFunctionExpr afe | + dt = afe.getType() and + c = afe + ) + or + e = + any(CallableAccess ca | + c = ca.getTarget().getUnboundDeclaration() and + dt = ca.getType() + ) + } + + private predicate delegateFlowStep(Expr pred, Expr succ) { + Steps::stepClosed(pred, succ) + or + exists(Call call, Callable callable | + callable.getUnboundDeclaration().canReturn(pred) and + call = succ + | + callable = call.getTarget() or + callable = call.getTarget().(Method).getAnOverrider+() or + callable = call.getTarget().(Method).getAnUltimateImplementor() or + callable = getARuntimeDelegateTarget(call, false) + ) + or + pred = succ.(DelegateCreation).getArgument() + or + exists(AssignableDefinition def, Assignable a | + a instanceof Field or + a instanceof Property + | + a = def.getTarget() and + succ.(AssignableRead) = a.getAnAccess() and + pred = def.getSource() + ) + or + exists(AddEventExpr ae | succ.(EventAccess).getTarget() = ae.getTarget() | + pred = ae.getRValue() + ) + } + + private predicate reachesDelegateCall(Expr e) { + delegateCall(_, e, _) + or + exists(Expr mid | reachesDelegateCall(mid) | delegateFlowStep(e, mid)) + } + + pragma[nomagic] + private predicate delegateFlowStepReaches(Expr pred, Expr succ) { + delegateFlowStep(pred, succ) and + reachesDelegateCall(succ) + } + + private Expr delegateCallSource(Callable c) { + delegateCreation(result, c, _) + or + delegateFlowStepReaches(delegateCallSource(c), result) + } + + /** Gets a run-time target for the delegate call `c`. */ + Callable getARuntimeDelegateTarget(Call c, boolean libraryDelegateCall) { + delegateCall(c, delegateCallSource(result), libraryDelegateCall) + } + } + + /** Holds if `(c1,c2)` is an edge in the call graph. */ + predicate callEdge(Callable c1, Callable c2) { + exists(Call c | c.getEnclosingCallable() = c1 and c2 = getARuntimeTarget(c, _)) + } +} + +private import CallGraph + +/** + * The SSA construction for a field or a property `fp` relies on implicit + * update nodes at every call site that conceivably could reach an update + * of the field or property. For example, there is an implicit update of + * `this.Field` on line 7 in + * + * ```csharp + * int Field; + * + * void SetField(int i) { Field = i; } + * + * int M() { + * Field = 0; + * SetField(1); // implicit update of `this.Field` + * return Field; + * } + * ``` + * + * At a first approximation, we need to find update paths of the form: + * + * ``` + * Call --(callEdge)-->* Callable(setter of fp) + * ``` + * + * This can be improved by excluding paths ending in: + * + * ``` + * Constructor --(intraInstanceCallEdge)-->+ Callable(setter of this.fp) + * ``` + * + * as these updates are guaranteed not to alias with the `fp` under + * consideration. + * + * This set of paths can be expressed positively by noting that those + * that set `this.fp`, end in zero or more `intraInstanceCallEdge`s between + * callables, and before those is either the originating `Call`: + * + * ``` + * Call --(intraInstanceCallEdge)-->* Callable(setter of this.fp) + * ``` + * + * or a `crossInstanceCallEdge`: + * + * ``` + * Call --crossInstanceCallEdge--> Callable + * --(intraInstanceCallEdge)-->* Callable(setter of this.fp) + * ``` + */ +private module FieldOrPropsImpl { + /** + * A callable that is neither static nor a constructor. + */ + private class InstanceCallable extends Callable { + InstanceCallable() { + not this.(Modifiable).isStatic() and + not this instanceof Constructor + } + } + + private class FieldOrPropDefinition extends AssignableDefinition { + FieldOrPropDefinition() { this.getTarget() instanceof FieldOrProp } + } + + /** + * Holds if `fpdef` is a definition that is not relevant as an implicit + * SSA update, since it is an initialization and therefore cannot alias. + */ + private predicate init(FieldOrPropDefinition fpdef) { + exists(FieldOrPropAccess access | access = fpdef.getTargetAccess() | + fpdef.getEnclosingCallable() instanceof Constructor and + ownFieldOrPropAccess(access) + or + exists(LocalVariable v | + v.getAnAccess() = access.getQualifier() and + not v.isCaptured() and + forex(AssignableDefinition def | def.getTarget() = v and exists(def.getSource()) | + def.getSource() instanceof ObjectCreation + ) + ) + ) + or + fpdef.(AssignableDefinitions::AssignmentDefinition).getAssignment() instanceof MemberInitializer + } + + /** + * Holds if `fpdef` is an update of `fp` in `c` that is relevant for SSA construction. + */ + private predicate relevantDefinition(Callable c, FieldOrProp fp, FieldOrPropDefinition fpdef) { + fpdef.getTarget() = fp and + not init(fpdef) and + fpdef.getEnclosingCallable() = c and + exists(FieldOrPropSourceVariable tf | tf.getAssignable() = fp) + } + + /** + * Holds if callable `c` can change the value of `this.fp` and is relevant + * for SSA construction. + */ + private predicate setsOwnFieldOrProp(InstanceCallable c, FieldOrProp fp) { + exists(FieldOrPropDefinition fpdef | relevantDefinition(c, fp, fpdef) | + ownFieldOrPropAccess(fpdef.getTargetAccess()) + ) + } + + /** + * Holds if callable `c` can change the value of `fp` and is relevant for SSA + * construction excluding those cases covered by `setsOwnFieldOrProp`. + */ + private predicate setsOtherFieldOrProp(Callable c, FieldOrProp fp) { + exists(FieldOrPropDefinition fpdef | relevantDefinition(c, fp, fpdef) | + not ownFieldOrPropAccess(fpdef.getTargetAccess()) + ) + } + + /** + * Holds if `(c1,c2)` is a call edge to a callable that does not change the + * value of `this`. + * + * Constructor-to-constructor calls can also be intra-instance, but are not + * included, as this does not affect whether a call chain ends in + * + * ``` + * Constructor --(intraInstanceCallEdge)-->+ Callable(setter of this.f) + * ``` + */ + private predicate intraInstanceCallEdge(Callable c1, InstanceCallable c2) { + exists(Call c | + c.getEnclosingCallable() = c1 and + c2 = getARuntimeTarget(c, _) and + c.(QualifiableExpr).targetIsLocalInstance() + ) + } + + /** + * Holds if `(c1,c2)` is an edge in the call graph excluding + * `intraInstanceCallEdge`. + */ + private predicate crossInstanceCallEdge(Callable c1, Callable c2) { + callEdge(c1, c2) and + not intraInstanceCallEdge(c1, c2) + } + + pragma[noinline] + predicate callAt(ControlFlow::BasicBlock bb, int i, Call call) { + bb.getNode(i) = call.getAControlFlowNode() and + getARuntimeTarget(call, _).hasBody() + } + + /** + * Holds if `call` occurs in basic block `bb` at index `i`, `fp` has + * an update somewhere, and `fp` is likely to be live in `bb` at index + * `i`. + */ + predicate updateCandidate( + ControlFlow::BasicBlock bb, int i, FieldOrPropSourceVariable fp, Call call + ) { + callAt(bb, i, call) and + call.getEnclosingCallable() = fp.getEnclosingCallable() and + relevantDefinition(_, fp.getAssignable(), _) and + not variableWriteDirect(bb, i, fp, _) + } + + private predicate source( + Call call, FieldOrPropSourceVariable fps, FieldOrProp fp, Callable c, boolean fresh + ) { + updateCandidate(_, _, fps, call) and + c = getARuntimeTarget(call, _) and + fp = fps.getAssignable() and + if c instanceof Constructor then fresh = true else fresh = false + } + + /** + * A callable in a potential call-chain between a source that cares about the + * value of some field `f` and a sink that may overwrite `f`. The Boolean + * `fresh` indicates whether the instance `this` in `c` has been freshly + * allocated along the call-chain. + */ + private newtype TCallableNode = + MkCallableNode(Callable c, boolean fresh) { source(_, _, _, c, fresh) or edge(_, c, fresh) } + + private predicate edge(TCallableNode n, Callable c2, boolean f2) { + exists(Callable c1, boolean f1 | n = MkCallableNode(c1, f1) | + intraInstanceCallEdge(c1, c2) and f2 = f1 + or + crossInstanceCallEdge(c1, c2) and + if c2 instanceof Constructor then f2 = true else f2 = false + ) + } + + private predicate edge(TCallableNode n1, TCallableNode n2) { + exists(Callable c2, boolean f2 | + edge(n1, c2, f2) and + n2 = MkCallableNode(c2, f2) + ) + } + + pragma[noinline] + private predicate source(Call call, FieldOrPropSourceVariable fps, FieldOrProp fp, TCallableNode n) { + exists(Callable c, boolean fresh | + source(call, fps, fp, c, fresh) and + n = MkCallableNode(c, fresh) + ) + } + + private predicate sink(Callable c, FieldOrProp fp, TCallableNode n) { + relevantDefinition(c, fp, _) and + ( + setsOwnFieldOrProp(c, fp) and n = MkCallableNode(c, false) + or + setsOtherFieldOrProp(c, fp) and n = MkCallableNode(c, _) + ) + } + + private predicate prunedNode(TCallableNode n) { + sink(_, _, n) + or + exists(TCallableNode mid | edge(n, mid) and prunedNode(mid)) + } + + private predicate prunedEdge(TCallableNode n1, TCallableNode n2) { + prunedNode(n1) and + prunedNode(n2) and + edge(n1, n2) + } + + private predicate edgePlus(TCallableNode c1, TCallableNode c2) = fastTC(prunedEdge/2)(c1, c2) + + pragma[noopt] + predicate updatesNamedFieldOrProp(FieldOrPropSourceVariable fps, Call call, Callable setter) { + exists(TCallableNode src, TCallableNode sink, FieldOrProp fp | + source(call, fps, fp, src) and + sink(setter, fp, sink) and + (src = sink or edgePlus(src, sink)) + ) + } +} + +/** + * As in the SSA construction for fields and properties, SSA construction + * for captured variables relies on implicit update nodes at every call + * site that conceivably could reach an update of the captured variable. + * For example, there is an implicit update of `v` on line 4 in + * + * ```csharp + * int M() { + * int i = 0; + * Action a = () => { i = 1; }; + * a(); // implicit update of `v` + * return i; + * } + * ``` + * + * We find update paths of the form: + * + * ``` + * Call --(callEdge)-->* Callable(update of v) + * ``` + * + * For simplicity, and for performance reasons, we ignore cases where a path + * goes through the callable that introduces `v`; such a path does not + * represent an actual update, as a new copy of `v` is updated. + */ +private module CapturedVariableImpl { + /** + * A local scope variable that is captured, and updated by at least one capturer. + */ + private class CapturedWrittenLocalScopeVariable extends LocalScopeVariable { + CapturedWrittenLocalScopeVariable() { + exists(AssignableDefinition def | def.getTarget() = this | + def.getEnclosingCallable() != this.getCallable() + ) + } + } + + private class CapturedWrittenLocalScopeSourceVariable extends LocalScopeSourceVariable { + CapturedWrittenLocalScopeSourceVariable() { + this.getAssignable() instanceof CapturedWrittenLocalScopeVariable + } + } + + private class CapturedWrittenLocalScopeVariableDefinition extends AssignableDefinition { + CapturedWrittenLocalScopeVariableDefinition() { + this.getTarget() instanceof CapturedWrittenLocalScopeVariable + } + } + + /** + * Holds if `vdef` is an update of captured variable `v` in callable `c` + * that is relevant for SSA construction. + */ + predicate relevantDefinition( + Callable c, CapturedWrittenLocalScopeVariable v, + CapturedWrittenLocalScopeVariableDefinition vdef + ) { + exists(ControlFlow::BasicBlock bb, int i, CapturedWrittenLocalScopeSourceVariable sv | + vdef.getTarget() = v and + vdef.getEnclosingCallable() = c and + sv.getAssignable() = v and + bb.getNode(i) = vdef.getAControlFlowNode() and + c != v.getCallable() + ) + } + + /** + * Holds if `call` occurs in basic block `bb` at index `i`, captured variable + * `v` has an update somewhere, and `v` is likely to be live in `bb` at index + * `i`. + */ + predicate updateCandidate( + ControlFlow::BasicBlock bb, int i, CapturedWrittenLocalScopeSourceVariable v, Call call + ) { + FieldOrPropsImpl::callAt(bb, i, call) and + call.getEnclosingCallable() = v.getEnclosingCallable() and + exists(Assignable a | + a = v.getAssignable() and + relevantDefinition(_, a, _) and + not exists(AssignableDefinitions::OutRefDefinition def | + def.getCall() = call and + def.getTarget() = a + ) + ) + } + + private predicate source( + Call call, CapturedWrittenLocalScopeSourceVariable v, + CapturedWrittenLocalScopeVariable captured, Callable c, boolean libraryDelegateCall + ) { + updateCandidate(_, _, v, call) and + c = getARuntimeTarget(call, libraryDelegateCall) and + captured = v.getAssignable() and + relevantDefinition(_, captured, _) + } + + /** + * Holds if `c` is a relevant part of the call graph for + * `updatesCapturedVariable` based on following edges in forward direction. + */ + private predicate reachbleFromSource(Callable c) { + source(_, _, _, c, _) + or + exists(Callable mid | reachbleFromSource(mid) | callEdge(mid, c)) + } + + private predicate sink(Callable c, CapturedWrittenLocalScopeVariable captured) { + reachbleFromSource(c) and + relevantDefinition(c, captured, _) + } + + private predicate prunedCallable(Callable c) { + sink(c, _) + or + exists(Callable mid | callEdge(c, mid) and prunedCallable(mid)) + } + + private predicate prunedEdge(Callable c1, Callable c2) { + prunedCallable(c1) and + prunedCallable(c2) and + callEdge(c1, c2) + } + + private predicate edgePlus(Callable c1, Callable c2) = fastTC(prunedEdge/2)(c1, c2) + + /** + * Holds if `call` may change the value of captured variable `v`. The actual + * update occurs in `writer`. That is, `writer` can be reached from `call` + * using zero or more additional calls (as indicated by `additionalCalls`). + * One of the intermediate callables may be the callable that introduces `v`, + * in which case `call` is not an actual update. + */ + pragma[noopt] + predicate updatesCapturedVariableWriter( + Call call, CapturedWrittenLocalScopeSourceVariable v, Callable writer, boolean additionalCalls + ) { + exists(Callable src, CapturedWrittenLocalScopeVariable captured, boolean libraryDelegateCall | + source(call, v, captured, src, libraryDelegateCall) and + sink(writer, captured) and + ( + src = writer and additionalCalls = libraryDelegateCall + or + edgePlus(src, writer) and additionalCalls = true + ) + ) + } +} + +/** + * Holds if the `i`th node of basic block `bb` is a (potential) write to source + * variable `v`. The Boolean `certain` indicates whether the write is certain. + * + * This includes implicit writes via calls. + */ +predicate variableWrite(ControlFlow::BasicBlock bb, int i, Ssa::SourceVariable v, boolean certain) { + variableWriteDirect(bb, i, v, certain) + or + variableWriteQualifier(bb, i, v, certain) + or + updatesNamedFieldOrProp(bb, i, _, v, _) and + certain = false + or + updatesCapturedVariable(bb, i, _, v, _, _) and + certain = false +} + +/** + * Liveness analysis to restrict the size of the SSA representation for + * captured variables. + * + * Example: + * + * ```csharp + * void M() { + * int i = 0; + * void M2() { + * System.Console.WriteLine(i); + * } + * M2(); + * } + * ``` + * + * The definition of `i` on line 2 is live, because of the call to `M2` on + * line 6. However, that call is not a direct read of `i`, so we account + * for that by inserting an implicit read of `i` on line 6. + * + * The predicates in this module follow the same structure as those in + * `CapturedVariableImpl`. + */ +private module CapturedVariableLivenessImpl { + /** + * Holds if `c` is a callable that captures local scope variable `v`, and + * `c` may read the value of the captured variable. + */ + private predicate capturerReads(Callable c, LocalScopeVariable v) { + exists(LocalScopeSourceVariable sv | + c = sv.getEnclosingCallable() and + v = sv.getAssignable() and + v.getCallable() != c + | + variableReadActual(_, _, sv) + or + refReadBeforeWrite(_, _, sv) + ) + } + + /** + * A local scope variable that is captured, and read by at least one capturer. + */ + private class CapturedReadLocalScopeVariable extends LocalScopeVariable { + CapturedReadLocalScopeVariable() { capturerReads(_, this) } + } + + private class CapturedReadLocalScopeSourceVariable extends LocalScopeSourceVariable { + CapturedReadLocalScopeSourceVariable() { + this.getAssignable() instanceof CapturedReadLocalScopeVariable + } + } + + /** + * Holds if a write to captured source variable `v` may be read by a + * callable reachable from the call `c`. + */ + private predicate implicitReadCandidate( + CapturedReadLocalScopeSourceVariable v, ControlFlow::Nodes::ElementNode c + ) { + exists(ControlFlow::BasicBlock bb, int i | variableWriteDirect(bb, i, v, _) | + c = bb.getNode(any(int j | j > i)) + or + c = bb.getASuccessor+().getANode() + ) + } + + private predicate source( + ControlFlow::Nodes::ElementNode call, CapturedReadLocalScopeSourceVariable v, + CapturedReadLocalScopeVariable captured, Callable c, boolean libraryDelegateCall + ) { + implicitReadCandidate(v, call) and + c = getARuntimeTarget(call.getElement(), libraryDelegateCall) and + captured = v.getAssignable() and + capturerReads(_, captured) + } + + /** + * Holds if `c` is a relevant part of the call graph for + * `readsCapturedVariable` based on following edges in forward direction. + */ + private predicate reachbleFromSource(Callable c) { + source(_, _, _, c, _) + or + exists(Callable mid | reachbleFromSource(mid) | callEdge(mid, c)) + } + + private predicate sink(Callable c, CapturedReadLocalScopeVariable captured) { + reachbleFromSource(c) and + capturerReads(c, captured) + } + + private predicate prunedCallable(Callable c) { + sink(c, _) + or + exists(Callable mid | callEdge(c, mid) and prunedCallable(mid)) + } + + private predicate prunedEdge(Callable c1, Callable c2) { + prunedCallable(c1) and + prunedCallable(c2) and + callEdge(c1, c2) + } + + private predicate edgePlus(Callable c1, Callable c2) = fastTC(prunedEdge/2)(c1, c2) + + /** + * Holds if `call` may read the value of captured variable `v`. The actual + * read occurs in `reader`. That is, `reader` can be reached from `call` + * using zero or more additional calls (as indicated by `additionalCalls`). + * One of the intermediate callables may be a callable that writes to `v`, + * in which case `call` is not an actual read. + */ + pragma[noopt] + private predicate readsCapturedVariable( + ControlFlow::Nodes::ElementNode call, CapturedReadLocalScopeSourceVariable v, Callable reader, + boolean additionalCalls + ) { + exists(Callable src, CapturedReadLocalScopeVariable captured, boolean libraryDelegateCall | + source(call, v, captured, src, libraryDelegateCall) and + sink(reader, captured) and + ( + src = reader and additionalCalls = libraryDelegateCall + or + edgePlus(src, reader) and additionalCalls = true + ) + ) + } + + /** + * Holds if captured local scope variable `v` is written inside the callable + * to which `bb` belongs, and the value may be read via `call` using zero or + * more additional calls (as indicated by `additionalCalls`). + * + * In this case a pseudo-read is inserted at the exit node at index `i` in `bb`, + * in order to make the write live. + * + * Example: + * + * ```csharp + * class C { + * void M1() { + * int i = 0; + * void M2() { i = 2; }; + * M2(); + * System.Console.WriteLine(i); + * } + * } + * ``` + * + * The write to `i` inside `M2` on line 4 is live because of the implicit call + * definition on line 5. + */ + predicate capturedReadOut( + ControlFlow::BasicBlock bb, int i, LocalScopeSourceVariable v, LocalScopeSourceVariable outer, + Call call, boolean additionalCalls + ) { + exists( + ControlFlow::Nodes::AnnotatedExitNode exit, ControlFlow::BasicBlock pred, + AssignableDefinition adef + | + exit.isNormal() and + variableDefinition(pred, _, v, adef) and + updatesCapturedVariable(_, _, call, outer, adef, additionalCalls) and + pred.getASuccessor*() = bb and + exit = bb.getNode(i) + ) + } + + /** + * Holds if a value written to captured local scope variable `outer` may be + * read as `inner` via `call`, at index `i` in basic block `bb`, using one or + * more calls (as indicated by `additionalCalls`). + * + * Example: + * + * ```csharp + * class C { + * void M1() { + * int i = 0; + * void M2() => System.Console.WriteLine(i); + * i = 1; + * M2(); + * } + * } + * ``` + * + * The write to `i` on line 5 is live because of the call to `M2` on line 6, which + * reaches the entry definition for `i` in `M2` on line 4. + */ + predicate capturedReadIn( + ControlFlow::BasicBlock bb, int i, LocalScopeSourceVariable outer, + LocalScopeSourceVariable inner, ControlFlow::Nodes::ElementNode call, boolean additionalCalls + ) { + exists(Callable reader | + implicitReadCandidate(outer, call) and + readsCapturedVariable(call, outer, reader, additionalCalls) and + reader = inner.getEnclosingCallable() and + outer.getAssignable() = inner.getAssignable() and + call = bb.getNode(i) + ) + } +} + +private import CapturedVariableLivenessImpl + +private predicate variableReadPseudo(ControlFlow::BasicBlock bb, int i, Ssa::SourceVariable v) { + outRefExitRead(bb, i, v) + or + refReadBeforeWrite(bb, i, v) + or + capturedReadOut(bb, i, v, _, _, _) + or + capturedReadIn(bb, i, v, _, _, _) +} + +/** + * Holds if the `i`th of basic block `bb` reads source variable `v`. + * + * This includes implicit reads via calls. + */ +predicate variableRead(ControlFlow::BasicBlock bb, int i, Ssa::SourceVariable v, boolean certain) { + variableReadActual(bb, i, v) and + certain = true + or + variableReadPseudo(bb, i, v) and + certain = false +} + +cached +private module Cached { + cached + newtype TSourceVariable = + TLocalVar(Callable c, LocalScopeVariable v) { + c = v.getCallable() + or + // Local scope variables can be captured + c = v.getAnAccess().getEnclosingCallable() + } or + TPlainFieldOrProp(Callable c, FieldOrProp f) { + exists(FieldOrPropRead fr | isPlainFieldOrPropAccess(fr, f, c)) and + trackFieldOrProp(f) + } or + TQualifiedFieldOrProp(Callable c, Ssa::SourceVariable q, InstanceFieldOrProp f) { + exists(FieldOrPropRead fr | isQualifiedFieldOrPropAccess(fr, f, c, q)) and + trackFieldOrProp(f) + } + + /** Gets an access to source variable `v`. */ + cached + AssignableAccess getAnAccess(Ssa::SourceVariable v) { + exists(Callable c | + exists(LocalScopeVariable lsv | v = TLocalVar(c, lsv) | + result = lsv.getAnAccess() and + result.getEnclosingCallable() = c + ) + or + exists(FieldOrProp fp | v = TPlainFieldOrProp(c, fp) | + isPlainFieldOrPropAccess(result, fp, c) + ) + or + exists(FieldOrProp fp, Ssa::SourceVariable q | v = TQualifiedFieldOrProp(c, q, fp) | + isQualifiedFieldOrPropAccess(result, fp, c, q) + ) + ) + } + + cached + predicate implicitEntryDefinition( + ControlFlow::ControlFlow::BasicBlocks::EntryBlock bb, Ssa::SourceVariable v + ) { + exists(Callable c | + c = bb.getCallable() and + c = v.getEnclosingCallable() + | + // Captured variable + exists(LocalScopeVariable lsv | + v = any(LocalScopeSourceVariable lv | lsv = lv.getAssignable()) + | + lsv.getCallable() != c + ) + or + // Each tracked field and property has an implicit entry definition + v instanceof PlainFieldOrPropSourceVariable + ) + } + + cached + AssignableDefinition getADefinition(Ssa::ExplicitDefinition def) { + exists(Ssa::SourceVariable v, AssignableDefinition ad | explicitDefinition(def, v, ad) | + result = ad or + result = getASameOutRefDefAfter(v, ad) + ) + } + + /** + * Holds if `call` may change the value of field or property `fp`. The actual + * update occurs in `setter`. + */ + cached + predicate updatesNamedFieldOrProp( + ControlFlow::BasicBlock bb, int i, Call c, FieldOrPropSourceVariable fp, Callable setter + ) { + FieldOrPropsImpl::updateCandidate(bb, i, fp, c) and + FieldOrPropsImpl::updatesNamedFieldOrProp(fp, c, setter) + } + + /** + * Holds if `call` may change the value of captured variable `v`. The actual + * update occurs in `def`. + */ + cached + predicate updatesCapturedVariable( + ControlFlow::BasicBlock bb, int i, Call call, LocalScopeSourceVariable v, + AssignableDefinition def, boolean additionalCalls + ) { + CapturedVariableImpl::updateCandidate(bb, i, v, call) and + exists(Callable writer | + CapturedVariableImpl::relevantDefinition(writer, v.getAssignable(), def) + | + CapturedVariableImpl::updatesCapturedVariableWriter(call, v, writer, additionalCalls) + ) + } + + cached + predicate variableWriteQualifier( + ControlFlow::BasicBlock bb, int i, QualifiedFieldOrPropSourceVariable v, boolean certain + ) { + variableWrite(bb, i, v.getQualifier(), certain) and + // Eliminate corner case where a call definition can overlap with a + // qualifier definition: if method `M` updates field `F`, then a call + // to `M` is both an update of `x.M` and `x.M.M`, so the former call + // definition should not give rise to an implicit qualifier definition + // for `x.M.M`. + not updatesNamedFieldOrProp(bb, i, _, v, _) + } + + cached + predicate isCapturedVariableDefinitionFlowIn( + Ssa::ExplicitDefinition def, Ssa::ImplicitEntryDefinition edef, + ControlFlow::Nodes::ElementNode c, boolean additionalCalls + ) { + exists(Ssa::SourceVariable v, Ssa::Definition def0, ControlFlow::BasicBlock bb, int i | + v = def.getSourceVariable() and + capturedReadIn(_, _, v, edef.getSourceVariable(), c, additionalCalls) and + def = def0.getAnUltimateDefinition() and + ssaDefReachesRead(_, def0, bb, i) and + capturedReadIn(bb, i, v, _, _, _) and + c = bb.getNode(i) + ) + } + + cached + predicate isCapturedVariableDefinitionFlowOut( + Ssa::ExplicitDefinition def, Ssa::ImplicitCallDefinition cdef, boolean additionalCalls + ) { + exists(Ssa::Definition def0, ControlFlow::BasicBlock bb, int i | + def = def0.getAnUltimateDefinition() and + capturedReadOut(bb, i, def0.getSourceVariable(), cdef.getSourceVariable(), cdef.getCall(), + additionalCalls) + ) + } + + cached + predicate explicitDefinition(WriteDefinition def, Ssa::SourceVariable v, AssignableDefinition ad) { + exists(ControlFlow::BasicBlock bb, int i | + def.definesAt(v, bb, i) and + variableDefinition(bb, i, v, ad) + ) + } + + cached + predicate isLiveAtEndOfBlock(Definition def, ControlFlow::BasicBlock bb) { + ssaDefReachesEndOfBlock(bb, def, _) + } + + cached + Definition phiHasInputFromBlock(PhiNode phi, ControlFlow::BasicBlock bb) { + phiHasInputFromBlock(phi, result, bb) + } + + cached + AssignableRead getAReadAtNode(Definition def, ControlFlow::Node cfn) { + exists(Ssa::SourceVariable v, ControlFlow::BasicBlock bb, int i | + ssaDefReachesRead(v, def, bb, i) and + variableReadActual(bb, i, v) and + cfn = bb.getNode(i) and + result.getAControlFlowNode() = cfn + ) + } + + /** + * Holds if the value defined at SSA definition `def` can reach a read at `cfn`, + * without passing through any other read. + */ + cached + predicate firstReadSameVar(Definition def, ControlFlow::Node cfn) { + exists(ControlFlow::BasicBlock bb1, int i1, ControlFlow::BasicBlock bb2, int i2 | + def.definesAt(_, bb1, i1) and + adjacentDefNoUncertainReads(def, bb1, i1, bb2, i2) and + cfn = bb2.getNode(i2) + ) + } + + /** + * Holds if the read at `cfn2` is a read of the same SSA definition `def` + * as the read at `cfn1`, and `cfn2` can be reached from `cfn1` without + * passing through another read. + */ + cached + predicate adjacentReadPairSameVar(Definition def, ControlFlow::Node cfn1, ControlFlow::Node cfn2) { + exists(ControlFlow::BasicBlock bb1, int i1, ControlFlow::BasicBlock bb2, int i2 | + cfn1 = bb1.getNode(i1) and + variableReadActual(bb1, i1, _) and + adjacentDefNoUncertainReads(def, bb1, i1, bb2, i2) and + cfn2 = bb2.getNode(i2) + ) + } + + cached + predicate lastRefBeforeRedef(Definition def, ControlFlow::BasicBlock bb, int i, Definition next) { + lastRefRedefNoUncertainReads(def, bb, i, next) + } + + cached + predicate lastReadSameVar(Definition def, ControlFlow::Node cfn) { + exists(ControlFlow::BasicBlock bb, int i | + lastRefNoUncertainReads(def, bb, i) and + variableReadActual(bb, i, _) and + cfn = bb.getNode(i) + ) + } + + cached + Definition uncertainWriteDefinitionInput(UncertainWriteDefinition def) { + uncertainWriteDefinitionInput(def, result) + } + + cached + predicate isLiveOutRefParameterDefinition(Ssa::Definition def, Parameter p) { + p.isOutOrRef() and + exists(Ssa::SourceVariable v, Ssa::Definition def0, ControlFlow::BasicBlock bb, int i | + v = def.getSourceVariable() and + p = v.getAssignable() and + def = def0.getAnUltimateDefinition() and + ssaDefReachesRead(_, def0, bb, i) and + outRefExitRead(bb, i, v) + ) + } +} + +import Cached diff --git a/csharp/ql/src/semmle/code/csharp/dataflow/internal/SsaImplCommon.qll b/csharp/ql/src/semmle/code/csharp/dataflow/internal/SsaImplCommon.qll new file mode 100644 index 00000000000..be01c05b8fa --- /dev/null +++ b/csharp/ql/src/semmle/code/csharp/dataflow/internal/SsaImplCommon.qll @@ -0,0 +1,619 @@ +/** + * Provides a language-independant implementation of static single assignment + * (SSA) form. + */ + +private import SsaImplSpecific + +private BasicBlock getABasicBlockPredecessor(BasicBlock bb) { getABasicBlockSuccessor(result) = bb } + +/** + * Liveness analysis (based on source variables) to restrict the size of the + * SSA representation. + */ +private module Liveness { + /** + * A classification of variable references into reads (of a given kind) and + * (certain or uncertain) writes. + */ + private newtype TRefKind = + Read(boolean certain) { certain in [false, true] } or + Write(boolean certain) { certain in [false, true] } + + private class RefKind extends TRefKind { + string toString() { + exists(boolean certain | this = Read(certain) and result = "read (" + certain + ")") + or + exists(boolean certain | this = Write(certain) and result = "write (" + certain + ")") + } + + int getOrder() { + this = Read(_) and + result = 0 + or + this = Write(_) and + result = 1 + } + } + + /** + * Holds if the `i`th node of basic block `bb` is a reference to `v` of kind `k`. + */ + private predicate ref(BasicBlock bb, int i, SourceVariable v, RefKind k) { + exists(boolean certain | variableRead(bb, i, v, certain) | k = Read(certain)) + or + exists(boolean certain | variableWrite(bb, i, v, certain) | k = Write(certain)) + } + + private newtype OrderedRefIndex = + MkOrderedRefIndex(int i, int tag) { + exists(RefKind rk | ref(_, i, _, rk) | tag = rk.getOrder()) + } + + private OrderedRefIndex refOrd(BasicBlock bb, int i, SourceVariable v, RefKind k, int ord) { + ref(bb, i, v, k) and + result = MkOrderedRefIndex(i, ord) and + ord = k.getOrder() + } + + /** + * Gets the (1-based) rank of the reference to `v` at the `i`th node of + * basic block `bb`, which has the given reference kind `k`. + * + * Reads are considered before writes when they happen at the same index. + */ + private int refRank(BasicBlock bb, int i, SourceVariable v, RefKind k) { + refOrd(bb, i, v, k, _) = + rank[result](int j, int ord, OrderedRefIndex res | + res = refOrd(bb, j, v, _, ord) + | + res order by j, ord + ) + } + + private int maxRefRank(BasicBlock bb, SourceVariable v) { + result = refRank(bb, _, v, _) and + not result + 1 = refRank(bb, _, v, _) + } + + /** + * Gets the (1-based) rank of the first reference to `v` inside basic block `bb` + * that is either a read or a certain write. + */ + private int firstReadOrCertainWrite(BasicBlock bb, SourceVariable v) { + result = + min(int r, RefKind k | + r = refRank(bb, _, v, k) and + k != Write(false) + | + r + ) + } + + /** + * Holds if source variable `v` is live at the beginning of basic block `bb`. + */ + predicate liveAtEntry(BasicBlock bb, SourceVariable v) { + // The first read or certain write to `v` inside `bb` is a read + refRank(bb, _, v, Read(_)) = firstReadOrCertainWrite(bb, v) + or + // There is no certain write to `v` inside `bb`, but `v` is live at entry + // to a successor basic block of `bb` + not exists(firstReadOrCertainWrite(bb, v)) and + liveAtExit(bb, v) + } + + /** + * Holds if source variable `v` is live at the end of basic block `bb`. + */ + predicate liveAtExit(BasicBlock bb, SourceVariable v) { + liveAtEntry(getABasicBlockSuccessor(bb), v) + } + + /** + * Holds if variable `v` is live in basic block `bb` at index `i`. + * The rank of `i` is `rnk` as defined by `refRank()`. + */ + private predicate liveAtRank(BasicBlock bb, int i, SourceVariable v, int rnk) { + exists(RefKind kind | rnk = refRank(bb, i, v, kind) | + rnk = maxRefRank(bb, v) and + liveAtExit(bb, v) + or + ref(bb, i, v, kind) and + kind = Read(_) + or + exists(RefKind nextKind | + liveAtRank(bb, _, v, rnk + 1) and + rnk + 1 = refRank(bb, _, v, nextKind) and + nextKind != Write(true) + ) + ) + } + + /** + * Holds if variable `v` is live after the (certain or uncertain) write at + * index `i` inside basic block `bb`. + */ + predicate liveAfterWrite(BasicBlock bb, int i, SourceVariable v) { + exists(int rnk | rnk = refRank(bb, i, v, Write(_)) | liveAtRank(bb, i, v, rnk)) + } +} + +private import Liveness + +/** Holds if `bb1` strictly dominates `bb2`. */ +private predicate strictlyDominates(BasicBlock bb1, BasicBlock bb2) { + bb1 = getImmediateBasicBlockDominator+(bb2) +} + +/** Holds if `bb1` dominates a predecessor of `bb2`. */ +private predicate dominatesPredecessor(BasicBlock bb1, BasicBlock bb2) { + exists(BasicBlock pred | pred = getABasicBlockPredecessor(bb2) | + bb1 = pred + or + strictlyDominates(bb1, pred) + ) +} + +/** Holds if `df` is in the dominance frontier of `bb`. */ +private predicate inDominanceFrontier(BasicBlock bb, BasicBlock df) { + dominatesPredecessor(bb, df) and + not strictlyDominates(bb, df) +} + +/** + * Holds if `bb` is in the dominance frontier of a block containing a + * definition of `v`. + */ +pragma[noinline] +private predicate inDefDominanceFrontier(BasicBlock bb, SourceVariable v) { + exists(BasicBlock defbb, Definition def | + def.definesAt(v, defbb, _) and + inDominanceFrontier(defbb, bb) + ) +} + +cached +newtype TDefinition = + TWriteDef(SourceVariable v, BasicBlock bb, int i) { + variableWrite(bb, i, v, _) and + liveAfterWrite(bb, i, v) + } or + TPhiNode(SourceVariable v, BasicBlock bb) { + inDefDominanceFrontier(bb, v) and + liveAtEntry(bb, v) + } + +private module SsaDefReaches { + newtype TSsaRefKind = + SsaRead() or + SsaDef() + + /** + * A classification of SSA variable references into reads and definitions. + */ + class SsaRefKind extends TSsaRefKind { + string toString() { + this = SsaRead() and + result = "SsaRead" + or + this = SsaDef() and + result = "SsaDef" + } + + int getOrder() { + this = SsaRead() and + result = 0 + or + this = SsaDef() and + result = 1 + } + } + + /** + * Holds if the `i`th node of basic block `bb` is a reference to `v`, + * either a read (when `k` is `SsaRead()`) or an SSA definition (when `k` + * is `SsaDef()`). + * + * Unlike `Liveness::ref`, this includes `phi` nodes. + */ + predicate ssaRef(BasicBlock bb, int i, SourceVariable v, SsaRefKind k) { + variableRead(bb, i, v, _) and + k = SsaRead() + or + exists(Definition def | def.definesAt(v, bb, i)) and + k = SsaDef() + } + + private newtype OrderedSsaRefIndex = + MkOrderedSsaRefIndex(int i, SsaRefKind k) { ssaRef(_, i, _, k) } + + private OrderedSsaRefIndex ssaRefOrd(BasicBlock bb, int i, SourceVariable v, SsaRefKind k, int ord) { + ssaRef(bb, i, v, k) and + result = MkOrderedSsaRefIndex(i, k) and + ord = k.getOrder() + } + + /** + * Gets the (1-based) rank of the reference to `v` at the `i`th node of basic + * block `bb`, which has the given reference kind `k`. + * + * For example, if `bb` is a basic block with a phi node for `v` (considered + * to be at index -1), reads `v` at node 2, and defines it at node 5, we have: + * + * ```ql + * ssaRefRank(bb, -1, v, SsaDef()) = 1 // phi node + * ssaRefRank(bb, 2, v, Read()) = 2 // read at node 2 + * ssaRefRank(bb, 5, v, SsaDef()) = 3 // definition at node 5 + * ``` + * + * Reads are considered before writes when they happen at the same index. + */ + int ssaRefRank(BasicBlock bb, int i, SourceVariable v, SsaRefKind k) { + ssaRefOrd(bb, i, v, k, _) = + rank[result](int j, int ord, OrderedSsaRefIndex res | + res = ssaRefOrd(bb, j, v, _, ord) + | + res order by j, ord + ) + } + + int maxSsaRefRank(BasicBlock bb, SourceVariable v) { + result = ssaRefRank(bb, _, v, _) and + not result + 1 = ssaRefRank(bb, _, v, _) + } + + /** + * Holds if the SSA definition `def` reaches rank index `rnk` in its own + * basic block `bb`. + */ + predicate ssaDefReachesRank(BasicBlock bb, Definition def, int rnk, SourceVariable v) { + exists(int i | + rnk = ssaRefRank(bb, i, v, SsaDef()) and + def.definesAt(v, bb, i) + ) + or + ssaDefReachesRank(bb, def, rnk - 1, v) and + rnk = ssaRefRank(bb, _, v, SsaRead()) + } + + /** + * Holds if the SSA definition of `v` at `def` reaches index `i` in the same + * basic block `bb`, without crossing another SSA definition of `v`. + */ + predicate ssaDefReachesReadWithinBlock(SourceVariable v, Definition def, BasicBlock bb, int i) { + exists(int rnk | + ssaDefReachesRank(bb, def, rnk, v) and + rnk = ssaRefRank(bb, i, v, SsaRead()) and + variableRead(bb, i, v, _) + ) + } + + /** + * Holds if the SSA definition of `v` at `def` reaches uncertain SSA definition + * `redef` in the same basic block, without crossing another SSA definition of `v`. + */ + predicate ssaDefReachesUncertainDefWithinBlock( + SourceVariable v, Definition def, UncertainWriteDefinition redef + ) { + exists(BasicBlock bb, int rnk, int i | + ssaDefReachesRank(bb, def, rnk, v) and + rnk = ssaRefRank(bb, i, v, SsaDef()) - 1 and + redef.definesAt(v, bb, i) + ) + } + + /** + * Same as `ssaRefRank()`, but restricted to a particular SSA definition `def`. + */ + int ssaDefRank(Definition def, SourceVariable v, BasicBlock bb, int i, SsaRefKind k) { + v = def.getSourceVariable() and + result = ssaRefRank(bb, i, v, k) and + ( + ssaDefReachesRead(_, def, bb, i) + or + def.definesAt(_, bb, i) + ) + } + + predicate defOccursInBlock(Definition def, BasicBlock bb, SourceVariable v) { + exists(ssaDefRank(def, v, bb, _, _)) + } + + pragma[noinline] + private BasicBlock getAMaybeLiveSuccessor(Definition def, BasicBlock bb) { + result = getABasicBlockSuccessor(bb) and + not defOccursInBlock(_, bb, def.getSourceVariable()) and + ssaDefReachesEndOfBlock(bb, def, _) + } + + /** + * Holds if `def` is accessed in basic block `bb1` (either a read or a write), + * `bb2` is a transitive successor of `bb1`, `def` is live at the end of `bb1`, + * and the underlying variable for `def` is neither read nor written in any block + * on the path between `bb1` and `bb2`. + */ + predicate varBlockReaches(Definition def, BasicBlock bb1, BasicBlock bb2) { + defOccursInBlock(def, bb1, _) and + bb2 = getABasicBlockSuccessor(bb1) + or + exists(BasicBlock mid | varBlockReaches(def, bb1, mid) | bb2 = getAMaybeLiveSuccessor(def, mid)) + } + + /** + * Holds if `def` is accessed in basic block `bb1` (either a read or a write), + * `def` is read at index `i2` in basic block `bb2`, `bb2` is in a transitive + * successor block of `bb1`, and `def` is neither read nor written in any block + * on a path between `bb1` and `bb2`. + */ + predicate defAdjacentRead(Definition def, BasicBlock bb1, BasicBlock bb2, int i2) { + varBlockReaches(def, bb1, bb2) and + ssaRefRank(bb2, i2, def.getSourceVariable(), SsaRead()) = 1 and + variableRead(bb2, i2, _, _) + } +} + +private import SsaDefReaches + +pragma[noinline] +private predicate ssaDefReachesEndOfBlockRec(BasicBlock bb, Definition def, SourceVariable v) { + exists(BasicBlock idom | ssaDefReachesEndOfBlock(idom, def, v) | + // The construction of SSA form ensures that each read of a variable is + // dominated by its definition. An SSA definition therefore reaches a + // control flow node if it is the _closest_ SSA definition that dominates + // the node. If two definitions dominate a node then one must dominate the + // other, so therefore the definition of _closest_ is given by the dominator + // tree. Thus, reaching definitions can be calculated in terms of dominance. + idom = getImmediateBasicBlockDominator(bb) + ) +} + +/** + * NB: If this predicate is exposed, it should be cached. + * + * Holds if the SSA definition of `v` at `def` reaches the end of basic + * block `bb`, at which point it is still live, without crossing another + * SSA definition of `v`. + */ +pragma[nomagic] +predicate ssaDefReachesEndOfBlock(BasicBlock bb, Definition def, SourceVariable v) { + exists(int last | last = maxSsaRefRank(bb, v) | + ssaDefReachesRank(bb, def, last, v) and + liveAtExit(bb, v) + ) + or + ssaDefReachesEndOfBlockRec(bb, def, v) and + liveAtExit(bb, v) and + not ssaRef(bb, _, v, SsaDef()) +} + +/** + * NB: If this predicate is exposed, it should be cached. + * + * Holds if `inp` is an input to the phi node `phi` along the edge originating in `bb`. + */ +pragma[nomagic] +predicate phiHasInputFromBlock(PhiNode phi, Definition inp, BasicBlock bb) { + exists(SourceVariable v, BasicBlock bbDef | + phi.definesAt(v, bbDef, _) and + getABasicBlockPredecessor(bbDef) = bb and + ssaDefReachesEndOfBlock(bb, inp, v) + ) +} + +/** + * NB: If this predicate is exposed, it should be cached. + * + * Holds if the SSA definition of `v` at `def` reaches a read at index `i` in + * basic block `bb`, without crossing another SSA definition of `v`. The read + * is of kind `rk`. + */ +pragma[nomagic] +predicate ssaDefReachesRead(SourceVariable v, Definition def, BasicBlock bb, int i) { + ssaDefReachesReadWithinBlock(v, def, bb, i) + or + variableRead(bb, i, v, _) and + ssaDefReachesEndOfBlock(getABasicBlockPredecessor(bb), def, v) and + not ssaDefReachesReadWithinBlock(v, _, bb, i) +} + +/** + * NB: If this predicate is exposed, it should be cached. + * + * Holds if `def` is accessed at index `i1` in basic block `bb1` (either a read + * or a write), `def` is read at index `i2` in basic block `bb2`, and there is a + * path between them without any read of `def`. + */ +pragma[nomagic] +predicate adjacentDefRead(Definition def, BasicBlock bb1, int i1, BasicBlock bb2, int i2) { + exists(int rnk | + rnk = ssaDefRank(def, _, bb1, i1, _) and + rnk + 1 = ssaDefRank(def, _, bb1, i2, SsaRead()) and + variableRead(bb1, i2, _, _) and + bb2 = bb1 + ) + or + exists(SourceVariable v | ssaDefRank(def, v, bb1, i1, _) = maxSsaRefRank(bb1, v)) and + defAdjacentRead(def, bb1, bb2, i2) +} + +private predicate adjacentDefReachesRead( + Definition def, BasicBlock bb1, int i1, BasicBlock bb2, int i2 +) { + adjacentDefRead(def, bb1, i1, bb2, i2) and + exists(SourceVariable v | v = def.getSourceVariable() | + ssaRef(bb1, i1, v, SsaDef()) + or + variableRead(bb1, i1, v, true) + ) + or + exists(BasicBlock bb3, int i3 | + adjacentDefReachesRead(def, bb1, i1, bb3, i3) and + variableRead(bb3, i3, _, false) and + adjacentDefRead(def, bb3, i3, bb2, i2) + ) +} + +/** + * NB: If this predicate is exposed, it should be cached. + * + * Same as `adjacentDefRead`, but ignores uncertain reads. + */ +pragma[nomagic] +predicate adjacentDefNoUncertainReads(Definition def, BasicBlock bb1, int i1, BasicBlock bb2, int i2) { + adjacentDefReachesRead(def, bb1, i1, bb2, i2) and + variableRead(bb2, i2, _, true) +} + +/** + * NB: If this predicate is exposed, it should be cached. + * + * Holds if the node at index `i` in `bb` is a last reference to SSA definition + * `def`. The reference is last because it can reach another write `next`, + * without passing through another read or write. + */ +pragma[nomagic] +predicate lastRefRedef(Definition def, BasicBlock bb, int i, Definition next) { + exists(int rnk, SourceVariable v, int j | rnk = ssaDefRank(def, v, bb, i, _) | + // Next reference to `v` inside `bb` is a write + next.definesAt(v, bb, j) and + rnk + 1 = ssaRefRank(bb, j, v, SsaDef()) + or + // Can reach a write using one or more steps + rnk = maxSsaRefRank(bb, v) and + exists(BasicBlock bb2 | + varBlockReaches(def, bb, bb2) and + next.definesAt(v, bb2, j) and + 1 = ssaRefRank(bb2, j, v, SsaDef()) + ) + ) +} + +/** + * NB: If this predicate is exposed, it should be cached. + * + * Holds if `inp` is an immediately preceding definition of uncertain definition + * `def`. Since `def` is uncertain, the value from the preceding definition might + * still be valid. + */ +pragma[nomagic] +predicate uncertainWriteDefinitionInput(UncertainWriteDefinition def, Definition inp) { + lastRefRedef(inp, _, _, def) +} + +private predicate adjacentDefReachesUncertainRead( + Definition def, BasicBlock bb1, int i1, BasicBlock bb2, int i2 +) { + adjacentDefReachesRead(def, bb1, i1, bb2, i2) and + variableRead(bb2, i2, _, false) +} + +/** + * NB: If this predicate is exposed, it should be cached. + * + * Same as `lastRefRedef`, but ignores uncertain reads. + */ +pragma[nomagic] +predicate lastRefRedefNoUncertainReads(Definition def, BasicBlock bb, int i, Definition next) { + lastRefRedef(def, bb, i, next) and + not variableRead(bb, i, def.getSourceVariable(), false) + or + exists(BasicBlock bb0, int i0 | + lastRefRedef(def, bb0, i0, next) and + adjacentDefReachesUncertainRead(def, bb, i, bb0, i0) + ) +} + +/** + * NB: If this predicate is exposed, it should be cached. + * + * Holds if the node at index `i` in `bb` is a last reference to SSA + * definition `def`. + * + * That is, the node can reach the end of the enclosing callable, or another + * SSA definition for the underlying source variable, without passing through + * another read. + */ +pragma[nomagic] +predicate lastRef(Definition def, BasicBlock bb, int i) { + lastRefRedef(def, bb, i, _) + or + exists(SourceVariable v | ssaDefRank(def, v, bb, i, _) = maxSsaRefRank(bb, v) | + // Can reach exit directly + bb instanceof ExitBasicBlock + or + // Can reach a block using one or more steps, where `def` is no longer live + exists(BasicBlock bb2 | varBlockReaches(def, bb, bb2) | + not defOccursInBlock(def, bb2, _) and + not ssaDefReachesEndOfBlock(bb2, def, _) + ) + ) +} + +/** + * NB: If this predicate is exposed, it should be cached. + * + * Same as `lastRefRedef`, but ignores uncertain reads. + */ +pragma[nomagic] +predicate lastRefNoUncertainReads(Definition def, BasicBlock bb, int i) { + lastRef(def, bb, i) and + not variableRead(bb, i, def.getSourceVariable(), false) + or + exists(BasicBlock bb0, int i0 | + lastRef(def, bb0, i0) and + adjacentDefReachesUncertainRead(def, bb, i, bb0, i0) + ) +} + +/** A static single assignment (SSA) definition. */ +class Definition extends TDefinition { + /** Gets the source variable underlying this SSA definition. */ + SourceVariable getSourceVariable() { this.definesAt(result, _, _) } + + /** + * Holds if this SSA definition defines `v` at index `i` in basic block `bb`. + * Phi nodes are considered to be at index `-1`, while normal variable writes + * are at the index of the control flow node they wrap. + */ + final predicate definesAt(SourceVariable v, BasicBlock bb, int i) { + this = TWriteDef(v, bb, i) + or + this = TPhiNode(v, bb) and i = -1 + } + + /** Gets the basic block to which this SSA definition belongs. */ + final BasicBlock getBasicBlock() { this.definesAt(_, result, _) } + + /** Gets a textual representation of this SSA definition. */ + string toString() { none() } +} + +/** An SSA definition that corresponds to a write. */ +class WriteDefinition extends Definition, TWriteDef { + private SourceVariable v; + private BasicBlock bb; + private int i; + + WriteDefinition() { this = TWriteDef(v, bb, i) } + + override string toString() { result = "WriteDef" } +} + +/** A phi node. */ +class PhiNode extends Definition, TPhiNode { + override string toString() { result = "Phi" } +} + +/** + * An SSA definition that represents an uncertain update of the underlying + * source variable. + */ +class UncertainWriteDefinition extends WriteDefinition { + UncertainWriteDefinition() { + exists(SourceVariable v, BasicBlock bb, int i | + this.definesAt(v, bb, i) and + variableWrite(bb, i, v, false) + ) + } +} diff --git a/csharp/ql/src/semmle/code/csharp/dataflow/internal/SsaImplSpecific.qll b/csharp/ql/src/semmle/code/csharp/dataflow/internal/SsaImplSpecific.qll new file mode 100644 index 00000000000..2091b73c388 --- /dev/null +++ b/csharp/ql/src/semmle/code/csharp/dataflow/internal/SsaImplSpecific.qll @@ -0,0 +1,19 @@ +/** Provides the C# specific parameters for `SsaImplCommon.qll`. */ + +private import csharp +private import AssignableDefinitions +private import SsaImpl as SsaImpl + +class BasicBlock = ControlFlow::BasicBlock; + +BasicBlock getImmediateBasicBlockDominator(BasicBlock bb) { result = bb.getImmediateDominator() } + +BasicBlock getABasicBlockSuccessor(BasicBlock bb) { result = bb.getASuccessor() } + +class ExitBasicBlock = ControlFlow::BasicBlocks::ExitBlock; + +class SourceVariable = SsaImpl::TSourceVariable; + +predicate variableWrite = SsaImpl::variableWrite/4; + +predicate variableRead = SsaImpl::variableRead/4; diff --git a/csharp/ql/src/semmle/code/csharp/dataflow/internal/rangeanalysis/ModulusAnalysisSpecific.qll b/csharp/ql/src/semmle/code/csharp/dataflow/internal/rangeanalysis/ModulusAnalysisSpecific.qll index 380bbe59485..f71b0d0ffcd 100644 --- a/csharp/ql/src/semmle/code/csharp/dataflow/internal/rangeanalysis/ModulusAnalysisSpecific.qll +++ b/csharp/ql/src/semmle/code/csharp/dataflow/internal/rangeanalysis/ModulusAnalysisSpecific.qll @@ -4,8 +4,9 @@ module Private { private import semmle.code.csharp.dataflow.internal.rangeanalysis.RangeUtils as RU private import SsaUtils as SU private import SsaReadPositionCommon + private import semmle.code.csharp.controlflow.internal.ControlFlowGraphImpl as CfgImpl - class BasicBlock = CS::Ssa::BasicBlock; + class BasicBlock = CS::ControlFlow::BasicBlock; class SsaVariable = SU::SsaVariable; @@ -43,22 +44,16 @@ module Private { Expr getABasicBlockExpr(BasicBlock bb) { result = bb.getANode() } - private class CallableOrCFE extends CS::Element { - CallableOrCFE() { this instanceof CS::Callable or this instanceof CS::ControlFlowElement } - } - - private predicate id(CallableOrCFE x, CallableOrCFE y) { x = y } - - private predicate idOf(CallableOrCFE x, int y) = equivalenceRelation(id/2)(x, y) - private class PhiInputEdgeBlock extends BasicBlock { PhiInputEdgeBlock() { this = any(SsaReadPositionPhiInputEdge edge).getOrigBlock() } } int getId(PhiInputEdgeBlock bb) { - idOf(bb.getFirstNode().getElement(), result) - or - idOf(bb.(CS::ControlFlow::BasicBlocks::EntryBlock).getCallable(), result) + exists(CfgImpl::ControlFlowTree::Range t | CfgImpl::ControlFlowTree::idOf(t, result) | + t = bb.getFirstNode().getElement() + or + t = bb.(CS::ControlFlow::BasicBlocks::EntryBlock).getCallable() + ) } private string getSplitString(PhiInputEdgeBlock bb) { diff --git a/csharp/ql/src/semmle/code/csharp/dataflow/internal/rangeanalysis/RangeUtils.qll b/csharp/ql/src/semmle/code/csharp/dataflow/internal/rangeanalysis/RangeUtils.qll index dcd0d9b1ec3..4d765f769ad 100644 --- a/csharp/ql/src/semmle/code/csharp/dataflow/internal/rangeanalysis/RangeUtils.qll +++ b/csharp/ql/src/semmle/code/csharp/dataflow/internal/rangeanalysis/RangeUtils.qll @@ -95,7 +95,7 @@ private module Impl { /** * Holds if basic block `bb` is guarded by this guard having value `v`. */ - predicate controlsBasicBlock(BasicBlock bb, G::AbstractValue v) { + predicate controlsBasicBlock(ControlFlow::BasicBlock bb, G::AbstractValue v) { this.(G::Guard).controlsBasicBlock(bb, v) } diff --git a/csharp/ql/src/semmle/code/csharp/dataflow/internal/rangeanalysis/SsaReadPositionSpecific.qll b/csharp/ql/src/semmle/code/csharp/dataflow/internal/rangeanalysis/SsaReadPositionSpecific.qll index d7df9781b2a..7afd9a2a33d 100644 --- a/csharp/ql/src/semmle/code/csharp/dataflow/internal/rangeanalysis/SsaReadPositionSpecific.qll +++ b/csharp/ql/src/semmle/code/csharp/dataflow/internal/rangeanalysis/SsaReadPositionSpecific.qll @@ -8,7 +8,7 @@ class SsaVariable = Ssa::Definition; class SsaPhiNode = Ssa::PhiNode; -class BasicBlock = Ssa::BasicBlock; +class BasicBlock = ControlFlow::BasicBlock; /** Gets a basic block in which SSA variable `v` is read. */ BasicBlock getAReadBasicBlock(SsaVariable v) { diff --git a/csharp/ql/src/semmle/code/csharp/exprs/Call.qll b/csharp/ql/src/semmle/code/csharp/exprs/Call.qll index 150533526ed..078ecd1a52a 100644 --- a/csharp/ql/src/semmle/code/csharp/exprs/Call.qll +++ b/csharp/ql/src/semmle/code/csharp/exprs/Call.qll @@ -527,6 +527,46 @@ class MutatorOperatorCall extends OperatorCall { predicate isPostfix() { mutator_invocation_mode(this, 2) } } +private class DelegateLikeCall_ = @delegate_invocation_expr or @function_pointer_invocation_expr; + +/** + * A function pointer or delegate call. + */ +class DelegateLikeCall extends Call, DelegateLikeCall_ { + override Callable getTarget() { none() } + + /** + * Gets a potential run-time target of this delegate or function pointer call in the given + * call context `cc`. + */ + Callable getARuntimeTarget(CallContext::CallContext cc) { + exists(DelegateLikeCallExpr call | + this = call.getCall() and + result = call.getARuntimeTarget(cc) + ) + } + + /** + * Gets the delegate or function pointer expression of this call. For example, the + * delegate expression of `X()` on line 5 is the access to the field `X` in + * + * ```csharp + * class A { + * Action X = () => { }; + * + * void CallX() { + * X(); + * } + * } + * ``` + */ + Expr getExpr() { result = this.getChild(-1) } + + override Callable getARuntimeTarget() { result = getARuntimeTarget(_) } + + override Expr getRuntimeArgument(int i) { result = getArgument(i) } +} + /** * A delegate call, for example `x()` on line 5 in * @@ -540,18 +580,13 @@ class MutatorOperatorCall extends OperatorCall { * } * ``` */ -class DelegateCall extends Call, @delegate_invocation_expr { - override Callable getTarget() { none() } - +class DelegateCall extends DelegateLikeCall, @delegate_invocation_expr { /** * Gets a potential run-time target of this delegate call in the given * call context `cc`. */ - Callable getARuntimeTarget(CallContext::CallContext cc) { - exists(DelegateCallExpr call | - this = call.getDelegateCall() and - result = call.getARuntimeTarget(cc) - ) + override Callable getARuntimeTarget(CallContext::CallContext cc) { + result = DelegateLikeCall.super.getARuntimeTarget(cc) or exists(AddEventSource aes, CallContext::CallContext cc2 | aes = this.getAnAddEventSource(_) and @@ -567,7 +602,7 @@ class DelegateCall extends Call, @delegate_invocation_expr { } private AddEventSource getAnAddEventSource(Callable enclosingCallable) { - this.getDelegateExpr().(EventAccess).getTarget() = result.getEvent() and + this.getExpr().(EventAccess).getTarget() = result.getEvent() and enclosingCallable = result.getExpr().getEnclosingCallable() } @@ -579,31 +614,35 @@ class DelegateCall extends Call, @delegate_invocation_expr { exists(Callable c | result = getAnAddEventSource(c) | c != this.getEnclosingCallable()) } - override Callable getARuntimeTarget() { result = getARuntimeTarget(_) } - - override Expr getRuntimeArgument(int i) { result = getArgument(i) } - /** - * Gets the delegate expression of this delegate call. For example, the - * delegate expression of `X()` on line 5 is the access to the field `X` in + * DEPRECATED: use `getExpr` instead. * - * ```csharp - * class A { - * Action X = () => { }; - * - * void CallX() { - * X(); - * } - * } - * ``` + * Gets the delegate expression of this call. */ - Expr getDelegateExpr() { result = this.getChild(-1) } + deprecated Expr getDelegateExpr() { result = this.getExpr() } override string toString() { result = "delegate call" } override string getAPrimaryQlClass() { result = "DelegateCall" } } +/** + * A function pointer call, for example `fp(1)` on line 3 in + * + * ```csharp + * class A { + * void Call(delegate* fp) { + * fp(1); + * } + * } + * ``` + */ +class FunctionPointerCall extends DelegateLikeCall, @function_pointer_invocation_expr { + override string toString() { result = "function pointer call" } + + override string getAPrimaryQlClass() { result = "FunctionPointerCall" } +} + /** * A call to an accessor. Either a property accessor call (`PropertyCall`), * an indexer accessor call (`IndexerCall`), or an event accessor call diff --git a/csharp/ql/src/semmle/code/csharp/exprs/Creation.qll b/csharp/ql/src/semmle/code/csharp/exprs/Creation.qll index bde4f4a319d..c9ae3919004 100644 --- a/csharp/ql/src/semmle/code/csharp/exprs/Creation.qll +++ b/csharp/ql/src/semmle/code/csharp/exprs/Creation.qll @@ -205,6 +205,9 @@ class ObjectCreation extends Call, LateBindableExpr, @object_creation_expr { */ ObjectOrCollectionInitializer getInitializer() { result = this.getChild(-1) } + /** Holds if the type of the created object is inferred. */ + predicate isImplicitlyTyped() { implicitly_typed_object_creation(this) } + override string toString() { result = "object creation of type " + this.getType().getName() } override Expr getRawArgument(int i) { @@ -271,6 +274,9 @@ class DelegateCreation extends Expr, @delegate_creation_expr { */ class ExplicitDelegateCreation extends DelegateCreation, @explicit_delegate_creation_expr { override string getAPrimaryQlClass() { result = "ExplicitDelegateCreation" } + + /** Holds if the type of the created delegate is inferred. */ + predicate isImplicitlyTyped() { implicitly_typed_object_creation(this) } } /** diff --git a/csharp/ql/src/semmle/code/csharp/exprs/Expr.qll b/csharp/ql/src/semmle/code/csharp/exprs/Expr.qll index b133b628732..5a954b7a925 100644 --- a/csharp/ql/src/semmle/code/csharp/exprs/Expr.qll +++ b/csharp/ql/src/semmle/code/csharp/exprs/Expr.qll @@ -51,9 +51,6 @@ class Expr extends DotNet::Expr, ControlFlowElement, @expr { /** Gets the value of this expression, if any */ override string getValue() { expr_value(this, result) } - /** Holds if this expression has a value. */ - predicate hasValue() { exists(getValue()) } - /** Gets the enclosing statement of this expression, if any. */ final Stmt getEnclosingStmt() { enclosingStmt(this, result) } @@ -293,10 +290,31 @@ private predicate hasChildPattern(ControlFlowElement pm, Expr child) { or exists(Expr mid | hasChildPattern(pm, mid) and - mid instanceof @recursive_pattern_expr - | - child = mid.getChild(2).getAChildExpr() or - child = mid.getChild(3).getAChildExpr() + mid instanceof @property_pattern_expr and + child = mid.getAChildExpr() + ) + or + exists(Expr mid | + hasChildPattern(pm, mid) and + mid instanceof @positional_pattern_expr and + child = mid.getAChildExpr() + ) + or + exists(Expr mid | + hasChildPattern(pm, mid) and + mid instanceof @recursive_pattern_expr and + child = mid.getAChildExpr() + ) + or + exists(Expr mid | + hasChildPattern(pm, mid) and + mid instanceof @unary_pattern_expr and + child = mid.getChildExpr(0) + ) + or + exists(Expr mid | hasChildPattern(pm, mid) and mid instanceof @binary_pattern_expr | + child = mid.getChildExpr(0) or + child = mid.getChildExpr(1) ) } @@ -342,6 +360,45 @@ class ConstantPatternExpr extends PatternExpr { override string getAPrimaryQlClass() { result = "ConstantPatternExpr" } } +/** A relational pattern, for example `>1` in `x is >1`. */ +class RelationalPatternExpr extends PatternExpr, @relational_pattern_expr { + /** Gets the name of the operator in this pattern. */ + string getOperator() { none() } + + /** Gets the expression of this relational pattern. */ + Expr getExpr() { result = this.getChild(0) } + + override string toString() { result = getOperator() + " ..." } +} + +/** A less-than pattern, for example `< 10` in `x is < 10`. */ +class LTPattern extends RelationalPatternExpr, @lt_pattern_expr { + override string getOperator() { result = "<" } + + override string getAPrimaryQlClass() { result = "LTPattern" } +} + +/** A greater-than pattern, for example `> 10` in `x is > 10`. */ +class GTPattern extends RelationalPatternExpr, @gt_pattern_expr { + override string getOperator() { result = ">" } + + override string getAPrimaryQlClass() { result = "GTPattern" } +} + +/** A less-than or equals pattern, for example `<= 10` in `x is <= 10`. */ +class LEPattern extends RelationalPatternExpr, @le_pattern_expr { + override string getOperator() { result = "<=" } + + override string getAPrimaryQlClass() { result = "LEPattern" } +} + +/** A greater-than or equals pattern, for example `>= 10` in `x is >= 10` */ +class GEPattern extends RelationalPatternExpr, @ge_pattern_expr { + override string getOperator() { result = ">=" } + + override string getAPrimaryQlClass() { result = "GEPattern" } +} + /** * A type pattern, for example `string` in `x is string`, `string s` in * `x is string s`, or `string _` in `x is string _`. @@ -415,7 +472,7 @@ class RecursivePatternExpr extends BindingPatternExpr, @recursive_pattern_expr { } /** A property pattern. For example, `{ Length: 5 }`. */ -class PropertyPatternExpr extends Expr, @property_pattern_expr { +class PropertyPatternExpr extends PatternExpr, @property_pattern_expr { override string toString() { result = "{ ... }" } /** Gets the `n`th pattern. */ @@ -438,7 +495,7 @@ class LabeledPatternExpr extends PatternExpr { } /** A positional pattern. For example, `(int x, int y)`. */ -class PositionalPatternExpr extends Expr, @positional_pattern_expr { +class PositionalPatternExpr extends PatternExpr, @positional_pattern_expr { override string toString() { result = "( ... )" } /** Gets the `n`th pattern. */ @@ -447,6 +504,45 @@ class PositionalPatternExpr extends Expr, @positional_pattern_expr { override string getAPrimaryQlClass() { result = "PositionalPatternExpr" } } +/** A unary pattern. For example, `not 1`. */ +class UnaryPatternExpr extends PatternExpr, @unary_pattern_expr { + /** Gets the underlying pattern. */ + PatternExpr getPattern() { result = this.getChild(0) } +} + +/** A not pattern. For example, `not 1`. */ +class NotPatternExpr extends UnaryPatternExpr, @not_pattern_expr { + override string toString() { result = "not ..." } + + override string getAPrimaryQlClass() { result = "NotPatternExpr" } +} + +/** A binary pattern. For example, `1 or 2`. */ +class BinaryPatternExpr extends PatternExpr, @binary_pattern_expr { + /** Gets a pattern. */ + PatternExpr getAnOperand() { result = getLeftOperand() or result = getRightOperand() } + + /** Gets the left pattern. */ + PatternExpr getLeftOperand() { result = this.getChild(0) } + + /** Gets the right pattern. */ + PatternExpr getRightOperand() { result = this.getChild(1) } +} + +/** A binary `or` pattern. For example, `1 or 2`. */ +class OrPatternExpr extends BinaryPatternExpr, @or_pattern_expr { + override string toString() { result = "... or ..." } + + override string getAPrimaryQlClass() { result = "OrPatternExpr" } +} + +/** A binary `and` pattern. For example, `< 1 and > 2`. */ +class AndPatternExpr extends BinaryPatternExpr, @and_pattern_expr { + override string toString() { result = "... and ..." } + + override string getAPrimaryQlClass() { result = "AndPatternExpr" } +} + /** * An expression or statement that matches the value of an expression against * a pattern. Either an `is` expression or a `case` expression/statement. @@ -562,7 +658,7 @@ class Cast extends Expr { TypeAccess getTypeAccess() { result = this.getChild(1) } /** Gets the type that the underlying expression is being cast to. */ - Type getTargetType() { result = this.getTypeAccess().getTarget() } + Type getTargetType() { result = this.getType() } /** Gets the type of the underlying expression. */ Type getSourceType() { result = this.getExpr().getType() } @@ -1038,3 +1134,21 @@ class SuppressNullableWarningExpr extends Expr, @suppress_nullable_warning_expr override string getAPrimaryQlClass() { result = "SuppressNullableWarningExpr" } } + +/** + * A preprocessor symbol inside an expression, such as DEBUG in line 2 + * ```csharp + * #define DEBUG + * #if (DEBUG == true) + * Console.WriteLine("Debug version"); + * #endif + * ``` + */ +class DefineSymbolExpr extends Expr, @define_symbol_expr { + /** Gets the name of the symbol. */ + string getName() { directive_define_symbols(this, result) } + + override string toString() { result = getName() } + + override string getAPrimaryQlClass() { result = "DefineSymbolExpr" } +} diff --git a/csharp/ql/src/semmle/code/csharp/frameworks/Format.qll b/csharp/ql/src/semmle/code/csharp/frameworks/Format.qll index a3f9cbff073..3c659d86d46 100644 --- a/csharp/ql/src/semmle/code/csharp/frameworks/Format.qll +++ b/csharp/ql/src/semmle/code/csharp/frameworks/Format.qll @@ -13,7 +13,6 @@ class FormatMethod extends Method { exists(Class declType | declType = this.getDeclaringType() | this.getParameter(0).getType() instanceof SystemIFormatProviderInterface and this.getParameter(1).getType() instanceof StringType and - this.getNumberOfParameters() >= 3 and ( this = any(SystemStringClass c).getFormatMethod() or @@ -21,7 +20,6 @@ class FormatMethod extends Method { ) or this.getParameter(0).getType() instanceof StringType and - this.getNumberOfParameters() >= 2 and ( this = any(SystemStringClass c).getFormatMethod() or @@ -173,7 +171,7 @@ class InvalidFormatString extends StringLiteral { } /** Provides a dataflow configuration for format strings. */ -module FormatFlow { +deprecated module FormatFlow { private import semmle.code.csharp.dataflow.DataFlow private class FormatConfiguration extends DataFlow2::Configuration { @@ -186,18 +184,20 @@ module FormatFlow { } } - query predicate nodes = DataFlow2::PathGraph::nodes/3; + deprecated query predicate nodes = DataFlow2::PathGraph::nodes/3; - query predicate edges = DataFlow2::PathGraph::edges/2; + deprecated query predicate edges = DataFlow2::PathGraph::edges/2; - class PathNode = DataFlow2::PathNode; + deprecated class PathNode = DataFlow2::PathNode; /** * Holds if there is flow from string literal `lit` to the format string in * `call`. `litNode` and `formatNode` are the corresponding data-flow path * nodes. */ - predicate hasFlowPath(StringLiteral lit, PathNode litNode, FormatCall call, PathNode formatNode) { + deprecated predicate hasFlowPath( + StringLiteral lit, PathNode litNode, FormatCall call, PathNode formatNode + ) { litNode.getNode().asExpr() = lit and formatNode.getNode().asExpr() = call.getFormatExpr() and any(FormatConfiguration conf).hasFlowPath(litNode, formatNode) @@ -220,6 +220,9 @@ class FormatCall extends MethodCall { /** Gets the argument number of the first supplied insert. */ int getFirstArgument() { result = this.getFormatArgument() + 1 } + /** Holds if this call has one or more insertions. */ + predicate hasInsertions() { exists(this.getArgument(this.getFirstArgument())) } + /** Holds if the arguments are supplied in an array, not individually. */ predicate hasArrayExpr() { this.getNumberOfArguments() = this.getFirstArgument() + 1 and @@ -254,7 +257,7 @@ class FormatCall extends MethodCall { } /** Gets a supplied argument that is not used in the format string `src`. */ - int getAnUnusedArgument(ValidFormatString src) { + deprecated int getAnUnusedArgument(ValidFormatString src) { result = this.getASuppliedArgument() and FormatFlow::hasFlowPath(src, _, this, _) and not result = src.getAnInsert() diff --git a/csharp/ql/src/semmle/code/csharp/frameworks/System.qll b/csharp/ql/src/semmle/code/csharp/frameworks/System.qll index 02f5169f826..ef1f11bf7b5 100644 --- a/csharp/ql/src/semmle/code/csharp/frameworks/System.qll +++ b/csharp/ql/src/semmle/code/csharp/frameworks/System.qll @@ -588,16 +588,19 @@ predicate implementsEquals(ValueOrRefType t) { getInvokedEqualsMethod(t).getDecl * from the `object.Equals(object)` method inherited by `t`. */ Method getInvokedEqualsMethod(ValueOrRefType t) { - result = getInheritedEqualsMethod(t) and + result = getInheritedEqualsMethod(t, _) and not exists(getInvokedIEquatableEqualsMethod(t, result)) or exists(EqualsMethod eq | result = getInvokedIEquatableEqualsMethod(t, eq) and - getInheritedEqualsMethod(t) = eq + getInheritedEqualsMethod(t, _) = eq ) } -private EqualsMethod getInheritedEqualsMethod(ValueOrRefType t) { t.hasMethod(result) } +pragma[noinline] +private EqualsMethod getInheritedEqualsMethod(ValueOrRefType t, ValueOrRefType decl) { + t.hasMethod(result) and decl = result.getDeclaringType() +} /** * Equals method `eq` is inherited by `t`, `t` overrides `IEquatable.Equals(T)` @@ -621,10 +624,9 @@ private EqualsMethod getInheritedEqualsMethod(ValueOrRefType t) { t.hasMethod(re */ private IEquatableEqualsMethod getInvokedIEquatableEqualsMethod(ValueOrRefType t, EqualsMethod eq) { t.hasMethod(result) and - eq = getInheritedEqualsMethod(t.getBaseClass()) and exists(IEquatableEqualsMethod ieem | result = ieem.getAnOverrider*() and - eq.getDeclaringType() = ieem.getDeclaringType() + eq = getInheritedEqualsMethod(t.getBaseClass(), ieem.getDeclaringType()) | not ieem.fromSource() or diff --git a/csharp/ql/src/semmle/code/csharp/frameworks/microsoft/AspNetCore.qll b/csharp/ql/src/semmle/code/csharp/frameworks/microsoft/AspNetCore.qll index 3ebd7028504..a00f7d21a05 100644 --- a/csharp/ql/src/semmle/code/csharp/frameworks/microsoft/AspNetCore.qll +++ b/csharp/ql/src/semmle/code/csharp/frameworks/microsoft/AspNetCore.qll @@ -195,7 +195,13 @@ class MicrosoftAspNetCoreMvcController extends Class { /** Gets a `Redirect*` method. */ Method getARedirectMethod() { result = this.getAMethod() and - result.getName().matches("Redirect%") + ( + result.getName().matches("Redirect%") + or + result.getName().matches("Accepted%") + or + result.getName().matches("Created%") + ) } } diff --git a/csharp/ql/src/semmle/code/csharp/metrics/Coupling.qll b/csharp/ql/src/semmle/code/csharp/metrics/Coupling.qll index 272b56093f6..0da867e116a 100644 --- a/csharp/ql/src/semmle/code/csharp/metrics/Coupling.qll +++ b/csharp/ql/src/semmle/code/csharp/metrics/Coupling.qll @@ -78,7 +78,7 @@ predicate depends(ValueOrRefType t, ValueOrRefType u) { or exists(DelegateCall dc, DelegateType dt | dc.getEnclosingCallable().getDeclaringType() = t and - dc.getDelegateExpr().getType() = dt and + dc.getExpr().getType() = dt and usesType(dt.getUnboundDeclaration(), u) ) or diff --git a/csharp/ql/src/semmle/code/dotnet/Callable.qll b/csharp/ql/src/semmle/code/dotnet/Callable.qll index 1443da24481..7cdb248d669 100644 --- a/csharp/ql/src/semmle/code/dotnet/Callable.qll +++ b/csharp/ql/src/semmle/code/dotnet/Callable.qll @@ -6,29 +6,13 @@ import Declaration import Variable import Expr +import Parameterizable /** A .Net callable. */ -class Callable extends Declaration, @dotnet_callable { - /** Gets raw parameter `i`, including the `this` parameter at index 0. */ - Parameter getRawParameter(int i) { none() } - - /** Gets the `i`th parameter, excluding the `this` parameter. */ - Parameter getParameter(int i) { none() } - +class Callable extends Parameterizable, @dotnet_callable { /** Holds if this callable has a body or an implementation. */ predicate hasBody() { none() } - override Callable getUnboundDeclaration() { result = Declaration.super.getUnboundDeclaration() } - - /** Gets the number of parameters of this callable. */ - int getNumberOfParameters() { result = count(getAParameter()) } - - /** Gets a parameter, if any. */ - Parameter getAParameter() { result = getParameter(_) } - - /** Gets a raw parameter (including the qualifier), if any. */ - final Parameter getARawParameter() { result = getRawParameter(_) } - /** Holds if this callable can return expression `e`. */ predicate canReturn(Expr e) { none() } diff --git a/csharp/ql/src/semmle/code/dotnet/Declaration.qll b/csharp/ql/src/semmle/code/dotnet/Declaration.qll index 11fc55f8f3e..7d6227486b0 100644 --- a/csharp/ql/src/semmle/code/dotnet/Declaration.qll +++ b/csharp/ql/src/semmle/code/dotnet/Declaration.qll @@ -52,10 +52,34 @@ class Declaration extends NamedElement, @dotnet_declaration { * | `C.Method` | `C<>.Method<>` | */ Declaration getUnboundDeclaration() { result = this } + + /** Holds if this declaration is unbound. */ + final predicate isUnboundDeclaration() { this.getUnboundDeclaration() = this } } /** A member of a type. */ -class Member extends Declaration, @dotnet_member { } +class Member extends Declaration, @dotnet_member { + /** Holds if this member is declared `public`. */ + predicate isPublic() { none() } + + /** Holds if this member is declared `protected.` */ + predicate isProtected() { none() } + + /** Holds if this member is `private`. */ + predicate isPrivate() { none() } + + /** Holds if this member is `internal`. */ + predicate isInternal() { none() } + + /** Holds if this member is `sealed`. */ + predicate isSealed() { none() } + + /** Holds if this member is `abstract`. */ + predicate isAbstract() { none() } + + /** Holds if this member is `static`. */ + predicate isStatic() { none() } +} /** A property. */ class Property extends Member, @dotnet_property { diff --git a/csharp/ql/src/semmle/code/dotnet/Element.qll b/csharp/ql/src/semmle/code/dotnet/Element.qll index 10a688d8ddd..956a5f2c052 100644 --- a/csharp/ql/src/semmle/code/dotnet/Element.qll +++ b/csharp/ql/src/semmle/code/dotnet/Element.qll @@ -36,6 +36,19 @@ class Element extends @dotnet_element { /** Gets the full textual representation of this element, including type information. */ string toStringWithTypes() { result = this.toString() } + + /** + * Gets the name of a primary CodeQL class to which this element belongs. + * + * For most elements, this is simply the most precise syntactic category to + * which they belong; for example, `AddExpr` is a primary class, but + * `BinaryOperation` is not. + * + * This predicate always has a result. If no primary class can be + * determined, the result is `"???"`. If multiple primary classes match, + * this predicate can have multiple results. + */ + string getAPrimaryQlClass() { result = "???" } } /** An element that has a name. */ diff --git a/csharp/ql/src/semmle/code/dotnet/Expr.qll b/csharp/ql/src/semmle/code/dotnet/Expr.qll index 29a9c6c170d..e5bea3a52d7 100644 --- a/csharp/ql/src/semmle/code/dotnet/Expr.qll +++ b/csharp/ql/src/semmle/code/dotnet/Expr.qll @@ -17,6 +17,9 @@ class Expr extends Element, @dotnet_expr { /** Gets the constant value of this expression, if any. */ string getValue() { none() } + /** Holds if this expression has a value. */ + final predicate hasValue() { exists(this.getValue()) } + /** * Gets the parent of this expression. This is for example the element * that uses the result of this expression. diff --git a/csharp/ql/src/semmle/code/dotnet/Parameterizable.qll b/csharp/ql/src/semmle/code/dotnet/Parameterizable.qll new file mode 100644 index 00000000000..8a1f9c108ca --- /dev/null +++ b/csharp/ql/src/semmle/code/dotnet/Parameterizable.qll @@ -0,0 +1,30 @@ +/** + * Provides a general parameterizable entity to represent constructs that might + * have parameters. + */ + +import Declaration + +/** + * A general parameterizable entity, such as a callable, delegate type, accessor, + * indexer, or function pointer type. + */ +class Parameterizable extends Declaration, @dotnet_parameterizable { + /** Gets raw parameter `i`, including the `this` parameter at index 0. */ + Parameter getRawParameter(int i) { none() } + + /** Gets the `i`th parameter, excluding the `this` parameter. */ + Parameter getParameter(int i) { none() } + + /** Gets the number of parameters of this callable. */ + int getNumberOfParameters() { result = count(this.getAParameter()) } + + /** Holds if this declaration has no parameters. */ + predicate hasNoParameters() { not exists(this.getAParameter()) } + + /** Gets a parameter, if any. */ + Parameter getAParameter() { result = this.getParameter(_) } + + /** Gets a raw parameter (including the qualifier), if any. */ + final Parameter getARawParameter() { result = this.getRawParameter(_) } +} diff --git a/csharp/ql/src/semmle/code/dotnet/Type.qll b/csharp/ql/src/semmle/code/dotnet/Type.qll index 32cd383f913..cfb6748cf7b 100644 --- a/csharp/ql/src/semmle/code/dotnet/Type.qll +++ b/csharp/ql/src/semmle/code/dotnet/Type.qll @@ -49,6 +49,18 @@ class ValueOrRefType extends Type, @dotnet_valueorreftype { /** Gets a base type of this type, if any. */ ValueOrRefType getABaseType() { none() } + + /** Holds if this type is a `record`. */ + predicate isRecord() { + exists(Callable c | + c.getDeclaringType() = this and + c.hasName("$") and + c.getNumberOfParameters() = 0 and + c.getReturnType() = this.getABaseType*() and + c.(Member).isPublic() and + not c.(Member).isStatic() + ) + } } /** diff --git a/csharp/ql/src/semmle/code/dotnet/Variable.qll b/csharp/ql/src/semmle/code/dotnet/Variable.qll index c004b9ab6b3..9f9a12e7d98 100644 --- a/csharp/ql/src/semmle/code/dotnet/Variable.qll +++ b/csharp/ql/src/semmle/code/dotnet/Variable.qll @@ -12,16 +12,19 @@ class Variable extends Declaration, @dotnet_variable { /** A .Net field. */ class Field extends Variable, Member, @dotnet_field { } -/** A parameter to a .Net callable or property. */ +/** A parameter to a .Net callable, property or function pointer type. */ class Parameter extends Variable, @dotnet_parameter { /** Gets the raw position of this parameter, including the `this` parameter at index 0. */ - final int getRawPosition() { this = getCallable().getRawParameter(result) } + final int getRawPosition() { this = getDeclaringElement().getRawParameter(result) } /** Gets the position of this parameter, excluding the `this` parameter. */ - int getPosition() { this = getCallable().getParameter(result) } + int getPosition() { this = getDeclaringElement().getParameter(result) } /** Gets the callable defining this parameter. */ - Callable getCallable() { none() } + Callable getCallable() { result = this.getDeclaringElement() } + + /** Gets the declaring `Parameterizable`. */ + Parameterizable getDeclaringElement() { none() } /** Holds if this is an `out` parameter. */ predicate isOut() { none() } diff --git a/csharp/ql/src/semmlecode.csharp.dbscheme b/csharp/ql/src/semmlecode.csharp.dbscheme index eedef9359e1..16936565fbe 100644 --- a/csharp/ql/src/semmlecode.csharp.dbscheme +++ b/csharp/ql/src/semmlecode.csharp.dbscheme @@ -151,6 +151,11 @@ compilation_finished( float elapsed_seconds : float ref ); +compilation_assembly( + unique int id : @compilation ref, + int assembly: @assembly ref +) + /* * External artifacts */ @@ -212,7 +217,7 @@ tokens( @element = @declaration | @stmt | @expr | @modifier | @attribute | @namespace_declaration | @using_directive | @type_parameter_constraints | @external_element - | @xmllocatable | @asp_element | @namespace; + | @xmllocatable | @asp_element | @namespace | @preprocessor_directive; @declaration = @callable | @generic | @assignable | @namespace; @@ -242,6 +247,10 @@ locations_default( int endLine: int ref, int endColumn: int ref); +locations_mapped( + unique int id: @location_default ref, + int mapped_to: @location_default ref); + @sourceline = @file | @callable | @xmllocatable; numlines( @@ -326,6 +335,111 @@ using_directive_location( unique int id: @using_directive ref, int loc: @location ref); +@preprocessor_directive = @pragma_warning | @pragma_checksum | @directive_define | @directive_undefine | @directive_warning + | @directive_error | @directive_nullable | @directive_line | @directive_region | @directive_endregion | @directive_if + | @directive_elif | @directive_else | @directive_endif; + +@conditional_directive = @directive_if | @directive_elif; +@branch_directive = @directive_if | @directive_elif | @directive_else; + +directive_ifs( + unique int id: @directive_if, + int branchTaken: int ref, /* 0: false, 1: true */ + int conditionValue: int ref); /* 0: false, 1: true */ + +directive_elifs( + unique int id: @directive_elif, + int branchTaken: int ref, /* 0: false, 1: true */ + int conditionValue: int ref, /* 0: false, 1: true */ + int parent: @directive_if ref, + int index: int ref); + +directive_elses( + unique int id: @directive_else, + int branchTaken: int ref, /* 0: false, 1: true */ + int parent: @directive_if ref, + int index: int ref); + +#keyset[id, start] +directive_endifs( + unique int id: @directive_endif, + unique int start: @directive_if ref); + +directive_define_symbols( + unique int id: @define_symbol_expr ref, + string name: string ref); + +directive_regions( + unique int id: @directive_region, + string name: string ref); + +#keyset[id, start] +directive_endregions( + unique int id: @directive_endregion, + unique int start: @directive_region ref); + +directive_lines( + unique int id: @directive_line, + int kind: int ref); /* 0: default, 1: hidden, 2: numeric */ + +directive_line_value( + unique int id: @directive_line ref, + int line: int ref); + +directive_line_file( + unique int id: @directive_line ref, + int file: @file ref +) + +directive_nullables( + unique int id: @directive_nullable, + int setting: int ref, /* 0: disable, 1: enable, 2: restore */ + int target: int ref); /* 0: none, 1: annotations, 2: warnings */ + +directive_warnings( + unique int id: @directive_warning, + string message: string ref); + +directive_errors( + unique int id: @directive_error, + string message: string ref); + +directive_undefines( + unique int id: @directive_undefine, + string name: string ref); + +directive_defines( + unique int id: @directive_define, + string name: string ref); + +pragma_checksums( + unique int id: @pragma_checksum, + int file: @file ref, + string guid: string ref, + string bytes: string ref); + +pragma_warnings( + unique int id: @pragma_warning, + int kind: int ref /* 0 = disable, 1 = restore */); + +#keyset[id, index] +pragma_warning_error_codes( + int id: @pragma_warning ref, + string errorCode: string ref, + int index: int ref); + +preprocessor_directive_location( + unique int id: @preprocessor_directive ref, + int loc: @location ref); + +preprocessor_directive_compilation( + unique int id: @preprocessor_directive ref, + int compilation: @compilation ref); + +preprocessor_directive_active( + unique int id: @preprocessor_directive ref, + int active: int ref); /* 0: false, 1: true */ + /** TYPES **/ types( @@ -364,6 +478,7 @@ case @type.kind of | 30 = @arglist_type | 31 = @unknown_type | 32 = @tuple_type +| 33 = @function_pointer_type ; @simple_type = @bool_type | @char_type | @integral_type | @floating_point_type | @decimal_type; @@ -409,10 +524,17 @@ delegate_return_type( unique int delegate_id: @delegate_type ref, int return_type_id: @type_or_ref ref); +function_pointer_return_type( + unique int function_pointer_id: @function_pointer_type ref, + int return_type_id: @type_or_ref ref); + extend( unique int sub: @type ref, int super: @type_or_ref ref); +anonymous_types( + unique int id: @type ref); + @interface_or_ref = @interface_type | @typeref; implement( @@ -453,7 +575,7 @@ type_mention_location( unique int id: @type_mention ref, int loc: @location ref); -@has_type_annotation = @assignable | @type_parameter | @callable | @expr | @delegate_type | @generic; +@has_type_annotation = @assignable | @type_parameter | @callable | @expr | @delegate_type | @generic | @function_pointer_type; /** * A direct annotation on an entity, for example `string? x;`. @@ -537,6 +659,18 @@ specific_type_parameter_nullability( int base_id: @type_or_ref ref, int nullability: @nullability ref); +/** FUNCTION POINTERS */ + +function_pointer_calling_conventions( + int id: @function_pointer_type ref, + int kind: int ref); + +#keyset[id, index] +has_unmanaged_calling_conventions( + int id: @function_pointer_type ref, + int index: int ref, + int conv_id: @type_or_ref ref); + /** MODIFIERS */ @modifiable = @modifiable_direct | @event_accessor; @@ -604,6 +738,9 @@ case @accessor.kind of | 2 = @setter ; +init_only_accessors( + unique int id: @accessor ref); + accessor_location( int id: @accessor ref, int loc: @location ref); @@ -747,7 +884,7 @@ localvar_location( unique int id: @local_variable ref, int loc: @location ref); -@parameterizable = @callable | @delegate_type | @indexer; +@parameterizable = @callable | @delegate_type | @indexer | @function_pointer_type; #keyset[name, parent_id] #keyset[index, parent_id] @@ -845,6 +982,18 @@ catch_type( int type_id: @type_or_ref ref, int kind: int ref /* explicit = 1, implicit = 2 */); +foreach_stmt_info( + unique int id: @foreach_stmt ref, + int kind: int ref /* non-async = 1, async = 2 */); + +@foreach_symbol = @method | @property | @type_or_ref; + +#keyset[id, kind] +foreach_stmt_desugar( + int id: @foreach_stmt ref, + int symbol: @foreach_symbol ref, + int kind: int ref /* GetEnumeratorMethod = 1, CurrentProperty = 2, MoveNextMethod = 3, DisposeMethod = 4, ElementType = 5 */); + /** EXPRESSIONS **/ expressions( @@ -858,7 +1007,7 @@ expr_parent( int index: int ref, int parent: @control_flow_element ref); -@top_level_expr_parent = @attribute | @field | @property | @indexer | @parameter; +@top_level_expr_parent = @attribute | @field | @property | @indexer | @parameter | @directive_if | @directive_elif; @top_level_exprorstmt_parent = @top_level_expr_parent | @top_level_stmt_parent; @@ -998,11 +1147,25 @@ case @expr.kind of | 119 = @assign_coalesce_expr | 120 = @suppress_nullable_warning_expr | 121 = @namespace_access_expr +/* C# 9.0 */ +| 122 = @lt_pattern_expr +| 123 = @gt_pattern_expr +| 124 = @le_pattern_expr +| 125 = @ge_pattern_expr +| 126 = @not_pattern_expr +| 127 = @and_pattern_expr +| 128 = @or_pattern_expr +| 129 = @function_pointer_invocation_expr +/* Preprocessor */ +| 999 = @define_symbol_expr ; @switch = @switch_stmt | @switch_expr; @case = @case_stmt | @switch_case_expr; @pattern_match = @case | @is_expr; +@unary_pattern_expr = @not_pattern_expr; +@relational_pattern_expr = @gt_pattern_expr | @lt_pattern_expr | @ge_pattern_expr | @le_pattern_expr; +@binary_pattern_expr = @and_pattern_expr | @or_pattern_expr; @integer_literal_expr = @int_literal_expr | @long_literal_expr | @uint_literal_expr | @ulong_literal_expr; @real_literal_expr = @float_literal_expr | @double_literal_expr | @decimal_literal_expr; @@ -1066,7 +1229,7 @@ case @expr.kind of @call = @method_invocation_expr | @constructor_init_expr | @operator_invocation_expr | @delegate_invocation_expr | @object_creation_expr | @call_access_expr - | @local_function_invocation_expr; + | @local_function_invocation_expr | @function_pointer_invocation_expr; @call_access_expr = @property_access_expr | @event_access_expr | @indexer_access_expr; @@ -1075,6 +1238,8 @@ case @expr.kind of @throw_element = @throw_expr | @throw_stmt; +@implicitly_typeable_object_creation_expr = @object_creation_expr | @explicit_delegate_creation_expr; + implicitly_typed_array_creation( unique int id: @array_creation_expr ref); @@ -1084,6 +1249,9 @@ explicitly_sized_array_creation( stackalloc_array_creation( unique int id: @array_creation_expr ref); +implicitly_typed_object_creation( + unique int id: @implicitly_typeable_object_creation_expr ref); + mutator_invocation_mode( unique int id: @operator_invocation_expr ref, int mode: int ref /* prefix = 1, postfix = 2*/); @@ -1653,6 +1821,7 @@ case @cil_type.kind of | 1 = @cil_typeparameter | 2 = @cil_array_type | 3 = @cil_pointer_type +| 4 = @cil_function_pointer_type ; cil_type( @@ -1671,6 +1840,10 @@ cil_array_type( int element_type: @cil_type ref, int rank: int ref); +cil_function_pointer_return_type( + unique int id: @cil_function_pointer_type ref, + int return_type: @cil_type ref); + cil_method( unique int id: @cil_method, string name: string ref, @@ -1704,11 +1877,14 @@ cil_field( @cil_variable = @cil_field | @cil_stack_variable; @cil_stack_variable = @cil_local_variable | @cil_parameter; @cil_member = @cil_method | @cil_type | @cil_field | @cil_property | @cil_event; +@cil_custom_modifier_receiver = @cil_method | @cil_property | @cil_parameter | @cil_field | @cil_function_pointer_type; +@cil_parameterizable = @cil_method | @cil_function_pointer_type; +@cil_has_type_annotation = @cil_stack_variable | @cil_property | @cil_method | @cil_function_pointer_type; -#keyset[method, index] +#keyset[parameterizable, index] cil_parameter( unique int id: @cil_parameter, - int method: @cil_method ref, + int parameterizable: @cil_parameterizable ref, int index: int ref, int param_type: @cil_type ref); @@ -1718,6 +1894,16 @@ cil_parameter_out(unique int id: @cil_parameter ref); cil_setter(unique int prop: @cil_property ref, int method: @cil_method ref); +#keyset[id, modifier] +cil_custom_modifiers( + int id: @cil_custom_modifier_receiver ref, + int modifier: @cil_type ref, + int kind: int ref); // modreq: 1, modopt: 0 + +cil_type_annotation( + int id: @cil_has_type_annotation ref, + int annotation: int ref); + cil_getter(unique int prop: @cil_property ref, int method: @cil_method ref); @@ -1747,6 +1933,10 @@ cil_local_variable( int index: int ref, int var_type: @cil_type ref); +cil_function_pointer_calling_conventions( + int id: @cil_function_pointer_type ref, + int kind: int ref); + // CIL handlers (exception handlers etc). case @cil_handler.kind of @@ -1803,6 +1993,7 @@ cil_newslot(int id: @cil_method ref); cil_base_class(unique int id: @cil_type ref, int base: @cil_type ref); cil_base_interface(int id: @cil_type ref, int base: @cil_type ref); +cil_enum_underlying_type(unique int id: @cil_type ref, int underlying: @cil_type ref); #keyset[unbound, index] cil_type_parameter( @@ -1858,6 +2049,7 @@ cil_attribute_positional_argument( @dotnet_member = @member | @cil_member; @dotnet_event = @event | @cil_event; @dotnet_property = @property | @cil_property | @indexer; +@dotnet_parameterizable = @parameterizable | @cil_parameterizable; // Common types @dotnet_type = @type | @cil_type; diff --git a/csharp/ql/src/semmlecode.csharp.dbscheme.stats b/csharp/ql/src/semmlecode.csharp.dbscheme.stats index a6f074f11ef..bb3e0fcb650 100644 --- a/csharp/ql/src/semmlecode.csharp.dbscheme.stats +++ b/csharp/ql/src/semmlecode.csharp.dbscheme.stats @@ -1,7 +1,7 @@ @compilation -1097 +1095 @diagnostic @@ -9,7 +9,7 @@ @extractor_message -10135 +7638 @externalDefect @@ -25,7 +25,7 @@ @duplication -22778 +22735 @similarity @@ -33,37 +33,93 @@ @location_default -14663251 +14080010 @assembly -4206 +4198 @file -42545 +47312 @folder -16961 +17831 @namespace -21982 +21942 @namespace_declaration -19796 +19760 @using_namespace_directive -144521 +144252 @using_static_directive 390 +@directive_if +5161 + + +@directive_elif +59 + + +@directive_else +2314 + + +@directive_endif +5161 + + +@directive_region +1954 + + +@directive_endregion +1954 + + +@directive_line +250436 + + +@directive_nullable +162190 + + +@directive_warning +1 + + +@directive_error +28 + + +@directive_undefine +1 + + +@directive_define +22 + + +@pragma_checksum +4846 + + +@pragma_warning +28609 + + @bool_type 4 @@ -117,23 +173,23 @@ @enum_type -11974 +11952 @struct_type -49758 +49665 @class_type -305667 +305098 @interface_type -178444 +178112 @delegate_type -107767 +107567 @null_type @@ -141,7 +197,7 @@ @type_parameter -202974 +202597 @pointer_type @@ -149,11 +205,11 @@ @nullable_type -976 +979 @array_type -9139 +9122 @void_type @@ -165,7 +221,7 @@ @tuple_type -1785 +1782 @uint_ptr_type @@ -184,32 +240,36 @@ 0 +@function_pointer_type +11 + + @typeref -235229 +234791 @attribute -750664 +745454 @type_mention -1269646 +1252212 @oblivious -1317 +1315 @not_annotated -619 +618 @annotated -116 +113 @type_parameter_constraints -611920 +594129 @modifier @@ -217,47 +277,47 @@ @property -424316 +425592 @indexer -17073 +17042 @getter -441156 +442401 @setter -127764 +127526 @event -15258 +15230 @add_event_accessor -15258 +15230 @remove_event_accessor -15258 +15230 @operator -12433 +12410 @method -1118708 +1117636 @constructor -278155 +277979 @destructor -444 +443 @local_function @@ -265,15 +325,15 @@ @addressable_field -371157 +371421 @constant -185559 +185214 @addressable_local_variable -162436 +162452 @local_constant @@ -281,71 +341,71 @@ @local_variable_ref -259 +264 @parameter -2421931 +2417427 @block_stmt -308619 +306459 @expr_stmt -367893 +367208 @return_stmt -96209 +94364 @using_block_stmt -1142 +1140 @var_decl_stmt -147906 +147598 @if_stmt -119191 +117703 @switch_stmt -3049 +3065 @while_stmt -4544 +4447 @do_stmt -1000 +981 @for_stmt -6967 +6794 @foreach_stmt -5362 +5352 @break_stmt -10915 +11004 @continue_stmt -2187 +2218 @goto_stmt -2700 +2733 @goto_case_stmt -348 +329 @goto_default_stmt @@ -353,27 +413,27 @@ @throw_stmt -74348 +75132 @yield_stmt -686 +680 @try_stmt -4325 +4294 @checked_stmt -256 +253 @unchecked_stmt -105 +104 @lock_stmt -1660 +1523 @const_decl_stmt @@ -381,295 +441,295 @@ @empty_stmt -357 +351 @unsafe_stmt -178 +182 @fixed_stmt -1126 +1149 @label_stmt -1009 +1017 @catch -3440 +3419 @case_stmt -22449 +22718 @local_function_stmt -1793 +1792 @using_decl_stmt -554 +551 @bool_literal_expr -69538 +69328 @int_literal_expr -759312 +752491 @long_literal_expr -325 +331 @double_literal_expr -854 +864 @string_literal_expr -412522 +411643 @null_literal_expr -107828 +107815 @local_variable_access_expr -524139 +522589 @parameter_access_expr -357629 +353685 @field_access_expr -460484 +459628 @property_access_expr -359773 +359104 @type_access_expr -346431 +346616 @typeof_expr -30103 +33657 @method_invocation_expr -547923 +547072 @cast_expr -262926 +264239 @object_creation_expr -62884 +62511 @array_creation_expr -180015 +179799 @array_init_expr -179843 +179348 @local_var_decl_expr -163740 +163320 @char_literal_expr -15901 +16183 @decimal_literal_expr -91 +93 @uint_literal_expr -2368 +2406 @ulong_literal_expr -382 +390 @float_literal_expr -446 +454 @this_access_expr -592919 +591816 @base_access_expr -2822 +2840 @method_access_expr -9226 +9222 @event_access_expr -431 +433 @indexer_access_expr -30815 +30757 @array_access_expr -19754 +19356 @delegate_invocation_expr -2140 +2001 @operator_invocation_expr -29964 +29946 @explicit_delegate_creation_expr -668 +679 @implicit_delegate_creation_expr -5118 +5109 @default_expr -6360 +6144 @plus_expr -46 +45 @minus_expr -7145 +7069 @bit_not_expr -741 +738 @log_not_expr -26433 +26384 @post_incr_expr -12569 +12312 @post_decr_expr -1739 +1697 @pre_incr_expr -1274 +1261 @pre_decr_expr -412 +406 @mul_expr -4627 +4626 @div_expr -1818 +1791 @rem_expr -717 +704 @add_expr -27889 +27751 @sub_expr -12846 +12573 @lshift_expr -4050 +4121 @rshift_expr -1765 +1763 @lt_expr -16301 +15922 @gt_expr -9590 +9379 @le_expr -3898 +3829 @ge_expr -6284 +6014 @eq_expr -53933 +53515 @ne_expr -37965 +37219 @bit_and_expr -6332 +6298 @bit_xor_expr -536 +528 @bit_or_expr -14993 +15227 @log_and_expr -20839 +21263 @log_or_expr -14084 +14197 @is_expr -6720 +6486 @as_expr -2760 +2728 @null_coalescing_expr -3684 +3615 @conditional_expr -9158 +8972 @simple_assign_expr -167514 +167202 @assign_add_expr @@ -677,7 +737,7 @@ @assign_sub_expr -1017 +1021 @assign_mul_expr @@ -685,7 +745,7 @@ @assign_div_expr -97 +99 @assign_rem_expr @@ -693,51 +753,51 @@ @assign_and_expr -343 +340 @assign_xor_expr -116 +114 @assign_or_expr -1392 +1412 @assign_lshift_expr -116 +118 @assign_rshift_expr -217 +216 @object_init_expr -7700 +7685 @collection_init_expr -595 +594 @checked_expr -327 +326 @unchecked_expr -1422 +1421 @constructor_init_expr -5822 +5796 @add_event_expr -170 +172 @remove_event_expr -120 +121 @par_expr @@ -745,7 +805,7 @@ @lambda_expr -48860 +48769 @anonymous_method_expr @@ -761,31 +821,31 @@ @dynamic_member_access_expr -6855 +6843 @pointer_indirection_expr -4060 +4141 @address_of_expr -1251 +1289 @sizeof_expr -1040 +1061 @await_expr -54852 +54750 @nameof_expr -15938 +15584 @interpolated_string_expr -3036 +3042 @unknown_expr @@ -793,11 +853,11 @@ @throw_expr -1543 +1527 @tuple_expr -1478 +1450 @local_function_invocation_expr @@ -805,23 +865,23 @@ @ref_expr -563 +459 @discard_expr -909 +903 @range_expr -32 +33 @index_expr -46 +47 @switch_expr -518 +508 @recursive_pattern_expr @@ -829,15 +889,15 @@ @property_pattern_expr -828 +836 @positional_pattern_expr -180 +172 @switch_case_expr -4352 +4334 @assign_coalesce_expr @@ -845,13 +905,49 @@ @suppress_nullable_warning_expr -14409 +13849 @namespace_access_expr 20 +@lt_pattern_expr +2 + + +@gt_pattern_expr +5 + + +@le_pattern_expr +1 + + +@ge_pattern_expr +1 + + +@not_pattern_expr +70 + + +@and_pattern_expr +3 + + +@or_pattern_expr +34 + + +@function_pointer_invocation_expr +6 + + +@define_symbol_expr +6226 + + @xmldtd 6 @@ -877,19 +973,19 @@ @singlelinecomment -184760 +189072 @multilinecomment -22112 +22567 @xmldoccomment -203757 +207952 @commentblock -144330 +147802 @asp_close_tag @@ -929,7 +1025,7 @@ @cil_nop -820445 +837337 @cil_break @@ -937,147 +1033,147 @@ @cil_ldarg_0 -3977043 +3969647 @cil_ldarg_1 -1217214 +1214950 @cil_ldarg_2 -444079 +443253 @cil_ldarg_3 -209259 +208870 @cil_ldloc_0 -929679 +927950 @cil_ldloc_1 -494149 +493230 @cil_ldloc_2 -288852 +288314 @cil_ldloc_3 -192146 +191789 @cil_stloc_0 -525203 +524227 @cil_stloc_1 -260628 +260143 @cil_stloc_2 -198402 +198033 @cil_stloc_3 -138363 +138105 @cil_ldarg_s -264639 +264147 @cil_ldarga_s -74805 +74666 @cil_starg_s -37192 +37123 @cil_ldloc_s -686691 +685414 @cil_ldloca_s -629540 +628370 @cil_stloc_s -481072 +480177 @cil_ldnull -604005 +602882 @cil_ldc_i4_m1 -126261 +126026 @cil_ldc_i4_0 -625881 +624717 @cil_ldc_i4_1 -494891 +493970 @cil_ldc_i4_2 -121089 +120863 @cil_ldc_i4_3 -64182 +64062 @cil_ldc_i4_4 -58907 +58797 @cil_ldc_i4_5 -38700 +38628 @cil_ldc_i4_6 -23276 +23232 @cil_ldc_i4_7 -20762 +20724 @cil_ldc_i4_8 -33498 +33436 @cil_ldc_i4_s -423535 +422748 @cil_ldc_i4 -511096 +510146 @cil_ldc_i8 -4889 +4880 @cil_ldc_r4 -10266 +10247 @cil_ldc_r8 -10335 +10315 @cil_dup -842592 +841025 @cil_pop -256587 +256110 @cil_jmp @@ -1085,115 +1181,115 @@ @cil_call -2743121 +2738019 @cil_calli -0 +4 @cil_ret -1787525 +1784201 @cil_br_s -346027 +345383 @cil_brfalse_s -466247 +465380 @cil_brtrue_s -430967 +430166 @cil_beq_s -82310 +82157 @cil_bge_s -34948 +34883 @cil_bgt_s -16507 +16477 @cil_ble_s -29219 +29165 @cil_blt_s -60971 +60858 @cil_bne_un_s -102721 +102530 @cil_bge_un_s -2186 +2182 @cil_bgt_un_s -8739 +8723 @cil_ble_un_s -6123 +6112 @cil_blt_un_s -1468 +1466 @cil_br -96217 +96038 @cil_brfalse -32415 +32355 @cil_brtrue -27350 +27299 @cil_beq -21524 +21484 @cil_bge -1390 +1388 @cil_bgt -1463 +1461 @cil_ble -4645 +4636 @cil_blt -7939 +7924 @cil_bne_un -7241 +7227 @cil_bge_un -140 +142 @cil_bgt_un -692 +691 @cil_ble_un -1102 +1100 @cil_blt_un @@ -1201,43 +1297,43 @@ @cil_switch -23895 +23851 @cil_ldind_i1 -86 +88 @cil_ldind_u1 -5514 +5503 @cil_ldind_i2 -512 +511 @cil_ldind_u2 -2445 +2496 @cil_ldind_i4 -9783 +9765 @cil_ldind_u4 -1483 +1480 @cil_ldind_i8 -1971 +1967 @cil_ldind_i -244 +249 @cil_ldind_r4 -702 +701 @cil_ldind_r8 @@ -1245,27 +1341,27 @@ @cil_ldind_ref -6660 +6648 @cil_stind_ref -16947 +16915 @cil_stind_i1 -8529 +8513 @cil_stind_i2 -1377 +1405 @cil_stind_i4 -10369 +10350 @cil_stind_i8 -2347 +2342 @cil_stind_r4 @@ -1277,19 +1373,19 @@ @cil_add -224128 +223711 @cil_sub -85340 +85181 @cil_mul -29970 +29915 @cil_div -9129 +9112 @cil_div_un @@ -1297,79 +1393,79 @@ @cil_rem -3410 +3404 @cil_rem_un -229 +228 @cil_and -59375 +59265 @cil_or -22163 +22122 @cil_xor -22729 +22687 @cil_shl -18981 +18946 @cil_shr -9183 +9166 @cil_shr_un -26125 +26077 @cil_neg -2337 +2333 @cil_not -1459 +1456 @cil_conv_i1 -1385 +1383 @cil_conv_i2 -1449 +1446 @cil_conv_i4 -59819 +59708 @cil_conv_i8 -50324 +50230 @cil_conv_r4 -2469 +2464 @cil_conv_r8 -5284 +5274 @cil_conv_u4 -7836 +7822 @cil_conv_u8 -19557 +19521 @cil_callvirt -2051813 +2047997 @cil_cpobj @@ -1377,23 +1473,23 @@ @cil_ldobj -12662 +12639 @cil_ldstr -927381 +925656 @cil_newobj -657521 +656298 @cil_castclass -97134 +96954 @cil_isinst -56487 +56382 @cil_conv_r_un @@ -1405,35 +1501,35 @@ @cil_throw -381487 +380778 @cil_ldfld -1677845 +1674725 @cil_ldflda -300909 +300350 @cil_stfld -1073830 +1071833 @cil_ldsfld -407618 +406860 @cil_ldsflda -2532 +2527 @cil_stsfld -131009 +130765 @cil_stobj -7026 +7013 @cil_conv_ovf_i1_un @@ -1477,19 +1573,19 @@ @cil_box -79894 +79746 @cil_newarr -112188 +111979 @cil_ldlen -55369 +55266 @cil_ldelema -9876 +9858 @cil_ldelem_i1 @@ -1497,27 +1593,27 @@ @cil_ldelem_u1 -15585 +15556 @cil_ldelem_i2 -429 +428 @cil_ldelem_u2 -6094 +6083 @cil_ldelem_i4 -17596 +17563 @cil_ldelem_u4 -19128 +19092 @cil_ldelem_i8 -11930 +11908 @cil_ldelem_i @@ -1525,15 +1621,15 @@ @cil_ldelem_r4 -283 +282 @cil_ldelem_r8 -458 +457 @cil_ldelem_ref -30722 +30665 @cil_stelem_i @@ -1541,43 +1637,43 @@ @cil_stelem_i1 -8798 +8781 @cil_stelem_i2 -8993 +8976 @cil_stelem_i4 -22841 +22799 @cil_stelem_i8 -9432 +9414 @cil_stelem_r4 -200 +199 @cil_stelem_r8 -478 +477 @cil_stelem_ref -363198 +362523 @cil_ldelem -2278 +2274 @cil_stelem -53656 +53557 @cil_unbox_any -14399 +14373 @cil_conv_ovf_i1 @@ -1589,7 +1685,7 @@ @cil_conv_ovf_i2 -78 +77 @cil_conv_ovf_u2 @@ -1601,7 +1697,7 @@ @cil_conv_ovf_u4 -78 +77 @cil_conv_ovf_i8 @@ -1625,23 +1721,23 @@ @cil_ldtoken -71365 +71232 @cil_conv_u2 -4342 +4334 @cil_conv_u1 -11267 +11246 @cil_conv_i -3664 +3740 @cil_conv_ovf_i -268 +267 @cil_conv_ovf_u @@ -1649,15 +1745,15 @@ @cil_add_ovf -1732 +1729 @cil_add_ovf_un -151 +150 @cil_mul_ovf -444 +443 @cil_mul_ovf_un @@ -1665,7 +1761,7 @@ @cil_sub_ovf -1112 +1110 @cil_sub_ovf_un @@ -1673,23 +1769,23 @@ @cil_endfinally -56940 +56834 @cil_leave -66910 +66785 @cil_leave_s -149449 +149171 @cil_stind_i -125 +127 @cil_conv_u -5812 +5932 @cil_arglist @@ -1697,31 +1793,31 @@ @cil_ceq -97037 +99035 @cil_cgt -11574 +11813 @cil_cgt_un -36733 +37489 @cil_clt -19535 +19937 @cil_clt_un -1314 +1341 @cil_ldftn -79987 +79838 @cil_ldvirtftn -1112 +1110 @cil_ldarg @@ -1749,11 +1845,11 @@ @cil_localloc -978 +999 @cil_endfilter -810 +808 @cil_unaligned @@ -1761,7 +1857,7 @@ @cil_volatile -8544 +8528 @cil_tail @@ -1769,11 +1865,11 @@ @cil_initobj -101848 +101659 @cil_constrained -25330 +25283 @cil_cpblk @@ -1785,11 +1881,11 @@ @cil_rethrow -3771 +3764 @cil_sizeof -1732 +1729 @cil_refanytype @@ -1801,80 +1897,84 @@ @cil_valueorreftype -596320 +595245 @cil_typeparameter -185095 +184751 @cil_array_type -14194 +14168 @cil_pointer_type -624 +599 + + +@cil_function_pointer_type +9 @cil_method -2315906 +2311725 @cil_method_implementation -1728901 +1725686 @cil_field -1010179 +1008300 @cil_parameter -4554714 +4546408 @cil_property -380599 +379891 @cil_event -20880 +20841 @cil_local_variable -1152739 +1150595 @cil_catch_handler -43887 +43806 @cil_filter_handler -810 +808 @cil_finally_handler -55467 +55364 @cil_fault_handler -1473 +1470 @cil_attribute -328870 +328258 compilations -1097 +1095 id -1097 +1095 cwd -785 +784 @@ -1888,7 +1988,7 @@ 1 2 -1097 +1095 @@ -1904,12 +2004,12 @@ 1 2 -473 +472 2 3 -312 +311 @@ -1919,11 +2019,11 @@ compilation_args -4938 +4953 id -1097 +1095 num @@ -1931,7 +2031,7 @@ arg -1122 +1120 @@ -1945,12 +2045,12 @@ 4 5 -551 +526 5 6 -546 +569 @@ -1966,12 +2066,12 @@ 4 5 -551 +526 5 6 -546 +569 @@ -1985,8 +2085,8 @@ 12 -112 -113 +117 +118 4 @@ -2011,13 +2111,13 @@ 14 -112 -113 +109 +110 4 -114 -115 +117 +118 4 @@ -2034,10 +2134,10 @@ 1 2 -1097 +1095 -112 +108 226 24 @@ -2055,7 +2155,7 @@ 1 2 -1112 +1110 2 @@ -2070,19 +2170,19 @@ compilation_compiling_files -22627 +22584 id -1097 +1095 num -712 +711 file -22622 +22580 @@ -2288,7 +2388,7 @@ 11 12 -78 +77 12 @@ -2369,7 +2469,7 @@ 11 12 -78 +77 12 @@ -2420,7 +2520,7 @@ 1 2 -22617 +22575 2 @@ -2441,7 +2541,7 @@ 1 2 -22617 +22575 2 @@ -2456,19 +2556,19 @@ compilation_referencing_files -359929 +359260 id -1097 +1095 num -2747 +2742 file -3420 +3414 @@ -2542,7 +2642,7 @@ 369 564 -39 +38 @@ -2618,7 +2718,7 @@ 369 564 -39 +38 @@ -2644,7 +2744,7 @@ 7 8 -697 +696 8 @@ -2659,12 +2759,12 @@ 222 223 -639 +638 224 225 -712 +711 225 @@ -2689,58 +2789,58 @@ 4 +5 +9 + + +5 6 -131 +594 6 -7 -575 +17 +209 -7 -22 -253 +17 +23 +233 -22 -28 +23 +31 219 -28 -33 -224 +31 +35 +228 -33 -42 -229 +35 +45 +228 -42 -54 -214 +45 +57 +209 -54 +57 62 -170 +189 62 -64 -175 +65 +224 -64 -66 -175 - - -66 +65 73 -156 +175 @@ -2756,7 +2856,7 @@ 1 2 -527 +526 2 @@ -2771,12 +2871,12 @@ 7 8 -317 +316 8 10 -278 +277 10 @@ -2801,12 +2901,12 @@ 222 223 -483 +482 224 225 -717 +715 @@ -2822,67 +2922,62 @@ 1 2 -561 +560 2 5 -258 +282 5 6 -136 +194 6 7 -336 +267 7 11 -287 +282 11 20 -273 +272 20 -24 -268 +25 +272 -24 +25 29 -268 +258 29 -44 -258 +45 +267 -44 -64 -239 +47 +63 +272 -64 -68 -268 +63 +67 +306 -68 -76 -258 - - -76 -77 -4 +67 +74 +175 @@ -2892,11 +2987,11 @@ compilation_time -7685 +7671 id -1097 +1095 num @@ -2908,7 +3003,7 @@ seconds -5504 +5688 @@ -2922,7 +3017,7 @@ 1 2 -1097 +1095 @@ -2938,7 +3033,7 @@ 7 8 -1097 +1095 @@ -2952,14 +3047,9 @@ 12 -6 -7 -4 - - 7 8 -1093 +1095 @@ -3005,8 +3095,8 @@ 12 -1128 -1129 +1168 +1169 4 @@ -3053,29 +3143,34 @@ 12 -148 -149 +171 +172 4 -151 -152 +175 +176 4 -173 -174 +180 +181 4 -179 -180 +182 +183 +4 + + +224 +225 4 225 226 -14 +9 @@ -3091,22 +3186,22 @@ 1 2 -4411 +4490 2 3 -483 +691 3 5 -468 +443 5 -8 -141 +7 +63 @@ -3122,7 +3217,7 @@ 1 2 -5504 +5688 @@ -3138,17 +3233,17 @@ 1 2 -4699 +4812 2 3 -648 +725 3 5 -156 +150 @@ -4391,11 +4486,11 @@ extractor_messages -10135 +7638 id -10135 +7638 severity @@ -4407,19 +4502,19 @@ text -441 +12 entity -5762 +5272 location -7475 +6707 stack_trace -312 +202 @@ -4433,7 +4528,7 @@ 1 2 -10135 +7638 @@ -4449,7 +4544,7 @@ 1 2 -10135 +7638 @@ -4465,7 +4560,7 @@ 1 2 -10135 +7638 @@ -4481,7 +4576,7 @@ 1 2 -10135 +7638 @@ -4497,7 +4592,7 @@ 1 2 -10135 +7638 @@ -4513,7 +4608,7 @@ 1 2 -10135 +7638 @@ -4532,13 +4627,13 @@ 1 -24 -25 +49 +50 1 -10106 -10107 +7584 +7585 1 @@ -4571,11 +4666,16 @@ 1 2 -2 +1 -439 -440 +2 +3 +1 + + +9 +10 1 @@ -4595,13 +4695,13 @@ 1 -5 -6 +6 +7 1 -5756 -5757 +5267 +5268 1 @@ -4621,706 +4721,473 @@ 1 +37 +38 +1 + + +6670 +6671 +1 + + + + + + +severity +stack_trace + + +12 + + +1 +2 +2 + + +201 +202 +1 + + + + + + +origin +id + + +12 + + +7638 +7639 +1 + + + + + + +origin +severity + + +12 + + +3 +4 +1 + + + + + + +origin +text + + +12 + + +12 +13 +1 + + + + + + +origin +entity + + +12 + + +5272 +5273 +1 + + + + + + +origin +location + + +12 + + +6707 +6708 +1 + + + + + + +origin +stack_trace + + +12 + + +202 +203 +1 + + + + + + +text +id + + +12 + + +2 +3 +1 + + +5 +6 +1 + + +11 +12 +1 + + +24 +25 +2 + + +25 +26 +1 + + +38 +39 +1 + + +104 +105 +1 + + +216 +217 +1 + + +326 +327 +1 + + +2412 +2413 +1 + + +4451 +4452 +1 + + + + + + +text +severity + + +12 + + +1 +2 +12 + + + + + + +text +origin + + +12 + + +1 +2 +12 + + + + + + +text +entity + + +12 + + +1 +2 +4 + + +5 +6 +1 + + +11 +12 +1 + + +19 +20 +1 + + +47 +48 +1 + + +51 +52 +1 + + +275 +276 +1 + + +1648 +1649 +1 + + +3224 +3225 +1 + + + + + + +text +location + + +12 + + +1 +2 +3 + + +11 +12 +1 + + 12 13 1 -7463 -7464 +19 +20 1 - - - - - -severity -stack_trace - - -12 - - -1 -2 -2 - - -311 -312 -1 - - - - - - -origin -id - - -12 - - -10135 -10136 -1 - - - - - - -origin -severity - - -12 - - -3 -4 -1 - - - - - - -origin -text - - -12 - - -441 -442 -1 - - - - - - -origin -entity - - -12 - - -5762 -5763 -1 - - - - - - -origin -location - - -12 - - -7475 -7476 -1 - - - - - - -origin -stack_trace - - -12 - - -312 -313 -1 - - - - - - -text -id - - -12 - - -1 -2 -30 - - -2 -3 -160 - - -3 -4 -203 - - -4 -11 -34 - - -12 -4452 -14 - - - - - - -text -severity - - -12 - - -1 -2 -441 - - - - - - -text -origin - - -12 - - -1 -2 -441 - - - - - - -text -entity - - -12 - - -1 -2 -432 - - -2 -3225 -9 - - - - - - -text -location - - -12 - - -1 -2 -410 - - -2 -4078 -31 - - - - - - -text -stack_trace - - -12 - - -1 -2 -216 - - -2 -3 -202 - - -3 -181 -23 - - - - - - -entity -id - - -12 - - -1 -2 -4272 - - -2 -3 -957 - - -3 -7 -456 - - -7 -624 -77 - - - - - - -entity -severity - - -12 - - -1 -2 -5762 - - - - - - -entity -origin - - -12 - - -1 -2 -5762 - - - - - - -entity -text - - -12 - - -1 -2 -5753 - - -2 -3 -9 - - - - - - -entity -location - - -12 - - -1 -2 -5051 - - -2 -3 -495 - - -3 -249 -216 - - - - - - -entity -stack_trace - - -12 - - -1 -2 -5365 - - -2 -14 -397 - - - - - - -location -id - - -12 - - -1 -2 -5886 - - -2 -3 -1265 - - -3 -632 -324 - - - - - - -location -severity - - -12 - - -1 -2 -7474 - - -2 -3 -1 - - - - - - -location -origin - - -12 - - -1 -2 -7475 - - - - - - -location -text - - -12 - - -1 -2 -7474 - - -2 -3 -1 - - - - - - -location -entity - - -12 - - -1 -2 -7474 - - -3 -4 -1 - - - - - - -location -stack_trace - - -12 - - -1 -2 -7032 - - -2 -9 -443 - - - - - - -stack_trace -id - - -12 - - -1 -2 -84 - - -2 -3 -46 - - -3 -4 -25 - - -4 -5 -17 - - -5 -7 -24 - - -7 -11 -28 - - -11 -27 -26 - - -27 -59 -24 - - -59 -200 -24 - - -205 -750 -14 - - - - - - -stack_trace -severity - - -12 - - -1 -2 -311 - - -2 -3 -1 - - - - - - -stack_trace -origin - - -12 - - -1 -2 -312 - - - - - - -stack_trace -text - - -12 - - -1 -2 -293 - - -2 -171 -19 - - - - - - -stack_trace -entity - - -12 - - -1 -2 -105 - - -2 -3 -44 - - -3 -4 -26 - - -4 -5 -16 - - -5 -7 -28 - - -7 -12 -24 - - -12 -25 -24 - 25 -63 -24 +26 +1 -67 -603 -21 +104 +105 +1 + + +113 +114 +1 + + +326 +327 +1 + + +2018 +2019 +1 + + +4077 +4078 +1 -stack_trace +text +stack_trace + + +12 + + +1 +2 +6 + + +3 +4 +3 + + +10 +11 +1 + + +55 +56 +1 + + +124 +125 +1 + + + + + + +entity +id + + +12 + + +1 +2 +4192 + + +2 +3 +792 + + +3 +133 +288 + + + + + + +entity +severity + + +12 + + +1 +2 +5271 + + +3 +4 +1 + + + + + + +entity +origin + + +12 + + +1 +2 +5272 + + + + + + +entity +text + + +12 + + +1 +2 +5262 + + +2 +5 +10 + + + + + + +entity location @@ -5329,47 +5196,385 @@ 1 2 -99 +4587 2 3 -42 +478 + + +3 +67 +207 + + + + + + +entity +stack_trace + + +12 + + +1 +2 +5188 + + +2 +6 +84 + + + + + + +location +id + + +12 + + +1 +2 +5803 + + +2 +3 +903 + + +29 +30 +1 + + + + + + +location +severity + + +12 + + +1 +2 +6706 + + +2 +3 +1 + + + + + + +location +origin + + +12 + + +1 +2 +6707 + + + + + + +location +text + + +12 + + +1 +2 +6706 + + +2 +3 +1 + + + + + + +location +entity + + +12 + + +1 +2 +6707 + + + + + + +location +stack_trace + + +12 + + +1 +2 +6685 + + +2 +3 +22 + + + + + + +stack_trace +id + + +12 + + +1 +2 +55 + + +2 +3 +34 3 4 -28 +17 4 6 -28 +18 6 -10 -26 +9 +18 -10 -20 -26 +9 +15 +18 -20 -52 -25 +15 +49 +16 -52 -120 -24 +54 +205 +16 -130 -750 -14 +253 +1137 +10 + + + + + + +stack_trace +severity + + +12 + + +1 +2 +201 + + +2 +3 +1 + + + + + + +stack_trace +origin + + +12 + + +1 +2 +202 + + + + + + +stack_trace +text + + +12 + + +1 +2 +201 + + +3 +4 +1 + + + + + + +stack_trace +entity + + +12 + + +1 +2 +70 + + +2 +3 +28 + + +3 +4 +22 + + +4 +6 +16 + + +6 +8 +15 + + +8 +15 +17 + + +15 +55 +16 + + +57 +403 +16 + + +571 +917 +2 + + + + + + +stack_trace +location + + +12 + + +1 +2 +63 + + +2 +3 +31 + + +3 +4 +19 + + +4 +5 +12 + + +5 +8 +17 + + +8 +13 +17 + + +13 +37 +16 + + +38 +158 +16 + + +162 +1137 +11 @@ -5379,19 +5584,19 @@ compilation_finished -1097 +1095 id -1097 +1095 cpu_seconds -961 +998 elapsed_seconds -1097 +1095 @@ -5405,7 +5610,7 @@ 1 2 -1097 +1095 @@ -5421,7 +5626,7 @@ 1 2 -1097 +1095 @@ -5437,17 +5642,12 @@ 1 2 -844 +901 2 3 -102 - - -3 -5 -14 +97 @@ -5463,17 +5663,12 @@ 1 2 -844 +901 2 3 -102 - - -3 -5 -14 +97 @@ -5489,7 +5684,7 @@ 1 2 -1097 +1095 @@ -5505,7 +5700,55 @@ 1 2 -1097 +1095 + + + + + + + + +compilation_assembly +1095 + + +id +1095 + + +assembly +1095 + + + + +id +assembly + + +12 + + +1 +2 +1095 + + + + + + +assembly +id + + +12 + + +1 +2 +1095 @@ -6167,19 +6410,19 @@ duplicateCode -22778 +22735 id -22778 +22735 relativePath -3811 +3803 equivClass -7021 +7008 @@ -6193,7 +6436,7 @@ 1 2 -22778 +22735 @@ -6209,7 +6452,7 @@ 1 2 -22778 +22735 @@ -6225,17 +6468,17 @@ 1 2 -1063 +1061 2 3 -566 +564 3 4 -424 +423 4 @@ -6255,12 +6498,12 @@ 8 10 -278 +277 10 14 -317 +316 14 @@ -6286,27 +6529,27 @@ 1 2 -1132 +1129 2 3 -522 +521 3 4 -444 +443 4 5 -234 +233 5 6 -229 +228 6 @@ -6316,12 +6559,12 @@ 8 10 -278 +277 10 14 -312 +311 14 @@ -6331,7 +6574,7 @@ 33 45 -39 +38 @@ -6347,32 +6590,32 @@ 2 3 -3771 +3764 3 4 -1146 +1144 4 5 -785 +784 5 6 -429 +428 6 8 -570 +569 8 11 -317 +316 @@ -6388,32 +6631,32 @@ 1 2 -678 +677 2 3 -3445 +3438 3 4 -1078 +1076 4 5 -678 +677 5 6 -385 +384 6 9 -580 +579 9 @@ -8496,15 +8739,15 @@ locations_default -14663251 +14080010 id -14663251 +14080010 file -6231 +6232 beginLine @@ -8534,7 +8777,7 @@ 1 2 -14663251 +14080010 @@ -8550,7 +8793,7 @@ 1 2 -14663251 +14080010 @@ -8566,7 +8809,7 @@ 1 2 -14663251 +14080010 @@ -8582,7 +8825,7 @@ 1 2 -14663251 +14080010 @@ -8598,7 +8841,7 @@ 1 2 -14663251 +14080010 @@ -8613,73 +8856,73 @@ 1 -20 -479 +19 +472 -20 -37 -491 +19 +34 +470 -37 -57 -471 +34 +50 +497 -57 -81 -471 - - -81 -110 -479 - - -110 -154 -474 - - -154 -214 -471 - - -214 -301 +50 +74 468 -301 -451 -471 +74 +106 +473 -451 -706 -471 +106 +150 +476 -706 -1217 +150 +208 +476 + + +208 +297 +473 + + +297 +446 +469 + + +446 +687 468 -1217 -2770 +687 +1204 468 -2775 -44373 -488 +1204 +2639 +468 -45351 -567388 -61 +2639 +42820 +494 + + +43087 +474768 +60 @@ -8694,73 +8937,68 @@ 1 -11 -460 +12 +541 -11 -17 -484 +12 +19 +506 -17 -24 -497 +19 +27 +519 -24 -32 -490 +27 +35 +494 -32 -42 -495 +35 +46 +512 -42 -55 -475 - - -55 -74 -495 - - -74 -101 +46 +61 474 -101 -144 -471 +61 +82 +504 -144 -227 -469 +82 +114 +477 -227 -408 -469 +114 +168 +475 -408 -905 +168 +273 468 -908 -30336 -481 +273 +504 +486 -47451 +504 +1742 +468 + + +1746 143014 -3 +308 @@ -8781,37 +9019,37 @@ 7 13 -509 +499 13 19 -488 +486 19 26 -478 +486 26 34 -523 +511 34 43 -495 +498 43 53 -481 +484 53 64 -477 +481 64 @@ -8821,12 +9059,12 @@ 76 91 -473 +476 91 112 -474 +477 112 @@ -8836,7 +9074,7 @@ 166 930 -316 +317 @@ -8852,67 +9090,72 @@ 1 12 -516 +480 12 18 -482 +476 18 25 -471 +481 25 34 -493 +496 34 -45 -537 +44 +468 -45 -59 -486 +44 +56 +483 -59 -80 +56 +76 +473 + + +76 +104 478 -80 -110 -470 +104 +146 +469 -110 -157 -471 - - -157 -256 -470 - - -256 -468 +146 +230 468 -468 -1222 +230 +405 468 -1222 +405 +840 +468 + + +845 +28774 +472 + + +46287 171760 -421 +52 @@ -8928,62 +9171,62 @@ 1 15 -497 +475 15 23 -474 +481 23 -32 -472 +33 +519 -32 -43 -507 +33 +44 +503 -43 +44 54 -530 +481 54 66 -484 +490 66 77 -472 +480 77 91 -476 +474 91 105 -492 +490 105 123 -485 +491 123 148 -468 +470 148 186 -469 +473 186 @@ -9004,72 +9247,62 @@ 1 2 -3575 +4162 2 3 -29135 +30681 3 4 -17678 +15896 4 5 -5446 +16240 5 6 -11008 +9901 6 -7 -11482 +8 +13417 -7 -9 -9234 - - -9 +8 13 -14232 +13925 13 -88 -12408 +101 +14154 -88 -111 -12836 +101 +117 +12389 -111 -171 -12483 +117 +182 +12558 -171 -270 -12452 +182 +301 +12385 -270 -2367 -12358 - - -2368 -11270 -434 +301 +10809 +9053 @@ -9085,37 +9318,37 @@ 1 2 -72393 +72389 2 3 -30311 +30310 3 38 -12530 +12534 38 52 -14355 +14356 52 -78 -12368 +79 +12462 -78 +79 118 -12664 +12565 118 -6164 -10140 +6166 +10145 @@ -9131,12 +9364,12 @@ 1 2 -23472 +23471 2 3 -30017 +30016 3 @@ -9146,32 +9379,32 @@ 4 5 -22184 +22185 5 6 -10198 +10197 6 7 -11742 +11740 7 9 -13753 +13756 9 12 -13098 +13097 12 19 -12775 +12777 19 @@ -9207,22 +9440,22 @@ 3 4 -18655 +18654 4 6 -13946 +13928 6 -35 -12404 +34 +12361 -35 +34 306 -555 +617 @@ -9243,22 +9476,22 @@ 2 3 -31626 +31624 3 4 -16669 +16670 4 5 -18712 +18713 5 6 -12090 +12088 6 @@ -9268,12 +9501,12 @@ 7 9 -14627 +14626 9 12 -14502 +14505 12 @@ -9283,17 +9516,17 @@ 17 29 -12449 +12447 29 111 -12415 +12416 111 389 -3919 +3920 @@ -9309,62 +9542,57 @@ 1 2 -304 +352 2 3 -172 +184 3 4 -97 +101 4 -5 -85 +6 +129 -5 -8 -120 +6 +13 +114 -8 -19 -115 - - -19 -58 +13 +40 111 -58 -158 +40 +110 +111 + + +112 +476 110 -158 -729 +490 +5418 110 -732 -9001 +5447 +74992 110 -9032 -178318 -110 - - -184038 -2240308 -12 +76227 +2221388 +24 @@ -9409,22 +9637,22 @@ 58 -193 +194 110 195 -1096 +1098 110 -1109 -3845 +1112 +3852 110 -3880 -6230 +3882 +6231 8 @@ -9624,62 +9852,62 @@ 1 2 -29957 +30736 2 3 -14651 +14517 3 4 -15954 +16816 4 +5 +12515 + + +5 6 -16139 +10358 6 -8 -12045 +9 +14907 -8 -12 -15237 +9 +51 +14737 -12 -53 -13516 +51 +64 +13404 -53 -89 +64 +109 +13430 + + +109 +170 13424 -89 -119 -13390 +170 +277 +13375 -119 -198 -13444 - - -198 -349 -13346 - - -349 -11177 -6608 +277 +10708 +9492 @@ -9695,27 +9923,27 @@ 1 2 -74588 +74587 2 3 -32294 +32293 3 51 -15349 +15351 51 53 -14844 +14842 53 91 -13581 +13579 91 @@ -9724,8 +9952,8 @@ 136 -5697 -12936 +5796 +12940 @@ -9746,22 +9974,22 @@ 2 3 -38081 +38080 3 4 -18056 +18054 4 6 -14158 +14148 6 61 -13147 +13160 @@ -9777,7 +10005,7 @@ 1 2 -31574 +31573 2 @@ -9787,7 +10015,7 @@ 3 4 -12788 +12789 4 @@ -9797,7 +10025,7 @@ 5 6 -11851 +11849 6 @@ -9807,27 +10035,27 @@ 7 9 -15127 +15126 9 12 -14463 +14464 12 18 -13365 +13367 18 58 -13379 +13376 58 353 -4976 +4979 @@ -9843,17 +10071,17 @@ 1 2 -31277 +31276 2 3 -18344 +18345 3 4 -19309 +19308 4 @@ -9863,7 +10091,7 @@ 5 6 -13461 +13460 6 @@ -9878,27 +10106,27 @@ 9 12 -13944 +13943 12 17 -13345 +13348 17 32 -13515 +13514 32 156 -13332 +13329 156 388 -1611 +1615 @@ -9914,57 +10142,57 @@ 1 2 -358 +406 2 3 -209 +205 3 4 -94 +116 4 -6 -121 +7 +126 -6 -16 -128 - - -16 -67 +7 +51 124 -67 -202 -125 +51 +122 +126 -202 -680 +122 +325 124 -685 -2824 +328 +1118 124 -2824 -40660 +1126 +9603 124 -41257 -908062 -110 +9620 +82632 +124 + + +82696 +908740 +42 @@ -10018,13 +10246,13 @@ 124 -715 -3686 +717 +3690 124 -3691 -5367 +3701 +5368 54 @@ -10080,16 +10308,16 @@ 549 -5838 +5840 124 6139 -19147 +19157 124 -19459 +19476 47830 14 @@ -10207,17 +10435,17 @@ 541 -5829 +5831 124 6123 -19057 +19067 124 -19443 -47820 +19460 +47823 14 @@ -10227,12 +10455,65 @@ +locations_mapped +483051 + + +id +483051 + + +mapped_to +410854 + + + + +id +mapped_to + + +12 + + +1 +2 +483051 + + + + + + +mapped_to +id + + +12 + + +1 +2 +399291 + + +2 +119 +11562 + + + + + + + + numlines -4585449 +4586385 element_id -4585442 +4586378 num_lines @@ -10258,7 +10539,7 @@ 1 2 -4585435 +4586371 2 @@ -10279,7 +10560,7 @@ 1 2 -4585435 +4586371 2 @@ -10300,7 +10581,7 @@ 1 2 -4585438 +4586374 2 @@ -10488,7 +10769,7 @@ 52 -1614447 +1615186 83 @@ -10626,7 +10907,7 @@ 215 -4548962 +4549896 19 @@ -10729,23 +11010,23 @@ assemblies -4206 +4198 id -4206 +4198 file -4206 +4198 fullname -3445 +3438 name -3176 +3170 version @@ -10763,7 +11044,7 @@ 1 2 -4206 +4198 @@ -10779,7 +11060,7 @@ 1 2 -4206 +4198 @@ -10795,7 +11076,7 @@ 1 2 -4206 +4198 @@ -10811,7 +11092,7 @@ 1 2 -4206 +4198 @@ -10827,7 +11108,7 @@ 1 2 -4206 +4198 @@ -10843,7 +11124,7 @@ 1 2 -4206 +4198 @@ -10859,7 +11140,7 @@ 1 2 -4206 +4198 @@ -10875,7 +11156,7 @@ 1 2 -4206 +4198 @@ -10891,12 +11172,12 @@ 1 2 -2683 +2678 2 3 -761 +759 @@ -10912,12 +11193,12 @@ 1 2 -2683 +2678 2 3 -761 +759 @@ -10933,7 +11214,7 @@ 1 2 -3445 +3438 @@ -10949,7 +11230,7 @@ 1 2 -3445 +3438 @@ -10965,12 +11246,12 @@ 1 2 -2190 +2186 2 3 -941 +940 3 @@ -10991,12 +11272,12 @@ 1 2 -2190 +2186 2 3 -941 +940 3 @@ -11017,7 +11298,7 @@ 1 2 -2952 +2946 2 @@ -11038,7 +11319,7 @@ 1 2 -2952 +2946 2 @@ -11217,23 +11498,23 @@ files -42545 +47312 id -42545 +47312 name -42545 +47312 simple -22978 +26578 ext -39 +43 fromSource @@ -11251,7 +11532,7 @@ 1 2 -42545 +47312 @@ -11267,7 +11548,7 @@ 1 2 -42545 +47312 @@ -11283,7 +11564,7 @@ 1 2 -42545 +47312 @@ -11299,7 +11580,7 @@ 1 2 -42545 +47312 @@ -11315,7 +11596,7 @@ 1 2 -42545 +47312 @@ -11331,7 +11612,7 @@ 1 2 -42545 +47312 @@ -11347,7 +11628,7 @@ 1 2 -42545 +47312 @@ -11363,7 +11644,7 @@ 1 2 -42545 +47312 @@ -11379,12 +11660,12 @@ 1 2 -21568 +24844 2 154 -1410 +1733 @@ -11400,12 +11681,12 @@ 1 2 -21568 +24844 2 154 -1410 +1733 @@ -11421,12 +11702,12 @@ 1 2 -22187 +25585 2 5 -790 +993 @@ -11442,7 +11723,7 @@ 1 2 -22978 +26578 @@ -11486,6 +11767,11 @@ 4 +995 +996 +4 + + 2875 2876 4 @@ -11537,6 +11823,11 @@ 4 +995 +996 +4 + + 2875 2876 4 @@ -11588,6 +11879,11 @@ 4 +790 +791 +4 + + 3818 3819 4 @@ -11606,7 +11902,7 @@ 1 2 -39 +43 @@ -11620,8 +11916,8 @@ 12 -8719 -8720 +9714 +9715 4 @@ -11636,8 +11932,8 @@ 12 -8719 -8720 +9714 +9715 4 @@ -11652,8 +11948,8 @@ 12 -4709 -4710 +5457 +5458 4 @@ -11668,8 +11964,8 @@ 12 -8 -9 +9 +10 4 @@ -11680,15 +11976,15 @@ folders -16961 +17831 id -16961 +17831 name -14741 +15615 simple @@ -11706,7 +12002,7 @@ 1 2 -16961 +17831 @@ -11722,7 +12018,7 @@ 1 2 -16961 +17831 @@ -11738,7 +12034,7 @@ 1 2 -14741 +15615 @@ -11754,12 +12050,12 @@ 1 2 -12521 +13399 2 3 -2220 +2216 @@ -11775,27 +12071,27 @@ 1 2 -1820 +1636 2 3 -380 +540 3 4 -200 - - -4 -11 209 -11 +4 +10 +209 + + +10 383 -165 +180 @@ -11811,27 +12107,27 @@ 1 2 -1820 +1636 2 3 -380 +540 3 4 -200 - - -4 -11 209 -11 +4 +10 +209 + + +10 383 -165 +180 @@ -11841,15 +12137,15 @@ containerparent -57277 +62918 parent -14741 +15615 child -57277 +62918 @@ -11863,37 +12159,37 @@ 1 2 -8266 +8465 2 3 -1937 +2079 3 4 -770 +944 4 5 -971 +1052 5 9 -1107 +1222 9 -18 -1141 +17 +1183 -18 -171 -546 +17 +170 +667 @@ -11909,7 +12205,7 @@ 1 2 -57277 +62918 @@ -11919,11 +12215,11 @@ file_extraction_mode -26828 +31624 file -26828 +31624 mode @@ -11941,7 +12237,7 @@ 1 2 -26828 +31624 @@ -11955,8 +12251,8 @@ 12 -5498 -5499 +6493 +6494 4 @@ -11967,15 +12263,15 @@ namespaces -21982 +21942 id -21982 +21942 name -4899 +4890 @@ -11989,7 +12285,7 @@ 1 2 -21982 +21942 @@ -12010,7 +12306,7 @@ 2 3 -3498 +3492 3 @@ -12020,7 +12316,7 @@ 4 5 -624 +623 6 @@ -12045,15 +12341,15 @@ namespace_declarations -19796 +19760 id -19796 +19760 namespace_id -3893 +3886 @@ -12067,7 +12363,7 @@ 1 2 -19796 +19760 @@ -12083,12 +12379,12 @@ 1 2 -1400 +1397 2 3 -800 +798 3 @@ -12098,7 +12394,7 @@ 4 5 -307 +306 5 @@ -12113,7 +12409,7 @@ 9 17 -302 +301 17 @@ -12128,15 +12424,15 @@ namespace_declaration_location -19796 +19760 id -19796 +19760 loc -19796 +19760 @@ -12150,7 +12446,7 @@ 1 2 -19796 +19760 @@ -12166,7 +12462,7 @@ 1 2 -19796 +19760 @@ -12176,15 +12472,15 @@ parent_namespace -778507 +777059 child_id -778507 +777059 namespace_id -13580 +13554 @@ -12198,7 +12494,7 @@ 1 2 -778507 +777059 @@ -12214,52 +12510,52 @@ 1 2 -3332 +3326 2 3 -1629 +1626 3 4 -1029 +1027 4 5 -917 +915 5 7 -1254 +1251 7 10 -1093 +1091 10 15 -1141 +1139 15 23 -1063 +1061 23 51 -1029 +1027 51 835 -1019 +1017 900 @@ -12274,15 +12570,15 @@ parent_namespace_declaration -88468 +88303 child_id -87951 +87787 namespace_id -19796 +19760 @@ -12296,12 +12592,12 @@ 1 2 -87799 +87636 2 60 -151 +150 @@ -12317,27 +12613,27 @@ 1 2 -13804 +13778 2 9 -1717 +1714 9 13 -1278 +1276 13 16 -1429 +1427 16 32 -1512 +1509 32 @@ -12352,15 +12648,15 @@ using_namespace_directives -144521 +144252 id -144521 +144252 namespace_id -4235 +4227 @@ -12374,7 +12670,7 @@ 1 2 -144521 +144252 @@ -12390,12 +12686,12 @@ 1 2 -1498 +1495 2 3 -473 +472 3 @@ -12405,7 +12701,7 @@ 4 5 -239 +238 5 @@ -12420,7 +12716,7 @@ 14 25 -322 +321 25 @@ -12430,7 +12726,7 @@ 64 465 -322 +321 510 @@ -12533,15 +12829,15 @@ using_directive_location -144579 +144310 id -144579 +144310 loc -144535 +144267 @@ -12555,7 +12851,7 @@ 1 2 -144579 +144310 @@ -12571,7 +12867,7 @@ 1 2 -144491 +144223 2 @@ -12585,20 +12881,1063 @@ -types -868781 +directive_ifs +5161 id -868781 +5161 -kind -131 +branchTaken +2 + + +conditionValue +2 + + + + +id +branchTaken + + +12 + + +1 +2 +5161 + + + + + + +id +conditionValue + + +12 + + +1 +2 +5161 + + + + + + +branchTaken +id + + +12 + + +1992 +1993 +1 + + +2162 +2163 +1 + + + + + + +branchTaken +conditionValue + + +12 + + +1 +2 +1 + + +2 +3 +1 + + + + + + +conditionValue +id + + +12 + + +2013 +2014 +1 + + +2141 +2142 +1 + + + + + + +conditionValue +branchTaken + + +12 + + +1 +2 +1 + + +2 +3 +1 + + + + + + + + +directive_elifs +59 + + +id +59 + + +branchTaken +2 + + +conditionValue +2 + + +parent +51 + + +index +2 + + + + +id +branchTaken + + +12 + + +1 +2 +59 + + + + + + +id +conditionValue + + +12 + + +1 +2 +59 + + + + + + +id +parent + + +12 + + +1 +2 +59 + + + + + + +id +index + + +12 + + +1 +2 +59 + + + + + + +branchTaken +id + + +12 + + +18 +19 +1 + + +41 +42 +1 + + + + + + +branchTaken +conditionValue + + +12 + + +1 +2 +2 + + + + + + +branchTaken +parent + + +12 + + +18 +19 +1 + + +39 +40 +1 + + + + + + +branchTaken +index + + +12 + + +2 +3 +2 + + + + + + +conditionValue +id + + +12 + + +18 +19 +1 + + +41 +42 +1 + + + + + + +conditionValue +branchTaken + + +12 + + +1 +2 +2 + + + + + + +conditionValue +parent + + +12 + + +18 +19 +1 + + +39 +40 +1 + + + + + + +conditionValue +index + + +12 + + +2 +3 +2 + + + + + + +parent +id + + +12 + + +1 +2 +43 + + +2 +3 +8 + + + + + + +parent +branchTaken + + +12 + + +1 +2 +45 + + +2 +3 +6 + + + + + + +parent +conditionValue + + +12 + + +1 +2 +45 + + +2 +3 +6 + + + + + + +parent +index + + +12 + + +1 +2 +43 + + +2 +3 +8 + + + + + + +index +id + + +12 + + +8 +9 +1 + + +51 +52 +1 + + + + + + +index +branchTaken + + +12 + + +2 +3 +2 + + + + + + +index +conditionValue + + +12 + + +2 +3 +2 + + + + + + +index +parent + + +12 + + +8 +9 +1 + + +51 +52 +1 + + + + + + + + +directive_elses +2314 + + +id +2314 + + +branchTaken +2 + + +parent +2314 + + +index +3 + + + + +id +branchTaken + + +12 + + +1 +2 +2314 + + + + + + +id +parent + + +12 + + +1 +2 +2314 + + + + + + +id +index + + +12 + + +1 +2 +2314 + + + + + + +branchTaken +id + + +12 + + +496 +497 +1 + + +1367 +1368 +1 + + + + + + +branchTaken +parent + + +12 + + +496 +497 +1 + + +1367 +1368 +1 + + + + + + +branchTaken +index + + +12 + + +2 +3 +1 + + +3 +4 +1 + + + + + + +parent +id + + +12 + + +1 +2 +2314 + + + + + + +parent +branchTaken + + +12 + + +1 +2 +2314 + + + + + + +parent +index + + +12 + + +1 +2 +2314 + + + + + + +index +id + + +12 + + +1 +2 +1 + + +10 +11 +1 + + +1852 +1853 +1 + + + + + + +index +branchTaken + + +12 + + +1 +2 +1 + + +2 +3 +2 + + + + + + +index +parent + + +12 + + +1 +2 +1 + + +10 +11 +1 + + +1852 +1853 +1 + + + + + + + + +directive_endifs +5161 + + +id +5161 + + +start +5161 + + + + +id +start + + +12 + + +1 +2 +5161 + + + + + + +start +id + + +12 + + +1 +2 +5161 + + + + + + + + +directive_define_symbols +6226 + + +id +6226 name -367541 +170 + + + + +id +name + + +12 + + +1 +2 +6226 + + + + + + +name +id + + +12 + + +1 +2 +37 + + +2 +3 +27 + + +3 +4 +13 + + +4 +5 +11 + + +5 +7 +11 + + +7 +10 +12 + + +10 +17 +14 + + +17 +27 +14 + + +27 +72 +13 + + +77 +1098 +13 + + + + + + + + +directive_regions +1954 + + +id +1954 + + +name +710 + + + + +id +name + + +12 + + +1 +2 +1954 + + + + + + +name +id + + +12 + + +1 +2 +8 + + +2 +3 +547 + + +3 +4 +22 + + +4 +5 +81 + + +5 +35 +52 + + + + + + + + +directive_endregions +1954 + + +id +1954 + + +start +1954 + + + + +id +start + + +12 + + +1 +2 +1954 + + + + + + +start +id + + +12 + + +1 +2 +1954 + + + + + + + + +directive_lines +250436 + + +id +250436 + + +kind +14 @@ -12612,7 +13951,1212 @@ 1 2 -868781 +250436 + + + + + + +kind +id + + +12 + + +16650 +16651 +9 + + +18118 +18119 +4 + + + + + + + + +directive_line_value +81095 + + +id +81095 + + +line +1378 + + + + +id +line + + +12 + + +1 +2 +81095 + + + + + + +line +id + + +12 + + +1 +2 +287 + + +2 +3 +136 + + +3 +4 +107 + + +4 +7 +126 + + +7 +11 +116 + + +11 +15 +107 + + +15 +27 +121 + + +27 +46 +107 + + +46 +104 +107 + + +106 +549 +107 + + +569 +727 +53 + + + + + + + + +directive_line_file +81095 + + +id +81095 + + +file +4656 + + + + +id +file + + +12 + + +1 +2 +81095 + + + + + + +file +id + + +12 + + +1 +2 +599 + + +2 +3 +769 + + +3 +4 +496 + + +4 +6 +399 + + +6 +7 +214 + + +7 +9 +389 + + +9 +12 +350 + + +12 +16 +399 + + +16 +27 +360 + + +27 +42 +365 + + +42 +2665 +311 + + + + + + + + +directive_nullables +162190 + + +id +162190 + + +setting +9 + + +target +4 + + + + +id +setting + + +12 + + +1 +2 +162190 + + + + + + +id +target + + +12 + + +1 +2 +162190 + + + + + + +setting +id + + +12 + + +16650 +16651 +9 + + + + + + +setting +target + + +12 + + +1 +2 +9 + + + + + + +target +id + + +12 + + +33300 +33301 +4 + + + + + + +target +setting + + +12 + + +2 +3 +4 + + + + + + + + +directive_warnings +1 + + +id +1 + + +message +1 + + + + +id +message + + +12 + + +1 +2 +1 + + + + + + +message +id + + +12 + + +1 +2 +1 + + + + + + + + +directive_errors +28 + + +id +28 + + +message +2 + + + + +id +message + + +12 + + +1 +2 +28 + + + + + + +message +id + + +12 + + +4 +5 +1 + + +24 +25 +1 + + + + + + + + +directive_undefines +1 + + +id +1 + + +name +1 + + + + +id +name + + +12 + + +1 +2 +1 + + + + + + +name +id + + +12 + + +1 +2 +1 + + + + + + + + +directive_defines +22 + + +id +22 + + +name +12 + + + + +id +name + + +12 + + +1 +2 +22 + + + + + + +name +id + + +12 + + +1 +2 +8 + + +2 +3 +1 + + +3 +4 +1 + + +6 +7 +1 + + + + + + + + +pragma_checksums +4846 + + +id +4846 + + +file +4846 + + +guid +4 + + +bytes +4544 + + + + +id +file + + +12 + + +1 +2 +4846 + + + + + + +id +guid + + +12 + + +1 +2 +4846 + + + + + + +id +bytes + + +12 + + +1 +2 +4846 + + + + + + +file +id + + +12 + + +1 +2 +4846 + + + + + + +file +guid + + +12 + + +1 +2 +4846 + + + + + + +file +bytes + + +12 + + +1 +2 +4846 + + + + + + +guid +id + + +12 + + +995 +996 +4 + + + + + + +guid +file + + +12 + + +995 +996 +4 + + + + + + +guid +bytes + + +12 + + +933 +934 +4 + + + + + + +bytes +id + + +12 + + +1 +2 +4446 + + +2 +19 +97 + + + + + + +bytes +file + + +12 + + +1 +2 +4446 + + +2 +19 +97 + + + + + + +bytes +guid + + +12 + + +1 +2 +4544 + + + + + + + + +pragma_warnings +28609 + + +id +28609 + + +kind +9 + + + + +id +kind + + +12 + + +1 +2 +28609 + + + + + + +kind +id + + +12 + + +2937 +2938 +9 + + + + + + + + +pragma_warning_error_codes +28619 + + +id +28609 + + +errorCode +29 + + +index +9 + + + + +id +errorCode + + +12 + + +1 +2 +28600 + + +2 +3 +9 + + + + + + +id +index + + +12 + + +1 +2 +28600 + + +2 +3 +9 + + + + + + +errorCode +id + + +12 + + +2 +3 +9 + + +946 +947 +9 + + +1990 +1991 +9 + + + + + + +errorCode +index + + +12 + + +1 +2 +29 + + + + + + +index +id + + +12 + + +2 +3 +4 + + +5874 +5875 +4 + + + + + + +index +errorCode + + +12 + + +1 +2 +4 + + +5 +6 +4 + + + + + + + + +preprocessor_directive_location +446370 + + +id +446370 + + +loc +446370 + + + + +id +loc + + +12 + + +1 +2 +446370 + + + + + + +loc +id + + +12 + + +1 +2 +446370 + + + + + + + + +preprocessor_directive_compilation +446370 + + +id +446370 + + +compilation +345 + + + + +id +compilation + + +12 + + +1 +2 +446370 + + + + + + +compilation +id + + +12 + + +4 +11 +29 + + +16 +48 +29 + + +61 +140 +29 + + +143 +198 +29 + + +225 +300 +29 + + +316 +453 +29 + + +458 +634 +29 + + +664 +1055 +29 + + +1089 +1250 +29 + + +1275 +1989 +29 + + +2000 +3215 +29 + + +4114 +19444 +24 + + + + + + + + +preprocessor_directive_active +446370 + + +id +446370 + + +active +9 + + + + +id +active + + +12 + + +1 +2 +446370 + + + + + + +active +id + + +12 + + +7 +8 +4 + + +91639 +91640 +4 + + + + + + + + +types +867165 + + +id +867165 + + +kind +131 + + +name +366858 + + + + +id +kind + + +12 + + +1 +2 +867165 @@ -12628,7 +15172,7 @@ 1 2 -868781 +867165 @@ -12726,17 +15270,17 @@ 1 2 -325215 +324610 2 5 -28892 +28838 5 6356 -13433 +13408 @@ -12752,12 +15296,12 @@ 1 2 -366102 +365421 2 4 -1439 +1436 @@ -12767,15 +15311,15 @@ typerefs -235229 +234791 id -235229 +234791 name -177312 +176982 @@ -12789,7 +15333,7 @@ 1 2 -235229 +234791 @@ -12805,17 +15349,17 @@ 1 2 -162737 +162434 2 7 -13506 +13481 7 2183 -1068 +1066 @@ -12825,15 +15369,15 @@ typeref_type -235048 +234611 id -235048 +234611 typeId -235048 +234611 @@ -12847,7 +15391,7 @@ 1 2 -235048 +234611 @@ -12863,7 +15407,7 @@ 1 2 -235048 +234611 @@ -12873,11 +15417,11 @@ array_element_type -9139 +9122 array -9139 +9122 dimension @@ -12889,7 +15433,7 @@ element -9129 +9112 @@ -12903,7 +15447,7 @@ 1 2 -9139 +9122 @@ -12919,7 +15463,7 @@ 1 2 -9139 +9122 @@ -12935,7 +15479,7 @@ 1 2 -9139 +9122 @@ -13077,7 +15621,7 @@ 1 2 -9120 +9103 2 @@ -13098,7 +15642,7 @@ 1 2 -9129 +9112 @@ -13114,7 +15658,7 @@ 1 2 -9120 +9103 2 @@ -13129,15 +15673,15 @@ nullable_underlying_type -976 +979 nullable -976 +979 underlying -976 +979 @@ -13151,7 +15695,7 @@ 1 2 -976 +979 @@ -13167,7 +15711,7 @@ 1 2 -976 +979 @@ -13225,15 +15769,15 @@ enum_underlying_type -11974 +11952 enum_id -11974 +11952 underlying_type_id -39 +38 @@ -13247,7 +15791,7 @@ 1 2 -11974 +11952 @@ -13303,15 +15847,15 @@ delegate_return_type -107752 +107552 delegate_id -107752 +107552 return_type_id -55613 +55510 @@ -13325,7 +15869,7 @@ 1 2 -107752 +107552 @@ -13341,12 +15885,70 @@ 1 2 -52295 +52198 2 4178 -3318 +3312 + + + + + + + + +function_pointer_return_type +11 + + +function_pointer_id +11 + + +return_type_id +3 + + + + +function_pointer_id +return_type_id + + +12 + + +1 +2 +11 + + + + + + +return_type_id +function_pointer_id + + +12 + + +2 +3 +1 + + +3 +4 +1 + + +4 +5 +1 @@ -13356,15 +15958,15 @@ extend -324088 +323485 sub -324088 +323485 super -31625 +31566 @@ -13378,7 +15980,7 @@ 1 2 -324088 +323485 @@ -13394,22 +15996,22 @@ 1 2 -22670 +22628 2 3 -3986 +3979 3 5 -2420 +2415 5 70 -2381 +2376 70 @@ -13423,16 +16025,27 @@ +anonymous_types +1212 + + +id +1212 + + + + + implement -542634 +541624 sub -226772 +226351 super -122772 +122544 @@ -13446,27 +16059,27 @@ 1 2 -100960 +100772 2 3 -57150 +57044 3 4 -36177 +36110 4 7 -19006 +18970 7 21 -13477 +13452 @@ -13482,27 +16095,27 @@ 1 2 -67075 +66951 2 3 -29839 +29783 3 4 -10266 +10247 4 6 -8710 +8694 6 21807 -6880 +6867 @@ -13512,15 +16125,15 @@ type_location -554720 +553689 id -467833 +466963 loc -29931 +29876 @@ -13534,17 +16147,17 @@ 1 2 -408145 +407386 2 3 -39305 +39232 3 638 -20382 +20344 @@ -13560,17 +16173,17 @@ 1 2 -26052 +26004 2 26 -2273 +2269 26 12195 -1605 +1602 @@ -13580,15 +16193,15 @@ tuple_underlying_type -1785 +1782 tuple -1785 +1782 struct -1141 +1139 @@ -13602,7 +16215,7 @@ 1 2 -1785 +1782 @@ -13618,12 +16231,12 @@ 1 2 -644 +642 2 3 -424 +423 3 @@ -13638,11 +16251,11 @@ tuple_element -6802 +6789 tuple -1781 +1777 index @@ -13650,7 +16263,7 @@ field -6802 +6789 @@ -13669,7 +16282,7 @@ 2 3 -1136 +1134 3 @@ -13715,7 +16328,7 @@ 2 3 -1136 +1134 3 @@ -13988,7 +16601,7 @@ 1 2 -6802 +6789 @@ -14004,7 +16617,7 @@ 1 2 -6802 +6789 @@ -14014,19 +16627,19 @@ attributes -750664 +745454 id -750664 +745454 type_id -1688 +1685 target -429850 +427019 @@ -14040,7 +16653,7 @@ 1 2 -750664 +745454 @@ -14056,7 +16669,7 @@ 1 2 -750664 +745454 @@ -14072,17 +16685,17 @@ 1 2 -185 +189 2 3 -195 +194 3 4 -92 +87 4 @@ -14092,12 +16705,12 @@ 7 10 -146 +150 10 18 -136 +131 18 @@ -14126,11 +16739,11 @@ 616 -5143 +4825 126 -5204 +5142 41857 19 @@ -14148,7 +16761,7 @@ 1 2 -312 +316 2 @@ -14158,7 +16771,7 @@ 3 4 -82 +77 4 @@ -14168,42 +16781,42 @@ 6 9 -136 +141 9 -13 +15 126 -14 -23 +15 +25 126 -24 -46 -126 - - -46 -78 +25 +47 131 -80 -173 +47 +81 126 -175 -559 +81 +176 126 -562 +180 +563 +126 + + +596 39377 -117 +112 @@ -14219,17 +16832,17 @@ 1 2 -366248 +365075 2 3 -48899 +47478 3 957 -14702 +14465 @@ -14245,17 +16858,17 @@ 1 2 -395516 +394279 2 -15 -33508 +16 +32369 -15 +16 20 -824 +370 @@ -14265,15 +16878,15 @@ attribute_location -818847 +813511 id -750664 +745454 loc -72463 +72328 @@ -14287,12 +16900,12 @@ 1 2 -682480 +677397 2 3 -68183 +68056 @@ -14308,12 +16921,12 @@ 1 2 -68251 +68125 4 -26710 -4211 +26599 +4203 @@ -14323,19 +16936,19 @@ type_mention -1269646 +1252212 id -1269646 +1252212 type_id -34469 +35186 parent -1029018 +1030376 @@ -14349,7 +16962,7 @@ 1 2 -1269646 +1252212 @@ -14365,7 +16978,7 @@ 1 2 -1269646 +1252212 @@ -14381,52 +16994,52 @@ 1 2 -4966 +5682 2 3 -6799 +7203 3 4 -3385 +3551 4 5 -4027 +3839 5 6 -2097 +1995 6 8 -2904 +2856 8 12 -2803 +2927 12 -20 -2616 +22 +2759 -20 -51 -2586 +22 +67 +2652 -51 -82736 -2280 +67 +80294 +1717 @@ -14442,52 +17055,52 @@ 1 2 -9469 +9874 2 3 -5705 +5858 3 4 -3312 +3388 4 5 -3002 +2829 5 6 -1948 +1929 6 8 -2515 +2625 8 13 -2762 +2874 13 -29 -2631 +28 +2640 -29 -206 -2588 +28 +207 +2639 -206 -67615 -533 +207 +66416 +525 @@ -14503,17 +17116,17 @@ 1 2 -871252 +872847 2 3 -137406 +141323 3 -342 -20359 +187 +16204 @@ -14529,12 +17142,12 @@ 1 2 -1008331 +1011056 2 22 -20686 +19319 @@ -14544,15 +17157,15 @@ type_mention_location -1269646 +1252212 id -1269646 +1252212 loc -1140136 +1163351 @@ -14566,7 +17179,7 @@ 1 2 -1269646 +1252212 @@ -14582,12 +17195,12 @@ 1 2 -1077623 +1126926 2 199 -62513 +36425 @@ -14597,11 +17210,11 @@ type_annotation -51021 +50926 id -51021 +50926 annotation @@ -14619,7 +17232,7 @@ 1 2 -51021 +50926 @@ -14655,11 +17268,11 @@ nullability -2000 +1996 nullability -2000 +1996 kind @@ -14677,7 +17290,7 @@ 1 2 -2000 +1996 @@ -14713,11 +17326,11 @@ nullability_parent -6289 +6278 nullability -522 +521 index @@ -14725,7 +17338,7 @@ parent -1986 +1982 @@ -14739,12 +17352,12 @@ 1 2 -341 +340 2 3 -117 +116 3 @@ -14785,12 +17398,12 @@ 4 5 -39 +38 5 8 -39 +38 8 @@ -14968,17 +17581,17 @@ 1 2 -595 +594 2 3 -1229 +1227 3 4 -161 +160 @@ -14994,12 +17607,12 @@ 1 2 -497 +496 2 3 -722 +720 3 @@ -15019,12 +17632,12 @@ 8 15 -156 +155 15 22 -39 +38 @@ -15034,15 +17647,15 @@ type_nullability -4604756 +4596996 id -4530378 +4529942 nullability -964 +959 @@ -15056,12 +17669,12 @@ 1 2 -4464837 +4469255 2 9 -65541 +60687 @@ -15082,22 +17695,22 @@ 2 3 -141 +146 3 4 -58 +60 4 5 -69 +67 5 7 -83 +81 7 @@ -15107,7 +17720,7 @@ 10 14 -75 +73 14 @@ -15116,22 +17729,22 @@ 23 -45 -75 +41 +72 -45 +41 123 -74 +72 123 -4618 -73 +4117 +72 -5091 -3680217 +4580 +3677458 10 @@ -15142,11 +17755,11 @@ expr_flowstate -2995289 +2970146 id -2995289 +2970146 state @@ -15164,7 +17777,7 @@ 1 2 -2995289 +2970146 @@ -15178,13 +17791,13 @@ 12 -205773 -205774 +197316 +197317 1 -2254389 -2254390 +2192983 +2192984 1 @@ -15195,11 +17808,11 @@ type_parameters -203062 +202684 id -203062 +202684 index @@ -15207,7 +17820,7 @@ generic_id -103897 +103704 variance @@ -15225,7 +17838,7 @@ 1 2 -203062 +202684 @@ -15241,7 +17854,7 @@ 1 2 -203062 +202684 @@ -15257,7 +17870,7 @@ 1 2 -203062 +202684 @@ -15515,7 +18128,7 @@ 3 4 -78 +77 @@ -15531,22 +18144,22 @@ 1 2 -80729 +80579 2 3 -10793 +10773 3 11 -8363 +8348 11 22 -4011 +4003 @@ -15562,22 +18175,22 @@ 1 2 -80729 +80579 2 3 -10793 +10773 3 11 -8363 +8348 11 22 -4011 +4003 @@ -15593,12 +18206,12 @@ 1 2 -103746 +103553 2 3 -151 +150 @@ -15686,11 +18299,11 @@ type_arguments -644965 +643766 id -273759 +273250 index @@ -15698,7 +18311,7 @@ constructed_id -413644 +412875 @@ -15712,17 +18325,17 @@ 1 2 -235097 +234660 2 3 -37183 +37113 3 21 -1478 +1475 @@ -15738,27 +18351,27 @@ 1 2 -174253 +173928 2 3 -56574 +56469 3 5 -20606 +20568 5 23 -20689 +20651 23 2800 -1634 +1631 @@ -15986,17 +18599,17 @@ 1 2 -290584 +290043 2 3 -96407 +96228 3 22 -26652 +26603 @@ -16012,17 +18625,17 @@ 1 2 -288417 +287881 2 3 -97407 +97226 3 22 -27819 +27767 @@ -16032,15 +18645,15 @@ constructed_generic -413644 +412875 constructed -413644 +412875 generic -8593 +8577 @@ -16054,7 +18667,7 @@ 1 2 -413644 +412875 @@ -16070,42 +18683,42 @@ 1 2 -3449 +3443 2 3 -1156 +1154 3 4 -619 +618 4 6 -653 +652 6 11 -727 +725 11 26 -648 +647 26 63 -658 +657 63 2866 -648 +647 2964 @@ -16120,15 +18733,15 @@ type_parameter_constraints -611920 +594129 id -611920 +594129 param_id -202974 +202597 @@ -16142,7 +18755,7 @@ 1 2 -611920 +594129 @@ -16158,22 +18771,22 @@ 1 2 -164522 +167246 2 3 -17718 +19984 3 -11 -16620 +307 +15196 -11 -2108 -4113 +311 +2109 +170 @@ -16219,11 +18832,11 @@ general_type_parameter_constraints -119035 +106692 id -68461 +60453 kind @@ -16241,12 +18854,12 @@ 1 2 -17887 +14214 2 3 -50574 +46239 @@ -16265,23 +18878,23 @@ 1 -447 -448 +279 +280 1 -5922 -5923 +5837 +5838 1 -50452 -50453 +46182 +46183 1 -62210 -62211 +54390 +54391 1 @@ -16292,15 +18905,15 @@ specific_type_parameter_constraints -57309 +46370 id -56448 +45666 base_id -1283 +1286 @@ -16314,12 +18927,12 @@ 1 2 -55635 +45008 2 5 -813 +658 @@ -16335,67 +18948,62 @@ 1 2 -76 +97 2 3 -213 +260 3 4 -76 +70 4 5 -97 +92 5 6 -54 +57 6 7 -119 +138 7 10 -104 +108 10 -13 -107 - - -13 -20 -93 - - -20 -26 -107 - - -26 -51 +15 99 -51 -198 +15 +21 +111 + + +21 +37 97 -204 -8438 -41 +37 +106 +97 + + +108 +4902 +60 @@ -16405,15 +19013,15 @@ specific_type_parameter_nullability -40020 +31518 id -39775 +31372 base_id -924 +912 nullability @@ -16431,12 +19039,12 @@ 1 2 -39530 +31226 2 3 -245 +146 @@ -16452,7 +19060,7 @@ 1 2 -39775 +31372 @@ -16468,67 +19076,62 @@ 1 2 -24 +97 2 3 -200 +154 3 4 -54 +45 4 5 -49 +42 5 6 -47 +51 6 7 -84 +102 7 -10 -68 +9 +73 -10 -12 -55 +9 +13 +84 -12 -16 -71 +14 +20 +65 -16 -23 -83 +20 +28 +69 -23 -37 -70 +28 +76 +73 -38 -106 -70 - - -106 -6999 -49 +77 +4327 +57 @@ -16544,12 +19147,12 @@ 1 2 -892 +890 2 3 -32 +22 @@ -16588,6 +19191,11 @@ 1 +12 +13 +1 + + 16 17 1 @@ -16598,18 +19206,13 @@ 1 -22 -23 +24 +25 1 -30 -31 -1 - - -62 -63 +64 +65 1 @@ -16618,18 +19221,18 @@ 1 -273 -274 +117 +118 1 -390 -391 +386 +387 1 -38848 -38849 +30619 +30620 1 @@ -16664,9 +19267,9 @@ 2 -8 -9 -1 +9 +10 +2 12 @@ -16674,18 +19277,13 @@ 1 -20 -21 +43 +44 1 -44 -45 -1 - - -847 -848 +836 +837 1 @@ -16695,6 +19293,134 @@ +function_pointer_calling_conventions +11 + + +id +11 + + +kind +1 + + + + +id +kind + + +12 + + +1 +2 +11 + + + + + + +kind +id + + +12 + + +9 +10 +1 + + + + + + + + +has_unmanaged_calling_conventions +0 + + +id +0 + + +index +0 + + +conv_id +0 + + + + +id +index + + +12 + + + + + +id +conv_id + + +12 + + + + + +index +id + + +12 + + + + + +index +conv_id + + +12 + + + + + +conv_id +id + + +12 + + + + + +conv_id +index + + +12 + + + + + + + modifiers 82 @@ -16744,11 +19470,11 @@ has_modifiers -5439325 +5504557 id -3648539 +3697015 mod_id @@ -16766,17 +19492,17 @@ 1 2 -1993462 +2024955 2 3 -1521212 +1538421 3 5 -133864 +133639 @@ -16815,8 +19541,8 @@ 4 -2567 -2568 +6163 +6164 4 @@ -16825,8 +19551,8 @@ 4 -23881 -23882 +23884 +23885 4 @@ -16860,18 +19586,18 @@ 4 -83361 -83362 +83872 +83873 4 -85523 -85524 +96025 +96026 4 -608943 -608944 +609801 +609802 4 @@ -16882,26 +19608,26 @@ compiler_generated -136094 +136181 id -136094 +136181 exprorstmt_name -3709 +3751 parent_id -3709 +3751 name -366 +374 @@ -16915,7 +19641,7 @@ 1 2 -3709 +3751 @@ -16931,47 +19657,47 @@ 2 3 -107 +110 3 4 -54 +55 4 5 -46 +50 5 6 -32 +34 6 8 -31 +32 8 -11 -30 - - -11 -21 -29 - - -21 -85 +12 28 -118 +12 +23 +31 + + +25 +214 +28 + + +239 240 -6 +1 @@ -16981,19 +19707,19 @@ nested_types -112139 +111931 id -112139 +111931 declaring_type_id -40672 +40596 unbound_id -81266 +81114 @@ -17007,7 +19733,7 @@ 1 2 -112139 +111931 @@ -17023,7 +19749,7 @@ 1 2 -112139 +111931 @@ -17039,32 +19765,32 @@ 1 2 -23529 +23486 2 3 -6348 +6336 3 4 -3235 +3229 4 7 -3362 +3355 7 12 -3098 +3092 12 262 -1097 +1095 @@ -17080,32 +19806,32 @@ 1 2 -23563 +23520 2 3 -6431 +6419 3 4 -3152 +3146 4 7 -3391 +3385 7 12 -3083 +3078 12 206 -1049 +1047 @@ -17121,12 +19847,12 @@ 1 2 -78245 +78100 2 415 -3020 +3014 @@ -17142,12 +19868,12 @@ 1 2 -78987 +78840 2 415 -2278 +2274 @@ -17157,27 +19883,27 @@ properties -424316 +425592 id -424316 +425592 name -84515 +84358 declaring_type_id -116589 +117951 type_id -52222 +53011 unbound_id -334462 +333840 @@ -17191,7 +19917,7 @@ 1 2 -424316 +425592 @@ -17207,7 +19933,7 @@ 1 2 -424316 +425592 @@ -17223,7 +19949,7 @@ 1 2 -424316 +425592 @@ -17239,7 +19965,7 @@ 1 2 -424316 +425592 @@ -17255,32 +19981,32 @@ 1 2 -50846 +50751 2 3 -14019 +13993 3 4 -5762 +5752 4 7 -6660 +6648 7 49 -6348 +6336 49 -2611 -878 +2886 +876 @@ -17296,32 +20022,32 @@ 1 2 -50846 +50751 2 3 -14087 +14061 3 4 -5748 +5737 4 7 -6694 +6682 7 51 -6343 +6331 51 2578 -795 +793 @@ -17337,17 +20063,17 @@ 1 2 -72970 +72834 2 3 -6943 +6930 3 -524 -4601 +773 +4592 @@ -17363,27 +20089,27 @@ 1 2 -51275 +51180 2 3 -14282 +14256 3 4 -5748 +5737 4 7 -6455 +6443 7 68 -6338 +6326 68 @@ -17404,42 +20130,42 @@ 1 2 -39457 +40635 2 3 -29922 +30139 3 4 -10920 +10900 4 5 -7856 +7841 5 6 -7143 +7184 6 8 -9344 +9327 8 16 -9583 +9565 16 250 -2361 +2357 @@ -17455,42 +20181,42 @@ 1 2 -43975 +45418 2 3 -25481 +25434 3 4 -10915 +10895 4 5 -7875 +7914 5 6 -7158 +7145 6 8 -9300 +9283 8 -14 -8759 +15 +9224 -14 +15 250 -3122 +2634 @@ -17506,32 +20232,32 @@ 1 2 -45532 +46699 2 3 -32674 +32886 3 4 -13863 +13890 4 5 -7558 +7544 5 7 -9398 +9380 7 48 -7563 +7549 @@ -17547,42 +20273,42 @@ 1 2 -39457 +40635 2 3 -29922 +30139 3 4 -10920 +10900 4 5 -7856 +7841 5 6 -7143 +7184 6 8 -9344 +9327 8 16 -9583 +9565 16 250 -2361 +2357 @@ -17598,27 +20324,27 @@ 1 2 -31473 +32014 2 3 -10798 +10953 3 5 -4640 +4700 5 21 -3952 +3984 21 12516 -1356 +1358 @@ -17634,17 +20360,17 @@ 1 2 -44156 +44809 2 3 -4406 +4461 3 3289 -3659 +3740 @@ -17660,27 +20386,27 @@ 1 2 -32659 +33193 2 3 -10501 +10666 3 5 -4430 +4490 5 -33 -3918 +35 +3993 -33 +35 6176 -712 +667 @@ -17696,27 +20422,27 @@ 1 2 -31615 +32155 2 3 -10930 +11080 3 5 -4674 +4739 5 -22 -3918 +23 +4003 -22 -10632 -1083 +23 +10636 +1032 @@ -17732,12 +20458,12 @@ 1 2 -329280 +328609 2 705 -5182 +5231 @@ -17753,7 +20479,7 @@ 1 2 -334462 +333840 @@ -17769,12 +20495,12 @@ 1 2 -329280 +328609 2 705 -5182 +5231 @@ -17790,12 +20516,12 @@ 1 2 -333252 +332608 2 -439 -1210 +690 +1232 @@ -17805,15 +20531,15 @@ property_location -535436 +536505 id -424316 +425592 loc -52993 +52894 @@ -17827,17 +20553,17 @@ 1 2 -338732 +340167 2 3 -64226 +64106 3 119 -21358 +21318 @@ -17853,12 +20579,12 @@ 1 2 -49504 +49412 2 7080 -3488 +3482 @@ -17868,11 +20594,11 @@ indexers -17073 +17042 id -17073 +17042 name @@ -17880,15 +20606,15 @@ declaring_type_id -13575 +13549 type_id -3976 +3969 unbound_id -4445 +4437 @@ -17902,7 +20628,7 @@ 1 2 -17073 +17042 @@ -17918,7 +20644,7 @@ 1 2 -17073 +17042 @@ -17934,7 +20660,7 @@ 1 2 -17073 +17042 @@ -17950,7 +20676,7 @@ 1 2 -17073 +17042 @@ -18085,12 +20811,12 @@ 1 2 -10525 +10505 2 3 -2752 +2747 3 @@ -18111,7 +20837,7 @@ 1 2 -13565 +13540 2 @@ -18132,12 +20858,12 @@ 1 2 -11067 +11046 2 3 -2508 +2503 @@ -18153,12 +20879,12 @@ 1 2 -10525 +10505 2 3 -2752 +2747 3 @@ -18179,27 +20905,27 @@ 1 2 -878 +876 2 3 -873 +871 3 4 -1629 +1626 4 6 -268 +267 6 18 -302 +301 18 @@ -18220,7 +20946,7 @@ 1 2 -3972 +3964 2 @@ -18241,22 +20967,22 @@ 1 2 -1034 +1032 2 3 -780 +779 3 4 -1663 +1660 4 6 -239 +238 6 @@ -18277,27 +21003,27 @@ 1 2 -878 +876 2 3 -873 +871 3 4 -1654 +1651 4 6 -268 +267 6 198 -302 +301 @@ -18313,7 +21039,7 @@ 1 2 -4108 +4101 2 @@ -18334,7 +21060,7 @@ 1 2 -4445 +4437 @@ -18350,7 +21076,7 @@ 1 2 -4108 +4101 2 @@ -18371,12 +21097,12 @@ 1 2 -4255 +4247 2 452 -190 +189 @@ -18386,11 +21112,11 @@ indexer_location -23644 +23899 id -12580 +12715 loc @@ -18408,17 +21134,17 @@ 1 2 -4484 +4500 2 3 -6583 +6699 3 4 -282 +285 4 @@ -18449,17 +21175,17 @@ 2 3 -22 +24 3 4 -18 +17 4 5 -14 +13 5 @@ -18469,12 +21195,12 @@ 8 13 -16 +17 13 21 -19 +18 23 @@ -18483,12 +21209,12 @@ 47 -2223 +2319 17 -3525 -5399 +3540 +5342 3 @@ -18499,11 +21225,11 @@ accessors -568920 +569927 id -568920 +569927 kind @@ -18511,15 +21237,15 @@ name -121469 +121243 declaring_member_id -441390 +442634 unbound_id -441239 +440418 @@ -18533,7 +21259,7 @@ 1 2 -568920 +569927 @@ -18549,7 +21275,7 @@ 1 2 -568920 +569927 @@ -18565,7 +21291,7 @@ 1 2 -568920 +569927 @@ -18581,7 +21307,7 @@ 1 2 -568920 +569927 @@ -18600,8 +21326,8 @@ 4 -90407 -90408 +90831 +90832 4 @@ -18642,8 +21368,8 @@ 4 -90406 -90407 +90830 +90831 4 @@ -18681,27 +21407,27 @@ 1 2 -75332 +75192 2 3 -19987 +19949 3 4 -7944 +7929 4 8 -10144 +10111 8 2558 -8061 +8060 @@ -18717,7 +21443,7 @@ 1 2 -121469 +121243 @@ -18733,27 +21459,27 @@ 1 2 -75342 +75201 2 3 -19977 +19940 3 4 -7944 +7929 4 8 -10144 +10111 8 2558 -8061 +8060 @@ -18769,27 +21495,27 @@ 1 2 -75981 +75840 2 3 -20655 +20617 3 4 -7778 +7763 4 8 -9671 +9653 8 1202 -7382 +7369 @@ -18805,12 +21531,12 @@ 1 2 -313870 +315351 2 3 -127515 +127278 4 @@ -18831,12 +21557,12 @@ 1 2 -313870 +315351 2 3 -127520 +127283 @@ -18852,12 +21578,12 @@ 1 2 -313870 +315351 2 3 -127520 +127283 @@ -18873,12 +21599,12 @@ 1 2 -313870 +315351 2 3 -127515 +127278 4 @@ -18899,12 +21625,12 @@ 1 2 -434563 +433697 2 705 -6675 +6721 @@ -18920,7 +21646,7 @@ 1 2 -441239 +440418 @@ -18936,7 +21662,7 @@ 1 2 -441239 +440418 @@ -18952,12 +21678,12 @@ 1 2 -434563 +433697 2 705 -6675 +6721 @@ -18966,16 +21692,27 @@ -accessor_location -749151 +init_only_accessors +4 id -568920 +4 + + + + + +accessor_location +749823 + + +id +569927 loc -93387 +93213 @@ -18989,17 +21726,17 @@ 1 2 -433509 +434768 2 3 -98588 +98405 3 119 -36821 +36753 @@ -19015,12 +21752,12 @@ 1 2 -89776 +89609 2 -8294 -3610 +8548 +3604 @@ -19030,27 +21767,27 @@ events -15258 +15230 id -15258 +15230 name -13014 +12989 declaring_type_id -1229 +1227 type_id -6377 +6365 unbound_id -15248 +15220 @@ -19064,7 +21801,7 @@ 1 2 -15258 +15230 @@ -19080,7 +21817,7 @@ 1 2 -15258 +15230 @@ -19096,7 +21833,7 @@ 1 2 -15258 +15230 @@ -19112,7 +21849,7 @@ 1 2 -15258 +15230 @@ -19128,12 +21865,12 @@ 1 2 -12023 +12001 2 12 -980 +978 14 @@ -19154,12 +21891,12 @@ 1 2 -12023 +12001 2 10 -980 +978 14 @@ -19180,7 +21917,7 @@ 1 2 -12872 +12848 2 @@ -19201,12 +21938,12 @@ 1 2 -12023 +12001 2 12 -980 +978 14 @@ -19227,12 +21964,12 @@ 1 2 -619 +618 2 3 -229 +228 3 @@ -19268,12 +22005,12 @@ 1 2 -619 +618 2 3 -239 +238 3 @@ -19309,12 +22046,12 @@ 1 2 -770 +769 2 3 -200 +199 3 @@ -19329,7 +22066,7 @@ 12 181 -78 +77 @@ -19345,12 +22082,12 @@ 1 2 -619 +618 2 3 -229 +228 3 @@ -19386,22 +22123,22 @@ 1 2 -4420 +4412 2 3 -1166 +1164 3 6 -517 +516 6 318 -273 +272 @@ -19417,17 +22154,17 @@ 1 2 -4811 +4802 2 3 -917 +915 3 8 -502 +501 8 @@ -19448,12 +22185,12 @@ 1 2 -5762 +5752 2 4 -522 +521 4 @@ -19474,22 +22211,22 @@ 1 2 -4420 +4412 2 3 -1166 +1164 3 6 -517 +516 6 318 -273 +272 @@ -19505,7 +22242,7 @@ 1 2 -15239 +15210 2 @@ -19526,7 +22263,7 @@ 1 2 -15248 +15220 @@ -19542,7 +22279,7 @@ 1 2 -15239 +15210 2 @@ -19563,7 +22300,7 @@ 1 2 -15239 +15210 2 @@ -19578,11 +22315,11 @@ event_location -15897 +15868 id -15258 +15230 loc @@ -19600,12 +22337,12 @@ 1 2 -14619 +14592 2 3 -639 +638 @@ -19681,11 +22418,11 @@ event_accessors -30517 +30460 id -30517 +30460 kind @@ -19693,15 +22430,15 @@ name -26740 +26690 declaring_event_id -15258 +15230 unbound_id -30497 +30441 @@ -19715,7 +22452,7 @@ 1 2 -30517 +30460 @@ -19731,7 +22468,7 @@ 1 2 -30517 +30460 @@ -19747,7 +22484,7 @@ 1 2 -30517 +30460 @@ -19763,7 +22500,7 @@ 1 2 -30517 +30460 @@ -19843,12 +22580,12 @@ 1 2 -24749 +24703 2 16 -1990 +1987 @@ -19864,7 +22601,7 @@ 1 2 -26740 +26690 @@ -19880,12 +22617,12 @@ 1 2 -24749 +24703 2 16 -1990 +1987 @@ -19901,12 +22638,12 @@ 1 2 -24749 +24703 2 16 -1990 +1987 @@ -19922,7 +22659,7 @@ 2 3 -15258 +15230 @@ -19938,7 +22675,7 @@ 2 3 -15258 +15230 @@ -19954,7 +22691,7 @@ 2 3 -15258 +15230 @@ -19970,7 +22707,7 @@ 2 3 -15258 +15230 @@ -19986,7 +22723,7 @@ 1 2 -30478 +30421 2 @@ -20007,7 +22744,7 @@ 1 2 -30497 +30441 @@ -20023,7 +22760,7 @@ 1 2 -30497 +30441 @@ -20039,7 +22776,7 @@ 1 2 -30478 +30421 2 @@ -20054,11 +22791,11 @@ event_accessor_location -31795 +31736 id -30517 +30460 loc @@ -20076,12 +22813,12 @@ 1 2 -29238 +29184 2 3 -1278 +1276 @@ -20157,11 +22894,11 @@ operators -12433 +12410 id -12433 +12410 name @@ -20169,19 +22906,19 @@ symbol -117 +116 declaring_type_id -3030 +3024 type_id -1624 +1621 unbound_id -11677 +11655 @@ -20195,7 +22932,7 @@ 1 2 -12433 +12410 @@ -20211,7 +22948,7 @@ 1 2 -12433 +12410 @@ -20227,7 +22964,7 @@ 1 2 -12433 +12410 @@ -20243,7 +22980,7 @@ 1 2 -12433 +12410 @@ -20259,7 +22996,7 @@ 1 2 -12433 +12410 @@ -20453,7 +23190,7 @@ 2 3 -39 +38 3 @@ -20758,7 +23495,7 @@ 2 3 -39 +38 3 @@ -20880,12 +23617,12 @@ 1 2 -473 +472 2 3 -1571 +1568 3 @@ -20895,7 +23632,7 @@ 4 6 -268 +267 6 @@ -20905,7 +23642,7 @@ 7 16 -229 +228 16 @@ -20926,12 +23663,12 @@ 1 2 -629 +628 2 3 -1541 +1539 3 @@ -20941,7 +23678,7 @@ 4 5 -273 +272 5 @@ -20967,27 +23704,27 @@ 1 2 -629 +628 2 3 -1546 +1543 3 4 -239 +238 4 5 -273 +272 5 9 -229 +228 9 @@ -21008,12 +23745,12 @@ 1 2 -2025 +2021 2 3 -419 +418 3 @@ -21044,12 +23781,12 @@ 1 2 -473 +472 2 3 -1571 +1568 3 @@ -21059,7 +23796,7 @@ 4 6 -268 +267 6 @@ -21069,7 +23806,7 @@ 7 16 -229 +228 16 @@ -21090,7 +23827,7 @@ 1 2 -795 +793 2 @@ -21131,17 +23868,17 @@ 1 2 -1210 +1207 2 3 -151 +150 3 5 -117 +116 5 @@ -21167,12 +23904,12 @@ 1 2 -1210 +1207 2 3 -161 +160 3 @@ -21203,7 +23940,7 @@ 1 2 -1268 +1266 2 @@ -21234,7 +23971,7 @@ 1 2 -795 +793 2 @@ -21275,7 +24012,7 @@ 1 2 -11530 +11509 2 @@ -21296,7 +24033,7 @@ 1 2 -11677 +11655 @@ -21312,7 +24049,7 @@ 1 2 -11677 +11655 @@ -21328,7 +24065,7 @@ 1 2 -11530 +11509 2 @@ -21349,7 +24086,7 @@ 1 2 -11618 +11596 2 @@ -21364,15 +24101,15 @@ operator_location -22297 +22756 id -5646 +5763 loc -3164 +3229 @@ -21386,32 +24123,32 @@ 1 2 -841 +858 2 3 -3155 +3220 3 9 -387 +395 9 11 -450 +459 11 12 -583 +595 12 14 -228 +233 @@ -21427,17 +24164,17 @@ 1 2 -2773 +2830 2 9 -237 +242 9 2695 -153 +156 @@ -21447,15 +24184,15 @@ constant_value -185695 +185350 id -185583 +185238 value -47942 +47853 @@ -21469,7 +24206,7 @@ 1 2 -185471 +185126 2 @@ -21490,27 +24227,27 @@ 1 2 -32952 +32891 2 3 -7231 +7218 3 4 -3893 +3886 4 61 -3596 +3589 61 2421 -268 +267 @@ -21520,27 +24257,27 @@ methods -1118708 +1117636 id -1118708 +1117636 name -133839 +133590 declaring_type_id -202408 +202387 type_id -113086 +112876 unbound_id -697851 +696553 @@ -21554,7 +24291,7 @@ 1 2 -1118708 +1117636 @@ -21570,7 +24307,7 @@ 1 2 -1118708 +1117636 @@ -21586,7 +24323,7 @@ 1 2 -1118708 +1117636 @@ -21602,7 +24339,7 @@ 1 2 -1118708 +1117636 @@ -21618,32 +24355,32 @@ 1 2 -69271 +69142 2 3 -23661 +23617 3 4 -10852 +10832 4 6 -10442 +10423 6 12 -10588 +10569 12 5621 -9022 +9005 @@ -21659,32 +24396,32 @@ 1 2 -79660 +79512 2 3 -19377 +19341 3 4 -11335 +11314 4 7 -11067 +11046 7 33 -10125 +10106 33 -4959 -2273 +5029 +2269 @@ -21700,22 +24437,22 @@ 1 2 -113066 +112856 2 3 -10613 +10593 3 174 -10042 +10023 177 2703 -117 +116 @@ -21731,32 +24468,32 @@ 1 2 -71013 +70881 2 3 -24530 +24484 3 4 -10925 +10905 4 6 -10740 +10720 6 12 -10047 +10028 12 4958 -6582 +6570 @@ -21772,42 +24509,42 @@ 1 2 -59834 +59752 2 3 -43063 +42983 3 4 -31351 +31619 4 5 -14277 +14251 5 6 -14814 +14787 6 10 -16127 +16097 10 23 -15683 +15654 23 1309 -7256 +7242 @@ -21823,37 +24560,37 @@ 1 2 -64909 +64817 2 3 -44751 +44668 3 4 -34455 +34717 4 5 -18225 +18191 5 8 -18191 +18157 8 18 -15278 +15249 18 457 -6597 +6585 @@ -21869,32 +24606,32 @@ 1 2 -97978 +97825 2 3 -48996 +49231 3 4 -22988 +22945 4 5 -11642 +11621 5 10 -15234 +15205 10 738 -5567 +5557 @@ -21910,42 +24647,42 @@ 1 2 -59941 +59859 2 3 -43141 +43060 3 4 -31351 +31619 4 5 -14312 +14285 5 6 -14834 +14806 6 10 -16044 +16014 10 23 -16141 +16111 23 698 -6641 +6628 @@ -21961,27 +24698,27 @@ 1 2 -75576 +75435 2 3 -14507 +14480 3 4 -8324 +8309 4 10 -8841 +8825 10 -62149 -5836 +62283 +5825 @@ -21997,22 +24734,22 @@ 1 2 -91737 +91567 2 3 -9632 +9614 3 8 -8680 +8664 8 7666 -3035 +3029 @@ -22028,22 +24765,22 @@ 1 2 -87555 +87393 2 3 -14004 +13978 3 8 -8817 +8801 8 -19632 -2708 +19699 +2703 @@ -22059,27 +24796,27 @@ 1 2 -75688 +75547 2 3 -14565 +14538 3 4 -8397 +8382 4 10 -8778 +8762 10 44480 -5655 +5645 @@ -22095,12 +24832,12 @@ 1 2 -670969 +669658 2 1367 -26882 +26895 @@ -22116,7 +24853,7 @@ 1 2 -697851 +696553 @@ -22132,12 +24869,12 @@ 1 2 -672838 +671523 2 1367 -25013 +25029 @@ -22153,12 +24890,12 @@ 1 2 -687467 +686189 2 1367 -10383 +10364 @@ -22168,15 +24905,15 @@ method_location -1282719 +1281341 id -1118708 +1117636 loc -40906 +40830 @@ -22190,17 +24927,17 @@ 1 2 -988094 +987264 2 3 -98447 +98264 3 119 -32166 +32106 @@ -22216,17 +24953,17 @@ 1 2 -36285 +36217 2 51 -3083 +3078 51 -27729 -1537 +27732 +1534 @@ -22236,23 +24973,23 @@ constructors -278155 +277979 id -278155 +277979 name -133712 +133464 declaring_type_id -212373 +212319 unbound_id -223664 +223248 @@ -22266,7 +25003,7 @@ 1 2 -278155 +277979 @@ -22282,7 +25019,7 @@ 1 2 -278155 +277979 @@ -22298,7 +25035,7 @@ 1 2 -278155 +277979 @@ -22314,22 +25051,22 @@ 1 2 -102375 +102185 2 3 -19206 +19170 3 8 -10266 +10247 8 2183 -1864 +1860 @@ -22345,17 +25082,17 @@ 1 2 -122709 +122480 2 11 -10100 +10082 11 2183 -902 +901 @@ -22371,22 +25108,22 @@ 1 2 -103258 +103066 2 3 -19362 +19326 3 10 -10105 +10087 10 2183 -985 +983 @@ -22402,17 +25139,17 @@ 1 2 -179645 +179651 2 3 -19787 +19750 3 20 -12940 +12916 @@ -22428,7 +25165,7 @@ 1 2 -212373 +212319 @@ -22444,17 +25181,17 @@ 1 2 -179645 +179651 2 3 -19787 +19750 3 20 -12940 +12916 @@ -22470,12 +25207,12 @@ 1 2 -221229 +220793 2 780 -2434 +2454 @@ -22491,7 +25228,7 @@ 1 2 -223664 +223248 @@ -22507,12 +25244,12 @@ 1 2 -221229 +220793 2 780 -2434 +2454 @@ -22522,15 +25259,15 @@ constructor_location -322033 +321707 id -278155 +277979 loc -24818 +24771 @@ -22544,17 +25281,17 @@ 1 2 -238762 +238659 2 3 -37641 +37639 3 87 -1751 +1680 @@ -22570,22 +25307,22 @@ 1 2 -19035 +19000 2 3 -3186 +3180 3 59 -1868 +1865 59 4796 -727 +725 @@ -22595,11 +25332,11 @@ destructors -444 +443 id -444 +443 name @@ -22607,11 +25344,11 @@ declaring_type_id -444 +443 unbound_id -429 +428 @@ -22625,7 +25362,7 @@ 1 2 -444 +443 @@ -22641,7 +25378,7 @@ 1 2 -444 +443 @@ -22657,7 +25394,7 @@ 1 2 -444 +443 @@ -22673,7 +25410,7 @@ 1 2 -395 +394 2 @@ -22694,7 +25431,7 @@ 1 2 -395 +394 2 @@ -22715,7 +25452,7 @@ 1 2 -400 +399 2 @@ -22736,7 +25473,7 @@ 1 2 -444 +443 @@ -22752,7 +25489,7 @@ 1 2 -444 +443 @@ -22768,7 +25505,7 @@ 1 2 -444 +443 @@ -22784,7 +25521,7 @@ 1 2 -419 +418 2 @@ -22805,7 +25542,7 @@ 1 2 -429 +428 @@ -22821,7 +25558,7 @@ 1 2 -419 +418 2 @@ -22836,15 +25573,15 @@ destructor_location -646 +659 id -161 +165 loc -322 +329 @@ -22858,12 +25595,12 @@ 1 2 -31 +32 2 3 -43 +44 3 @@ -22873,7 +25610,7 @@ 4 5 -15 +16 5 @@ -22914,7 +25651,7 @@ 1 2 -254 +259 2 @@ -22929,7 +25666,7 @@ 5 27 -20 +21 @@ -22939,15 +25676,15 @@ overrides -274437 +273927 id -274413 +273902 base_id -65524 +65402 @@ -22961,7 +25698,7 @@ 1 2 -274388 +273878 2 @@ -22982,27 +25719,27 @@ 1 2 -40325 +40250 2 3 -10491 +10471 3 4 -4294 +4286 4 7 -5348 +5338 7 184 -4918 +4909 215 @@ -23017,15 +25754,15 @@ explicitly_implements -156232 +156755 id -156232 +156755 interface_id -13306 +13282 @@ -23039,7 +25776,7 @@ 1 2 -156232 +156755 @@ -23055,32 +25792,32 @@ 1 2 -6782 +6770 2 3 -2493 +2488 3 4 -1185 +1183 4 5 -458 +457 5 7 -1210 +1207 7 58 -1000 +998 58 @@ -23391,11 +26128,11 @@ local_function_stmts -1793 +1792 fn -1793 +1792 stmt @@ -23413,7 +26150,7 @@ 1 2 -1793 +1792 @@ -23429,12 +26166,7 @@ 1 2 -1791 - - -2 -3 -1 +1792 @@ -23444,11 +26176,11 @@ fields -556716 +556636 id -556716 +556636 kind @@ -23456,19 +26188,19 @@ name -218623 +218217 declaring_type_id -103771 +103919 type_id -89678 +89633 unbound_id -549006 +547985 @@ -23482,7 +26214,7 @@ 1 2 -556716 +556636 @@ -23498,7 +26230,7 @@ 1 2 -556716 +556636 @@ -23514,7 +26246,7 @@ 1 2 -556716 +556636 @@ -23530,7 +26262,7 @@ 1 2 -556716 +556636 @@ -23546,7 +26278,7 @@ 1 2 -556716 +556636 @@ -23565,8 +26297,8 @@ 4 -76062 -76063 +76258 +76259 4 @@ -23607,8 +26339,8 @@ 4 -18155 -18156 +18225 +18226 4 @@ -23628,8 +26360,8 @@ 4 -16366 -16367 +16391 +16392 4 @@ -23667,22 +26399,22 @@ 1 2 -176497 +176159 2 3 -22607 +22565 3 14 -16586 +16564 14 4800 -2932 +2927 @@ -23698,12 +26430,12 @@ 1 2 -209250 +208860 2 3 -9373 +9356 @@ -23719,22 +26451,22 @@ 1 2 -176522 +176184 2 3 -22592 +22550 3 14 -16576 +16555 14 4800 -2932 +2927 @@ -23750,17 +26482,17 @@ 1 2 -189028 +188667 2 3 -17688 +17660 3 2459 -11906 +11889 @@ -23776,22 +26508,22 @@ 1 2 -176888 +176559 2 3 -22612 +22570 3 15 -16503 +16472 15 4800 -2620 +2615 @@ -23807,42 +26539,42 @@ 1 2 -27370 +27319 2 3 -21187 +21216 3 4 -12594 +12843 4 5 -10120 +10101 5 6 -7948 +7934 6 8 -9290 +9273 8 12 -8163 +8148 12 4204 -7095 +7081 @@ -23858,12 +26590,12 @@ 1 2 -102678 +102828 2 3 -1093 +1091 @@ -23879,42 +26611,42 @@ 1 2 -27370 +27319 2 3 -21192 +21221 3 4 -12599 +12848 4 5 -10115 +10096 5 6 -7948 +7934 6 8 -9295 +9278 8 12 -8163 +8148 12 4204 -7085 +7072 @@ -23930,37 +26662,37 @@ 1 2 -44609 +44526 2 3 -21241 +21269 3 4 -9451 +9707 4 5 -7378 +7364 5 6 -6172 +6161 6 9 -9608 +9590 9 132 -5309 +5299 @@ -23976,42 +26708,42 @@ 1 2 -27370 +27319 2 3 -21187 +21216 3 4 -12594 +12843 4 5 -10120 +10101 5 6 -7948 +7934 6 8 -9290 +9273 8 12 -8163 +8148 12 4204 -7095 +7081 @@ -24027,32 +26759,32 @@ 1 2 -55901 +55880 2 3 -10901 +10910 3 4 -6221 +6210 4 7 -7983 +7973 7 27 -6802 +6789 27 -9290 -1868 +9294 +1870 @@ -24068,12 +26800,12 @@ 1 2 -87477 +87436 2 3 -2200 +2196 @@ -24089,27 +26821,27 @@ 1 2 -63845 +63795 2 3 -9334 +9356 3 5 -7900 +7895 5 18 -6851 +6838 18 -5213 -1746 +5214 +1748 @@ -24125,22 +26857,22 @@ 1 2 -68437 +68392 2 3 -10057 +10062 3 7 -7246 +7242 7 -5746 -3937 +5816 +3935 @@ -24156,32 +26888,32 @@ 1 2 -55945 +55924 2 3 -11228 +11236 3 4 -5933 +5922 4 7 -7958 +7948 7 27 -6758 +6745 27 -9185 -1854 +9188 +1855 @@ -24197,12 +26929,12 @@ 1 2 -548094 +547011 2 234 -912 +974 @@ -24218,7 +26950,7 @@ 1 2 -549006 +547985 @@ -24234,7 +26966,7 @@ 1 2 -549006 +547985 @@ -24250,12 +26982,12 @@ 1 2 -548094 +547011 2 234 -912 +974 @@ -24271,12 +27003,12 @@ 1 2 -548509 +547469 2 138 -497 +516 @@ -24286,15 +27018,15 @@ field_location -637621 +637390 id -549338 +549271 loc -52944 +52845 @@ -24308,17 +27040,17 @@ 1 2 -467082 +467168 2 3 -78240 +78095 3 57 -4015 +4008 @@ -24334,12 +27066,12 @@ 1 2 -49431 +49339 2 8882 -3513 +3506 @@ -24349,11 +27081,11 @@ localvars -163688 +163269 id -163688 +163269 kind @@ -24361,7 +27093,7 @@ name -22588 +22591 implicitly_typed @@ -24369,11 +27101,11 @@ type_id -7294 +7298 parent_id -163688 +163269 @@ -24387,7 +27119,7 @@ 1 2 -163688 +163269 @@ -24403,7 +27135,7 @@ 1 2 -163688 +163269 @@ -24419,7 +27151,7 @@ 1 2 -163688 +163269 @@ -24435,7 +27167,7 @@ 1 2 -163688 +163269 @@ -24451,7 +27183,7 @@ 1 2 -163688 +163269 @@ -24475,8 +27207,8 @@ 1 -162436 -162437 +162452 +162453 1 @@ -24501,8 +27233,8 @@ 1 -22375 -22376 +22378 +22379 1 @@ -24548,8 +27280,8 @@ 1 -7289 -7290 +7293 +7294 1 @@ -24564,8 +27296,8 @@ 12 -20 -21 +18 +19 1 @@ -24574,8 +27306,8 @@ 1 -162869 -162870 +162452 +162453 1 @@ -24592,17 +27324,17 @@ 1 2 -14109 +14112 2 3 -3484 +3482 3 4 -1460 +1462 4 @@ -24628,7 +27360,7 @@ 1 2 -22496 +22499 2 @@ -24649,12 +27381,12 @@ 1 2 -19929 +19931 2 3 -2659 +2660 @@ -24670,12 +27402,12 @@ 1 2 -19219 +19221 2 3 -1908 +1909 3 @@ -24696,27 +27428,27 @@ 1 2 -14075 +14112 2 3 -3502 +3482 3 4 -1460 +1462 4 8 -1884 +1876 8 15750 -1667 +1659 @@ -24730,13 +27462,13 @@ 12 -36617 -36618 +36626 +36627 1 -126636 -126637 +126643 +126644 1 @@ -24772,13 +27504,13 @@ 12 -8547 -8548 +8549 +8550 1 -16700 -16701 +16702 +16703 1 @@ -24793,13 +27525,13 @@ 12 -2802 -2803 +2805 +2806 1 -6176 -6177 +6179 +6180 1 @@ -24814,13 +27546,13 @@ 12 -36766 -36767 +36626 +36627 1 -126922 -126923 +126643 +126644 1 @@ -24837,12 +27569,12 @@ 1 2 -3306 +3308 2 3 -1136 +1138 3 @@ -24883,7 +27615,7 @@ 1 2 -7265 +7269 2 @@ -24904,12 +27636,12 @@ 1 2 -4169 +4172 2 3 -1327 +1328 3 @@ -24945,12 +27677,12 @@ 1 2 -5610 +5612 2 3 -1684 +1686 @@ -24966,37 +27698,37 @@ 1 2 -3240 +3308 2 3 -1169 +1138 3 4 -761 +772 4 6 -648 +624 6 11 -608 +591 11 35 -549 +548 35 -37235 -319 +37230 +317 @@ -25012,7 +27744,7 @@ 1 2 -163688 +163269 @@ -25028,7 +27760,7 @@ 1 2 -163688 +163269 @@ -25044,7 +27776,7 @@ 1 2 -163688 +163269 @@ -25060,7 +27792,7 @@ 1 2 -163688 +163269 @@ -25076,7 +27808,7 @@ 1 2 -163688 +163269 @@ -25086,15 +27818,15 @@ localvar_location -163253 +163269 id -163253 +163269 loc -163174 +163189 @@ -25108,7 +27840,7 @@ 1 2 -163253 +163269 @@ -25124,12 +27856,12 @@ 1 2 -163095 +163109 2 3 -79 +80 @@ -25139,23 +27871,23 @@ params -2421931 +2417427 id -2421931 +2417427 name -80958 +80808 type_id -331188 +330572 index -200 +199 mode @@ -25163,11 +27895,11 @@ parent_id -1372139 +1369587 unbound_id -1437614 +1434940 @@ -25181,7 +27913,7 @@ 1 2 -2421931 +2417427 @@ -25197,7 +27929,7 @@ 1 2 -2421931 +2417427 @@ -25213,7 +27945,7 @@ 1 2 -2421931 +2417427 @@ -25229,7 +27961,7 @@ 1 2 -2421931 +2417427 @@ -25245,7 +27977,7 @@ 1 2 -2421931 +2417427 @@ -25261,7 +27993,7 @@ 1 2 -2421931 +2417427 @@ -25277,42 +28009,42 @@ 1 2 -31171 +31113 2 3 -13877 +13851 3 4 -7070 +7057 4 5 -4845 +4836 5 7 -6660 +6648 7 13 -6909 +6896 13 41 -6089 +6078 41 46351 -4333 +4325 @@ -25328,22 +28060,22 @@ 1 2 -64328 +64209 2 3 -8173 +8158 3 12 -6182 +6171 12 6855 -2273 +2269 @@ -25359,22 +28091,22 @@ 1 2 -55106 +55003 2 3 -14590 +14563 3 4 -5523 +5513 4 33 -5738 +5727 @@ -25390,12 +28122,12 @@ 1 2 -75917 +75776 2 7 -5040 +5031 @@ -25411,42 +28143,42 @@ 1 2 -31171 +31113 2 3 -13877 +13851 3 4 -7070 +7057 4 5 -4845 +4836 5 7 -6660 +6648 7 13 -6909 +6896 13 41 -6089 +6078 41 46351 -4333 +4325 @@ -25462,42 +28194,42 @@ 1 2 -31561 +31503 2 3 -14107 +14080 3 4 -7085 +7072 4 5 -4962 +4953 5 7 -6489 +6477 7 13 -6924 +6911 13 43 -6163 +6151 43 36753 -3664 +3657 @@ -25513,27 +28245,27 @@ 1 2 -227983 +227559 2 3 -39012 +38940 3 6 -30136 +30080 6 24 -25105 +25059 24 48952 -8949 +8932 @@ -25549,17 +28281,17 @@ 1 2 -289623 +289084 2 4 -30546 +30489 4 2470 -11018 +10997 @@ -25575,17 +28307,17 @@ 1 2 -292692 +292148 2 3 -25120 +25073 3 36 -13375 +13350 @@ -25601,12 +28333,12 @@ 1 2 -322463 +321863 2 5 -8724 +8708 @@ -25622,27 +28354,27 @@ 1 2 -230486 +230057 2 3 -37051 +36982 3 6 -30551 +30494 6 25 -25066 +25020 25 40409 -8031 +8017 @@ -25658,27 +28390,27 @@ 1 2 -233682 +233247 2 3 -34967 +34902 3 5 -25789 +25741 5 16 -25354 +25307 16 33990 -11394 +11372 @@ -26376,27 +29108,27 @@ 1 2 -805999 +804500 2 3 -333252 +332632 3 4 -129428 +129187 4 17 -102946 +102754 17 42 -512 +511 @@ -26412,27 +29144,27 @@ 1 2 -805999 +804500 2 3 -333252 +332632 3 4 -129428 +129187 4 17 -102946 +102754 17 42 -512 +511 @@ -26448,22 +29180,22 @@ 1 2 -855640 +854049 2 3 -333549 +332929 3 4 -113486 +113275 4 23 -69462 +69332 @@ -26479,27 +29211,27 @@ 1 2 -805999 +804500 2 3 -333252 +332632 3 4 -129428 +129187 4 17 -102946 +102754 17 42 -512 +511 @@ -26515,12 +29247,12 @@ 1 2 -1303506 +1301082 2 4 -68632 +68504 @@ -26536,27 +29268,27 @@ 1 2 -805999 +804500 2 3 -333252 +332632 3 4 -129428 +129187 4 17 -102946 +102754 17 42 -512 +511 @@ -26572,12 +29304,12 @@ 1 2 -1387241 +1384661 2 11328 -50372 +50279 @@ -26593,7 +29325,7 @@ 1 2 -1437614 +1434940 @@ -26609,12 +29341,12 @@ 1 2 -1419476 +1416836 2 3718 -18137 +18104 @@ -26630,7 +29362,7 @@ 1 2 -1437614 +1434940 @@ -26646,7 +29378,7 @@ 1 2 -1437614 +1434940 @@ -26662,12 +29394,12 @@ 1 2 -1387241 +1384661 2 11328 -50372 +50279 @@ -26677,15 +29409,15 @@ param_location -2692055 +2687049 id -2418233 +2413735 loc -137792 +137535 @@ -26699,17 +29431,17 @@ 1 2 -2154623 +2150616 2 3 -256792 +256315 3 60 -6816 +6804 @@ -26725,12 +29457,12 @@ 1 2 -133463 +133215 2 99581 -4328 +4320 @@ -26740,15 +29472,15 @@ statements -991711 +982702 id -991711 +982702 kind -37 +38 @@ -26762,7 +29494,7 @@ 1 2 -991711 +982702 @@ -26777,82 +29509,82 @@ 57 -88 +85 2 -99 +97 148 2 -211 -287 +204 +266 2 -294 -315 +283 +308 2 -332 -601 +312 +593 2 -822 -830 +790 +820 2 -925 -939 +918 +926 2 -1364 -1798 +1226 +1786 2 -2218 -2506 +2200 +2468 2 -2826 -3319 +2752 +3191 2 -3553 -3734 +3456 +3580 2 -5723 -8966 +5468 +8857 2 -18439 -61067 +18283 +60466 2 -64722 -79022 +62422 +75943 2 -97897 -197966 +94725 +191608 2 -253483 -253484 +246631 +246632 1 @@ -26863,19 +29595,19 @@ stmt_parent -820024 +811174 stmt -820024 +811174 index -439 +448 parent -434414 +429777 @@ -26889,7 +29621,7 @@ 1 2 -820024 +811174 @@ -26905,7 +29637,7 @@ 1 2 -820024 +811174 @@ -26921,22 +29653,22 @@ 1 2 -112 +114 2 3 -43 +44 3 5 -25 +26 5 8 -32 +33 8 @@ -26946,12 +29678,12 @@ 9 10 -41 +42 10 26 -35 +36 26 @@ -26960,22 +29692,22 @@ 45 -96 +95 34 -99 -473 +98 +472 34 -511 -81801 +510 +78794 34 -202913 -240184 +196048 +233227 2 @@ -26992,22 +29724,22 @@ 1 2 -112 +114 2 3 -43 +44 3 5 -25 +26 5 8 -32 +33 8 @@ -27017,12 +29749,12 @@ 9 10 -41 +42 10 26 -35 +36 26 @@ -27031,22 +29763,22 @@ 45 -96 +95 34 -99 -473 +98 +472 34 -511 -81801 +510 +78794 34 -202913 -240184 +196048 +233227 2 @@ -27063,22 +29795,22 @@ 1 2 -293576 +290998 2 3 -75348 +74368 3 5 -38126 +37451 5 361 -27363 +26959 @@ -27094,22 +29826,22 @@ 1 2 -293576 +290998 2 3 -75348 +74368 3 5 -38126 +37451 5 361 -27363 +26959 @@ -27119,11 +29851,11 @@ stmt_parent_top_level -171686 +171527 stmt -171686 +171527 index @@ -27131,7 +29863,7 @@ parent -123176 +125712 @@ -27145,7 +29877,7 @@ 1 2 -171686 +171527 @@ -27161,7 +29893,7 @@ 1 2 -171686 +171527 @@ -27175,8 +29907,8 @@ 12 -141014 -141015 +138041 +138042 1 @@ -27209,17 +29941,17 @@ 1 2 -77140 +80545 2 3 -43665 +44525 3 5 -2370 +641 @@ -27235,7 +29967,7 @@ 1 2 -123176 +125712 @@ -27245,15 +29977,15 @@ stmt_location -991711 +982702 id -991711 +982702 loc -960052 +979818 @@ -27267,7 +29999,7 @@ 1 2 -991711 +982702 @@ -27283,12 +30015,12 @@ 1 2 -928393 +976934 2 3 -31659 +2884 @@ -27298,15 +30030,15 @@ catch_type -3440 +3419 catch_id -3440 +3419 type_id -126 +129 kind @@ -27324,7 +30056,7 @@ 1 2 -3440 +3419 @@ -27340,7 +30072,7 @@ 1 2 -3440 +3419 @@ -27356,47 +30088,47 @@ 1 2 -30 +32 2 3 -23 +22 3 4 -10 +11 4 5 -10 +12 5 8 -10 +9 8 13 -10 +11 13 -28 -10 - - -28 -54 +24 9 -97 -733 -8 +27 +47 +9 + + +48 +702 +9 @@ -27412,7 +30144,7 @@ 1 2 -126 +129 @@ -27426,13 +30158,13 @@ 12 -495 -496 +492 +493 1 -2331 -2332 +2260 +2261 1 @@ -27463,20 +30195,16 @@ -expressions -4261763 +foreach_stmt_info +5338 id -4261763 +5338 kind -106 - - -type_id -22995 +9 @@ -27490,7 +30218,235 @@ 1 2 -4261763 +5338 + + + + + + +kind +id + + +12 + + +13 +14 +4 + + +1083 +1084 +4 + + + + + + + + +foreach_stmt_desugar +26642 + + +id +5338 + + +symbol +5118 + + +kind +24 + + + + +id +symbol + + +12 + + +4 +5 +48 + + +5 +6 +5289 + + + + + + +id +kind + + +12 + + +4 +5 +48 + + +5 +6 +5289 + + + + + + +symbol +id + + +12 + + +1 +2 +3097 + + +2 +3 +857 + + +3 +4 +370 + + +4 +7 +414 + + +7 +1074 +379 + + + + + + +symbol +kind + + +12 + + +1 +2 +5118 + + + + + + +kind +id + + +12 + + +1086 +1087 +4 + + +1096 +1097 +19 + + + + + + +kind +symbol + + +12 + + +2 +3 +4 + + +85 +86 +4 + + +318 +319 +4 + + +320 +321 +4 + + +326 +327 +4 + + + + + + + + +expressions +4249848 + + +id +4249848 + + +kind +132 + + +type_id +33337 + + + + +id +kind + + +12 + + +1 +2 +4249848 @@ -27506,7 +30462,7 @@ 1 2 -4261763 +4249848 @@ -27520,74 +30476,64 @@ 12 -2 -19 -8 +1 +39 +11 -20 -31 -8 +43 +148 +11 -50 -87 -8 +174 +371 +11 -91 -165 -8 +409 +693 +11 -165 -259 -8 +696 +1145 +11 -328 -714 -8 +1194 +1938 +11 -828 -1309 -8 +1945 +3489 +11 -1392 -1961 -8 +3723 +7222 +11 -2053 -3102 -8 +7548 +12815 +11 -3775 -7544 -8 +13024 +36215 +11 -8310 -19440 -8 +37825 +155093 +11 -24209 -163741 -8 - - -179843 -524140 -8 - - -547923 -759313 -2 +212653 +415548 +9 @@ -27603,52 +30549,52 @@ 1 2 -36 +37 2 -5 -9 +6 +11 -5 -7 -7 +8 +10 +11 -7 -14 -9 +11 +25 +11 -14 -93 -8 +33 +70 +11 -100 -186 -8 +70 +174 +11 -200 -373 -8 +195 +312 +11 -375 -925 -8 +369 +870 +11 -1701 -4715 -8 +940 +7017 +11 -6912 -7293 -5 +7043 +10152 +6 @@ -27664,62 +30610,57 @@ 1 2 -5199 +7041 2 3 -2978 +3514 3 4 -1233 +2355 4 5 -1734 +1973 5 -6 -1082 +7 +2941 -6 -8 -1752 +7 +11 +3050 -8 -12 -1850 +11 +17 +2562 -12 -20 -1928 +17 +28 +2624 -20 -37 -1757 +28 +50 +2526 -37 -88 -1730 +50 +129 +2501 -88 -11916 -1725 - - -12983 -493694 -27 +129 +637120 +2246 @@ -27735,42 +30676,42 @@ 1 2 -8859 +13053 2 3 -4639 +4824 3 4 -2981 +4688 4 5 -1855 +2594 5 6 -1201 +2037 6 8 -1594 +2775 8 -16 -1751 +12 +2524 -16 -56 -115 +12 +57 +837 @@ -27780,19 +30721,19 @@ expr_parent -3939840 +3919489 expr -3939840 +3919489 index -79800 +81443 parent -2586341 +2571970 @@ -27806,7 +30747,7 @@ 1 2 -3939840 +3919489 @@ -27822,7 +30763,7 @@ 1 2 -3939840 +3919489 @@ -27838,22 +30779,22 @@ 1 2 -66179 +67541 2 6 -6195 +6323 6 13 -6040 +6164 13 -1629890 -1385 +1590335 +1414 @@ -27869,22 +30810,22 @@ 1 2 -66179 +67541 2 6 -6195 +6323 6 13 -6040 +6164 13 -1629890 -1385 +1590335 +1414 @@ -27900,17 +30841,17 @@ 1 2 -1623702 +1616500 2 3 -833315 +828257 3 65537 -129323 +127211 @@ -27926,17 +30867,17 @@ 1 2 -1623702 +1616500 2 3 -833315 +828257 3 65537 -129323 +127211 @@ -27946,11 +30887,11 @@ expr_parent_top_level -504733 +500059 expr -504733 +500059 index @@ -27958,7 +30899,7 @@ parent -436423 +431875 @@ -27972,7 +30913,7 @@ 1 2 -504733 +500059 @@ -27988,7 +30929,7 @@ 1 2 -504733 +500059 @@ -28042,8 +30983,8 @@ 4 -89041 -89042 +88274 +88275 4 @@ -28098,8 +31039,8 @@ 4 -88977 -88978 +88210 +88211 4 @@ -28116,17 +31057,17 @@ 1 2 -396336 +391863 2 4 -35714 +35647 4 9 -4372 +4364 @@ -28142,17 +31083,17 @@ 1 2 -396517 +392043 2 4 -35592 +35526 4 9 -4313 +4305 @@ -28162,33 +31103,44 @@ implicitly_typed_array_creation -10806 +10813 id -10806 +10813 explicitly_sized_array_creation -4357 +4258 id -4357 +4258 stackalloc_array_creation -826 +830 id -826 +830 + + + + + +implicitly_typed_object_creation +769 + + +id +769 @@ -28243,26 +31195,26 @@ expr_compiler_generated -1636661 +1629608 id -1636661 +1629608 expr_value -1405724 +1399039 id -1405724 +1399039 value -102750 +102863 @@ -28276,7 +31228,7 @@ 1 2 -1405724 +1399039 @@ -28292,27 +31244,27 @@ 1 2 -72193 +72292 2 3 -14936 +14945 3 6 -7872 +7875 6 -1885 -7707 +2259 +7715 -1885 -273629 -42 +2294 +272384 +36 @@ -28322,15 +31274,15 @@ expr_call -678131 +677208 caller_id -678131 +677208 target_id -53459 +53760 @@ -28344,7 +31296,7 @@ 1 2 -678131 +677208 @@ -28360,32 +31312,32 @@ 1 2 -28109 +28797 2 3 -10362 +10035 3 4 -4305 +4354 4 7 -4774 +4652 7 24 -4059 +4067 24 43831 -1850 +1855 @@ -28395,15 +31347,15 @@ expr_access -1389088 +1375134 accesser_id -1389088 +1375134 target_id -331365 +338201 @@ -28417,7 +31369,7 @@ 1 2 -1389088 +1375134 @@ -28433,42 +31385,37 @@ 1 2 -104688 +110095 2 3 -70720 +71039 3 4 -51578 +54599 4 5 -33419 +33048 5 6 -18850 +19820 6 9 -27039 +25648 9 -185 -24855 - - -185 -8176 -211 +7782 +23949 @@ -28478,15 +31425,15 @@ expr_location -4261763 +4249848 id -4261763 +4249848 loc -3000067 +3325383 @@ -28500,7 +31447,7 @@ 1 2 -4261763 +4249848 @@ -28516,17 +31463,17 @@ 1 2 -2746074 +2815023 2 3 -248612 +493349 3 -542623 -5381 +105362 +17010 @@ -28536,15 +31483,15 @@ dynamic_member_name -13653 +13627 id -13653 +13627 name -1410 +1407 @@ -28558,7 +31505,7 @@ 1 2 -13653 +13627 @@ -28584,7 +31531,7 @@ 3 4 -161 +160 4 @@ -28594,7 +31541,7 @@ 5 7 -117 +116 7 @@ -28624,22 +31571,22 @@ conditional_access -3079 +3073 id -3079 +3073 expr_argument -873946 +897951 id -873946 +897951 mode @@ -28657,7 +31604,7 @@ 1 2 -873946 +897951 @@ -28671,23 +31618,23 @@ 12 -244 -245 +213 +214 1 -4305 -4306 +4293 +4294 1 -5697 -5698 +5669 +5670 1 -863700 -863701 +887776 +887777 1 @@ -28698,15 +31645,15 @@ expr_argument_name -60611 +60805 id -60611 +60805 name -2708 +2738 @@ -28720,7 +31667,7 @@ 1 2 -60611 +60805 @@ -28736,47 +31683,42 @@ 1 2 -873 +895 2 3 -488 +486 3 4 -270 +281 4 5 -198 +195 5 -7 -194 +8 +251 -7 -12 -246 +8 +13 +232 -12 -22 +13 +28 207 -22 -235 -204 - - -236 +28 11230 -28 +191 @@ -33195,7 +36137,7 @@ location -9932678 +9338663 @@ -33230,7 +36172,12 @@ 1 2 -9932678 +8757787 + + +2 +13 +580876 @@ -33240,11 +36187,11 @@ commentline -410630 +419593 id -410630 +419593 kind @@ -33252,11 +36199,11 @@ text -196984 +201215 rawtext -199596 +203884 @@ -33270,7 +36217,7 @@ 1 2 -410630 +419593 @@ -33286,7 +36233,7 @@ 1 2 -410630 +419593 @@ -33302,7 +36249,7 @@ 1 2 -410630 +419593 @@ -33321,8 +36268,8 @@ 1 -151752 -151753 +152161 +152162 1 @@ -33352,8 +36299,8 @@ 1 -89979 -89980 +90120 +90121 1 @@ -33378,8 +36325,8 @@ 1 -90313 -90314 +90457 +90458 1 @@ -33396,17 +36343,17 @@ 1 2 -161405 +164841 2 3 -23478 +23991 3 24462 -12100 +12382 @@ -33422,12 +36369,12 @@ 1 2 -195894 +200103 2 4 -1089 +1112 @@ -33443,12 +36390,12 @@ 1 2 -194908 +199092 2 51 -2075 +2122 @@ -33464,17 +36411,17 @@ 1 2 -164727 +168234 2 3 -23012 +23515 3 24457 -11856 +12133 @@ -33490,7 +36437,7 @@ 1 2 -199596 +203884 @@ -33506,7 +36453,7 @@ 1 2 -199596 +203884 @@ -33516,15 +36463,15 @@ commentline_location -410630 +419593 id -410630 +419593 loc -410630 +419593 @@ -33538,7 +36485,7 @@ 1 2 -410630 +419593 @@ -33554,7 +36501,7 @@ 1 2 -410630 +419593 @@ -33564,26 +36511,26 @@ commentblock -144330 +147802 id -144330 +147802 commentblock_location -144330 +147802 id -144330 +147802 loc -144330 +147802 @@ -33597,7 +36544,7 @@ 1 2 -144330 +147802 @@ -33613,7 +36560,7 @@ 1 2 -144330 +147802 @@ -33623,15 +36570,15 @@ commentblock_binding -499895 +511943 id -144272 +147743 entity -216054 +220972 bindtype @@ -33649,22 +36596,22 @@ 1 2 -18058 +18478 2 3 -29054 +29773 3 4 -96868 +99191 4 7 -290 +299 @@ -33680,22 +36627,22 @@ 1 2 -12956 +13258 2 3 -5221 +5343 3 4 -29008 +29728 4 5 -97084 +99412 @@ -33711,17 +36658,17 @@ 1 2 -158335 +161677 2 3 -42066 +43223 3 -9895 -15652 +9897 +16071 @@ -33737,22 +36684,22 @@ 1 2 -94328 +96451 2 3 -92774 +94876 3 4 -28080 +28747 4 5 -870 +897 @@ -33766,23 +36713,23 @@ 12 -83795 -83796 +84123 +84124 1 -104319 -104320 +104686 +104687 1 -107785 -107786 +108160 +108161 1 -113759 -113760 +114096 +114097 1 @@ -33797,23 +36744,23 @@ 12 -35897 -35898 +35989 +35990 1 -77380 -77381 +77578 +77579 1 -86313 -86314 +86538 +86539 1 -102338 -102339 +102518 +102519 1 @@ -33824,19 +36771,19 @@ commentblock_child -543889 +555877 id -144330 +147802 commentline -410544 +419504 index -4989 +5092 @@ -33850,32 +36797,32 @@ 1 2 -76905 +78982 2 3 -19919 +20337 3 4 -18979 +19370 4 5 -8965 +9150 5 8 -11476 +11712 8 4098 -8083 +8249 @@ -33891,37 +36838,37 @@ 1 2 -4206 +4380 2 3 -73601 +75536 3 4 -21669 +22212 4 5 -17226 +17481 5 6 -8623 +8801 6 9 -11196 +11424 9 4099 -7806 +7966 @@ -33937,7 +36884,7 @@ 1 2 -410535 +419496 2 @@ -33958,12 +36905,12 @@ 1 2 -277207 +283141 2 3 -133336 +136363 @@ -33979,32 +36926,32 @@ 1 2 -2226 +2272 2 3 -1379 +1407 3 7 -398 +406 7 10 -439 +448 11 28 -379 +387 28 -118546 -165 +118949 +168 @@ -34020,32 +36967,32 @@ 1 2 -2226 +2272 2 3 -1379 +1407 3 7 -398 +406 7 10 -439 +448 11 28 -379 +387 28 -118539 -165 +118942 +168 @@ -34517,7 +37464,7 @@ name -1 +2 @@ -34545,8 +37492,13 @@ 12 -3 -4 +1 +2 +1 + + +2 +3 1 @@ -34844,7 +37796,7 @@ name -6 +3 @@ -34872,19 +37824,9 @@ 12 -1 -2 -4 - - -2 -3 -1 - - 3 4 -1 +3 @@ -34905,23 +37847,23 @@ cil_instruction -32220325 +32160402 id -32220325 +32160402 opcode -966 +964 index -332939 +332320 impl -1728901 +1725686 @@ -34935,7 +37877,7 @@ 1 2 -32220325 +32160402 @@ -34951,7 +37893,7 @@ 1 2 -32220325 +32160402 @@ -34967,7 +37909,7 @@ 1 2 -32220325 +32160402 @@ -34983,7 +37925,7 @@ 1 7 -78 +77 7 @@ -35089,7 +38031,7 @@ 214 313 -78 +77 323 @@ -35140,7 +38082,7 @@ 1 6 -78 +77 7 @@ -35221,22 +38163,22 @@ 1 2 -260789 +260304 2 11 -30644 +30587 11 25 -25530 +25482 25 354308 -15976 +15946 @@ -35252,22 +38194,22 @@ 1 2 -261384 +260898 2 3 -17708 +17675 3 5 -28775 +28721 5 160 -24974 +24927 160 @@ -35288,22 +38230,22 @@ 1 2 -260789 +260304 2 11 -30644 +30587 11 25 -25530 +25482 25 354308 -15976 +15946 @@ -35319,57 +38261,57 @@ 1 2 -84135 +83978 2 3 -252210 +251741 3 4 -332827 +332208 4 5 -196157 +195793 5 6 -107221 +107021 6 9 -158218 +157924 9 14 -151216 +150934 14 21 -134034 +133785 21 35 -131682 +131437 35 106 -129706 +129465 106 68231 -51490 +51394 @@ -35385,57 +38327,57 @@ 1 2 -84135 +83978 2 3 -252498 +252028 3 4 -338805 +338175 4 5 -239806 +239360 5 6 -132624 +132377 6 7 -96466 +96286 7 9 -147995 +147720 9 12 -129042 +128802 12 17 -136001 +135748 17 33 -132278 +132032 33 74 -39247 +39174 @@ -35451,57 +38393,57 @@ 1 2 -84135 +83978 2 3 -252210 +251741 3 4 -332827 +332208 4 5 -196157 +195793 5 6 -107221 +107021 6 9 -158218 +157924 9 14 -151216 +150934 14 21 -134034 +133785 21 35 -131682 +131437 35 106 -129706 +129465 106 68231 -51490 +51394 @@ -35511,15 +38453,15 @@ cil_jump -2007076 +2003344 instruction -2007076 +2003344 target -1607461 +1604471 @@ -35533,7 +38475,7 @@ 1 2 -2007076 +2003344 @@ -35549,17 +38491,17 @@ 1 2 -1393468 +1390876 2 3 -143950 +143682 3 360 -70042 +69912 @@ -35569,15 +38511,15 @@ cil_access -11947142 +11924922 instruction -11947142 +11924922 target -2669502 +2664615 @@ -35591,7 +38533,7 @@ 1 2 -11947142 +11924922 @@ -35607,37 +38549,37 @@ 1 2 -946680 +944934 2 3 -741304 +739974 3 4 -269523 +269051 4 5 -187462 +187123 5 7 -227109 +226687 7 14 -203936 +203537 14 25741 -93484 +93306 @@ -35647,15 +38589,15 @@ cil_value -1887505 +1883995 instruction -1887505 +1883995 value -495769 +494847 @@ -35669,7 +38611,7 @@ 1 2 -1887505 +1883995 @@ -35685,27 +38627,27 @@ 1 2 -334989 +334366 2 3 -79153 +79005 3 6 -40784 +40708 6 33 -37319 +37250 33 86799 -3523 +3516 @@ -35715,19 +38657,19 @@ cil_switch -194762 +194400 instruction -23895 +23851 index -2522 +2518 target -130848 +130605 @@ -35741,42 +38683,42 @@ 3 4 -7031 +7018 4 5 -4601 +4592 5 6 -3235 +3229 6 7 -1688 +1685 7 8 -1444 +1441 8 11 -2161 +2157 11 17 -1849 +1845 17 128 -1795 +1792 141 @@ -35797,42 +38739,42 @@ 1 3 -1058 +1056 3 4 -8261 +8245 4 5 -5499 +5489 5 6 -2576 +2571 6 7 -1844 +1841 7 9 -1703 +1699 9 14 -1800 +1797 14 204 -1151 +1149 @@ -35853,7 +38795,7 @@ 2 3 -990 +988 3 @@ -35863,7 +38805,7 @@ 4 5 -361 +360 6 @@ -35878,17 +38820,17 @@ 18 24 -190 +189 25 47 -200 +199 47 225 -190 +189 238 @@ -35909,12 +38851,12 @@ 1 2 -39 +38 2 3 -975 +974 3 @@ -35924,7 +38866,7 @@ 4 5 -312 +311 5 @@ -35944,12 +38886,12 @@ 24 47 -195 +194 47 271 -190 +189 289 @@ -35970,12 +38912,12 @@ 1 2 -129213 +128973 2 12 -1634 +1631 @@ -35991,17 +38933,17 @@ 1 2 -118434 +118214 2 7 -10017 +9999 7 253 -2395 +2391 @@ -36079,15 +39021,15 @@ cil_type_location -277858 +277341 id -255445 +254970 loc -3420 +3414 @@ -36101,12 +39043,12 @@ 1 2 -233033 +232600 2 3 -22412 +22370 @@ -36132,7 +39074,7 @@ 4 6 -234 +233 6 @@ -36142,17 +39084,17 @@ 9 13 -273 +272 13 17 -268 +267 17 23 -283 +282 23 @@ -36162,7 +39104,7 @@ 32 43 -268 +267 43 @@ -36192,15 +39134,15 @@ cil_method_location -1887461 +1883951 id -1799842 +1796543 loc -3132 +3126 @@ -36214,12 +39156,12 @@ 1 2 -1712222 +1709135 2 3 -87619 +87407 @@ -36255,12 +39197,12 @@ 53 79 -239 +238 80 107 -239 +238 107 @@ -36275,22 +39217,22 @@ 204 278 -239 +238 281 385 -239 +238 388 734 -239 +238 735 1631 -239 +238 1646 @@ -36305,15 +39247,15 @@ cil_type -796235 +794764 id -796235 +794764 name -179401 +179043 kind @@ -36321,11 +39263,11 @@ parent -155715 +155425 sourceDecl -465466 +464610 @@ -36339,7 +39281,7 @@ 1 2 -796235 +794764 @@ -36355,7 +39297,7 @@ 1 2 -796235 +794764 @@ -36371,7 +39313,7 @@ 1 2 -796235 +794764 @@ -36387,7 +39329,7 @@ 1 2 -796235 +794764 @@ -36403,22 +39345,22 @@ 1 2 -137914 +137633 2 3 -22534 +22472 3 7 -14175 +14168 7 21324 -4777 +4768 @@ -36434,7 +39376,7 @@ 1 2 -179401 +179043 @@ -36450,17 +39392,17 @@ 1 2 -162722 +162395 2 4 -13667 +13642 4 21324 -3010 +3005 @@ -36476,12 +39418,12 @@ 1 2 -146390 +146093 2 3 -22558 +22497 3 @@ -36500,8 +39442,8 @@ 12 -128 -129 +123 +124 4 @@ -36515,8 +39457,8 @@ 4 -122205 -122206 +122212 +122213 4 @@ -36536,8 +39478,8 @@ 4 -106 -107 +101 +102 4 @@ -36567,8 +39509,8 @@ 4 -32 -33 +31 +32 4 @@ -36593,8 +39535,8 @@ 12 -128 -129 +123 +124 4 @@ -36608,8 +39550,8 @@ 4 -54865 -54866 +54872 +54873 4 @@ -36626,27 +39568,27 @@ 1 2 -101965 +101775 2 3 -26843 +26793 3 6 -13365 +13340 6 33 -11720 +11699 33 -26080 -1820 +26079 +1816 @@ -36662,27 +39604,27 @@ 1 2 -102541 +102350 2 3 -27262 +27212 3 6 -13262 +13238 6 38 -11706 +11684 38 -1430 -941 +1426 +940 @@ -36698,12 +39640,12 @@ 1 2 -152504 +152225 2 4 -3210 +3199 @@ -36719,27 +39661,27 @@ 1 2 -102438 +102248 2 3 -27282 +27231 3 6 -13170 +13145 6 38 -11686 +11665 38 -3477 -1136 +3476 +1134 @@ -36755,12 +39697,12 @@ 1 2 -438633 +437827 2 3705 -26833 +26783 @@ -36776,7 +39718,7 @@ 1 2 -465466 +464610 @@ -36792,7 +39734,7 @@ 1 2 -465466 +464610 @@ -36808,12 +39750,12 @@ 1 2 -457127 +456287 2 225 -8339 +8323 @@ -36823,15 +39765,15 @@ cil_pointer_type -624 +599 id -624 +599 pointee -624 +599 @@ -36845,7 +39787,7 @@ 1 2 -624 +599 @@ -36861,7 +39803,7 @@ 1 2 -624 +599 @@ -36871,15 +39813,15 @@ cil_array_type -14194 +14168 id -14194 +14168 element_type -14116 +14090 rank @@ -36897,7 +39839,7 @@ 1 2 -14194 +14168 @@ -36913,7 +39855,7 @@ 1 2 -14194 +14168 @@ -36929,7 +39871,7 @@ 1 2 -14043 +14017 2 @@ -36950,7 +39892,7 @@ 1 2 -14043 +14017 2 @@ -37016,24 +39958,77 @@ -cil_method -2315906 +cil_function_pointer_return_type +9 id -2315906 - - -name -440439 - - -parent -380604 +9 return_type -214246 +6 + + + + +id +return_type + + +12 + + +1 +2 +9 + + + + + + +return_type +id + + +12 + + +1 +2 +5 + + +4 +5 +1 + + + + + + + + +cil_method +2311725 + + +id +2311725 + + +name +439619 + + +parent +379896 + + +return_type +213848 @@ -37047,7 +40042,7 @@ 1 2 -2315906 +2311725 @@ -37063,7 +40058,7 @@ 1 2 -2315906 +2311725 @@ -37079,7 +40074,7 @@ 1 2 -2315906 +2311725 @@ -37095,27 +40090,27 @@ 1 2 -271373 +270858 2 3 -79699 +79561 3 4 -25071 +25020 4 7 -33533 +33475 7 64064 -30761 +30704 @@ -37131,27 +40126,27 @@ 1 2 -285392 +284861 2 3 -76664 +76521 3 5 -39920 +39846 5 25 -33201 +33139 25 52725 -5260 +5250 @@ -37167,17 +40162,17 @@ 1 2 -384596 +383880 2 4 -40281 +40206 4 2803 -15561 +15532 @@ -37193,42 +40188,42 @@ 1 2 -108109 +107908 2 3 -84613 +84456 3 4 -50065 +49918 4 5 -28560 +28551 5 7 -30898 +30850 7 11 -32957 +32896 11 21 -28999 +28936 21 3536 -16400 +16379 @@ -37244,42 +40239,42 @@ 1 2 -114506 +114293 2 3 -86770 +86608 3 4 -50568 +50473 4 5 -28951 +28897 5 7 -32913 +32852 7 11 -30049 +29993 11 26 -28726 +28673 26 1885 -8119 +8104 @@ -37295,32 +40290,32 @@ 1 2 -162361 +162059 2 3 -93806 +93632 3 4 -46449 +46363 4 5 -23324 +23281 5 7 -28428 +28376 7 1924 -26233 +26184 @@ -37336,27 +40331,27 @@ 1 2 -132126 +131881 2 3 -38295 +38214 3 5 -18859 +18829 5 13 -16581 +16555 13 190707 -8383 +8367 @@ -37372,22 +40367,22 @@ 1 2 -153724 +153438 2 3 -30380 +30324 3 6 -19167 +19131 6 28461 -10974 +10953 @@ -37403,22 +40398,22 @@ 1 2 -145565 +145294 2 3 -35431 +35365 3 5 -17571 +17539 5 62018 -15678 +15649 @@ -37428,15 +40423,15 @@ cil_method_source_declaration -2109413 +2105616 method -2109413 +2105616 source -1866513 +1863168 @@ -37450,7 +40445,7 @@ 1 2 -2109413 +2105616 @@ -37466,12 +40461,12 @@ 1 2 -1761448 +1758299 2 1021 -105064 +104868 @@ -37481,19 +40476,19 @@ cil_method_implementation -1728901 +1725686 id -1728901 +1725686 method -1641926 +1638921 location -3098 +3092 @@ -37507,7 +40502,7 @@ 1 2 -1728901 +1725686 @@ -37523,7 +40518,7 @@ 1 2 -1728901 +1725686 @@ -37539,12 +40534,12 @@ 1 2 -1554951 +1552156 2 3 -86975 +86764 @@ -37560,12 +40555,12 @@ 1 2 -1554951 +1552156 2 3 -86975 +86764 @@ -37581,22 +40576,22 @@ 1 11 -273 +272 11 22 -239 +238 22 36 -239 +238 36 50 -234 +233 50 @@ -37611,17 +40606,17 @@ 104 133 -239 +238 133 192 -234 +233 192 271 -234 +233 271 @@ -37631,17 +40626,17 @@ 372 654 -234 +233 682 1597 -239 +238 1599 33053 -190 +189 @@ -37657,22 +40652,22 @@ 1 11 -273 +272 11 22 -239 +238 22 36 -239 +238 36 50 -234 +233 50 @@ -37687,17 +40682,17 @@ 104 133 -239 +238 133 192 -234 +233 192 271 -234 +233 271 @@ -37707,17 +40702,17 @@ 372 654 -234 +233 682 1597 -239 +238 1599 33053 -190 +189 @@ -37727,15 +40722,15 @@ cil_implements -107250 +107050 id -106489 +106291 decl -17752 +17719 @@ -37749,12 +40744,12 @@ 1 2 -105727 +105531 2 3 -761 +759 @@ -37770,27 +40765,27 @@ 1 2 -11555 +11533 2 3 -2708 +2703 3 5 -1581 +1578 5 18 -1332 +1329 18 2180 -575 +574 @@ -37800,23 +40795,23 @@ cil_field -1010179 +1008300 id -1010179 +1008300 parent -201486 +201111 name -361476 +360803 field_type -166143 +165834 @@ -37830,7 +40825,7 @@ 1 2 -1010179 +1008300 @@ -37846,7 +40841,7 @@ 1 2 -1010179 +1008300 @@ -37862,7 +40857,7 @@ 1 2 -1010179 +1008300 @@ -37878,47 +40873,47 @@ 1 2 -60722 +60609 2 3 -41101 +41025 3 4 -22329 +22287 4 5 -15507 +15478 5 6 -11730 +11708 6 8 -16976 +16944 8 12 -17883 +17850 12 227 -15117 +15089 237 4205 -117 +116 @@ -37934,47 +40929,47 @@ 1 2 -60722 +60609 2 3 -41101 +41025 3 4 -22329 +22287 4 5 -15507 +15478 5 6 -11730 +11708 6 8 -16976 +16944 8 12 -17883 +17850 12 227 -15117 +15089 237 4205 -117 +116 @@ -37990,37 +40985,37 @@ 1 2 -70525 +70394 2 3 -59858 +59747 3 4 -20455 +20417 4 5 -11481 +11460 5 7 -15712 +15683 7 11 -16083 +16053 11 132 -7368 +7354 @@ -38036,22 +41031,22 @@ 1 2 -262296 +261809 2 3 -55447 +55344 3 7 -30122 +30066 7 5664 -13609 +13584 @@ -38067,22 +41062,22 @@ 1 2 -262296 +261809 2 3 -55447 +55344 3 7 -30122 +30066 7 5664 -13609 +13584 @@ -38098,17 +41093,17 @@ 1 2 -305921 +305352 2 3 -34113 +34050 3 2790 -21441 +21401 @@ -38124,32 +41119,32 @@ 1 2 -82759 +82605 2 3 -43838 +43757 3 4 -8973 +8957 4 7 -15283 +15254 7 31 -12560 +12536 31 21103 -2727 +2722 @@ -38165,22 +41160,22 @@ 1 2 -96861 +96681 2 3 -44566 +44483 3 6 -14253 +14227 6 12257 -10462 +10442 @@ -38196,27 +41191,27 @@ 1 2 -120015 +119792 2 3 -17991 +17957 3 5 -13262 +13238 5 20 -12487 +12463 20 8901 -2386 +2381 @@ -38226,29 +41221,29 @@ cil_parameter -4554714 +4546408 id -4554714 +4546408 -method -2224236 +parameterizable +2220226 index -200 +199 param_type -553515 +552486 id -method +parameterizable 12 @@ -38256,7 +41251,7 @@ 1 2 -4554714 +4546408 @@ -38272,7 +41267,7 @@ 1 2 -4554714 +4546408 @@ -38288,14 +41283,14 @@ 1 2 -4554714 +4546408 -method +parameterizable id @@ -38304,34 +41299,34 @@ 1 2 -902114 +900524 2 3 -788803 +787375 3 4 -325215 +324610 4 7 -175243 +174917 7 42 -32859 +32798 -method +parameterizable index @@ -38340,34 +41335,34 @@ 1 2 -902114 +900524 2 3 -788803 +787375 3 4 -325215 +324610 4 7 -175243 +174917 7 42 -32859 +32798 -method +parameterizable param_type @@ -38376,22 +41371,22 @@ 1 2 -950232 +948553 2 3 -799329 +797881 3 4 -313557 +312974 4 23 -161116 +160817 @@ -38466,7 +41461,7 @@ 109294 -455818 +455844 14 @@ -38475,7 +41470,7 @@ index -method +parameterizable 12 @@ -38542,7 +41537,7 @@ 109294 -455818 +455844 14 @@ -38640,42 +41635,42 @@ 1 2 -185734 +185389 2 3 -137309 +137053 3 4 -45097 +45014 4 5 -38520 +38448 5 7 -43931 +43849 7 11 -42858 +42758 11 27 -41935 +41877 27 -58009 -18127 +58010 +18094 @@ -38683,7 +41678,7 @@ param_type -method +parameterizable 12 @@ -38691,42 +41686,42 @@ 1 2 -188945 +188594 2 3 -136006 +135753 3 4 -45512 +45428 4 5 -37300 +37230 5 7 -44380 +44298 7 11 -42916 +42817 11 28 -41774 +41716 28 -46067 -16678 +46068 +16647 @@ -38742,22 +41737,22 @@ 1 2 -386274 +385556 2 3 -110026 +109822 3 4 -44546 +44463 4 36 -12667 +12644 @@ -38767,37 +41762,37 @@ cil_parameter_in -32410 +32350 id -32410 +32350 cil_parameter_out -46108 +46022 id -46108 +46022 cil_setter -106952 +106753 prop -106952 +106753 method -106952 +106753 @@ -38811,7 +41806,7 @@ 1 2 -106952 +106753 @@ -38827,7 +41822,221 @@ 1 2 -106952 +106753 + + + + + + + + +cil_custom_modifiers +4105 + + +id +4105 + + +modifier +53 + + +kind +4 + + + + +id +modifier + + +12 + + +1 +2 +4105 + + + + + + +id +kind + + +12 + + +1 +2 +4105 + + + + + + +modifier +id + + +12 + + +5 +6 +4 + + +10 +11 +4 + + +11 +12 +4 + + +19 +20 +4 + + +25 +26 +4 + + +29 +30 +4 + + +51 +52 +4 + + +68 +69 +4 + + +87 +88 +4 + + +94 +95 +4 + + +444 +445 +4 + + + + + + +modifier +kind + + +12 + + +1 +2 +53 + + + + + + +kind +id + + +12 + + +843 +844 +4 + + + + + + +kind +modifier + + +12 + + +11 +12 +4 + + + + + + + + +cil_type_annotation +196056 + + +id +196056 + + +annotation +4 + + + + +id +annotation + + +12 + + +1 +2 +196056 + + + + + + +annotation +id + + +12 + + +40253 +40254 +4 @@ -38837,15 +42046,15 @@ cil_getter -380053 +379346 prop -380053 +379346 method -380053 +379346 @@ -38859,7 +42068,7 @@ 1 2 -380053 +379346 @@ -38875,7 +42084,7 @@ 1 2 -380053 +379346 @@ -38885,15 +42094,15 @@ cil_adder -20909 +20870 event -20909 +20870 method -20909 +20870 @@ -38907,7 +42116,7 @@ 1 2 -20909 +20870 @@ -38923,7 +42132,7 @@ 1 2 -20909 +20870 @@ -38933,15 +42142,15 @@ cil_remover -20909 +20870 event -20909 +20870 method -20909 +20870 @@ -38955,7 +42164,7 @@ 1 2 -20909 +20870 @@ -38971,7 +42180,7 @@ 1 2 -20909 +20870 @@ -39029,23 +42238,23 @@ cil_property -380599 +379891 id -380599 +379891 parent -93821 +93646 name -106425 +106227 property_type -49914 +49821 @@ -39059,7 +42268,7 @@ 1 2 -380599 +379891 @@ -39075,7 +42284,7 @@ 1 2 -380599 +379891 @@ -39091,7 +42300,7 @@ 1 2 -380599 +379891 @@ -39107,42 +42316,42 @@ 1 2 -28916 +28863 2 3 -22314 +22273 3 4 -11433 +11411 4 5 -8466 +8450 5 6 -5748 +5737 6 9 -8676 +8659 9 25 -7109 +7096 25 1883 -1156 +1154 @@ -39158,42 +42367,42 @@ 1 2 -33669 +33607 2 3 -17820 +17787 3 4 -11330 +11309 4 5 -8475 +8460 5 6 -5728 +5718 6 8 -6636 +6624 8 15 -7226 +7213 15 1883 -2932 +2927 @@ -39209,32 +42418,32 @@ 1 2 -35118 +35053 2 3 -25803 +25755 3 4 -13497 +13472 4 5 -8114 +8099 5 8 -7768 +7753 8 50 -3518 +3511 @@ -39250,27 +42459,27 @@ 1 2 -62742 +62626 2 3 -21470 +21430 3 4 -6489 +6477 4 8 -8773 +8757 8 2134 -6948 +6935 @@ -39286,27 +42495,27 @@ 1 2 -62742 +62626 2 3 -21543 +21503 3 4 -6465 +6453 4 8 -8788 +8771 8 1400 -6885 +6872 @@ -39322,17 +42531,17 @@ 1 2 -89566 +89399 2 3 -10989 +10968 3 568 -5870 +5859 @@ -39348,27 +42557,27 @@ 1 2 -31473 +31415 2 3 -7529 +7515 3 4 -3186 +3180 4 8 -4372 +4364 8 15452 -3352 +3346 @@ -39384,27 +42593,27 @@ 1 2 -33264 +33202 2 3 -7041 +7028 3 4 -3049 +3044 4 8 -3869 +3862 8 5858 -2688 +2683 @@ -39420,22 +42629,22 @@ 1 2 -39998 +39924 2 3 -5318 +5308 3 12 -3806 +3799 12 6253 -790 +789 @@ -39445,23 +42654,23 @@ cil_event -20880 +20841 id -20880 +20841 parent -6470 +6458 name -13087 +13062 event_type -6807 +6794 @@ -39475,7 +42684,7 @@ 1 2 -20880 +20841 @@ -39491,7 +42700,7 @@ 1 2 -20880 +20841 @@ -39507,7 +42716,7 @@ 1 2 -20880 +20841 @@ -39523,12 +42732,12 @@ 1 2 -5753 +5742 2 7 -492 +491 7 @@ -39549,12 +42758,12 @@ 1 2 -5753 +5742 2 7 -492 +491 7 @@ -39575,7 +42784,7 @@ 1 2 -5928 +5917 2 @@ -39601,17 +42810,17 @@ 1 2 -11677 +11655 2 4 -966 +964 4 566 -444 +443 @@ -39627,17 +42836,17 @@ 1 2 -11677 +11655 2 4 -966 +964 4 566 -444 +443 @@ -39653,12 +42862,12 @@ 1 2 -12491 +12468 2 566 -595 +594 @@ -39674,22 +42883,22 @@ 1 2 -946 +944 2 3 -4523 +4515 3 4 -585 +584 4 8 -575 +574 8 @@ -39710,12 +42919,12 @@ 1 2 -1424 +1422 2 3 -5094 +5084 3 @@ -39736,22 +42945,22 @@ 1 2 -1312 +1310 2 3 -4352 +4344 3 4 -497 +496 4 10 -531 +530 10 @@ -39766,23 +42975,23 @@ cil_local_variable -1152739 +1150595 id -1152739 +1150595 impl -349257 +348608 index -692 +691 var_type -154519 +154212 @@ -39796,7 +43005,7 @@ 1 2 -1152739 +1150595 @@ -39812,7 +43021,7 @@ 1 2 -1152739 +1150595 @@ -39828,7 +43037,7 @@ 1 2 -1152739 +1150595 @@ -39844,37 +43053,37 @@ 1 2 -140149 +139888 2 3 -62142 +62027 3 4 -49406 +49314 4 5 -23515 +23471 5 7 -31932 +31873 7 12 -28907 +28853 12 143 -13204 +13179 @@ -39890,37 +43099,37 @@ 1 2 -140149 +139888 2 3 -62142 +62027 3 4 -49406 +49314 4 5 -23515 +23471 5 7 -31932 +31873 7 12 -28907 +28853 12 143 -13204 +13179 @@ -39936,17 +43145,17 @@ 1 2 -168856 +168337 2 3 -70140 +70112 3 4 -37900 +37932 4 @@ -39956,12 +43165,12 @@ 5 7 -27740 +27664 7 47 -23978 +23919 @@ -40168,17 +43377,17 @@ 143 -541 +539 53 -600 -4921 +599 +4919 53 -7228 -19499 +7226 +19498 14 @@ -40195,37 +43404,37 @@ 1 2 -81427 +81285 2 3 -27306 +27236 3 4 -8383 +8372 4 5 -11847 +11820 5 8 -12809 +12785 8 76 -11598 +11572 76 -35710 -1146 +35712 +1139 @@ -40241,32 +43450,32 @@ 1 2 -85467 +85313 2 3 -31054 +30976 3 4 -8397 +8382 4 5 -11716 +11699 5 14 -12043 +12020 14 21451 -5840 +5820 @@ -40282,27 +43491,80 @@ 1 2 -96788 +96613 2 3 -28736 +28673 3 4 -13789 +13769 4 9 -11896 +11859 9 122 -3308 +3297 + + + + + + + + +cil_function_pointer_calling_conventions +9 + + +id +9 + + +kind +2 + + + + +id +kind + + +12 + + +1 +2 +9 + + + + + + +kind +id + + +12 + + +1 +2 +1 + + +8 +9 +1 @@ -40312,19 +43574,19 @@ cil_handler -101638 +101449 id -101638 +101449 impl -71555 +71422 index -78 +77 kind @@ -40332,15 +43594,15 @@ try_start -97793 +97611 try_end -100013 +99827 handler_start -101638 +101449 @@ -40354,7 +43616,7 @@ 1 2 -101638 +101449 @@ -40370,7 +43632,7 @@ 1 2 -101638 +101449 @@ -40386,7 +43648,7 @@ 1 2 -101638 +101449 @@ -40402,7 +43664,7 @@ 1 2 -101638 +101449 @@ -40418,7 +43680,7 @@ 1 2 -101638 +101449 @@ -40434,7 +43696,7 @@ 1 2 -101638 +101449 @@ -40450,22 +43712,22 @@ 1 2 -53876 +53776 2 3 -11174 +11153 3 5 -5435 +5425 5 17 -1068 +1066 @@ -40481,22 +43743,22 @@ 1 2 -53876 +53776 2 3 -11174 +11153 3 5 -5435 +5425 5 17 -1068 +1066 @@ -40512,12 +43774,12 @@ 1 2 -61976 +61861 2 3 -9354 +9336 3 @@ -40538,17 +43800,17 @@ 1 2 -54906 +54803 2 3 -10867 +10846 3 7 -5538 +5528 7 @@ -40569,22 +43831,22 @@ 1 2 -54427 +54326 2 3 -11086 +11065 3 6 -5533 +5523 6 16 -507 +506 @@ -40600,22 +43862,22 @@ 1 2 -53876 +53776 2 3 -11174 +11153 3 5 -5435 +5425 5 17 -1068 +1066 @@ -41278,12 +44540,12 @@ 1 2 -94489 +94314 2 8 -3303 +3297 @@ -41299,7 +44561,7 @@ 1 2 -97793 +97611 @@ -41315,12 +44577,12 @@ 1 2 -94489 +94314 2 8 -3303 +3297 @@ -41336,12 +44598,12 @@ 1 2 -95529 +95351 2 4 -2264 +2259 @@ -41357,12 +44619,12 @@ 1 2 -95573 +95395 2 3 -2220 +2216 @@ -41378,12 +44640,12 @@ 1 2 -94489 +94314 2 8 -3303 +3297 @@ -41399,12 +44661,12 @@ 1 2 -98784 +98600 2 7 -1229 +1227 @@ -41420,7 +44682,7 @@ 1 2 -100013 +99827 @@ -41436,12 +44698,12 @@ 1 2 -98784 +98600 2 7 -1229 +1227 @@ -41457,7 +44719,7 @@ 1 2 -99838 +99652 2 @@ -41478,7 +44740,7 @@ 1 2 -100013 +99827 @@ -41494,12 +44756,12 @@ 1 2 -98784 +98600 2 7 -1229 +1227 @@ -41515,7 +44777,7 @@ 1 2 -101638 +101449 @@ -41531,7 +44793,7 @@ 1 2 -101638 +101449 @@ -41547,7 +44809,7 @@ 1 2 -101638 +101449 @@ -41563,7 +44825,7 @@ 1 2 -101638 +101449 @@ -41579,7 +44841,7 @@ 1 2 -101638 +101449 @@ -41595,7 +44857,7 @@ 1 2 -101638 +101449 @@ -41605,15 +44867,15 @@ cil_handler_filter -810 +808 id -810 +808 filter_start -810 +808 @@ -41627,7 +44889,7 @@ 1 2 -810 +808 @@ -41643,7 +44905,7 @@ 1 2 -810 +808 @@ -41653,15 +44915,15 @@ cil_handler_type -43887 +43806 id -43887 +43806 catch_type -1263 +1261 @@ -41675,7 +44937,7 @@ 1 2 -43887 +43806 @@ -41691,17 +44953,17 @@ 1 2 -439 +438 2 3 -268 +267 3 4 -151 +150 4 @@ -41736,15 +44998,15 @@ cil_method_stack_size -1728901 +1725686 method -1728901 +1725686 size -161 +160 @@ -41758,7 +45020,7 @@ 1 2 -1728901 +1725686 @@ -41839,110 +45101,110 @@ cil_public -1913382 +1909872 id -1913382 +1909872 cil_private -929992 +928262 id -929992 +928262 cil_protected -1820619 +1817282 id -1820619 +1817282 cil_internal -41740 +41663 id -41740 +41663 cil_static -795957 +794476 id -795957 +794476 cil_sealed -357025 +356362 id -357025 +356362 cil_virtual -678493 +677231 id -678493 +677231 cil_abstract -165401 +165093 id -165401 +165093 cil_class -238874 +238430 id -238874 +238430 cil_interface -16571 +16540 id -16571 +16540 @@ -41971,37 +45233,37 @@ cil_specialname -812060 +810549 id -812060 +810549 cil_newslot -422828 +422041 id -422828 +422041 cil_base_class -235888 +235449 id -235888 +235449 base -21436 +21396 @@ -42015,7 +45277,7 @@ 1 2 -235888 +235449 @@ -42031,27 +45293,27 @@ 1 2 -12330 +12307 2 3 -3864 +3857 3 4 -1615 +1612 4 7 -1893 +1889 7 84 -1610 +1607 86 @@ -42066,15 +45328,15 @@ cil_base_interface -125368 +125135 id -68686 +68558 base -31234 +31176 @@ -42088,27 +45350,27 @@ 1 2 -47757 +47668 2 3 -8124 +8109 3 5 -6270 +6258 5 9 -5382 +5372 9 25 -1151 +1149 @@ -42124,27 +45386,110 @@ 1 2 -22505 +22463 2 3 -3435 +3428 3 5 -2522 +2518 5 30 -2347 +2342 30 2180 -424 +423 + + + + + + + + +cil_enum_underlying_type +14061 + + +id +14061 + + +underlying +38 + + + + +id +underlying + + +12 + + +1 +2 +14061 + + + + + + +underlying +id + + +12 + + +5 +6 +4 + + +6 +7 +4 + + +25 +26 +4 + + +31 +32 +4 + + +41 +42 +4 + + +173 +174 +4 + + +291 +292 +4 + + +2315 +2316 +4 @@ -42154,11 +45499,11 @@ cil_type_parameter -185095 +184751 unbound -104049 +103855 index @@ -42166,7 +45511,7 @@ param -185095 +184751 @@ -42180,22 +45525,22 @@ 1 2 -75083 +74943 2 3 -19025 +18990 3 13 -8168 +8153 13 22 -1771 +1768 @@ -42211,22 +45556,22 @@ 1 2 -75083 +74943 2 3 -19025 +18990 3 13 -8168 +8153 13 22 -1771 +1768 @@ -42474,7 +45819,7 @@ 1 2 -185095 +184751 @@ -42490,7 +45835,7 @@ 1 2 -185095 +184751 @@ -42500,11 +45845,11 @@ cil_type_argument -738342 +736969 bound -482155 +481258 index @@ -42512,7 +45857,7 @@ t -252625 +252155 @@ -42526,17 +45871,17 @@ 1 2 -336746 +336119 2 3 -117556 +117337 3 22 -27853 +27801 @@ -42552,17 +45897,17 @@ 1 2 -341659 +341024 2 3 -115438 +115223 3 22 -25057 +25010 @@ -42790,27 +46135,27 @@ 1 2 -100487 +100300 2 3 -72873 +72737 3 4 -42560 +42481 4 6 -20138 +20100 6 4208 -16566 +16535 @@ -42826,17 +46171,17 @@ 1 2 -191126 +190771 2 3 -55579 +55476 3 20 -5919 +5908 @@ -42937,19 +46282,19 @@ cil_attribute -328870 +328258 attributeid -328870 +328258 element -249029 +248565 constructor -3381 +3375 @@ -42963,7 +46308,7 @@ 1 2 -328870 +328258 @@ -42979,7 +46324,7 @@ 1 2 -328870 +328258 @@ -42995,17 +46340,17 @@ 1 2 -197690 +197322 2 3 -36758 +36690 3 92 -14580 +14553 @@ -43021,17 +46366,17 @@ 1 2 -213573 +213176 2 3 -31049 +30991 3 7 -4406 +4398 @@ -43047,12 +46392,12 @@ 1 2 -556 +555 2 3 -400 +399 3 @@ -43062,12 +46407,12 @@ 4 5 -317 +316 5 8 -307 +306 8 @@ -43077,7 +46422,7 @@ 11 19 -268 +267 19 @@ -43113,22 +46458,22 @@ 1 2 -600 +599 2 3 -385 +384 3 4 -283 +282 4 5 -317 +316 5 @@ -43138,7 +46483,7 @@ 7 10 -283 +282 10 @@ -43163,7 +46508,7 @@ 152 15028 -239 +238 @@ -43173,19 +46518,19 @@ cil_attribute_named_argument -3845 +10939 attribute_id -3352 +7978 param -141 +155 value -1093 +1095 @@ -43199,12 +46544,12 @@ 1 2 -2932 +5089 2 3 -346 +2815 3 @@ -43225,12 +46570,12 @@ 1 2 -2932 +6560 2 3 -405 +1402 3 @@ -43255,8 +46600,8 @@ 2 -3 -4 +4 +9 4 @@ -43308,6 +46653,11 @@ 308 9 + +725 +731 +9 + @@ -43322,12 +46672,12 @@ 1 2 -73 +77 2 3 -9 +19 3 @@ -43368,22 +46718,22 @@ 1 2 -722 +720 2 3 -239 +238 3 -6 -87 +5 +82 -6 -308 -43 +5 +866 +53 @@ -43399,11 +46749,11 @@ 1 2 -1063 +1066 2 -8 +10 29 @@ -43414,11 +46764,11 @@ cil_attribute_positional_argument -87287 +103139 attribute_id -84110 +97017 index @@ -43426,7 +46776,7 @@ value -15004 +17261 @@ -43440,12 +46790,12 @@ 1 2 -81422 +92336 2 7 -2688 +4680 @@ -43461,12 +46811,12 @@ 1 2 -81431 +92346 2 7 -2678 +4670 @@ -43490,23 +46840,23 @@ 4 -26 -27 +117 +118 4 -36 -37 +141 +142 4 -551 -552 +961 +962 4 -17237 -17238 +19919 +19920 4 @@ -43521,8 +46871,8 @@ 12 -3 -4 +4 +5 4 @@ -43531,18 +46881,18 @@ 9 -10 -11 +25 +26 4 -321 -322 +433 +434 4 -2772 -2773 +3150 +3151 4 @@ -43559,22 +46909,22 @@ 1 2 -11647 +12298 2 3 -1864 +2527 3 -9 -1146 +6 +1446 -9 -5463 -346 +6 +5556 +988 @@ -43590,12 +46940,12 @@ 1 2 -14843 +16935 2 6 -161 +326 @@ -43605,19 +46955,19 @@ metadata_handle -6187593 +6174756 entity -5695873 +5684969 location -3420 +3414 handle -274530 +274019 @@ -43631,17 +46981,17 @@ 1 2 -5222365 +5213358 2 3 -464476 +462594 3 638 -9032 +9015 @@ -43657,12 +47007,12 @@ 1 2 -5454657 +5445218 2 59 -241216 +239750 @@ -43688,7 +47038,7 @@ 36 79 -268 +267 79 @@ -43702,28 +47052,28 @@ 200 -289 -263 - - -290 -404 +288 258 -407 -529 +288 +400 258 -531 -748 +403 +527 258 -749 +528 +744 +258 + + +747 1109 -258 +263 1116 @@ -43764,12 +47114,12 @@ 3 20 -283 +282 20 46 -268 +267 46 @@ -43835,62 +47185,62 @@ 1 2 -18962 +18927 2 3 -45088 +45004 3 5 -23949 +23904 5 6 -17537 +17504 6 7 -30180 +30124 7 9 -19001 +18966 9 11 -22119 +22078 11 13 -21065 +21026 13 21 -21494 +21454 21 39 -21158 +21118 39 83 -20601 +20563 83 1061 -13370 +13345 @@ -43906,52 +47256,52 @@ 1 2 -62996 +62879 2 3 -21124 +21084 3 4 -47054 +46967 4 5 -18962 +18927 5 6 -19425 +19389 6 7 -22095 +22054 7 11 -23324 +23281 11 19 -22026 +21985 19 41 -20884 +20846 41 702 -16634 +16603 diff --git a/csharp/ql/test/library-tests/arguments/PrintAst.expected b/csharp/ql/test/library-tests/arguments/PrintAst.expected index 21e925fbd68..fa42026085d 100644 --- a/csharp/ql/test/library-tests/arguments/PrintAst.expected +++ b/csharp/ql/test/library-tests/arguments/PrintAst.expected @@ -240,7 +240,7 @@ arguments.cs: # 72| 0: [TypeMention] Attribute # 74| 4: [Field] x # 74| -1: [TypeMention] int -# 75| 5: [IndexerProperty] y +# 75| 5: [Property] y # 75| -1: [TypeMention] string # 75| 3: [Getter] get_y # 75| 4: [Setter] set_y diff --git a/csharp/ql/test/library-tests/arguments/argumentType.expected b/csharp/ql/test/library-tests/arguments/argumentType.expected index 39697e63729..e2cd7fc4a51 100644 --- a/csharp/ql/test/library-tests/arguments/argumentType.expected +++ b/csharp/ql/test/library-tests/arguments/argumentType.expected @@ -22,3 +22,15 @@ | arguments.cs:40:41:40:41 | 0 | 0 | | arguments.cs:45:12:45:32 | array creation of type Object[] | 0 | | arguments.cs:45:35:45:38 | null | 0 | +| arguments.cs:55:21:55:21 | 1 | 0 | +| arguments.cs:55:24:55:24 | 2 | 0 | +| arguments.cs:56:21:56:21 | 3 | 0 | +| arguments.cs:56:24:56:24 | 4 | 0 | +| arguments.cs:59:14:59:14 | 8 | 0 | +| arguments.cs:59:17:59:17 | 9 | 0 | +| arguments.cs:60:14:60:15 | 10 | 0 | +| arguments.cs:60:14:60:15 | 10 | 0 | +| arguments.cs:60:18:60:19 | 11 | 0 | +| arguments.cs:60:18:60:19 | 11 | 0 | +| arguments.cs:62:21:62:22 | 15 | 0 | +| arguments.cs:62:25:62:26 | 16 | 0 | diff --git a/csharp/ql/test/library-tests/assemblies/compilation.expected b/csharp/ql/test/library-tests/assemblies/compilation.expected new file mode 100644 index 00000000000..5075507382c --- /dev/null +++ b/csharp/ql/test/library-tests/assemblies/compilation.expected @@ -0,0 +1,9 @@ +| Assembly1, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null | no compilation | +| Locations, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null | has compilation | +| System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 | no compilation | +| System.Console, Version=4.1.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a | no compilation | +| System.Core, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 | no compilation | +| System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e | no compilation | +| System.Runtime, Version=4.2.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a | no compilation | +| System.Runtime.Extensions, Version=4.2.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a | no compilation | +| mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 | no compilation | diff --git a/csharp/ql/test/library-tests/assemblies/compilation.ql b/csharp/ql/test/library-tests/assemblies/compilation.ql new file mode 100644 index 00000000000..6783c6eebca --- /dev/null +++ b/csharp/ql/test/library-tests/assemblies/compilation.ql @@ -0,0 +1,8 @@ +import csharp + +private string hasCompilation(Assembly a) { + if exists(a.getCompilation()) then result = "has compilation" else result = "no compilation" +} + +from Assembly a +select a.getFullName(), hasCompilation(a) diff --git a/csharp/ql/test/library-tests/attributes/AttributeArguments.expected b/csharp/ql/test/library-tests/attributes/AttributeArguments.expected index d8234457cb1..22bd3b71cda 100644 --- a/csharp/ql/test/library-tests/attributes/AttributeArguments.expected +++ b/csharp/ql/test/library-tests/attributes/AttributeArguments.expected @@ -47,18 +47,23 @@ arguments | attributes.cs:57:6:57:16 | [My(...)] | 0 | attributes.cs:57:18:57:21 | true | | attributes.cs:57:6:57:16 | [My(...)] | 1 | attributes.cs:57:28:57:29 | "" | | attributes.cs:57:6:57:16 | [My(...)] | 2 | attributes.cs:57:36:57:36 | 0 | -| attributes.cs:76:2:76:5 | [Args(...)] | 0 | attributes.cs:76:7:76:8 | 42 | -| attributes.cs:76:2:76:5 | [Args(...)] | 1 | attributes.cs:76:11:76:14 | null | -| attributes.cs:76:2:76:5 | [Args(...)] | 2 | attributes.cs:76:17:76:25 | typeof(...) | -| attributes.cs:76:2:76:5 | [Args(...)] | 3 | attributes.cs:76:28:76:30 | access to constant A | -| attributes.cs:76:2:76:5 | [Args(...)] | 4 | attributes.cs:76:33:76:53 | array creation of type Int32[] | -| attributes.cs:76:2:76:5 | [Args(...)] | 5 | attributes.cs:76:63:76:93 | array creation of type Object[] | -| attributes.cs:79:6:79:9 | [Args(...)] | 0 | attributes.cs:79:11:79:16 | ... + ... | -| attributes.cs:79:6:79:9 | [Args(...)] | 1 | attributes.cs:79:19:79:39 | array creation of type Int32[] | -| attributes.cs:79:6:79:9 | [Args(...)] | 2 | attributes.cs:79:42:79:45 | null | -| attributes.cs:79:6:79:9 | [Args(...)] | 3 | attributes.cs:79:48:79:52 | (...) ... | -| attributes.cs:79:6:79:9 | [Args(...)] | 4 | attributes.cs:79:55:79:58 | null | -| attributes.cs:79:6:79:9 | [Args(...)] | 5 | attributes.cs:79:68:79:98 | array creation of type Object[] | +| attributes.cs:58:6:58:8 | [My2(...)] | 0 | attributes.cs:58:28:58:32 | false | +| attributes.cs:58:6:58:8 | [My2(...)] | 1 | attributes.cs:58:13:58:16 | true | +| attributes.cs:58:6:58:8 | [My2(...)] | 2 | attributes.cs:58:6:58:8 | 12 | +| attributes.cs:58:6:58:8 | [My2(...)] | 3 | attributes.cs:58:22:58:22 | 1 | +| attributes.cs:58:6:58:8 | [My2(...)] | 4 | attributes.cs:58:39:58:40 | 42 | +| attributes.cs:77:2:77:5 | [Args(...)] | 0 | attributes.cs:77:7:77:8 | 42 | +| attributes.cs:77:2:77:5 | [Args(...)] | 1 | attributes.cs:77:11:77:14 | null | +| attributes.cs:77:2:77:5 | [Args(...)] | 2 | attributes.cs:77:17:77:25 | typeof(...) | +| attributes.cs:77:2:77:5 | [Args(...)] | 3 | attributes.cs:77:28:77:30 | access to constant A | +| attributes.cs:77:2:77:5 | [Args(...)] | 4 | attributes.cs:77:33:77:53 | array creation of type Int32[] | +| attributes.cs:77:2:77:5 | [Args(...)] | 5 | attributes.cs:77:63:77:93 | array creation of type Object[] | +| attributes.cs:80:6:80:9 | [Args(...)] | 0 | attributes.cs:80:11:80:16 | ... + ... | +| attributes.cs:80:6:80:9 | [Args(...)] | 1 | attributes.cs:80:19:80:39 | array creation of type Int32[] | +| attributes.cs:80:6:80:9 | [Args(...)] | 2 | attributes.cs:80:42:80:45 | null | +| attributes.cs:80:6:80:9 | [Args(...)] | 3 | attributes.cs:80:48:80:52 | (...) ... | +| attributes.cs:80:6:80:9 | [Args(...)] | 4 | attributes.cs:80:55:80:58 | null | +| attributes.cs:80:6:80:9 | [Args(...)] | 5 | attributes.cs:80:68:80:98 | array creation of type Object[] | constructorArguments | Assembly1.dll:0:0:0:0 | [Custom(...)] | 0 | Assembly1.dll:0:0:0:0 | 1 | | Assembly1.dll:0:0:0:0 | [Custom(...)] | 0 | Assembly1.dll:0:0:0:0 | 3 | @@ -101,16 +106,20 @@ constructorArguments | attributes.cs:46:6:46:16 | [Conditional(...)] | 0 | attributes.cs:46:18:46:25 | "DEBUG2" | | attributes.cs:54:6:54:16 | [My(...)] | 0 | attributes.cs:54:18:54:22 | false | | attributes.cs:57:6:57:16 | [My(...)] | 0 | attributes.cs:57:18:57:21 | true | -| attributes.cs:76:2:76:5 | [Args(...)] | 0 | attributes.cs:76:7:76:8 | 42 | -| attributes.cs:76:2:76:5 | [Args(...)] | 1 | attributes.cs:76:11:76:14 | null | -| attributes.cs:76:2:76:5 | [Args(...)] | 2 | attributes.cs:76:17:76:25 | typeof(...) | -| attributes.cs:76:2:76:5 | [Args(...)] | 3 | attributes.cs:76:28:76:30 | access to constant A | -| attributes.cs:76:2:76:5 | [Args(...)] | 4 | attributes.cs:76:33:76:53 | array creation of type Int32[] | -| attributes.cs:79:6:79:9 | [Args(...)] | 0 | attributes.cs:79:11:79:16 | ... + ... | -| attributes.cs:79:6:79:9 | [Args(...)] | 1 | attributes.cs:79:19:79:39 | array creation of type Int32[] | -| attributes.cs:79:6:79:9 | [Args(...)] | 2 | attributes.cs:79:42:79:45 | null | -| attributes.cs:79:6:79:9 | [Args(...)] | 3 | attributes.cs:79:48:79:52 | (...) ... | -| attributes.cs:79:6:79:9 | [Args(...)] | 4 | attributes.cs:79:55:79:58 | null | +| attributes.cs:58:6:58:8 | [My2(...)] | 0 | attributes.cs:58:28:58:32 | false | +| attributes.cs:58:6:58:8 | [My2(...)] | 1 | attributes.cs:58:13:58:16 | true | +| attributes.cs:58:6:58:8 | [My2(...)] | 2 | attributes.cs:58:6:58:8 | 12 | +| attributes.cs:58:6:58:8 | [My2(...)] | 3 | attributes.cs:58:22:58:22 | 1 | +| attributes.cs:77:2:77:5 | [Args(...)] | 0 | attributes.cs:77:7:77:8 | 42 | +| attributes.cs:77:2:77:5 | [Args(...)] | 1 | attributes.cs:77:11:77:14 | null | +| attributes.cs:77:2:77:5 | [Args(...)] | 2 | attributes.cs:77:17:77:25 | typeof(...) | +| attributes.cs:77:2:77:5 | [Args(...)] | 3 | attributes.cs:77:28:77:30 | access to constant A | +| attributes.cs:77:2:77:5 | [Args(...)] | 4 | attributes.cs:77:33:77:53 | array creation of type Int32[] | +| attributes.cs:80:6:80:9 | [Args(...)] | 0 | attributes.cs:80:11:80:16 | ... + ... | +| attributes.cs:80:6:80:9 | [Args(...)] | 1 | attributes.cs:80:19:80:39 | array creation of type Int32[] | +| attributes.cs:80:6:80:9 | [Args(...)] | 2 | attributes.cs:80:42:80:45 | null | +| attributes.cs:80:6:80:9 | [Args(...)] | 3 | attributes.cs:80:48:80:52 | (...) ... | +| attributes.cs:80:6:80:9 | [Args(...)] | 4 | attributes.cs:80:55:80:58 | null | namedArguments | Assembly1.dll:0:0:0:0 | [Custom(...)] | Prop2 | Assembly1.dll:0:0:0:0 | array creation of type Object[] | | Assembly1.dll:0:0:0:0 | [Custom(...)] | Prop2 | Assembly1.dll:0:0:0:0 | array creation of type Object[] | @@ -119,5 +128,6 @@ namedArguments | attributes.cs:41:10:41:13 | [Args(...)] | Prop | attributes.cs:41:90:41:120 | array creation of type Object[] | | attributes.cs:57:6:57:16 | [My(...)] | x | attributes.cs:57:36:57:36 | 0 | | attributes.cs:57:6:57:16 | [My(...)] | y | attributes.cs:57:28:57:29 | "" | -| attributes.cs:76:2:76:5 | [Args(...)] | Prop | attributes.cs:76:63:76:93 | array creation of type Object[] | -| attributes.cs:79:6:79:9 | [Args(...)] | Prop | attributes.cs:79:68:79:98 | array creation of type Object[] | +| attributes.cs:58:6:58:8 | [My2(...)] | X | attributes.cs:58:39:58:40 | 42 | +| attributes.cs:77:2:77:5 | [Args(...)] | Prop | attributes.cs:77:63:77:93 | array creation of type Object[] | +| attributes.cs:80:6:80:9 | [Args(...)] | Prop | attributes.cs:80:68:80:98 | array creation of type Object[] | diff --git a/csharp/ql/test/library-tests/attributes/AttributeElements.expected b/csharp/ql/test/library-tests/attributes/AttributeElements.expected index 47fe8a4cef7..b9e12f35bcf 100644 --- a/csharp/ql/test/library-tests/attributes/AttributeElements.expected +++ b/csharp/ql/test/library-tests/attributes/AttributeElements.expected @@ -13,9 +13,10 @@ | attributes.cs:47:17:47:19 | foo | attributes.cs:46:6:46:16 | [Conditional(...)] | System.Diagnostics.ConditionalAttribute | | attributes.cs:52:23:52:23 | x | attributes.cs:52:14:52:16 | [Foo(...)] | Foo | | attributes.cs:55:10:55:11 | M1 | attributes.cs:54:6:54:16 | [My(...)] | MyAttribute | -| attributes.cs:58:10:58:11 | M2 | attributes.cs:57:6:57:16 | [My(...)] | MyAttribute | -| attributes.cs:77:14:77:14 | X | attributes.cs:76:2:76:5 | [Args(...)] | ArgsAttribute | -| attributes.cs:81:9:81:18 | SomeMethod | attributes.cs:79:6:79:9 | [Args(...)] | ArgsAttribute | +| attributes.cs:59:10:59:11 | M2 | attributes.cs:57:6:57:16 | [My(...)] | MyAttribute | +| attributes.cs:59:10:59:11 | M2 | attributes.cs:58:6:58:8 | [My2(...)] | My2Attribute | +| attributes.cs:78:14:78:14 | X | attributes.cs:77:2:77:5 | [Args(...)] | ArgsAttribute | +| attributes.cs:82:9:82:18 | SomeMethod | attributes.cs:80:6:80:9 | [Args(...)] | ArgsAttribute | | attributes.dll:0:0:0:0 | attributes, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null | attributes.cs:10:12:10:24 | [AssemblyTitle(...)] | System.Reflection.AssemblyTitleAttribute | | attributes.dll:0:0:0:0 | attributes, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null | attributes.cs:11:12:11:30 | [AssemblyDescription(...)] | System.Reflection.AssemblyDescriptionAttribute | | attributes.dll:0:0:0:0 | attributes, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null | attributes.cs:12:12:12:32 | [AssemblyConfiguration(...)] | System.Reflection.AssemblyConfigurationAttribute | diff --git a/csharp/ql/test/library-tests/attributes/PrintAst.expected b/csharp/ql/test/library-tests/attributes/PrintAst.expected index e42d90a89ea..5876e9521e9 100644 --- a/csharp/ql/test/library-tests/attributes/PrintAst.expected +++ b/csharp/ql/test/library-tests/attributes/PrintAst.expected @@ -130,118 +130,146 @@ attributes.cs: # 54| -1: [TypeMention] MyAttribute # 54| 0: [BoolLiteral] false # 55| 4: [BlockStmt] {...} -# 58| 7: [Method] M2 -# 58| -1: [TypeMention] Void +# 59| 7: [Method] M2 +# 59| -1: [TypeMention] Void #-----| 0: (Attributes) # 57| 1: [Attribute] [My(...)] # 57| -1: [TypeMention] MyAttribute # 57| 0: [BoolLiteral] true # 57| 1: [StringLiteral] "" # 57| 2: [IntLiteral] 0 -# 58| 4: [BlockStmt] {...} -# 61| [Class] MyAttribute +# 58| 2: [Attribute] [My2(...)] +# 58| -1: [TypeMention] My2Attribute +# 58| 0: [BoolLiteral] false +# 58| 1: [BoolLiteral] true +# 58| 3: [IntLiteral] 1 +# 58| 4: [IntLiteral] 42 +# 59| 4: [BlockStmt] {...} +# 62| [Class] MyAttribute #-----| 3: (Base types) -# 61| 0: [TypeMention] Attribute -# 63| 4: [Field] x -# 63| -1: [TypeMention] int -# 64| 5: [IndexerProperty] y -# 64| -1: [TypeMention] string -# 64| 3: [Getter] get_y -# 64| 4: [Setter] set_y +# 62| 0: [TypeMention] Attribute +# 64| 4: [Field] x +# 64| -1: [TypeMention] int +# 65| 5: [Property] y +# 65| -1: [TypeMention] string +# 65| 3: [Getter] get_y +# 65| 4: [Setter] set_y #-----| 2: (Parameters) -# 64| 0: [Parameter] value -# 65| 6: [InstanceConstructor] MyAttribute +# 65| 0: [Parameter] value +# 66| 6: [InstanceConstructor] MyAttribute #-----| 2: (Parameters) -# 65| 0: [Parameter] b -# 65| -1: [TypeMention] bool -# 65| 4: [BlockStmt] {...} -# 68| [Enum] E -# 68| 5: [Field] A -# 68| 1: [AssignExpr] ... = ... -# 68| 0: [MemberConstantAccess] access to constant A -# 68| 1: [IntLiteral] 42 -# 70| [Class] ArgsAttribute +# 66| 0: [Parameter] b +# 66| -1: [TypeMention] bool +# 66| 4: [BlockStmt] {...} +# 69| [Enum] E +# 69| 5: [Field] A +# 69| 1: [AssignExpr] ... = ... +# 69| 0: [MemberConstantAccess] access to constant A +# 69| 1: [IntLiteral] 42 +# 71| [Class] ArgsAttribute #-----| 3: (Base types) -# 70| 0: [TypeMention] Attribute -# 72| 4: [Property] Prop -# 72| -1: [TypeMention] Object[] -# 72| 1: [TypeMention] object -# 72| 3: [Getter] get_Prop -# 72| 4: [Setter] set_Prop +# 71| 0: [TypeMention] Attribute +# 73| 4: [Property] Prop +# 73| -1: [TypeMention] Object[] +# 73| 1: [TypeMention] object +# 73| 3: [Getter] get_Prop +# 73| 4: [Setter] set_Prop #-----| 2: (Parameters) -# 72| 0: [Parameter] value -# 73| 5: [InstanceConstructor] ArgsAttribute +# 73| 0: [Parameter] value +# 74| 5: [InstanceConstructor] ArgsAttribute #-----| 2: (Parameters) -# 73| 0: [Parameter] i -# 73| -1: [TypeMention] int -# 73| 1: [Parameter] o -# 73| -1: [TypeMention] object -# 73| 2: [Parameter] t -# 73| -1: [TypeMention] Type -# 73| 3: [Parameter] e -# 73| -1: [TypeMention] E -# 73| 4: [Parameter] arr -# 73| -1: [TypeMention] Int32[] -# 73| 1: [TypeMention] int -# 73| 4: [BlockStmt] {...} -# 77| [Class] X +# 74| 0: [Parameter] i +# 74| -1: [TypeMention] int +# 74| 1: [Parameter] o +# 74| -1: [TypeMention] object +# 74| 2: [Parameter] t +# 74| -1: [TypeMention] Type +# 74| 3: [Parameter] e +# 74| -1: [TypeMention] E +# 74| 4: [Parameter] arr +# 74| -1: [TypeMention] Int32[] +# 74| 1: [TypeMention] int +# 74| 4: [BlockStmt] {...} +# 78| [Class] X #-----| 0: (Attributes) -# 76| 1: [Attribute] [Args(...)] -# 76| -1: [TypeMention] ArgsAttribute -# 76| 0: [IntLiteral] 42 -# 76| 1: [NullLiteral] null -# 76| 2: [TypeofExpr] typeof(...) -# 76| 0: [TypeAccess] access to type X -# 76| 0: [TypeMention] X -# 76| 3: [MemberConstantAccess] access to constant A -# 76| -1: [TypeAccess] access to type E -# 76| 0: [TypeMention] E -# 76| 4: [ArrayCreation] array creation of type Int32[] -# 76| -2: [TypeMention] Int32[] -# 76| 1: [TypeMention] int -# 76| -1: [ArrayInitializer] { ..., ... } -# 76| 0: [IntLiteral] 1 -# 76| 1: [IntLiteral] 2 -# 76| 2: [IntLiteral] 3 -# 76| 5: [ArrayCreation] array creation of type Object[] -# 76| -2: [TypeMention] Object[] -# 76| 1: [TypeMention] object -# 76| -1: [ArrayInitializer] { ..., ... } -# 76| 0: [CastExpr] (...) ... -# 76| 1: [IntLiteral] 1 -# 76| 1: [TypeofExpr] typeof(...) -# 76| 0: [TypeAccess] access to type Int32 -# 76| 0: [TypeMention] int -# 81| 5: [Method] SomeMethod -# 81| -1: [TypeMention] int +# 77| 1: [Attribute] [Args(...)] +# 77| -1: [TypeMention] ArgsAttribute +# 77| 0: [IntLiteral] 42 +# 77| 1: [NullLiteral] null +# 77| 2: [TypeofExpr] typeof(...) +# 77| 0: [TypeAccess] access to type X +# 77| 0: [TypeMention] X +# 77| 3: [MemberConstantAccess] access to constant A +# 77| -1: [TypeAccess] access to type E +# 77| 0: [TypeMention] E +# 77| 4: [ArrayCreation] array creation of type Int32[] +# 77| -2: [TypeMention] Int32[] +# 77| 1: [TypeMention] int +# 77| -1: [ArrayInitializer] { ..., ... } +# 77| 0: [IntLiteral] 1 +# 77| 1: [IntLiteral] 2 +# 77| 2: [IntLiteral] 3 +# 77| 5: [ArrayCreation] array creation of type Object[] +# 77| -2: [TypeMention] Object[] +# 77| 1: [TypeMention] object +# 77| -1: [ArrayInitializer] { ..., ... } +# 77| 0: [CastExpr] (...) ... +# 77| 1: [IntLiteral] 1 +# 77| 1: [TypeofExpr] typeof(...) +# 77| 0: [TypeAccess] access to type Int32 +# 77| 0: [TypeMention] int +# 82| 5: [Method] SomeMethod +# 82| -1: [TypeMention] int #-----| 0: (Attributes) -# 79| 1: [Attribute] [Args(...)] -# 79| -1: [TypeMention] ArgsAttribute -# 79| 0: [AddExpr] ... + ... -# 79| 0: [IntLiteral] 42 -# 79| 1: [IntLiteral] 0 -# 79| 1: [ArrayCreation] array creation of type Int32[] -# 79| -2: [TypeMention] Int32[] -# 79| 1: [TypeMention] int -# 79| -1: [ArrayInitializer] { ..., ... } -# 79| 0: [IntLiteral] 1 -# 79| 1: [IntLiteral] 2 -# 79| 2: [IntLiteral] 3 -# 79| 2: [NullLiteral] null -# 79| 3: [CastExpr] (...) ... -# 79| 0: [TypeAccess] access to type E -# 79| 0: [TypeMention] E -# 79| 1: [IntLiteral] 12 -# 79| 4: [NullLiteral] null -# 79| 5: [ArrayCreation] array creation of type Object[] -# 79| -2: [TypeMention] Object[] -# 79| 1: [TypeMention] object -# 79| -1: [ArrayInitializer] { ..., ... } -# 79| 0: [CastExpr] (...) ... -# 79| 1: [IntLiteral] 1 -# 79| 1: [TypeofExpr] typeof(...) -# 79| 0: [TypeAccess] access to type Int32 -# 79| 0: [TypeMention] int -# 81| 4: [BlockStmt] {...} -# 81| 0: [ReturnStmt] return ...; -# 81| 0: [IntLiteral] 1 +# 80| 1: [Attribute] [Args(...)] +# 80| -1: [TypeMention] ArgsAttribute +# 80| 0: [AddExpr] ... + ... +# 80| 0: [IntLiteral] 42 +# 80| 1: [IntLiteral] 0 +# 80| 1: [ArrayCreation] array creation of type Int32[] +# 80| -2: [TypeMention] Int32[] +# 80| 1: [TypeMention] int +# 80| -1: [ArrayInitializer] { ..., ... } +# 80| 0: [IntLiteral] 1 +# 80| 1: [IntLiteral] 2 +# 80| 2: [IntLiteral] 3 +# 80| 2: [NullLiteral] null +# 80| 3: [CastExpr] (...) ... +# 80| 0: [TypeAccess] access to type E +# 80| 0: [TypeMention] E +# 80| 1: [IntLiteral] 12 +# 80| 4: [NullLiteral] null +# 80| 5: [ArrayCreation] array creation of type Object[] +# 80| -2: [TypeMention] Object[] +# 80| 1: [TypeMention] object +# 80| -1: [ArrayInitializer] { ..., ... } +# 80| 0: [CastExpr] (...) ... +# 80| 1: [IntLiteral] 1 +# 80| 1: [TypeofExpr] typeof(...) +# 80| 0: [TypeAccess] access to type Int32 +# 80| 0: [TypeMention] int +# 82| 4: [BlockStmt] {...} +# 82| 0: [ReturnStmt] return ...; +# 82| 0: [IntLiteral] 1 +# 85| [Class] My2Attribute +#-----| 3: (Base types) +# 85| 0: [TypeMention] Attribute +# 87| 4: [Property] X +# 87| -1: [TypeMention] int +# 87| 3: [Getter] get_X +# 87| 4: [Setter] set_X +#-----| 2: (Parameters) +# 87| 0: [Parameter] value +# 88| 5: [InstanceConstructor] My2Attribute +#-----| 2: (Parameters) +# 88| 0: [Parameter] a +# 88| -1: [TypeMention] bool +# 88| 1: [Parameter] b +# 88| -1: [TypeMention] bool +# 88| 2: [Parameter] i +# 88| -1: [TypeMention] int +# 88| 1: [IntLiteral] 12 +# 88| 3: [Parameter] j +# 88| -1: [TypeMention] int +# 88| 1: [IntLiteral] 13 +# 88| 4: [BlockStmt] {...} diff --git a/csharp/ql/test/library-tests/attributes/attributes.cs b/csharp/ql/test/library-tests/attributes/attributes.cs index 9fce3449109..7f03eb9c941 100644 --- a/csharp/ql/test/library-tests/attributes/attributes.cs +++ b/csharp/ql/test/library-tests/attributes/attributes.cs @@ -55,6 +55,7 @@ class Bar void M1() { } [MyAttribute(true, y = "", x = 0)] + [My2(b: true, j: 1, a: false, X = 42)] void M2() { } } @@ -80,3 +81,9 @@ public class X [return: Args(42 + 0, new int[] { 1, 2, 3 }, null, (E)12, null, Prop = new object[] { 1, typeof(int) })] int SomeMethod() { return 1; } } + +class My2Attribute : Attribute +{ + public int X { get; set; } + public My2Attribute(bool a, bool b, int i = 12, int j = 13) { } +} \ No newline at end of file diff --git a/csharp/ql/test/library-tests/cil/attributes/Test.cs b/csharp/ql/test/library-tests/cil/attributes/Test.cs new file mode 100644 index 00000000000..c72cfe0b0b3 --- /dev/null +++ b/csharp/ql/test/library-tests/cil/attributes/Test.cs @@ -0,0 +1,7 @@ +// semmle-extractor-options: --cil + +using System; + +class Test +{ +} \ No newline at end of file diff --git a/csharp/ql/test/library-tests/cil/attributes/attribute.expected b/csharp/ql/test/library-tests/cil/attributes/attribute.expected new file mode 100644 index 00000000000..6ec0b072ec8 --- /dev/null +++ b/csharp/ql/test/library-tests/cil/attributes/attribute.expected @@ -0,0 +1,2799 @@ +attrNoArg +| !0 System.ReadOnlySpan`1.Enumerator.Current | [IsReadOnlyAttribute(...)] | +| !0 System.ReadOnlySpan`1.Item | [IsReadOnlyAttribute(...)] | +| <>f__AnonymousType0`1 | [CompilerGeneratedAttribute(...)] | +| | [CompilerGeneratedAttribute(...)] | +| Internal.Runtime.InteropServices.ComponentActivator.<>c__DisplayClass6_0 | [CompilerGeneratedAttribute(...)] | +| Interop.Sys.<>c__DisplayClass39_0 | [CompilerGeneratedAttribute(...)] | +| Interop.Sys.FileStatusFlags | [FlagsAttribute(...)] | +| Interop.Sys.OpenFlags | [FlagsAttribute(...)] | +| Interop.Sys.PollEvents | [FlagsAttribute(...)] | +| InteropErrorExtensions | [ExtensionAttribute(...)] | +| Microsoft.CodeAnalysis.EmbeddedAttribute | [CompilerGeneratedAttribute(...)] | +| Microsoft.CodeAnalysis.EmbeddedAttribute | [EmbeddedAttribute(...)] | +| Microsoft.Reflection.ReflectionExtensions | [ExtensionAttribute(...)] | +| Microsoft.Win32.SafeHandles.SafeFileHandle.<>c | [CompilerGeneratedAttribute(...)] | +| Microsoft.Win32.SafeHandles.SafeFileHandle.k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.AppContext.FirstChanceException | [CompilerGeneratedAttribute(...)] | +| System.AppContext.ProcessExit | [CompilerGeneratedAttribute(...)] | +| System.AppContext.UnhandledException | [CompilerGeneratedAttribute(...)] | +| System.AppDomain.DomainUnload | [CompilerGeneratedAttribute(...)] | +| System.AppDomain.ReflectionOnlyAssemblyResolve | [CompilerGeneratedAttribute(...)] | +| System.ArgIterator | [IsByRefLikeAttribute(...)] | +| System.Array.SorterGenericArray | [IsReadOnlyAttribute(...)] | +| System.Array.SorterObjectArray | [IsReadOnlyAttribute(...)] | +| System.ArraySegment`1 | [IsReadOnlyAttribute(...)] | +| System.ArraySegment`1.k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.AssemblyLoadEventArgs.k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.AttributeTargets | [FlagsAttribute(...)] | +| System.Base64FormattingOptions | [FlagsAttribute(...)] | +| System.BitConverter.<>c | [CompilerGeneratedAttribute(...)] | +| System.BitConverter.IsLittleEndian | [IntrinsicAttribute(...)] | +| System.Buffers.StandardFormat | [IsReadOnlyAttribute(...)] | +| System.Buffers.Text.Utf8Parser.ParseNumberOptions | [FlagsAttribute(...)] | +| System.Buffers.TlsOverPerCoreLockedStacksArrayPool`1.t_tlsBuckets | [ThreadStaticAttribute(...)] | +| System.ByReference`1 | [IsByRefLikeAttribute(...)] | +| System.ByReference`1 | [IsReadOnlyAttribute(...)] | +| System.ByReference`1 | [NonVersionableAttribute(...)] | +| System.Collections.Concurrent.ConcurrentQueueSegment`1.Slot.Item | [AllowNullAttribute(...)] | +| System.Collections.Concurrent.ConcurrentQueueSegment`1.Slot.Item | [MaybeNullAttribute(...)] | +| System.Collections.Concurrent.ConcurrentQueue`1.d__26 | [CompilerGeneratedAttribute(...)] | +| System.Collections.Generic.Comparer`1.k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Collections.Generic.Dictionary`2.KeyCollection.Enumerator._currentKey | [AllowNullAttribute(...)] | +| System.Collections.Generic.Dictionary`2.KeyCollection.Enumerator._currentKey | [MaybeNullAttribute(...)] | +| System.Collections.Generic.Dictionary`2.ValueCollection.Enumerator._currentValue | [AllowNullAttribute(...)] | +| System.Collections.Generic.Dictionary`2.ValueCollection.Enumerator._currentValue | [MaybeNullAttribute(...)] | +| System.Collections.Generic.EqualityComparer`1.k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Collections.Generic.KeyValuePair`2 | [IsReadOnlyAttribute(...)] | +| System.Collections.Generic.List`1.Enumerator._current | [AllowNullAttribute(...)] | +| System.Collections.Generic.List`1.Enumerator._current | [MaybeNullAttribute(...)] | +| System.Collections.Generic.NonRandomizedStringEqualityComparer.k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Collections.Generic.ValueListBuilder`1 | [IsByRefLikeAttribute(...)] | +| System.CommonlyUsedGenericInstantiations.d__4`1 | [CompilerGeneratedAttribute(...)] | +| System.CommonlyUsedGenericInstantiations.d__5 | [CompilerGeneratedAttribute(...)] | +| System.CommonlyUsedGenericInstantiations.d__3`1 | [CompilerGeneratedAttribute(...)] | +| System.ComponentModel.EditorBrowsableAttribute.k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Console.<>c | [CompilerGeneratedAttribute(...)] | +| System.ConsoleCancelEventArgs.k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.ConsoleKeyInfo | [IsReadOnlyAttribute(...)] | +| System.ConsoleModifiers | [FlagsAttribute(...)] | +| System.ConsolePal.<>c | [CompilerGeneratedAttribute(...)] | +| System.ConsolePal.<>c__DisplayClass115_0 | [CompilerGeneratedAttribute(...)] | +| System.ConsolePal.ControlCHandlerRegistrar.<>c | [CompilerGeneratedAttribute(...)] | +| System.ConsolePal.TerminalFormatStrings.<>c | [CompilerGeneratedAttribute(...)] | +| System.Convert | [ExtensionAttribute(...)] | +| System.DTSubString | [IsByRefLikeAttribute(...)] | +| System.DateTime | [IsReadOnlyAttribute(...)] | +| System.DateTimeOffset | [IsReadOnlyAttribute(...)] | +| System.DateTimeResult | [IsByRefLikeAttribute(...)] | +| System.DefaultBinder.Primitives | [FlagsAttribute(...)] | +| System.Diagnostics.CodeAnalysis.DoesNotReturnIfAttribute.k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Diagnostics.CodeAnalysis.MaybeNullWhenAttribute.k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Diagnostics.CodeAnalysis.NotNullIfNotNullAttribute.k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Diagnostics.CodeAnalysis.NotNullWhenAttribute.k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Diagnostics.CodeAnalysis.SuppressMessageAttribute.k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Diagnostics.CodeAnalysis.SuppressMessageAttribute.k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Diagnostics.CodeAnalysis.SuppressMessageAttribute.k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Diagnostics.CodeAnalysis.SuppressMessageAttribute.k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Diagnostics.CodeAnalysis.SuppressMessageAttribute.k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Diagnostics.CodeAnalysis.SuppressMessageAttribute.k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Diagnostics.ConditionalAttribute.k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Diagnostics.Debug.t_indentLevel | [ThreadStaticAttribute(...)] | +| System.Diagnostics.DebuggableAttribute.k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Diagnostics.DebuggableAttribute.DebuggingModes | [FlagsAttribute(...)] | +| System.Diagnostics.DebuggerBrowsableAttribute.k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Diagnostics.DebuggerDisplayAttribute.k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Diagnostics.DebuggerDisplayAttribute.k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Diagnostics.DebuggerDisplayAttribute.k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Diagnostics.DebuggerDisplayAttribute.k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Diagnostics.DebuggerTypeProxyAttribute.k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Diagnostics.DebuggerTypeProxyAttribute.k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Diagnostics.DebuggerVisualizerAttribute.k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Diagnostics.DebuggerVisualizerAttribute.k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Diagnostics.DebuggerVisualizerAttribute.k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Diagnostics.DebuggerVisualizerAttribute.k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Diagnostics.StackFrameHelper.t_reentrancy | [ThreadStaticAttribute(...)] | +| System.Diagnostics.Tracing.CounterPayload | [EventDataAttribute(...)] | +| System.Diagnostics.Tracing.CounterPayload.k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Diagnostics.Tracing.CounterPayload.k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Diagnostics.Tracing.CounterPayload.k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Diagnostics.Tracing.CounterPayload.k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Diagnostics.Tracing.CounterPayload.k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Diagnostics.Tracing.CounterPayload.k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Diagnostics.Tracing.CounterPayload.k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Diagnostics.Tracing.CounterPayload.k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Diagnostics.Tracing.CounterPayload.k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Diagnostics.Tracing.CounterPayload.k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Diagnostics.Tracing.CounterPayload.k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Diagnostics.Tracing.CounterPayload.k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Diagnostics.Tracing.CounterPayload.d__51 | [CompilerGeneratedAttribute(...)] | +| System.Diagnostics.Tracing.CounterPayloadType | [EventDataAttribute(...)] | +| System.Diagnostics.Tracing.CounterPayloadType.k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Diagnostics.Tracing.DataCollector.ThreadInstance | [ThreadStaticAttribute(...)] | +| System.Diagnostics.Tracing.DiagnosticCounter.k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Diagnostics.Tracing.DiagnosticCounter.k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Diagnostics.Tracing.EventActivityOptions | [FlagsAttribute(...)] | +| System.Diagnostics.Tracing.EventAttribute.k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Diagnostics.Tracing.EventAttribute.k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Diagnostics.Tracing.EventAttribute.k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Diagnostics.Tracing.EventAttribute.k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Diagnostics.Tracing.EventAttribute.k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Diagnostics.Tracing.EventAttribute.k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Diagnostics.Tracing.EventAttribute.k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Diagnostics.Tracing.EventAttribute.k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Diagnostics.Tracing.EventAttribute.k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Diagnostics.Tracing.EventChannelAttribute.k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Diagnostics.Tracing.EventChannelAttribute.k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Diagnostics.Tracing.EventCommandEventArgs.k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Diagnostics.Tracing.EventCommandEventArgs.k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Diagnostics.Tracing.EventDataAttribute.k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Diagnostics.Tracing.EventDataAttribute.k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Diagnostics.Tracing.EventDataAttribute.k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Diagnostics.Tracing.EventFieldAttribute.k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Diagnostics.Tracing.EventFieldAttribute.k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Diagnostics.Tracing.EventFieldAttribute.k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Diagnostics.Tracing.EventFieldTags | [FlagsAttribute(...)] | +| System.Diagnostics.Tracing.EventKeywords | [FlagsAttribute(...)] | +| System.Diagnostics.Tracing.EventListener.<>c | [CompilerGeneratedAttribute(...)] | +| System.Diagnostics.Tracing.EventListener.EventWritten | [CompilerGeneratedAttribute(...)] | +| System.Diagnostics.Tracing.EventListener._EventSourceCreated | [CompilerGeneratedAttribute(...)] | +| System.Diagnostics.Tracing.EventManifestOptions | [FlagsAttribute(...)] | +| System.Diagnostics.Tracing.EventPayload.d__17 | [CompilerGeneratedAttribute(...)] | +| System.Diagnostics.Tracing.EventPipeController.k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Diagnostics.Tracing.EventPipeEventDispatcher.EventListenerSubscription.k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Diagnostics.Tracing.EventPipeEventDispatcher.EventListenerSubscription.k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Diagnostics.Tracing.EventProvider.<>c | [CompilerGeneratedAttribute(...)] | +| System.Diagnostics.Tracing.EventProvider.s_returnCode | [ThreadStaticAttribute(...)] | +| System.Diagnostics.Tracing.EventSource.m_EventSourceExceptionRecurenceCount | [ThreadStaticAttribute(...)] | +| System.Diagnostics.Tracing.EventSource.m_EventSourceInDecodeObject | [ThreadStaticAttribute(...)] | +| System.Diagnostics.Tracing.EventSourceAttribute.k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Diagnostics.Tracing.EventSourceAttribute.k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Diagnostics.Tracing.EventSourceAttribute.k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Diagnostics.Tracing.EventSourceCreatedEventArgs.k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Diagnostics.Tracing.EventSourceSettings | [FlagsAttribute(...)] | +| System.Diagnostics.Tracing.EventTags | [FlagsAttribute(...)] | +| System.Diagnostics.Tracing.EventWrittenEventArgs.k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Diagnostics.Tracing.EventWrittenEventArgs.k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Diagnostics.Tracing.EventWrittenEventArgs.k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Diagnostics.Tracing.EventWrittenEventArgs.k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Diagnostics.Tracing.IncrementingCounterPayload | [EventDataAttribute(...)] | +| System.Diagnostics.Tracing.IncrementingCounterPayload.k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Diagnostics.Tracing.IncrementingCounterPayload.k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Diagnostics.Tracing.IncrementingCounterPayload.k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Diagnostics.Tracing.IncrementingCounterPayload.k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Diagnostics.Tracing.IncrementingCounterPayload.k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Diagnostics.Tracing.IncrementingCounterPayload.k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Diagnostics.Tracing.IncrementingCounterPayload.k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Diagnostics.Tracing.IncrementingCounterPayload.k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Diagnostics.Tracing.IncrementingCounterPayload.k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Diagnostics.Tracing.IncrementingCounterPayload.d__39 | [CompilerGeneratedAttribute(...)] | +| System.Diagnostics.Tracing.IncrementingEventCounter.k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Diagnostics.Tracing.IncrementingEventCounterPayloadType | [EventDataAttribute(...)] | +| System.Diagnostics.Tracing.IncrementingEventCounterPayloadType.k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Diagnostics.Tracing.IncrementingPollingCounter.k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Diagnostics.Tracing.IncrementingPollingCounterPayloadType | [EventDataAttribute(...)] | +| System.Diagnostics.Tracing.IncrementingPollingCounterPayloadType.k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Diagnostics.Tracing.ManifestBuilder.<>c | [CompilerGeneratedAttribute(...)] | +| System.Diagnostics.Tracing.PollingPayloadType | [EventDataAttribute(...)] | +| System.Diagnostics.Tracing.PollingPayloadType.k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Diagnostics.Tracing.PropertyValue | [IsReadOnlyAttribute(...)] | +| System.Diagnostics.Tracing.PropertyValue.<>c | [CompilerGeneratedAttribute(...)] | +| System.Diagnostics.Tracing.PropertyValue.<>c__DisplayClass33_0 | [CompilerGeneratedAttribute(...)] | +| System.Diagnostics.Tracing.PropertyValue.ReferenceTypeHelper`1.<>c__DisplayClass0_0 | [CompilerGeneratedAttribute(...)] | +| System.Diagnostics.Tracing.PropertyValue.ReferenceTypeHelper`1.<>c__DisplayClass0_1 | [CompilerGeneratedAttribute(...)] | +| System.Diagnostics.Tracing.PropertyValue.ReferenceTypeHelper`1.<>c__DisplayClass0_2 | [CompilerGeneratedAttribute(...)] | +| System.Diagnostics.Tracing.PropertyValue.ReferenceTypeHelper`1.<>c__DisplayClass0_3 | [CompilerGeneratedAttribute(...)] | +| System.Diagnostics.Tracing.PropertyValue.ReferenceTypeHelper`1.<>c__DisplayClass0_4 | [CompilerGeneratedAttribute(...)] | +| System.Diagnostics.Tracing.PropertyValue.ReferenceTypeHelper`1.<>c__DisplayClass0_5 | [CompilerGeneratedAttribute(...)] | +| System.Diagnostics.Tracing.PropertyValue.ReferenceTypeHelper`1.<>c__DisplayClass0_6 | [CompilerGeneratedAttribute(...)] | +| System.Diagnostics.Tracing.PropertyValue.ReferenceTypeHelper`1.<>c__DisplayClass0_7 | [CompilerGeneratedAttribute(...)] | +| System.Diagnostics.Tracing.PropertyValue.ReferenceTypeHelper`1.<>c__DisplayClass0_8 | [CompilerGeneratedAttribute(...)] | +| System.Diagnostics.Tracing.PropertyValue.ReferenceTypeHelper`1.<>c__DisplayClass0_9 | [CompilerGeneratedAttribute(...)] | +| System.Diagnostics.Tracing.PropertyValue.ReferenceTypeHelper`1.<>c__DisplayClass0_10 | [CompilerGeneratedAttribute(...)] | +| System.Diagnostics.Tracing.PropertyValue.ReferenceTypeHelper`1.<>c__DisplayClass0_11 | [CompilerGeneratedAttribute(...)] | +| System.Diagnostics.Tracing.PropertyValue.ReferenceTypeHelper`1.<>c__DisplayClass0_12 | [CompilerGeneratedAttribute(...)] | +| System.Diagnostics.Tracing.PropertyValue.ReferenceTypeHelper`1.<>c__DisplayClass0_13 | [CompilerGeneratedAttribute(...)] | +| System.Diagnostics.Tracing.PropertyValue.ReferenceTypeHelper`1.<>c__DisplayClass0_14 | [CompilerGeneratedAttribute(...)] | +| System.Diagnostics.Tracing.PropertyValue.ReferenceTypeHelper`1.<>c__DisplayClass0_15 | [CompilerGeneratedAttribute(...)] | +| System.Diagnostics.Tracing.PropertyValue.ReferenceTypeHelper`1.<>c__DisplayClass0_16 | [CompilerGeneratedAttribute(...)] | +| System.Diagnostics.Tracing.PropertyValue.ReferenceTypeHelper`1.<>c__DisplayClass0_17 | [CompilerGeneratedAttribute(...)] | +| System.Diagnostics.Tracing.PropertyValue.ReferenceTypeHelper`1.<>c__DisplayClass0_18 | [CompilerGeneratedAttribute(...)] | +| System.Diagnostics.Tracing.PropertyValue.ReferenceTypeHelper`1.<>c__DisplayClass0_19 | [CompilerGeneratedAttribute(...)] | +| System.Diagnostics.Tracing.PropertyValue.ReferenceTypeHelper`1.<>c__DisplayClass0_20 | [CompilerGeneratedAttribute(...)] | +| System.Diagnostics.Tracing.RuntimeEventSource.<>c | [CompilerGeneratedAttribute(...)] | +| System.Diagnostics.Tracing.ScalarArrayTypeInfo.<>c | [CompilerGeneratedAttribute(...)] | +| System.Diagnostics.Tracing.ScalarTypeInfo.<>c | [CompilerGeneratedAttribute(...)] | +| System.Diagnostics.Tracing.TraceLoggingMetadataCollector.k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Diagnostics.Tracing.TraceLoggingTypeInfo.threadCache | [ThreadStaticAttribute(...)] | +| System.Diagnostics.Tracing.XplatEventLogger.<>c | [CompilerGeneratedAttribute(...)] | +| System.Environment.<>c | [CompilerGeneratedAttribute(...)] | +| System.Exception.DispatchState | [IsReadOnlyAttribute(...)] | +| System.GC.MemoryLoadChangeNotification | [IsReadOnlyAttribute(...)] | +| System.GC.MemoryLoadChangeNotification.k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.GC.MemoryLoadChangeNotification.k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.GC.MemoryLoadChangeNotification.k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.GCMemoryInfo | [IsReadOnlyAttribute(...)] | +| System.GCMemoryInfo.k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.GCMemoryInfo.k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.GCMemoryInfo.k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.GCMemoryInfo.k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.GCMemoryInfo.k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Globalization.CalendarData.<>c | [CompilerGeneratedAttribute(...)] | +| System.Globalization.CompareOptions | [FlagsAttribute(...)] | +| System.Globalization.CultureInfo.s_currentThreadCulture | [ThreadStaticAttribute(...)] | +| System.Globalization.CultureInfo.s_currentThreadUICulture | [ThreadStaticAttribute(...)] | +| System.Globalization.CultureTypes | [FlagsAttribute(...)] | +| System.Globalization.DateTimeFormatFlags | [FlagsAttribute(...)] | +| System.Globalization.DateTimeStyles | [FlagsAttribute(...)] | +| System.Globalization.DaylightTimeStruct | [IsReadOnlyAttribute(...)] | +| System.Globalization.GlobalizationExtensions | [ExtensionAttribute(...)] | +| System.Globalization.GlobalizationMode.k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Globalization.MonthNameStyles | [FlagsAttribute(...)] | +| System.Globalization.NumberStyles | [FlagsAttribute(...)] | +| System.Globalization.TextInfo.ToLowerConversion | [IsReadOnlyAttribute(...)] | +| System.Globalization.TextInfo.ToUpperConversion | [IsReadOnlyAttribute(...)] | +| System.Globalization.TimeSpanParse.StringParser | [IsByRefLikeAttribute(...)] | +| System.Globalization.TimeSpanParse.TimeSpanRawInfo | [IsByRefLikeAttribute(...)] | +| System.Globalization.TimeSpanParse.TimeSpanResult | [IsByRefLikeAttribute(...)] | +| System.Globalization.TimeSpanParse.TimeSpanStandardStyles | [FlagsAttribute(...)] | +| System.Globalization.TimeSpanParse.TimeSpanToken | [IsByRefLikeAttribute(...)] | +| System.Globalization.TimeSpanParse.TimeSpanTokenizer | [IsByRefLikeAttribute(...)] | +| System.Globalization.TimeSpanStyles | [FlagsAttribute(...)] | +| System.Guid | [NonVersionableAttribute(...)] | +| System.IO.FileAccess | [FlagsAttribute(...)] | +| System.IO.FileAttributes | [FlagsAttribute(...)] | +| System.IO.FileLoadException.k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.IO.FileLoadException.k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.IO.FileNotFoundException.k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.IO.FileNotFoundException.k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.IO.FileOptions | [FlagsAttribute(...)] | +| System.IO.FileShare | [FlagsAttribute(...)] | +| System.IO.FileStream.<>c | [CompilerGeneratedAttribute(...)] | +| System.IO.Path.<>c | [CompilerGeneratedAttribute(...)] | +| System.IO.Stream.<g__FinishReadAsync\|47_0>d | [CompilerGeneratedAttribute(...)] | +| System.IO.Stream.<>c | [CompilerGeneratedAttribute(...)] | +| System.IO.Stream.d__30 | [CompilerGeneratedAttribute(...)] | +| System.IO.Stream.d__60 | [CompilerGeneratedAttribute(...)] | +| System.IO.Stream.SynchronousAsyncResult.<>c | [CompilerGeneratedAttribute(...)] | +| System.IO.StreamReader.d__64 | [CompilerGeneratedAttribute(...)] | +| System.IO.StreamReader.d__67 | [CompilerGeneratedAttribute(...)] | +| System.IO.StreamReader.d__59 | [CompilerGeneratedAttribute(...)] | +| System.IO.StreamReader.d__61 | [CompilerGeneratedAttribute(...)] | +| System.IO.StreamWriter.d__33 | [CompilerGeneratedAttribute(...)] | +| System.IO.StreamWriter.d__74 | [CompilerGeneratedAttribute(...)] | +| System.IO.StreamWriter.d__61 | [CompilerGeneratedAttribute(...)] | +| System.IO.StreamWriter.d__63 | [CompilerGeneratedAttribute(...)] | +| System.IO.StreamWriter.d__66 | [CompilerGeneratedAttribute(...)] | +| System.IO.TextReader.<>c | [CompilerGeneratedAttribute(...)] | +| System.IO.TextReader.d__20 | [CompilerGeneratedAttribute(...)] | +| System.IO.TextReader.d__14 | [CompilerGeneratedAttribute(...)] | +| System.IO.TextWriter.<g__WriteAsyncCore\|60_0>d | [CompilerGeneratedAttribute(...)] | +| System.IO.TextWriter.<g__WriteLineAsyncCore\|66_0>d | [CompilerGeneratedAttribute(...)] | +| System.IO.TextWriter.<>c | [CompilerGeneratedAttribute(...)] | +| System.Index | [IsReadOnlyAttribute(...)] | +| System.IntPtr | [IsReadOnlyAttribute(...)] | +| System.IntPtr.Zero | [IntrinsicAttribute(...)] | +| System.LazyHelper.k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.LocalDataStoreSlot.k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Marvin.k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.MdUtf8String | [IsReadOnlyAttribute(...)] | +| System.MemoryExtensions | [ExtensionAttribute(...)] | +| System.Memory`1 | [IsReadOnlyAttribute(...)] | +| System.Nullable`1 | [NonVersionableAttribute(...)] | +| System.Number.BigInteger | [IsByRefLikeAttribute(...)] | +| System.Number.BigInteger.<_blocks>e__FixedBuffer | [CompilerGeneratedAttribute(...)] | +| System.Number.BigInteger.<_blocks>e__FixedBuffer | [UnsafeValueTypeAttribute(...)] | +| System.Number.DiyFp | [IsByRefLikeAttribute(...)] | +| System.Number.DiyFp | [IsReadOnlyAttribute(...)] | +| System.Number.FloatingPointInfo | [IsReadOnlyAttribute(...)] | +| System.Number.FloatingPointInfo.k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Number.FloatingPointInfo.k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Number.FloatingPointInfo.k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Number.FloatingPointInfo.k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Number.FloatingPointInfo.k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Number.FloatingPointInfo.k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Number.FloatingPointInfo.k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Number.FloatingPointInfo.k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Number.FloatingPointInfo.k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Number.FloatingPointInfo.k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Number.FloatingPointInfo.k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Number.NumberBuffer | [IsByRefLikeAttribute(...)] | +| System.Numerics.Vector | [IntrinsicAttribute(...)] | +| System.Numerics.Vector`1 | [IntrinsicAttribute(...)] | +| System.ParamsArray | [IsReadOnlyAttribute(...)] | +| System.ParseFlags | [FlagsAttribute(...)] | +| System.Progress`1.ProgressChanged | [CompilerGeneratedAttribute(...)] | +| System.Random.t_threadRandom | [ThreadStaticAttribute(...)] | +| System.Range | [IsReadOnlyAttribute(...)] | +| System.Range.k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Range.k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.ReadOnlyMemory`1 | [IsReadOnlyAttribute(...)] | +| System.ReadOnlySpan`1 | [IsByRefLikeAttribute(...)] | +| System.ReadOnlySpan`1 | [IsReadOnlyAttribute(...)] | +| System.ReadOnlySpan`1 | [NonVersionableAttribute(...)] | +| System.ReadOnlySpan`1.Enumerator | [IsByRefLikeAttribute(...)] | +| System.Reflection.AssemblyAlgorithmIdAttribute.k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Reflection.AssemblyCompanyAttribute.k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Reflection.AssemblyConfigurationAttribute.k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Reflection.AssemblyCopyrightAttribute.k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Reflection.AssemblyCultureAttribute.k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Reflection.AssemblyDefaultAliasAttribute.k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Reflection.AssemblyDelaySignAttribute.k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Reflection.AssemblyDescriptionAttribute.k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Reflection.AssemblyFileVersionAttribute.k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Reflection.AssemblyInformationalVersionAttribute.k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Reflection.AssemblyKeyFileAttribute.k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Reflection.AssemblyKeyNameAttribute.k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Reflection.AssemblyMetadataAttribute.k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Reflection.AssemblyMetadataAttribute.k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Reflection.AssemblyNameFlags | [FlagsAttribute(...)] | +| System.Reflection.AssemblyNameFormatter | [ExtensionAttribute(...)] | +| System.Reflection.AssemblyProductAttribute.k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Reflection.AssemblySignatureKeyAttribute.k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Reflection.AssemblySignatureKeyAttribute.k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Reflection.AssemblyTitleAttribute.k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Reflection.AssemblyTrademarkAttribute.<Trademark>k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Reflection.AssemblyVersionAttribute.<Version>k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Reflection.Associates.Attributes | [FlagsAttribute(...)] | +| System.Reflection.BindingFlags | [FlagsAttribute(...)] | +| System.Reflection.CallingConventions | [FlagsAttribute(...)] | +| System.Reflection.ConstArray | [IsReadOnlyAttribute(...)] | +| System.Reflection.CustomAttributeCtorParameter | [IsReadOnlyAttribute(...)] | +| System.Reflection.CustomAttributeEncodedArgument | [IsReadOnlyAttribute(...)] | +| System.Reflection.CustomAttributeExtensions | [ExtensionAttribute(...)] | +| System.Reflection.CustomAttributeNamedArgument | [IsReadOnlyAttribute(...)] | +| System.Reflection.CustomAttributeNamedParameter | [IsReadOnlyAttribute(...)] | +| System.Reflection.CustomAttributeType | [IsReadOnlyAttribute(...)] | +| System.Reflection.CustomAttributeTypedArgument | [IsReadOnlyAttribute(...)] | +| System.Reflection.DefaultMemberAttribute.<MemberName>k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Reflection.Emit.AssemblyBuilderAccess | [FlagsAttribute(...)] | +| System.Reflection.Emit.DynamicResolver.SecurityControlFlags | [FlagsAttribute(...)] | +| System.Reflection.Emit.EventToken.<Token>k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Reflection.Emit.ExceptionHandler | [IsReadOnlyAttribute(...)] | +| System.Reflection.Emit.FieldToken.<Token>k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Reflection.Emit.Label | [IsReadOnlyAttribute(...)] | +| System.Reflection.Emit.MethodToken.<Token>k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Reflection.Emit.OpCode | [IsReadOnlyAttribute(...)] | +| System.Reflection.Emit.ParameterToken.<Token>k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Reflection.Emit.PropertyToken.<Token>k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Reflection.Emit.SignatureToken.<Token>k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Reflection.Emit.StringToken.<Token>k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Reflection.Emit.TypeToken.<Token>k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Reflection.EventAttributes | [FlagsAttribute(...)] | +| System.Reflection.ExceptionHandlingClauseOptions | [FlagsAttribute(...)] | +| System.Reflection.FieldAttributes | [FlagsAttribute(...)] | +| System.Reflection.GenericParameterAttributes | [FlagsAttribute(...)] | +| System.Reflection.INVOCATION_FLAGS | [FlagsAttribute(...)] | +| System.Reflection.IntrospectionExtensions | [ExtensionAttribute(...)] | +| System.Reflection.ManifestResourceInfo.<FileName>k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Reflection.ManifestResourceInfo.<ReferencedAssembly>k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Reflection.ManifestResourceInfo.<ResourceLocation>k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Reflection.MdSigCallingConvention | [FlagsAttribute(...)] | +| System.Reflection.MemberTypes | [FlagsAttribute(...)] | +| System.Reflection.Metadata.AssemblyExtensions | [ExtensionAttribute(...)] | +| System.Reflection.MetadataEnumResult.<smallResult>e__FixedBuffer | [CompilerGeneratedAttribute(...)] | +| System.Reflection.MetadataEnumResult.<smallResult>e__FixedBuffer | [UnsafeValueTypeAttribute(...)] | +| System.Reflection.MetadataImport | [IsReadOnlyAttribute(...)] | +| System.Reflection.MethodAttributes | [FlagsAttribute(...)] | +| System.Reflection.MethodSemanticsAttributes | [FlagsAttribute(...)] | +| System.Reflection.Module.<>c | [CompilerGeneratedAttribute(...)] | +| System.Reflection.ObfuscateAssemblyAttribute.<AssemblyIsPrivate>k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Reflection.ObfuscateAssemblyAttribute.<StripAfterObfuscation>k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Reflection.ObfuscationAttribute.<ApplyToMembers>k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Reflection.ObfuscationAttribute.<Exclude>k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Reflection.ObfuscationAttribute.<Feature>k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Reflection.ObfuscationAttribute.<StripAfterObfuscation>k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Reflection.PInvokeAttributes | [FlagsAttribute(...)] | +| System.Reflection.ParameterAttributes | [FlagsAttribute(...)] | +| System.Reflection.ParameterModifier | [IsReadOnlyAttribute(...)] | +| System.Reflection.PortableExecutableKinds | [FlagsAttribute(...)] | +| System.Reflection.PropertyAttributes | [FlagsAttribute(...)] | +| System.Reflection.ReflectionTypeLoadException.<LoaderExceptions>k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Reflection.ReflectionTypeLoadException.<Types>k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Reflection.ResourceAttributes | [FlagsAttribute(...)] | +| System.Reflection.ResourceLocation | [FlagsAttribute(...)] | +| System.Reflection.RuntimeAssembly._ModuleResolve | [CompilerGeneratedAttribute(...)] | +| System.Reflection.RuntimeReflectionExtensions | [ExtensionAttribute(...)] | +| System.Reflection.SignatureTypeExtensions | [ExtensionAttribute(...)] | +| System.Reflection.TypeAttributes | [FlagsAttribute(...)] | +| System.Reflection.TypeInfo.<GetDeclaredMethods>d__10 | [CompilerGeneratedAttribute(...)] | +| System.Reflection.TypeInfo.<get_DeclaredNestedTypes>d__22 | [CompilerGeneratedAttribute(...)] | +| System.ResolveEventArgs.<Name>k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.ResolveEventArgs.<RequestingAssembly>k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Resources.NeutralResourcesLanguageAttribute.<CultureName>k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Resources.NeutralResourcesLanguageAttribute.<Location>k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Resources.ResourceFallbackManager.<GetEnumerator>d__5 | [CompilerGeneratedAttribute(...)] | +| System.Resources.ResourceReader.<>c | [CompilerGeneratedAttribute(...)] | +| System.Resources.ResourceReader.<>c__DisplayClass49_0`1 | [CompilerGeneratedAttribute(...)] | +| System.Resources.SatelliteContractVersionAttribute.<Version>k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Runtime.AssemblyTargetedPatchBandAttribute.<TargetedPatchBand>k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Runtime.CompilerServices.AccessedThroughPropertyAttribute.<PropertyName>k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Runtime.CompilerServices.AsyncMethodBuilderAttribute.<BuilderType>k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1.AsyncStateMachineBox`1.StateMachine | [AllowNullAttribute(...)] | +| System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1.AsyncStateMachineBox`1.StateMachine | [MaybeNullAttribute(...)] | +| System.Runtime.CompilerServices.CallerArgumentExpressionAttribute.<ParameterName>k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Runtime.CompilerServices.CompilationRelaxations | [FlagsAttribute(...)] | +| System.Runtime.CompilerServices.CompilationRelaxationsAttribute.<CompilationRelaxations>k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Runtime.CompilerServices.ConditionalWeakTable`2.<>c | [CompilerGeneratedAttribute(...)] | +| System.Runtime.CompilerServices.ConfiguredAsyncDisposable | [IsReadOnlyAttribute(...)] | +| System.Runtime.CompilerServices.ConfiguredCancelableAsyncEnumerable`1 | [IsReadOnlyAttribute(...)] | +| System.Runtime.CompilerServices.ConfiguredCancelableAsyncEnumerable`1.Enumerator | [IsReadOnlyAttribute(...)] | +| System.Runtime.CompilerServices.ConfiguredTaskAwaitable | [IsReadOnlyAttribute(...)] | +| System.Runtime.CompilerServices.ConfiguredTaskAwaitable.ConfiguredTaskAwaiter | [IsReadOnlyAttribute(...)] | +| System.Runtime.CompilerServices.ConfiguredTaskAwaitable`1 | [IsReadOnlyAttribute(...)] | +| System.Runtime.CompilerServices.ConfiguredTaskAwaitable`1.ConfiguredTaskAwaiter | [IsReadOnlyAttribute(...)] | +| System.Runtime.CompilerServices.ConfiguredValueTaskAwaitable | [IsReadOnlyAttribute(...)] | +| System.Runtime.CompilerServices.ConfiguredValueTaskAwaitable.ConfiguredValueTaskAwaiter | [IsReadOnlyAttribute(...)] | +| System.Runtime.CompilerServices.ConfiguredValueTaskAwaitable`1 | [IsReadOnlyAttribute(...)] | +| System.Runtime.CompilerServices.ConfiguredValueTaskAwaitable`1.ConfiguredValueTaskAwaiter | [IsReadOnlyAttribute(...)] | +| System.Runtime.CompilerServices.ContractHelper.InternalContractFailed | [CompilerGeneratedAttribute(...)] | +| System.Runtime.CompilerServices.DefaultDependencyAttribute.<LoadHint>k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Runtime.CompilerServices.DependencyAttribute.<DependentAssembly>k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Runtime.CompilerServices.DependencyAttribute.<LoadHint>k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Runtime.CompilerServices.FixedBufferAttribute.<ElementType>k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Runtime.CompilerServices.FixedBufferAttribute.<Length>k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Runtime.CompilerServices.InternalsVisibleToAttribute.<AllInternalsVisible>k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Runtime.CompilerServices.InternalsVisibleToAttribute.<AssemblyName>k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Runtime.CompilerServices.JitHelpers | [ExtensionAttribute(...)] | +| System.Runtime.CompilerServices.MethodImplAttribute.<Value>k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Runtime.CompilerServices.MethodImplOptions | [FlagsAttribute(...)] | +| System.Runtime.CompilerServices.NullableAttribute | [CompilerGeneratedAttribute(...)] | +| System.Runtime.CompilerServices.NullableAttribute | [EmbeddedAttribute(...)] | +| System.Runtime.CompilerServices.NullableContextAttribute | [CompilerGeneratedAttribute(...)] | +| System.Runtime.CompilerServices.NullableContextAttribute | [EmbeddedAttribute(...)] | +| System.Runtime.CompilerServices.NullablePublicOnlyAttribute | [CompilerGeneratedAttribute(...)] | +| System.Runtime.CompilerServices.NullablePublicOnlyAttribute | [EmbeddedAttribute(...)] | +| System.Runtime.CompilerServices.ReferenceAssemblyAttribute.<Description>k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Runtime.CompilerServices.RuntimeCompatibilityAttribute.<WrapNonExceptionThrows>k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Runtime.CompilerServices.StateMachineAttribute.<StateMachineType>k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Runtime.CompilerServices.StrongBox`1.Value | [MaybeNullAttribute(...)] | +| System.Runtime.CompilerServices.TaskAwaiter | [IsReadOnlyAttribute(...)] | +| System.Runtime.CompilerServices.TaskAwaiter.<>c | [CompilerGeneratedAttribute(...)] | +| System.Runtime.CompilerServices.TaskAwaiter`1 | [IsReadOnlyAttribute(...)] | +| System.Runtime.CompilerServices.TypeForwardedFromAttribute.<AssemblyFullName>k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Runtime.CompilerServices.TypeForwardedToAttribute.<Destination>k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Runtime.CompilerServices.ValueTaskAwaiter | [IsReadOnlyAttribute(...)] | +| System.Runtime.CompilerServices.ValueTaskAwaiter.<>c | [CompilerGeneratedAttribute(...)] | +| System.Runtime.CompilerServices.ValueTaskAwaiter`1 | [IsReadOnlyAttribute(...)] | +| System.Runtime.CompilerServices.YieldAwaitable | [IsReadOnlyAttribute(...)] | +| System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter | [IsReadOnlyAttribute(...)] | +| System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter.<>c | [CompilerGeneratedAttribute(...)] | +| System.Runtime.ConstrainedExecution.ReliabilityContractAttribute.<Cer>k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Runtime.ConstrainedExecution.ReliabilityContractAttribute.<ConsistencyGuarantee>k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Runtime.ExceptionServices.FirstChanceExceptionEventArgs.<Exception>k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Runtime.InteropServices.BStrWrapper.<WrappedObject>k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Runtime.InteropServices.BestFitMappingAttribute.<BestFitMapping>k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Runtime.InteropServices.ClassInterfaceAttribute.<Value>k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Runtime.InteropServices.CoClassAttribute.<CoClass>k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Runtime.InteropServices.ComDefaultInterfaceAttribute.<Value>k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Runtime.InteropServices.ComEventInterfaceAttribute.<EventProvider>k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Runtime.InteropServices.ComEventInterfaceAttribute.<SourceInterface>k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Runtime.InteropServices.ComSourceInterfacesAttribute.<Value>k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Runtime.InteropServices.ComTypes.FUNCFLAGS | [FlagsAttribute(...)] | +| System.Runtime.InteropServices.ComTypes.IDLFLAG | [FlagsAttribute(...)] | +| System.Runtime.InteropServices.ComTypes.IMPLTYPEFLAGS | [FlagsAttribute(...)] | +| System.Runtime.InteropServices.ComTypes.INVOKEKIND | [FlagsAttribute(...)] | +| System.Runtime.InteropServices.ComTypes.LIBFLAGS | [FlagsAttribute(...)] | +| System.Runtime.InteropServices.ComTypes.PARAMFLAG | [FlagsAttribute(...)] | +| System.Runtime.InteropServices.ComTypes.TYPEFLAGS | [FlagsAttribute(...)] | +| System.Runtime.InteropServices.ComTypes.VARFLAGS | [FlagsAttribute(...)] | +| System.Runtime.InteropServices.ComVisibleAttribute.<Value>k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Runtime.InteropServices.CurrencyWrapper.<WrappedObject>k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Runtime.InteropServices.DefaultCharSetAttribute.<CharSet>k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Runtime.InteropServices.DefaultDllImportSearchPathsAttribute.<Paths>k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Runtime.InteropServices.DefaultParameterValueAttribute.<Value>k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Runtime.InteropServices.DispIdAttribute.<Value>k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Runtime.InteropServices.DispatchWrapper.<WrappedObject>k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Runtime.InteropServices.DllImportAttribute.<Value>k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Runtime.InteropServices.DllImportSearchPath | [FlagsAttribute(...)] | +| System.Runtime.InteropServices.ErrorWrapper.<ErrorCode>k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Runtime.InteropServices.FieldOffsetAttribute.<Value>k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Runtime.InteropServices.GuidAttribute.<Value>k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Runtime.InteropServices.HandleRef | [IsReadOnlyAttribute(...)] | +| System.Runtime.InteropServices.InterfaceTypeAttribute.<Value>k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Runtime.InteropServices.LCIDConversionAttribute.<Value>k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Runtime.InteropServices.Marshal.<>c | [CompilerGeneratedAttribute(...)] | +| System.Runtime.InteropServices.MarshalAsAttribute.<Value>k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Runtime.InteropServices.MemoryMarshal.<ToEnumerable>d__3`1 | [CompilerGeneratedAttribute(...)] | +| System.Runtime.InteropServices.ProgIdAttribute.<Value>k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Runtime.InteropServices.StructLayoutAttribute.<Value>k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Runtime.InteropServices.TypeIdentifierAttribute.<Identifier>k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Runtime.InteropServices.TypeIdentifierAttribute.<Scope>k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Runtime.InteropServices.UnknownWrapper.<WrappedObject>k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Runtime.InteropServices.UnmanagedFunctionPointerAttribute.<CallingConvention>k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Runtime.InteropServices.VariantWrapper.<WrappedObject>k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Runtime.Intrinsics.Vector64 | [ExtensionAttribute(...)] | +| System.Runtime.Intrinsics.Vector64DebugView`1 | [IsReadOnlyAttribute(...)] | +| System.Runtime.Intrinsics.Vector64`1 | [IntrinsicAttribute(...)] | +| System.Runtime.Intrinsics.Vector64`1 | [IsReadOnlyAttribute(...)] | +| System.Runtime.Intrinsics.Vector128 | [ExtensionAttribute(...)] | +| System.Runtime.Intrinsics.Vector128DebugView`1 | [IsReadOnlyAttribute(...)] | +| System.Runtime.Intrinsics.Vector128`1 | [IntrinsicAttribute(...)] | +| System.Runtime.Intrinsics.Vector128`1 | [IsReadOnlyAttribute(...)] | +| System.Runtime.Intrinsics.Vector256 | [ExtensionAttribute(...)] | +| System.Runtime.Intrinsics.Vector256DebugView`1 | [IsReadOnlyAttribute(...)] | +| System.Runtime.Intrinsics.Vector256`1 | [IntrinsicAttribute(...)] | +| System.Runtime.Intrinsics.Vector256`1 | [IsReadOnlyAttribute(...)] | +| System.Runtime.Intrinsics.X86.Aes | [IntrinsicAttribute(...)] | +| System.Runtime.Intrinsics.X86.Avx | [IntrinsicAttribute(...)] | +| System.Runtime.Intrinsics.X86.Avx2 | [IntrinsicAttribute(...)] | +| System.Runtime.Intrinsics.X86.Bmi1 | [IntrinsicAttribute(...)] | +| System.Runtime.Intrinsics.X86.Bmi1.X64 | [IntrinsicAttribute(...)] | +| System.Runtime.Intrinsics.X86.Bmi2 | [IntrinsicAttribute(...)] | +| System.Runtime.Intrinsics.X86.Bmi2.X64 | [IntrinsicAttribute(...)] | +| System.Runtime.Intrinsics.X86.Fma | [IntrinsicAttribute(...)] | +| System.Runtime.Intrinsics.X86.Lzcnt | [IntrinsicAttribute(...)] | +| System.Runtime.Intrinsics.X86.Lzcnt.X64 | [IntrinsicAttribute(...)] | +| System.Runtime.Intrinsics.X86.Pclmulqdq | [IntrinsicAttribute(...)] | +| System.Runtime.Intrinsics.X86.Popcnt | [IntrinsicAttribute(...)] | +| System.Runtime.Intrinsics.X86.Popcnt.X64 | [IntrinsicAttribute(...)] | +| System.Runtime.Intrinsics.X86.Sse | [IntrinsicAttribute(...)] | +| System.Runtime.Intrinsics.X86.Sse2 | [IntrinsicAttribute(...)] | +| System.Runtime.Intrinsics.X86.Sse2.X64 | [IntrinsicAttribute(...)] | +| System.Runtime.Intrinsics.X86.Sse3 | [IntrinsicAttribute(...)] | +| System.Runtime.Intrinsics.X86.Sse41 | [IntrinsicAttribute(...)] | +| System.Runtime.Intrinsics.X86.Sse41.X64 | [IntrinsicAttribute(...)] | +| System.Runtime.Intrinsics.X86.Sse42 | [IntrinsicAttribute(...)] | +| System.Runtime.Intrinsics.X86.Sse42.X64 | [IntrinsicAttribute(...)] | +| System.Runtime.Intrinsics.X86.Sse.X64 | [IntrinsicAttribute(...)] | +| System.Runtime.Intrinsics.X86.Ssse3 | [IntrinsicAttribute(...)] | +| System.Runtime.Loader.AssemblyDependencyResolver.<>c__DisplayClass6_0 | [CompilerGeneratedAttribute(...)] | +| System.Runtime.Loader.AssemblyDependencyResolver.corehost_error_writer_fn | [UnmanagedFunctionPointerAttribute(...)] | +| System.Runtime.Loader.AssemblyDependencyResolver.corehost_resolve_component_dependencies_result_fn | [UnmanagedFunctionPointerAttribute(...)] | +| System.Runtime.Loader.AssemblyLoadContext.<get_All>d__88 | [CompilerGeneratedAttribute(...)] | +| System.Runtime.Loader.AssemblyLoadContext.<get_Assemblies>d__58 | [CompilerGeneratedAttribute(...)] | +| System.Runtime.Loader.AssemblyLoadContext.AssemblyLoad | [CompilerGeneratedAttribute(...)] | +| System.Runtime.Loader.AssemblyLoadContext.AssemblyResolve | [CompilerGeneratedAttribute(...)] | +| System.Runtime.Loader.AssemblyLoadContext.ResourceResolve | [CompilerGeneratedAttribute(...)] | +| System.Runtime.Loader.AssemblyLoadContext.TypeResolve | [CompilerGeneratedAttribute(...)] | +| System.Runtime.Loader.AssemblyLoadContext._resolving | [CompilerGeneratedAttribute(...)] | +| System.Runtime.Loader.AssemblyLoadContext._resolvingUnmanagedDll | [CompilerGeneratedAttribute(...)] | +| System.Runtime.Loader.AssemblyLoadContext._unloading | [CompilerGeneratedAttribute(...)] | +| System.Runtime.Loader.LibraryNameVariation.<DetermineLibraryNameVariations>d__5 | [CompilerGeneratedAttribute(...)] | +| System.Runtime.Serialization.DeserializationToken | [IsReadOnlyAttribute(...)] | +| System.Runtime.Serialization.DeserializationTracker.<DeserializationInProgress>k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Runtime.Serialization.SafeSerializationEventArgs.<StreamingContext>k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Runtime.Serialization.SerializationEntry | [IsReadOnlyAttribute(...)] | +| System.Runtime.Serialization.SerializationInfo.<AsyncDeserializationInProgress>k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Runtime.Serialization.SerializationInfo.<IsAssemblyNameSetExplicit>k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Runtime.Serialization.SerializationInfo.<IsFullTypeNameSetExplicit>k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Runtime.Serialization.StreamingContext | [IsReadOnlyAttribute(...)] | +| System.Runtime.Serialization.StreamingContextStates | [FlagsAttribute(...)] | +| System.Runtime.TargetedPatchingOptOutAttribute.<Reason>k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.RuntimeArgumentHandle | [IsByRefLikeAttribute(...)] | +| System.RuntimeType.RuntimeTypeCache.Filter | [IsReadOnlyAttribute(...)] | +| System.Security.AllowPartiallyTrustedCallersAttribute.<PartialTrustVisibilityLevel>k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Security.SecurityCriticalAttribute.<Scope>k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Security.SecurityElement.<>c | [CompilerGeneratedAttribute(...)] | +| System.Security.SecurityException.<Demanded>k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Security.SecurityException.<DenySetInstance>k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Security.SecurityException.<FailedAssemblyInfo>k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Security.SecurityException.<GrantedSet>k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Security.SecurityException.<Method>k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Security.SecurityException.<PermissionState>k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Security.SecurityException.<PermissionType>k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Security.SecurityException.<PermitOnlySetInstance>k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Security.SecurityException.<RefusedSet>k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Security.SecurityException.<Url>k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Security.SecurityRulesAttribute.<RuleSet>k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Security.SecurityRulesAttribute.<SkipVerificationInFullTrust>k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.SpanHelpers | [ExtensionAttribute(...)] | +| System.SpanHelpers.ComparerComparable`2 | [IsReadOnlyAttribute(...)] | +| System.Span`1 | [IsByRefLikeAttribute(...)] | +| System.Span`1 | [IsReadOnlyAttribute(...)] | +| System.Span`1 | [NonVersionableAttribute(...)] | +| System.Span`1.Enumerator | [IsByRefLikeAttribute(...)] | +| System.StringSplitOptions | [FlagsAttribute(...)] | +| System.TermInfo.ParameterizedStrings.FormatParam | [IsReadOnlyAttribute(...)] | +| System.TermInfo.ParameterizedStrings.t_cachedOneElementArgsArray | [ThreadStaticAttribute(...)] | +| System.TermInfo.ParameterizedStrings.t_cachedStack | [ThreadStaticAttribute(...)] | +| System.TermInfo.ParameterizedStrings.t_cachedTwoElementArgsArray | [ThreadStaticAttribute(...)] | +| System.Text.CodePageDataItem.<BodyName>k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Text.CodePageDataItem.<CodePage>k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Text.CodePageDataItem.<DisplayName>k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Text.CodePageDataItem.<Flags>k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Text.CodePageDataItem.<HeaderName>k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Text.CodePageDataItem.<UIFamilyCodePage>k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Text.CodePageDataItem.<WebName>k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Text.EncodingExtensions | [ExtensionAttribute(...)] | +| System.Text.EncodingInfo.<CodePage>k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Text.EncodingInfo.<DisplayName>k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Text.EncodingInfo.<Name>k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Text.Rune | [IsReadOnlyAttribute(...)] | +| System.Text.SpanRuneEnumerator | [IsByRefLikeAttribute(...)] | +| System.Text.StringBuilderCache.t_cachedInstance | [ThreadStaticAttribute(...)] | +| System.Text.StringOrCharArray | [IsReadOnlyAttribute(...)] | +| System.Text.ValueStringBuilder | [IsByRefLikeAttribute(...)] | +| System.Threading.AsyncLocalValueChangedArgs`1 | [IsReadOnlyAttribute(...)] | +| System.Threading.AsyncLocalValueChangedArgs`1.<CurrentValue>k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Threading.AsyncLocalValueChangedArgs`1.<PreviousValue>k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Threading.AsyncLocalValueChangedArgs`1.<ThreadContextChanged>k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Threading.AsyncLocalValueMap.<Empty>k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Threading.CancellationToken | [IsReadOnlyAttribute(...)] | +| System.Threading.CancellationToken.<>c | [CompilerGeneratedAttribute(...)] | +| System.Threading.CancellationTokenRegistration | [IsReadOnlyAttribute(...)] | +| System.Threading.CancellationTokenSource.<>c | [CompilerGeneratedAttribute(...)] | +| System.Threading.CancellationTokenSource.CallbackNode.<>c | [CompilerGeneratedAttribute(...)] | +| System.Threading.CancellationTokenSource.LinkedNCancellationTokenSource.<>c | [CompilerGeneratedAttribute(...)] | +| System.Threading.QueueUserWorkItemCallback.<>c | [CompilerGeneratedAttribute(...)] | +| System.Threading.ReaderWriterLockSlim.WaiterStates | [FlagsAttribute(...)] | +| System.Threading.ReaderWriterLockSlim.t_rwc | [ThreadStaticAttribute(...)] | +| System.Threading.SemaphoreSlim.<>c | [CompilerGeneratedAttribute(...)] | +| System.Threading.SemaphoreSlim.<WaitUntilCountOrTimeoutAsync>d__33 | [CompilerGeneratedAttribute(...)] | +| System.Threading.SynchronizationContext.<>c | [CompilerGeneratedAttribute(...)] | +| System.Threading.Tasks.AwaitTaskContinuation.<>c | [CompilerGeneratedAttribute(...)] | +| System.Threading.Tasks.ConcurrentExclusiveSchedulerPair.<>c | [CompilerGeneratedAttribute(...)] | +| System.Threading.Tasks.ConcurrentExclusiveSchedulerPair.ProcessingMode | [FlagsAttribute(...)] | +| System.Threading.Tasks.GenericDelegateCache`2.<>c | [CompilerGeneratedAttribute(...)] | +| System.Threading.Tasks.InternalTaskOptions | [FlagsAttribute(...)] | +| System.Threading.Tasks.SingleProducerSingleConsumerQueue`1.<GetEnumerator>d__11 | [CompilerGeneratedAttribute(...)] | +| System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore`1.<>c | [CompilerGeneratedAttribute(...)] | +| System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore`1.<RunContinuationsAsynchronously>k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore`1._result | [AllowNullAttribute(...)] | +| System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore`1._result | [MaybeNullAttribute(...)] | +| System.Threading.Tasks.Sources.ValueTaskSourceOnCompletedFlags | [FlagsAttribute(...)] | +| System.Threading.Tasks.SynchronizationContextAwaitTaskContinuation.<>c | [CompilerGeneratedAttribute(...)] | +| System.Threading.Tasks.SynchronizationContextAwaitTaskContinuation.<>c__DisplayClass6_0 | [CompilerGeneratedAttribute(...)] | +| System.Threading.Tasks.SynchronizationContextTaskScheduler.<>c | [CompilerGeneratedAttribute(...)] | +| System.Threading.Tasks.Task.<>c | [CompilerGeneratedAttribute(...)] | +| System.Threading.Tasks.Task.<CompletedTask>k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Threading.Tasks.Task.<Factory>k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Threading.Tasks.Task.DelayPromise.<>c | [CompilerGeneratedAttribute(...)] | +| System.Threading.Tasks.Task.DelayPromiseWithCancellation.<>c | [CompilerGeneratedAttribute(...)] | +| System.Threading.Tasks.Task.t_currentTask | [ThreadStaticAttribute(...)] | +| System.Threading.Tasks.TaskAsyncEnumerableExtensions | [ExtensionAttribute(...)] | +| System.Threading.Tasks.TaskContinuationOptions | [FlagsAttribute(...)] | +| System.Threading.Tasks.TaskCreationOptions | [FlagsAttribute(...)] | +| System.Threading.Tasks.TaskExtensions | [ExtensionAttribute(...)] | +| System.Threading.Tasks.TaskFactory`1.<>c | [CompilerGeneratedAttribute(...)] | +| System.Threading.Tasks.TaskFactory`1.<>c__DisplayClass32_0 | [CompilerGeneratedAttribute(...)] | +| System.Threading.Tasks.TaskFactory`1.<>c__DisplayClass35_0 | [CompilerGeneratedAttribute(...)] | +| System.Threading.Tasks.TaskFactory`1.<>c__DisplayClass38_0`1 | [CompilerGeneratedAttribute(...)] | +| System.Threading.Tasks.TaskFactory`1.<>c__DisplayClass41_0`2 | [CompilerGeneratedAttribute(...)] | +| System.Threading.Tasks.TaskFactory`1.<>c__DisplayClass44_0`3 | [CompilerGeneratedAttribute(...)] | +| System.Threading.Tasks.TaskFactory`1.FromAsyncTrimPromise`1.m_thisRef | [AllowNullAttribute(...)] | +| System.Threading.Tasks.TaskFactory`1.FromAsyncTrimPromise`1.m_thisRef | [MaybeNullAttribute(...)] | +| System.Threading.Tasks.TaskScheduler.UnobservedTaskException | [CompilerGeneratedAttribute(...)] | +| System.Threading.Tasks.TaskSchedulerAwaitTaskContinuation.<>c | [CompilerGeneratedAttribute(...)] | +| System.Threading.Tasks.TaskToApm.<>c__DisplayClass3_0 | [CompilerGeneratedAttribute(...)] | +| System.Threading.Tasks.Task`1.TaskWhenAnyCast.<>c | [CompilerGeneratedAttribute(...)] | +| System.Threading.Tasks.Task`1.m_result | [MaybeNullAttribute(...)] | +| System.Threading.Tasks.ThreadPoolTaskScheduler.<>c | [CompilerGeneratedAttribute(...)] | +| System.Threading.Tasks.ThreadPoolTaskScheduler.<FilterTasksFromWorkItems>d__6 | [CompilerGeneratedAttribute(...)] | +| System.Threading.Tasks.UnwrapPromise`1.<>c | [CompilerGeneratedAttribute(...)] | +| System.Threading.Tasks.ValueTask | [IsReadOnlyAttribute(...)] | +| System.Threading.Tasks.ValueTask.ValueTaskSourceAsTask.<>c | [CompilerGeneratedAttribute(...)] | +| System.Threading.Tasks.ValueTask`1 | [IsReadOnlyAttribute(...)] | +| System.Threading.Tasks.ValueTask`1.ValueTaskSourceAsTask.<>c | [CompilerGeneratedAttribute(...)] | +| System.Threading.Tasks.ValueTask`1._result | [AllowNullAttribute(...)] | +| System.Threading.Thread.t_currentProcessorIdCache | [ThreadStaticAttribute(...)] | +| System.Threading.Thread.t_currentThread | [ThreadStaticAttribute(...)] | +| System.Threading.ThreadHandle | [IsReadOnlyAttribute(...)] | +| System.Threading.ThreadLocal`1.LinkedSlot._value | [AllowNullAttribute(...)] | +| System.Threading.ThreadLocal`1.LinkedSlot._value | [MaybeNullAttribute(...)] | +| System.Threading.ThreadLocal`1.ts_finalizationHelper | [ThreadStaticAttribute(...)] | +| System.Threading.ThreadLocal`1.ts_slotArray | [ThreadStaticAttribute(...)] | +| System.Threading.ThreadPool.<GetLocallyQueuedWorkItems>d__51 | [CompilerGeneratedAttribute(...)] | +| System.Threading.ThreadPool.<GetQueuedWorkItems>d__50 | [CompilerGeneratedAttribute(...)] | +| System.Threading.ThreadPoolGlobals.<>c | [CompilerGeneratedAttribute(...)] | +| System.Threading.ThreadPoolWorkQueueThreadLocals.threadLocals | [ThreadStaticAttribute(...)] | +| System.Threading.ThreadState | [FlagsAttribute(...)] | +| System.Threading.TimerQueue.<ActiveCount>k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Threading.TimerQueue.<Instances>k__BackingField | [CompilerGeneratedAttribute(...)] | +| System.Threading.TimerQueueTimer.<>c | [CompilerGeneratedAttribute(...)] | +| System.Threading.WaitHandle.t_safeWaitHandlesForRent | [ThreadStaticAttribute(...)] | +| System.Threading.WaitHandleExtensions | [ExtensionAttribute(...)] | +| System.ThrowHelper | [StackTraceHiddenAttribute(...)] | +| System.TimeSpan | [IsReadOnlyAttribute(...)] | +| System.TimeZoneInfo.<>c | [CompilerGeneratedAttribute(...)] | +| System.TimeZoneInfo.<>c__DisplayClass125_0 | [CompilerGeneratedAttribute(...)] | +| System.TimeZoneInfo.TransitionTime | [IsReadOnlyAttribute(...)] | +| System.TimeZoneInfoOptions | [FlagsAttribute(...)] | +| System.TupleExtensions | [ExtensionAttribute(...)] | +| System.Type.<>c | [CompilerGeneratedAttribute(...)] | +| System.TypedReference | [IsByRefLikeAttribute(...)] | +| System.TypedReference | [NonVersionableAttribute(...)] | +| System.UIntPtr | [IsReadOnlyAttribute(...)] | +| System.UIntPtr.Zero | [IntrinsicAttribute(...)] | +| System.__DTString | [IsByRefLikeAttribute(...)] | +| bool | [IsReadOnlyAttribute(...)] | +| byte | [IsReadOnlyAttribute(...)] | +| char | [IsReadOnlyAttribute(...)] | +| decimal | [IsReadOnlyAttribute(...)] | +| decimal | [NonVersionableAttribute(...)] | +| double | [IsReadOnlyAttribute(...)] | +| float | [IsReadOnlyAttribute(...)] | +| int | [IsReadOnlyAttribute(...)] | +| long | [IsReadOnlyAttribute(...)] | +| sbyte | [IsReadOnlyAttribute(...)] | +| short | [IsReadOnlyAttribute(...)] | +| string.Empty | [IntrinsicAttribute(...)] | +| uint | [IsReadOnlyAttribute(...)] | +| ulong | [IsReadOnlyAttribute(...)] | +| ushort | [IsReadOnlyAttribute(...)] | +attrArgNamed +| System.Attribute | [AttributeUsageAttribute(...)] | AllowMultiple | False | +| System.Attribute | [AttributeUsageAttribute(...)] | Inherited | True | +| System.AttributeUsageAttribute | [AttributeUsageAttribute(...)] | Inherited | True | +| System.Buffers.ArrayPoolEventSource | [EventSourceAttribute(...)] | Guid | 0866B2B8-5CEF-5DB9-2612-0C0FFD814A44 | +| System.Buffers.ArrayPoolEventSource | [EventSourceAttribute(...)] | Name | System.Buffers.ArrayPoolEventSource | +| System.CLSCompliantAttribute | [AttributeUsageAttribute(...)] | AllowMultiple | False | +| System.CLSCompliantAttribute | [AttributeUsageAttribute(...)] | Inherited | True | +| System.Collections.KeyValuePairs | [DebuggerDisplayAttribute(...)] | Name | [{_key}] | +| System.Diagnostics.CodeAnalysis.AllowNullAttribute | [AttributeUsageAttribute(...)] | Inherited | False | +| System.Diagnostics.CodeAnalysis.DisallowNullAttribute | [AttributeUsageAttribute(...)] | Inherited | False | +| System.Diagnostics.CodeAnalysis.DoesNotReturnAttribute | [AttributeUsageAttribute(...)] | Inherited | False | +| System.Diagnostics.CodeAnalysis.DoesNotReturnIfAttribute | [AttributeUsageAttribute(...)] | Inherited | False | +| System.Diagnostics.CodeAnalysis.MaybeNullAttribute | [AttributeUsageAttribute(...)] | Inherited | False | +| System.Diagnostics.CodeAnalysis.MaybeNullWhenAttribute | [AttributeUsageAttribute(...)] | Inherited | False | +| System.Diagnostics.CodeAnalysis.NotNullAttribute | [AttributeUsageAttribute(...)] | Inherited | False | +| System.Diagnostics.CodeAnalysis.NotNullIfNotNullAttribute | [AttributeUsageAttribute(...)] | AllowMultiple | True | +| System.Diagnostics.CodeAnalysis.NotNullIfNotNullAttribute | [AttributeUsageAttribute(...)] | Inherited | False | +| System.Diagnostics.CodeAnalysis.NotNullWhenAttribute | [AttributeUsageAttribute(...)] | Inherited | False | +| System.Diagnostics.CodeAnalysis.SuppressMessageAttribute | [AttributeUsageAttribute(...)] | AllowMultiple | True | +| System.Diagnostics.CodeAnalysis.SuppressMessageAttribute | [AttributeUsageAttribute(...)] | Inherited | False | +| System.Diagnostics.ConditionalAttribute | [AttributeUsageAttribute(...)] | AllowMultiple | True | +| System.Diagnostics.Contracts.ContractAbbreviatorAttribute | [AttributeUsageAttribute(...)] | AllowMultiple | False | +| System.Diagnostics.Contracts.ContractArgumentValidatorAttribute | [AttributeUsageAttribute(...)] | AllowMultiple | False | +| System.Diagnostics.Contracts.ContractClassAttribute | [AttributeUsageAttribute(...)] | AllowMultiple | False | +| System.Diagnostics.Contracts.ContractClassAttribute | [AttributeUsageAttribute(...)] | Inherited | False | +| System.Diagnostics.Contracts.ContractClassForAttribute | [AttributeUsageAttribute(...)] | AllowMultiple | False | +| System.Diagnostics.Contracts.ContractClassForAttribute | [AttributeUsageAttribute(...)] | Inherited | False | +| System.Diagnostics.Contracts.ContractInvariantMethodAttribute | [AttributeUsageAttribute(...)] | AllowMultiple | False | +| System.Diagnostics.Contracts.ContractInvariantMethodAttribute | [AttributeUsageAttribute(...)] | Inherited | False | +| System.Diagnostics.Contracts.ContractOptionAttribute | [AttributeUsageAttribute(...)] | AllowMultiple | True | +| System.Diagnostics.Contracts.ContractOptionAttribute | [AttributeUsageAttribute(...)] | Inherited | False | +| System.Diagnostics.Contracts.ContractRuntimeIgnoredAttribute | [AttributeUsageAttribute(...)] | AllowMultiple | False | +| System.Diagnostics.Contracts.ContractRuntimeIgnoredAttribute | [AttributeUsageAttribute(...)] | Inherited | True | +| System.Diagnostics.Contracts.PureAttribute | [AttributeUsageAttribute(...)] | AllowMultiple | False | +| System.Diagnostics.Contracts.PureAttribute | [AttributeUsageAttribute(...)] | Inherited | True | +| System.Diagnostics.DebuggableAttribute | [AttributeUsageAttribute(...)] | AllowMultiple | False | +| System.Diagnostics.DebuggerBrowsableAttribute | [AttributeUsageAttribute(...)] | AllowMultiple | False | +| System.Diagnostics.DebuggerDisplayAttribute | [AttributeUsageAttribute(...)] | AllowMultiple | True | +| System.Diagnostics.DebuggerHiddenAttribute | [AttributeUsageAttribute(...)] | Inherited | False | +| System.Diagnostics.DebuggerNonUserCodeAttribute | [AttributeUsageAttribute(...)] | Inherited | False | +| System.Diagnostics.DebuggerStepThroughAttribute | [AttributeUsageAttribute(...)] | Inherited | False | +| System.Diagnostics.DebuggerStepperBoundaryAttribute | [AttributeUsageAttribute(...)] | Inherited | False | +| System.Diagnostics.DebuggerTypeProxyAttribute | [AttributeUsageAttribute(...)] | AllowMultiple | True | +| System.Diagnostics.DebuggerVisualizerAttribute | [AttributeUsageAttribute(...)] | AllowMultiple | True | +| System.Diagnostics.StackTraceHiddenAttribute | [AttributeUsageAttribute(...)] | Inherited | False | +| System.Diagnostics.Tracing.EventDataAttribute | [AttributeUsageAttribute(...)] | Inherited | False | +| System.Diagnostics.Tracing.FrameworkEventSource | [EventSourceAttribute(...)] | Guid | 8E9F5090-2D75-4d03-8A81-E5AFBF85DAF1 | +| System.Diagnostics.Tracing.FrameworkEventSource | [EventSourceAttribute(...)] | Name | System.Diagnostics.Eventing.FrameworkEventSource | +| System.Diagnostics.Tracing.NativeRuntimeEventSource | [EventSourceAttribute(...)] | Guid | 5E5BB766-BBFC-5662-0548-1D44FAD9BB56 | +| System.Diagnostics.Tracing.NativeRuntimeEventSource | [EventSourceAttribute(...)] | Name | Microsoft-Windows-DotNETRuntime | +| System.Diagnostics.Tracing.RuntimeEventSource | [EventSourceAttribute(...)] | Guid | 49592C0F-5A05-516D-AA4B-A64E02026C89 | +| System.Diagnostics.Tracing.RuntimeEventSource | [EventSourceAttribute(...)] | Name | System.Runtime | +| System.FlagsAttribute | [AttributeUsageAttribute(...)] | Inherited | False | +| System.Globalization.CompareInfo.m_SortVersion | [OptionalFieldAttribute(...)] | VersionAdded | 3 | +| System.Globalization.CompareInfo.m_name | [OptionalFieldAttribute(...)] | VersionAdded | 2 | +| System.NonSerializedAttribute | [AttributeUsageAttribute(...)] | Inherited | False | +| System.ObsoleteAttribute | [AttributeUsageAttribute(...)] | Inherited | False | +| System.ParamArrayAttribute | [AttributeUsageAttribute(...)] | AllowMultiple | False | +| System.ParamArrayAttribute | [AttributeUsageAttribute(...)] | Inherited | True | +| System.Reflection.AssemblyAlgorithmIdAttribute | [AttributeUsageAttribute(...)] | Inherited | False | +| System.Reflection.AssemblyCompanyAttribute | [AttributeUsageAttribute(...)] | Inherited | False | +| System.Reflection.AssemblyConfigurationAttribute | [AttributeUsageAttribute(...)] | Inherited | False | +| System.Reflection.AssemblyCopyrightAttribute | [AttributeUsageAttribute(...)] | Inherited | False | +| System.Reflection.AssemblyCultureAttribute | [AttributeUsageAttribute(...)] | Inherited | False | +| System.Reflection.AssemblyDefaultAliasAttribute | [AttributeUsageAttribute(...)] | Inherited | False | +| System.Reflection.AssemblyDelaySignAttribute | [AttributeUsageAttribute(...)] | Inherited | False | +| System.Reflection.AssemblyDescriptionAttribute | [AttributeUsageAttribute(...)] | Inherited | False | +| System.Reflection.AssemblyFileVersionAttribute | [AttributeUsageAttribute(...)] | Inherited | False | +| System.Reflection.AssemblyFlagsAttribute | [AttributeUsageAttribute(...)] | Inherited | False | +| System.Reflection.AssemblyInformationalVersionAttribute | [AttributeUsageAttribute(...)] | Inherited | False | +| System.Reflection.AssemblyKeyFileAttribute | [AttributeUsageAttribute(...)] | Inherited | False | +| System.Reflection.AssemblyKeyNameAttribute | [AttributeUsageAttribute(...)] | Inherited | False | +| System.Reflection.AssemblyMetadataAttribute | [AttributeUsageAttribute(...)] | AllowMultiple | True | +| System.Reflection.AssemblyMetadataAttribute | [AttributeUsageAttribute(...)] | Inherited | False | +| System.Reflection.AssemblyProductAttribute | [AttributeUsageAttribute(...)] | Inherited | False | +| System.Reflection.AssemblySignatureKeyAttribute | [AttributeUsageAttribute(...)] | AllowMultiple | False | +| System.Reflection.AssemblySignatureKeyAttribute | [AttributeUsageAttribute(...)] | Inherited | False | +| System.Reflection.AssemblyTitleAttribute | [AttributeUsageAttribute(...)] | Inherited | False | +| System.Reflection.AssemblyTrademarkAttribute | [AttributeUsageAttribute(...)] | Inherited | False | +| System.Reflection.AssemblyVersionAttribute | [AttributeUsageAttribute(...)] | Inherited | False | +| System.Reflection.ObfuscateAssemblyAttribute | [AttributeUsageAttribute(...)] | AllowMultiple | False | +| System.Reflection.ObfuscateAssemblyAttribute | [AttributeUsageAttribute(...)] | Inherited | False | +| System.Reflection.ObfuscationAttribute | [AttributeUsageAttribute(...)] | AllowMultiple | True | +| System.Reflection.ObfuscationAttribute | [AttributeUsageAttribute(...)] | Inherited | False | +| System.Resources.NeutralResourcesLanguageAttribute | [AttributeUsageAttribute(...)] | AllowMultiple | False | +| System.Resources.SatelliteContractVersionAttribute | [AttributeUsageAttribute(...)] | AllowMultiple | False | +| System.Runtime.AssemblyTargetedPatchBandAttribute | [AttributeUsageAttribute(...)] | Inherited | False | +| System.Runtime.CompilerServices.AsyncIteratorStateMachineAttribute | [AttributeUsageAttribute(...)] | AllowMultiple | False | +| System.Runtime.CompilerServices.AsyncIteratorStateMachineAttribute | [AttributeUsageAttribute(...)] | Inherited | False | +| System.Runtime.CompilerServices.AsyncMethodBuilderAttribute | [AttributeUsageAttribute(...)] | AllowMultiple | False | +| System.Runtime.CompilerServices.AsyncMethodBuilderAttribute | [AttributeUsageAttribute(...)] | Inherited | False | +| System.Runtime.CompilerServices.AsyncStateMachineAttribute | [AttributeUsageAttribute(...)] | AllowMultiple | False | +| System.Runtime.CompilerServices.AsyncStateMachineAttribute | [AttributeUsageAttribute(...)] | Inherited | False | +| System.Runtime.CompilerServices.CallerArgumentExpressionAttribute | [AttributeUsageAttribute(...)] | AllowMultiple | False | +| System.Runtime.CompilerServices.CallerArgumentExpressionAttribute | [AttributeUsageAttribute(...)] | Inherited | False | +| System.Runtime.CompilerServices.CallerFilePathAttribute | [AttributeUsageAttribute(...)] | Inherited | False | +| System.Runtime.CompilerServices.CallerLineNumberAttribute | [AttributeUsageAttribute(...)] | Inherited | False | +| System.Runtime.CompilerServices.CallerMemberNameAttribute | [AttributeUsageAttribute(...)] | Inherited | False | +| System.Runtime.CompilerServices.CompilerGeneratedAttribute | [AttributeUsageAttribute(...)] | Inherited | True | +| System.Runtime.CompilerServices.CustomConstantAttribute | [AttributeUsageAttribute(...)] | Inherited | False | +| System.Runtime.CompilerServices.DateTimeConstantAttribute | [AttributeUsageAttribute(...)] | Inherited | False | +| System.Runtime.CompilerServices.DecimalConstantAttribute | [AttributeUsageAttribute(...)] | Inherited | False | +| System.Runtime.CompilerServices.DependencyAttribute | [AttributeUsageAttribute(...)] | AllowMultiple | True | +| System.Runtime.CompilerServices.DisablePrivateReflectionAttribute | [AttributeUsageAttribute(...)] | AllowMultiple | False | +| System.Runtime.CompilerServices.DisablePrivateReflectionAttribute | [AttributeUsageAttribute(...)] | Inherited | False | +| System.Runtime.CompilerServices.EnumeratorCancellationAttribute | [AttributeUsageAttribute(...)] | Inherited | False | +| System.Runtime.CompilerServices.FixedBufferAttribute | [AttributeUsageAttribute(...)] | Inherited | False | +| System.Runtime.CompilerServices.IndexerNameAttribute | [AttributeUsageAttribute(...)] | Inherited | True | +| System.Runtime.CompilerServices.InternalsVisibleToAttribute | [AttributeUsageAttribute(...)] | AllowMultiple | True | +| System.Runtime.CompilerServices.InternalsVisibleToAttribute | [AttributeUsageAttribute(...)] | Inherited | False | +| System.Runtime.CompilerServices.IntrinsicAttribute | [AttributeUsageAttribute(...)] | Inherited | False | +| System.Runtime.CompilerServices.IsReadOnlyAttribute | [AttributeUsageAttribute(...)] | Inherited | False | +| System.Runtime.CompilerServices.IteratorStateMachineAttribute | [AttributeUsageAttribute(...)] | AllowMultiple | False | +| System.Runtime.CompilerServices.IteratorStateMachineAttribute | [AttributeUsageAttribute(...)] | Inherited | False | +| System.Runtime.CompilerServices.MethodImplAttribute | [AttributeUsageAttribute(...)] | Inherited | False | +| System.Runtime.CompilerServices.NullableAttribute | [AttributeUsageAttribute(...)] | AllowMultiple | False | +| System.Runtime.CompilerServices.NullableAttribute | [AttributeUsageAttribute(...)] | Inherited | False | +| System.Runtime.CompilerServices.NullableContextAttribute | [AttributeUsageAttribute(...)] | AllowMultiple | False | +| System.Runtime.CompilerServices.NullableContextAttribute | [AttributeUsageAttribute(...)] | Inherited | False | +| System.Runtime.CompilerServices.NullablePublicOnlyAttribute | [AttributeUsageAttribute(...)] | AllowMultiple | False | +| System.Runtime.CompilerServices.NullablePublicOnlyAttribute | [AttributeUsageAttribute(...)] | Inherited | False | +| System.Runtime.CompilerServices.ReferenceAssemblyAttribute | [AttributeUsageAttribute(...)] | AllowMultiple | False | +| System.Runtime.CompilerServices.RuntimeCompatibilityAttribute | [AttributeUsageAttribute(...)] | AllowMultiple | False | +| System.Runtime.CompilerServices.RuntimeCompatibilityAttribute | [AttributeUsageAttribute(...)] | Inherited | False | +| System.Runtime.CompilerServices.StateMachineAttribute | [AttributeUsageAttribute(...)] | AllowMultiple | False | +| System.Runtime.CompilerServices.StateMachineAttribute | [AttributeUsageAttribute(...)] | Inherited | False | +| System.Runtime.CompilerServices.StringFreezingAttribute | [AttributeUsageAttribute(...)] | Inherited | False | +| System.Runtime.CompilerServices.TypeDependencyAttribute | [AttributeUsageAttribute(...)] | AllowMultiple | True | +| System.Runtime.CompilerServices.TypeDependencyAttribute | [AttributeUsageAttribute(...)] | Inherited | False | +| System.Runtime.CompilerServices.TypeForwardedFromAttribute | [AttributeUsageAttribute(...)] | AllowMultiple | False | +| System.Runtime.CompilerServices.TypeForwardedFromAttribute | [AttributeUsageAttribute(...)] | Inherited | False | +| System.Runtime.CompilerServices.TypeForwardedToAttribute | [AttributeUsageAttribute(...)] | AllowMultiple | True | +| System.Runtime.CompilerServices.TypeForwardedToAttribute | [AttributeUsageAttribute(...)] | Inherited | False | +| System.Runtime.ConstrainedExecution.PrePrepareMethodAttribute | [AttributeUsageAttribute(...)] | Inherited | False | +| System.Runtime.ConstrainedExecution.ReliabilityContractAttribute | [AttributeUsageAttribute(...)] | Inherited | False | +| System.Runtime.ExceptionServices.HandleProcessCorruptedStateExceptionsAttribute | [AttributeUsageAttribute(...)] | AllowMultiple | False | +| System.Runtime.ExceptionServices.HandleProcessCorruptedStateExceptionsAttribute | [AttributeUsageAttribute(...)] | Inherited | False | +| System.Runtime.InteropServices.AllowReversePInvokeCallsAttribute | [AttributeUsageAttribute(...)] | AllowMultiple | False | +| System.Runtime.InteropServices.AllowReversePInvokeCallsAttribute | [AttributeUsageAttribute(...)] | Inherited | False | +| System.Runtime.InteropServices.BestFitMappingAttribute | [AttributeUsageAttribute(...)] | Inherited | False | +| System.Runtime.InteropServices.ClassInterfaceAttribute | [AttributeUsageAttribute(...)] | Inherited | False | +| System.Runtime.InteropServices.CoClassAttribute | [AttributeUsageAttribute(...)] | Inherited | False | +| System.Runtime.InteropServices.ComDefaultInterfaceAttribute | [AttributeUsageAttribute(...)] | Inherited | False | +| System.Runtime.InteropServices.ComEventInterfaceAttribute | [AttributeUsageAttribute(...)] | Inherited | False | +| System.Runtime.InteropServices.ComImportAttribute | [AttributeUsageAttribute(...)] | Inherited | False | +| System.Runtime.InteropServices.ComSourceInterfacesAttribute | [AttributeUsageAttribute(...)] | Inherited | True | +| System.Runtime.InteropServices.ComVisibleAttribute | [AttributeUsageAttribute(...)] | Inherited | False | +| System.Runtime.InteropServices.DefaultCharSetAttribute | [AttributeUsageAttribute(...)] | Inherited | False | +| System.Runtime.InteropServices.DefaultDllImportSearchPathsAttribute | [AttributeUsageAttribute(...)] | AllowMultiple | False | +| System.Runtime.InteropServices.DispIdAttribute | [AttributeUsageAttribute(...)] | Inherited | False | +| System.Runtime.InteropServices.DllImportAttribute | [AttributeUsageAttribute(...)] | Inherited | False | +| System.Runtime.InteropServices.FieldOffsetAttribute | [AttributeUsageAttribute(...)] | Inherited | False | +| System.Runtime.InteropServices.GuidAttribute | [AttributeUsageAttribute(...)] | Inherited | False | +| System.Runtime.InteropServices.InAttribute | [AttributeUsageAttribute(...)] | Inherited | False | +| System.Runtime.InteropServices.InterfaceTypeAttribute | [AttributeUsageAttribute(...)] | Inherited | False | +| System.Runtime.InteropServices.LCIDConversionAttribute | [AttributeUsageAttribute(...)] | Inherited | False | +| System.Runtime.InteropServices.MarshalAsAttribute | [AttributeUsageAttribute(...)] | Inherited | False | +| System.Runtime.InteropServices.OptionalAttribute | [AttributeUsageAttribute(...)] | Inherited | False | +| System.Runtime.InteropServices.OutAttribute | [AttributeUsageAttribute(...)] | Inherited | False | +| System.Runtime.InteropServices.PreserveSigAttribute | [AttributeUsageAttribute(...)] | Inherited | False | +| System.Runtime.InteropServices.ProgIdAttribute | [AttributeUsageAttribute(...)] | Inherited | False | +| System.Runtime.InteropServices.StructLayoutAttribute | [AttributeUsageAttribute(...)] | Inherited | False | +| System.Runtime.InteropServices.TypeIdentifierAttribute | [AttributeUsageAttribute(...)] | AllowMultiple | False | +| System.Runtime.InteropServices.TypeIdentifierAttribute | [AttributeUsageAttribute(...)] | Inherited | False | +| System.Runtime.InteropServices.UnmanagedFunctionPointerAttribute | [AttributeUsageAttribute(...)] | AllowMultiple | False | +| System.Runtime.InteropServices.UnmanagedFunctionPointerAttribute | [AttributeUsageAttribute(...)] | Inherited | False | +| System.Runtime.Serialization.OnDeserializedAttribute | [AttributeUsageAttribute(...)] | Inherited | False | +| System.Runtime.Serialization.OnDeserializingAttribute | [AttributeUsageAttribute(...)] | Inherited | False | +| System.Runtime.Serialization.OnSerializedAttribute | [AttributeUsageAttribute(...)] | Inherited | False | +| System.Runtime.Serialization.OnSerializingAttribute | [AttributeUsageAttribute(...)] | Inherited | False | +| System.Runtime.Serialization.OptionalFieldAttribute | [AttributeUsageAttribute(...)] | Inherited | False | +| System.Runtime.TargetedPatchingOptOutAttribute | [AttributeUsageAttribute(...)] | AllowMultiple | False | +| System.Runtime.TargetedPatchingOptOutAttribute | [AttributeUsageAttribute(...)] | Inherited | False | +| System.Runtime.Versioning.NonVersionableAttribute | [AttributeUsageAttribute(...)] | AllowMultiple | False | +| System.Runtime.Versioning.NonVersionableAttribute | [AttributeUsageAttribute(...)] | Inherited | False | +| System.Runtime.Versioning.TargetFrameworkAttribute | [AttributeUsageAttribute(...)] | AllowMultiple | False | +| System.Runtime.Versioning.TargetFrameworkAttribute | [AttributeUsageAttribute(...)] | Inherited | False | +| System.Security.AllowPartiallyTrustedCallersAttribute | [AttributeUsageAttribute(...)] | AllowMultiple | False | +| System.Security.AllowPartiallyTrustedCallersAttribute | [AttributeUsageAttribute(...)] | Inherited | False | +| System.Security.SecurityCriticalAttribute | [AttributeUsageAttribute(...)] | AllowMultiple | False | +| System.Security.SecurityCriticalAttribute | [AttributeUsageAttribute(...)] | Inherited | False | +| System.Security.SecurityRulesAttribute | [AttributeUsageAttribute(...)] | AllowMultiple | False | +| System.Security.SecuritySafeCriticalAttribute | [AttributeUsageAttribute(...)] | AllowMultiple | False | +| System.Security.SecuritySafeCriticalAttribute | [AttributeUsageAttribute(...)] | Inherited | False | +| System.Security.SecurityTransparentAttribute | [AttributeUsageAttribute(...)] | AllowMultiple | False | +| System.Security.SecurityTransparentAttribute | [AttributeUsageAttribute(...)] | Inherited | False | +| System.Security.SecurityTreatAsSafeAttribute | [AttributeUsageAttribute(...)] | AllowMultiple | False | +| System.Security.SecurityTreatAsSafeAttribute | [AttributeUsageAttribute(...)] | Inherited | False | +| System.Security.SuppressUnmanagedCodeSecurityAttribute | [AttributeUsageAttribute(...)] | AllowMultiple | True | +| System.Security.SuppressUnmanagedCodeSecurityAttribute | [AttributeUsageAttribute(...)] | Inherited | False | +| System.Security.UnverifiableCodeAttribute | [AttributeUsageAttribute(...)] | AllowMultiple | True | +| System.Security.UnverifiableCodeAttribute | [AttributeUsageAttribute(...)] | Inherited | False | +| System.SerializableAttribute | [AttributeUsageAttribute(...)] | Inherited | False | +| System.Text.Encoding._isReadOnly | [OptionalFieldAttribute(...)] | VersionAdded | 2 | +| System.ThreadStaticAttribute | [AttributeUsageAttribute(...)] | Inherited | False | +| System.Threading.Tasks.TplEventSource | [EventSourceAttribute(...)] | Guid | 2e5dba47-a3d2-4d16-8ee0-6671ffdcd7b5 | +| System.Threading.Tasks.TplEventSource | [EventSourceAttribute(...)] | LocalizationResources | System.Private.CoreLib.Resources.Strings | +| System.Threading.Tasks.TplEventSource | [EventSourceAttribute(...)] | Name | System.Threading.Tasks.TplEventSource | +attrArgPositional +| !0 System.ArraySegment`1.Enumerator.Current | [NullableAttribute(...)] | 0 | 1 | +| !0 System.Collections.Generic.Dictionary`2.KeyCollection.Enumerator.Current | [NullableAttribute(...)] | 0 | 1 | +| !0 System.Collections.Generic.IAsyncEnumerator`1.Current | [NullableAttribute(...)] | 0 | 1 | +| !0 System.Collections.Generic.IEnumerator`1.Current | [NullableAttribute(...)] | 0 | 1 | +| !0 System.Collections.Generic.List`1.Enumerator.Current | [NullableAttribute(...)] | 0 | 1 | +| !0 System.Lazy`1.Value | [DebuggerBrowsableAttribute(...)] | 0 | 0 | +| !0 System.Runtime.CompilerServices.ConfiguredCancelableAsyncEnumerable`1.Enumerator.Current | [NullableAttribute(...)] | 0 | 1 | +| !0 System.Threading.Tasks.Task`1.Result | [DebuggerBrowsableAttribute(...)] | 0 | 0 | +| !0 System.Threading.Tasks.ValueTask`1.Result | [DebuggerBrowsableAttribute(...)] | 0 | 0 | +| !0 System.Threading.ThreadLocal`1.Value | [DebuggerBrowsableAttribute(...)] | 0 | 0 | +| !0 System.Tuple`1.Item1 | [NullableAttribute(...)] | 0 | 1 | +| !0 System.Tuple`2.Item1 | [NullableAttribute(...)] | 0 | 1 | +| !0[] System.ArraySegment`1.Array | [NullableAttribute(...)] | 0 | [2,1] | +| !0[] System.Collections.Concurrent.IProducerConsumerCollectionDebugView`1.Items | [DebuggerBrowsableAttribute(...)] | 0 | 3 | +| !0[] System.Collections.Generic.DictionaryKeyCollectionDebugView`2.Items | [DebuggerBrowsableAttribute(...)] | 0 | 3 | +| !0[] System.Collections.Generic.ICollectionDebugView`1.Items | [DebuggerBrowsableAttribute(...)] | 0 | 3 | +| !0[] System.MemoryDebugView`1.Items | [DebuggerBrowsableAttribute(...)] | 0 | 3 | +| !0[] System.SpanDebugView`1.Items | [DebuggerBrowsableAttribute(...)] | 0 | 3 | +| !1 System.Collections.Generic.Dictionary`2.ValueCollection.Enumerator.Current | [NullableAttribute(...)] | 0 | 1 | +| !1 System.Tuple`2.Item2 | [NullableAttribute(...)] | 0 | 1 | +| !1[] System.Collections.Generic.DictionaryValueCollectionDebugView`2.Items | [DebuggerBrowsableAttribute(...)] | 0 | 3 | +| <>f__AnonymousType0`1.<message>i__Field | [DebuggerBrowsableAttribute(...)] | 0 | 0 | +| Internal.Runtime.CompilerServices.Unsafe | [CLSCompliantAttribute(...)] | 0 | False | +| Internal.Runtime.CompilerServices.Unsafe | [NullableAttribute(...)] | 0 | 0 | +| Internal.Runtime.CompilerServices.Unsafe | [NullableContextAttribute(...)] | 0 | 1 | +| Internal.Threading.Tasks.AsyncCausalitySupport | [NullableAttribute(...)] | 0 | 0 | +| Internal.Threading.Tasks.AsyncCausalitySupport | [NullableContextAttribute(...)] | 0 | 1 | +| Interop.Sys.MountPointFound | [UnmanagedFunctionPointerAttribute(...)] | 0 | 2 | +| System.AccessViolationException | [NullableAttribute(...)] | 0 | 0 | +| System.AccessViolationException | [NullableContextAttribute(...)] | 0 | 2 | +| System.AccessViolationException | [TypeForwardedFromAttribute(...)] | 0 | mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 | +| System.Action`4 | [NullableAttribute(...)] | 0 | 0 | +| System.Action`4 | [NullableContextAttribute(...)] | 0 | 2 | +| System.Action`5 | [NullableAttribute(...)] | 0 | 0 | +| System.Action`5 | [NullableContextAttribute(...)] | 0 | 2 | +| System.Action`6 | [NullableAttribute(...)] | 0 | 0 | +| System.Action`6 | [NullableContextAttribute(...)] | 0 | 2 | +| System.Action`7 | [NullableAttribute(...)] | 0 | 0 | +| System.Action`7 | [NullableContextAttribute(...)] | 0 | 2 | +| System.Action`8 | [NullableAttribute(...)] | 0 | 0 | +| System.Action`8 | [NullableContextAttribute(...)] | 0 | 2 | +| System.Action`9 | [NullableAttribute(...)] | 0 | 0 | +| System.Action`9 | [NullableContextAttribute(...)] | 0 | 2 | +| System.Action`10 | [NullableAttribute(...)] | 0 | 0 | +| System.Action`10 | [NullableContextAttribute(...)] | 0 | 2 | +| System.Action`11 | [NullableAttribute(...)] | 0 | 0 | +| System.Action`11 | [NullableContextAttribute(...)] | 0 | 2 | +| System.Action`12 | [NullableAttribute(...)] | 0 | 0 | +| System.Action`12 | [NullableContextAttribute(...)] | 0 | 2 | +| System.Action`13 | [NullableAttribute(...)] | 0 | 0 | +| System.Action`13 | [NullableContextAttribute(...)] | 0 | 2 | +| System.Action`14 | [NullableAttribute(...)] | 0 | 0 | +| System.Action`14 | [NullableContextAttribute(...)] | 0 | 2 | +| System.Action`15 | [NullableAttribute(...)] | 0 | 0 | +| System.Action`15 | [NullableContextAttribute(...)] | 0 | 2 | +| System.Action`16 | [NullableAttribute(...)] | 0 | 0 | +| System.Action`16 | [NullableContextAttribute(...)] | 0 | 2 | +| System.Activator | [NullableAttribute(...)] | 0 | 0 | +| System.Activator | [NullableContextAttribute(...)] | 0 | 1 | +| System.AggregateException | [DebuggerDisplayAttribute(...)] | 0 | Count = {InnerExceptionCount} | +| System.AggregateException | [NullableAttribute(...)] | 0 | 0 | +| System.AggregateException | [NullableContextAttribute(...)] | 0 | 1 | +| System.AggregateException | [TypeForwardedFromAttribute(...)] | 0 | mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 | +| System.AggregateException System.Threading.Tasks.Task.Exception | [NullableAttribute(...)] | 0 | 2 | +| System.AppContext | [NullableAttribute(...)] | 0 | 0 | +| System.AppContext | [NullableContextAttribute(...)] | 0 | 2 | +| System.AppContext.FirstChanceException | [NullableAttribute(...)] | 0 | [2,1] | +| System.AppDomain | [NullableAttribute(...)] | 0 | 0 | +| System.AppDomain | [NullableContextAttribute(...)] | 0 | 2 | +| System.AppDomain System.AppDomain.CurrentDomain | [NullableAttribute(...)] | 0 | 1 | +| System.AppDomain.FirstChanceException | [NullableAttribute(...)] | 0 | [2,1] | +| System.AppDomainSetup | [NullableAttribute(...)] | 0 | 0 | +| System.AppDomainSetup | [NullableContextAttribute(...)] | 0 | 2 | +| System.AppDomainSetup System.AppDomain.SetupInformation | [NullableAttribute(...)] | 0 | 1 | +| System.ApplicationException | [NullableAttribute(...)] | 0 | 0 | +| System.ApplicationException | [NullableContextAttribute(...)] | 0 | 2 | +| System.ApplicationException | [TypeForwardedFromAttribute(...)] | 0 | mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 | +| System.ArgumentException | [NullableAttribute(...)] | 0 | 0 | +| System.ArgumentException | [NullableContextAttribute(...)] | 0 | 2 | +| System.ArgumentException | [TypeForwardedFromAttribute(...)] | 0 | mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 | +| System.ArgumentNullException | [NullableAttribute(...)] | 0 | 0 | +| System.ArgumentNullException | [NullableContextAttribute(...)] | 0 | 2 | +| System.ArgumentNullException | [TypeForwardedFromAttribute(...)] | 0 | mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 | +| System.ArgumentOutOfRangeException | [NullableAttribute(...)] | 0 | 0 | +| System.ArgumentOutOfRangeException | [NullableContextAttribute(...)] | 0 | 2 | +| System.ArgumentOutOfRangeException | [TypeForwardedFromAttribute(...)] | 0 | mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 | +| System.ArithmeticException | [NullableAttribute(...)] | 0 | 0 | +| System.ArithmeticException | [NullableContextAttribute(...)] | 0 | 2 | +| System.ArithmeticException | [TypeForwardedFromAttribute(...)] | 0 | mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 | +| System.Array | [NullableAttribute(...)] | 0 | 0 | +| System.Array | [NullableContextAttribute(...)] | 0 | 1 | +| System.Array | [TypeForwardedFromAttribute(...)] | 0 | mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 | +| System.ArraySegment<!0> System.ArraySegment`1.Empty | [NullableAttribute(...)] | 0 | [0,1] | +| System.ArraySegment`1 | [DefaultMemberAttribute(...)] | 0 | Item | +| System.ArraySegment`1 | [NullableAttribute(...)] | 0 | 0 | +| System.ArraySegment`1 | [NullableContextAttribute(...)] | 0 | 1 | +| System.ArraySegment`1 | [TypeForwardedFromAttribute(...)] | 0 | mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 | +| System.ArraySegment`1.Enumerator | [NullableContextAttribute(...)] | 0 | 0 | +| System.ArrayTypeMismatchException | [NullableAttribute(...)] | 0 | 0 | +| System.ArrayTypeMismatchException | [NullableContextAttribute(...)] | 0 | 2 | +| System.ArrayTypeMismatchException | [TypeForwardedFromAttribute(...)] | 0 | mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 | +| System.AssemblyLoadEventArgs | [NullableAttribute(...)] | 0 | 0 | +| System.AssemblyLoadEventArgs | [NullableContextAttribute(...)] | 0 | 1 | +| System.Attribute | [AttributeUsageAttribute(...)] | 0 | 32767 | +| System.Attribute | [NullableAttribute(...)] | 0 | 0 | +| System.Attribute | [NullableContextAttribute(...)] | 0 | 1 | +| System.Attribute | [TypeForwardedFromAttribute(...)] | 0 | mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 | +| System.AttributeUsageAttribute | [AttributeUsageAttribute(...)] | 0 | 4 | +| System.BadImageFormatException | [NullableAttribute(...)] | 0 | 0 | +| System.BadImageFormatException | [NullableContextAttribute(...)] | 0 | 2 | +| System.BadImageFormatException | [TypeForwardedFromAttribute(...)] | 0 | mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 | +| System.BitConverter | [NullableAttribute(...)] | 0 | 0 | +| System.BitConverter | [NullableContextAttribute(...)] | 0 | 1 | +| System.BitConverter.<>c.<>9__39_0 | [TupleElementNamesAttribute(...)] | 0 | [value,startIndex,length] | +| System.Buffer | [NullableAttribute(...)] | 0 | 0 | +| System.Buffer | [NullableContextAttribute(...)] | 0 | 1 | +| System.Buffers.ArrayPool`1 | [NullableAttribute(...)] | 0 | 0 | +| System.Buffers.ArrayPool`1 | [NullableContextAttribute(...)] | 0 | 1 | +| System.ByReference`1 | [ObsoleteAttribute(...)] | 0 | Types with embedded references are not supported in this version of your compiler. | +| System.ByReference`1 | [ObsoleteAttribute(...)] | 1 | True | +| System.CLSCompliantAttribute | [AttributeUsageAttribute(...)] | 0 | 32767 | +| System.CannotUnloadAppDomainException | [NullableAttribute(...)] | 0 | 0 | +| System.CannotUnloadAppDomainException | [NullableContextAttribute(...)] | 0 | 2 | +| System.CannotUnloadAppDomainException | [TypeForwardedFromAttribute(...)] | 0 | mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 | +| System.Collections.ArrayList | [DebuggerDisplayAttribute(...)] | 0 | Count = {Count} | +| System.Collections.ArrayList | [DebuggerTypeProxyAttribute(...)] | 0 | System.Collections.ArrayList.ArrayListDebugView | +| System.Collections.ArrayList | [DefaultMemberAttribute(...)] | 0 | Item | +| System.Collections.ArrayList | [NullableAttribute(...)] | 0 | 0 | +| System.Collections.ArrayList | [NullableContextAttribute(...)] | 0 | 1 | +| System.Collections.ArrayList | [TypeForwardedFromAttribute(...)] | 0 | mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 | +| System.Collections.ArrayList.FixedSizeArrayList | [DefaultMemberAttribute(...)] | 0 | Item | +| System.Collections.ArrayList.FixedSizeList | [DefaultMemberAttribute(...)] | 0 | Item | +| System.Collections.ArrayList.IListWrapper | [DefaultMemberAttribute(...)] | 0 | Item | +| System.Collections.ArrayList.Range | [DefaultMemberAttribute(...)] | 0 | Item | +| System.Collections.ArrayList.ReadOnlyArrayList | [DefaultMemberAttribute(...)] | 0 | Item | +| System.Collections.ArrayList.ReadOnlyList | [DefaultMemberAttribute(...)] | 0 | Item | +| System.Collections.ArrayList.SyncArrayList | [DefaultMemberAttribute(...)] | 0 | Item | +| System.Collections.ArrayList.SyncIList | [DefaultMemberAttribute(...)] | 0 | Item | +| System.Collections.Comparer | [NullableAttribute(...)] | 0 | 0 | +| System.Collections.Comparer | [NullableContextAttribute(...)] | 0 | 1 | +| System.Collections.Comparer | [TypeForwardedFromAttribute(...)] | 0 | mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 | +| System.Collections.Concurrent.ConcurrentQueueSegment`1 | [DebuggerDisplayAttribute(...)] | 0 | Capacity = {Capacity} | +| System.Collections.Concurrent.ConcurrentQueueSegment`1.Slot | [DebuggerDisplayAttribute(...)] | 0 | Item = {Item}, SequenceNumber = {SequenceNumber} | +| System.Collections.Concurrent.ConcurrentQueue`1 | [DebuggerDisplayAttribute(...)] | 0 | Count = {Count} | +| System.Collections.Concurrent.ConcurrentQueue`1 | [DebuggerTypeProxyAttribute(...)] | 0 | System.Collections.Concurrent.IProducerConsumerCollectionDebugView`1 | +| System.Collections.Concurrent.ConcurrentQueue`1 | [NullableAttribute(...)] | 0 | 0 | +| System.Collections.Concurrent.ConcurrentQueue`1 | [NullableContextAttribute(...)] | 0 | 1 | +| System.Collections.Concurrent.IProducerConsumerCollection`1 | [NullableContextAttribute(...)] | 0 | 1 | +| System.Collections.Concurrent.PaddedHeadAndTail | [DebuggerDisplayAttribute(...)] | 0 | Head = {Head}, Tail = {Tail} | +| System.Collections.DictionaryEntry | [NullableAttribute(...)] | 0 | 0 | +| System.Collections.DictionaryEntry | [NullableContextAttribute(...)] | 0 | 1 | +| System.Collections.DictionaryEntry | [TypeForwardedFromAttribute(...)] | 0 | mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 | +| System.Collections.EmptyReadOnlyDictionaryInternal | [DefaultMemberAttribute(...)] | 0 | Item | +| System.Collections.Generic.ArraySortHelper`1 | [TypeDependencyAttribute(...)] | 0 | System.Collections.Generic.GenericArraySortHelper`1 | +| System.Collections.Generic.ArraySortHelper`2 | [TypeDependencyAttribute(...)] | 0 | System.Collections.Generic.GenericArraySortHelper`2 | +| System.Collections.Generic.ByteEqualityComparer | [TypeForwardedFromAttribute(...)] | 0 | mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 | +| System.Collections.Generic.Comparer`1 | [NullableAttribute(...)] | 0 | 0 | +| System.Collections.Generic.Comparer`1 | [NullableContextAttribute(...)] | 0 | 1 | +| System.Collections.Generic.Comparer`1 | [TypeDependencyAttribute(...)] | 0 | System.Collections.Generic.ObjectComparer`1 | +| System.Collections.Generic.Comparer`1 | [TypeForwardedFromAttribute(...)] | 0 | mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 | +| System.Collections.Generic.Dictionary<!0,!1>.KeyCollection System.Collections.Generic.Dictionary`2.Keys | [NullableAttribute(...)] | 0 | [1,0,0] | +| System.Collections.Generic.Dictionary<!0,!1>.ValueCollection System.Collections.Generic.Dictionary`2.Values | [NullableAttribute(...)] | 0 | [1,0,0] | +| System.Collections.Generic.Dictionary`2 | [DebuggerDisplayAttribute(...)] | 0 | Count = {Count} | +| System.Collections.Generic.Dictionary`2 | [DebuggerTypeProxyAttribute(...)] | 0 | System.Collections.Generic.IDictionaryDebugView`2 | +| System.Collections.Generic.Dictionary`2 | [DefaultMemberAttribute(...)] | 0 | Item | +| System.Collections.Generic.Dictionary`2 | [NullableAttribute(...)] | 0 | 0 | +| System.Collections.Generic.Dictionary`2 | [NullableContextAttribute(...)] | 0 | 1 | +| System.Collections.Generic.Dictionary`2 | [TypeForwardedFromAttribute(...)] | 0 | mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 | +| System.Collections.Generic.Dictionary`2.Enumerator | [NullableContextAttribute(...)] | 0 | 0 | +| System.Collections.Generic.Dictionary`2.KeyCollection | [DebuggerDisplayAttribute(...)] | 0 | Count = {Count} | +| System.Collections.Generic.Dictionary`2.KeyCollection | [DebuggerTypeProxyAttribute(...)] | 0 | System.Collections.Generic.DictionaryKeyCollectionDebugView`2 | +| System.Collections.Generic.Dictionary`2.KeyCollection | [NullableContextAttribute(...)] | 0 | 0 | +| System.Collections.Generic.Dictionary`2.ValueCollection | [DebuggerDisplayAttribute(...)] | 0 | Count = {Count} | +| System.Collections.Generic.Dictionary`2.ValueCollection | [DebuggerTypeProxyAttribute(...)] | 0 | System.Collections.Generic.DictionaryValueCollectionDebugView`2 | +| System.Collections.Generic.Dictionary`2.ValueCollection | [NullableContextAttribute(...)] | 0 | 0 | +| System.Collections.Generic.EnumEqualityComparer`1 | [TypeForwardedFromAttribute(...)] | 0 | mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 | +| System.Collections.Generic.EqualityComparer`1 | [NullableAttribute(...)] | 0 | 0 | +| System.Collections.Generic.EqualityComparer`1 | [NullableContextAttribute(...)] | 0 | 1 | +| System.Collections.Generic.EqualityComparer`1 | [TypeDependencyAttribute(...)] | 0 | System.Collections.Generic.ObjectEqualityComparer`1 | +| System.Collections.Generic.EqualityComparer`1 | [TypeForwardedFromAttribute(...)] | 0 | mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 | +| System.Collections.Generic.GenericComparer`1 | [NullableAttribute(...)] | 0 | [0,1] | +| System.Collections.Generic.GenericComparer`1 | [NullableContextAttribute(...)] | 0 | 1 | +| System.Collections.Generic.GenericComparer`1 | [TypeForwardedFromAttribute(...)] | 0 | mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 | +| System.Collections.Generic.GenericEqualityComparer`1 | [NullableAttribute(...)] | 0 | [0,1] | +| System.Collections.Generic.GenericEqualityComparer`1 | [TypeForwardedFromAttribute(...)] | 0 | mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 | +| System.Collections.Generic.IAsyncEnumerable`1 | [NullableContextAttribute(...)] | 0 | 1 | +| System.Collections.Generic.ICollection`1 | [NullableContextAttribute(...)] | 0 | 1 | +| System.Collections.Generic.IComparer`1 | [NullableContextAttribute(...)] | 0 | 1 | +| System.Collections.Generic.IDictionary<System.String,System.String> System.Diagnostics.Tracing.EventCommandEventArgs.Arguments | [NullableAttribute(...)] | 0 | [2,1,2] | +| System.Collections.Generic.IDictionary`2 | [DefaultMemberAttribute(...)] | 0 | Item | +| System.Collections.Generic.IDictionary`2 | [NullableContextAttribute(...)] | 0 | 1 | +| System.Collections.Generic.IEqualityComparer<System.String> System.Collections.Generic.NonRandomizedStringEqualityComparer.Default | [NullableAttribute(...)] | 0 | [1,2] | +| System.Collections.Generic.IEqualityComparer`1 | [NullableContextAttribute(...)] | 0 | 1 | +| System.Collections.Generic.IList<System.String> System.Runtime.CompilerServices.TupleElementNamesAttribute.TransformNames | [NullableAttribute(...)] | 0 | [1,2] | +| System.Collections.Generic.IList`1 | [DefaultMemberAttribute(...)] | 0 | Item | +| System.Collections.Generic.IList`1 | [NullableContextAttribute(...)] | 0 | 1 | +| System.Collections.Generic.IReadOnlyDictionary`2 | [DefaultMemberAttribute(...)] | 0 | Item | +| System.Collections.Generic.IReadOnlyDictionary`2 | [NullableContextAttribute(...)] | 0 | 1 | +| System.Collections.Generic.IReadOnlyList`1 | [DefaultMemberAttribute(...)] | 0 | Item | +| System.Collections.Generic.IReadOnlyList`1 | [NullableContextAttribute(...)] | 0 | 1 | +| System.Collections.Generic.ISet`1 | [NullableContextAttribute(...)] | 0 | 1 | +| System.Collections.Generic.KeyNotFoundException | [NullableAttribute(...)] | 0 | 0 | +| System.Collections.Generic.KeyNotFoundException | [NullableContextAttribute(...)] | 0 | 2 | +| System.Collections.Generic.KeyNotFoundException | [TypeForwardedFromAttribute(...)] | 0 | mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 | +| System.Collections.Generic.KeyValuePair<!0,!1> System.Collections.Generic.Dictionary`2.Enumerator.Current | [NullableAttribute(...)] | 0 | [0,1,1] | +| System.Collections.Generic.KeyValuePair<!0,!1>[] System.Collections.Generic.IDictionaryDebugView`2.Items | [DebuggerBrowsableAttribute(...)] | 0 | 3 | +| System.Collections.Generic.KeyValuePair`2 | [NullableAttribute(...)] | 0 | 0 | +| System.Collections.Generic.KeyValuePair`2 | [NullableContextAttribute(...)] | 0 | 1 | +| System.Collections.Generic.KeyValuePair`2 | [TypeForwardedFromAttribute(...)] | 0 | mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 | +| System.Collections.Generic.List<!0> System.Threading.ThreadLocal`1.ValuesForDebugDisplay | [NullableAttribute(...)] | 0 | [2,1] | +| System.Collections.Generic.List`1 | [DebuggerDisplayAttribute(...)] | 0 | Count = {Count} | +| System.Collections.Generic.List`1 | [DebuggerTypeProxyAttribute(...)] | 0 | System.Collections.Generic.ICollectionDebugView`1 | +| System.Collections.Generic.List`1 | [DefaultMemberAttribute(...)] | 0 | Item | +| System.Collections.Generic.List`1 | [NullableAttribute(...)] | 0 | 0 | +| System.Collections.Generic.List`1 | [NullableContextAttribute(...)] | 0 | 1 | +| System.Collections.Generic.List`1 | [TypeForwardedFromAttribute(...)] | 0 | mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 | +| System.Collections.Generic.List`1.Enumerator | [NullableContextAttribute(...)] | 0 | 0 | +| System.Collections.Generic.NonRandomizedStringEqualityComparer | [NullableAttribute(...)] | 0 | [0,2] | +| System.Collections.Generic.NonRandomizedStringEqualityComparer | [NullableContextAttribute(...)] | 0 | 2 | +| System.Collections.Generic.NullableComparer`1 | [TypeForwardedFromAttribute(...)] | 0 | mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 | +| System.Collections.Generic.NullableEqualityComparer`1 | [TypeForwardedFromAttribute(...)] | 0 | mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 | +| System.Collections.Generic.ObjectComparer`1 | [NullableAttribute(...)] | 0 | [0,1] | +| System.Collections.Generic.ObjectComparer`1 | [NullableContextAttribute(...)] | 0 | 2 | +| System.Collections.Generic.ObjectComparer`1 | [TypeForwardedFromAttribute(...)] | 0 | mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 | +| System.Collections.Generic.ObjectEqualityComparer`1 | [NullableAttribute(...)] | 0 | [0,1] | +| System.Collections.Generic.ObjectEqualityComparer`1 | [NullableContextAttribute(...)] | 0 | 1 | +| System.Collections.Generic.ObjectEqualityComparer`1 | [TypeForwardedFromAttribute(...)] | 0 | mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 | +| System.Collections.Generic.ValueListBuilder`1 | [DefaultMemberAttribute(...)] | 0 | Item | +| System.Collections.Generic.ValueListBuilder`1 | [ObsoleteAttribute(...)] | 0 | Types with embedded references are not supported in this version of your compiler. | +| System.Collections.Generic.ValueListBuilder`1 | [ObsoleteAttribute(...)] | 1 | True | +| System.Collections.Hashtable | [DebuggerDisplayAttribute(...)] | 0 | Count = {Count} | +| System.Collections.Hashtable | [DebuggerTypeProxyAttribute(...)] | 0 | System.Collections.Hashtable.HashtableDebugView | +| System.Collections.Hashtable | [DefaultMemberAttribute(...)] | 0 | Item | +| System.Collections.Hashtable | [NullableAttribute(...)] | 0 | 0 | +| System.Collections.Hashtable | [NullableContextAttribute(...)] | 0 | 1 | +| System.Collections.Hashtable | [TypeForwardedFromAttribute(...)] | 0 | mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 | +| System.Collections.Hashtable.SyncHashtable | [DefaultMemberAttribute(...)] | 0 | Item | +| System.Collections.ICollection | [NullableContextAttribute(...)] | 0 | 1 | +| System.Collections.IComparer | [NullableContextAttribute(...)] | 0 | 2 | +| System.Collections.IComparer System.Collections.Hashtable.comparer | [NullableAttribute(...)] | 0 | 2 | +| System.Collections.IComparer System.Collections.Hashtable.comparer | [ObsoleteAttribute(...)] | 0 | Please use KeyComparer properties. | +| System.Collections.IDictionary | [DefaultMemberAttribute(...)] | 0 | Item | +| System.Collections.IDictionary | [NullableContextAttribute(...)] | 0 | 1 | +| System.Collections.IDictionary System.Exception.Data | [NullableAttribute(...)] | 0 | 1 | +| System.Collections.IDictionaryEnumerator | [NullableContextAttribute(...)] | 0 | 1 | +| System.Collections.IEnumerable | [ComVisibleAttribute(...)] | 0 | True | +| System.Collections.IEnumerable | [GuidAttribute(...)] | 0 | 496B0ABE-CDEE-11d3-88E8-00902754C43A | +| System.Collections.IEnumerable | [NullableContextAttribute(...)] | 0 | 1 | +| System.Collections.IEnumerator | [NullableContextAttribute(...)] | 0 | 2 | +| System.Collections.IEqualityComparer | [NullableContextAttribute(...)] | 0 | 1 | +| System.Collections.IEqualityComparer System.Collections.Hashtable.EqualityComparer | [NullableAttribute(...)] | 0 | 2 | +| System.Collections.IHashCodeProvider | [NullableContextAttribute(...)] | 0 | 1 | +| System.Collections.IHashCodeProvider | [ObsoleteAttribute(...)] | 0 | Please use IEqualityComparer instead. | +| System.Collections.IHashCodeProvider | [TypeForwardedFromAttribute(...)] | 0 | mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 | +| System.Collections.IHashCodeProvider System.Collections.Hashtable.hcp | [NullableAttribute(...)] | 0 | 2 | +| System.Collections.IHashCodeProvider System.Collections.Hashtable.hcp | [ObsoleteAttribute(...)] | 0 | Please use EqualityComparer property. | +| System.Collections.IList | [DefaultMemberAttribute(...)] | 0 | Item | +| System.Collections.IList | [NullableContextAttribute(...)] | 0 | 2 | +| System.Collections.IStructuralComparable | [NullableContextAttribute(...)] | 0 | 1 | +| System.Collections.IStructuralEquatable | [NullableContextAttribute(...)] | 0 | 1 | +| System.Collections.KeyValuePairs | [DebuggerDisplayAttribute(...)] | 0 | {_value} | +| System.Collections.KeyValuePairs._key | [DebuggerBrowsableAttribute(...)] | 0 | 0 | +| System.Collections.KeyValuePairs._value | [DebuggerBrowsableAttribute(...)] | 0 | 0 | +| System.Collections.KeyValuePairs[] System.Collections.Hashtable.HashtableDebugView.Items | [DebuggerBrowsableAttribute(...)] | 0 | 3 | +| System.Collections.ListDictionaryInternal | [DefaultMemberAttribute(...)] | 0 | Item | +| System.Collections.ListDictionaryInternal | [NullableAttribute(...)] | 0 | 0 | +| System.Collections.ListDictionaryInternal | [NullableContextAttribute(...)] | 0 | 1 | +| System.Collections.ListDictionaryInternal | [TypeForwardedFromAttribute(...)] | 0 | mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 | +| System.Collections.ObjectModel.Collection`1 | [DebuggerDisplayAttribute(...)] | 0 | Count = {Count} | +| System.Collections.ObjectModel.Collection`1 | [DebuggerTypeProxyAttribute(...)] | 0 | System.Collections.Generic.ICollectionDebugView`1 | +| System.Collections.ObjectModel.Collection`1 | [DefaultMemberAttribute(...)] | 0 | Item | +| System.Collections.ObjectModel.Collection`1 | [NullableAttribute(...)] | 0 | 0 | +| System.Collections.ObjectModel.Collection`1 | [NullableContextAttribute(...)] | 0 | 1 | +| System.Collections.ObjectModel.Collection`1 | [TypeForwardedFromAttribute(...)] | 0 | mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 | +| System.Collections.ObjectModel.ReadOnlyCollection<System.String> System.Diagnostics.Tracing.EventWrittenEventArgs.PayloadNames | [NullableAttribute(...)] | 0 | [2,1] | +| System.Collections.ObjectModel.ReadOnlyCollection`1 | [DebuggerDisplayAttribute(...)] | 0 | Count = {Count} | +| System.Collections.ObjectModel.ReadOnlyCollection`1 | [DebuggerTypeProxyAttribute(...)] | 0 | System.Collections.Generic.ICollectionDebugView`1 | +| System.Collections.ObjectModel.ReadOnlyCollection`1 | [DefaultMemberAttribute(...)] | 0 | Item | +| System.Collections.ObjectModel.ReadOnlyCollection`1 | [NullableAttribute(...)] | 0 | 0 | +| System.Collections.ObjectModel.ReadOnlyCollection`1 | [NullableContextAttribute(...)] | 0 | 1 | +| System.Collections.ObjectModel.ReadOnlyCollection`1 | [TypeForwardedFromAttribute(...)] | 0 | mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 | +| System.ComponentModel.DefaultValueAttribute | [AttributeUsageAttribute(...)] | 0 | 32767 | +| System.ComponentModel.DefaultValueAttribute | [NullableAttribute(...)] | 0 | 0 | +| System.ComponentModel.DefaultValueAttribute | [NullableContextAttribute(...)] | 0 | 2 | +| System.ComponentModel.EditorBrowsableAttribute | [AttributeUsageAttribute(...)] | 0 | 6140 | +| System.Convert | [NullableAttribute(...)] | 0 | 0 | +| System.Convert | [NullableContextAttribute(...)] | 0 | 2 | +| System.Convert.DBNull | [NullableAttribute(...)] | 0 | 1 | +| System.CultureAwareComparer | [NullableAttribute(...)] | 0 | 0 | +| System.CultureAwareComparer | [NullableContextAttribute(...)] | 0 | 2 | +| System.CultureAwareComparer | [TypeForwardedFromAttribute(...)] | 0 | mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 | +| System.CurrentSystemTimeZone | [ObsoleteAttribute(...)] | 0 | System.CurrentSystemTimeZone has been deprecated. Please investigate the use of System.TimeZoneInfo.Local instead. | +| System.DBNull | [NullableAttribute(...)] | 0 | 0 | +| System.DBNull | [NullableContextAttribute(...)] | 0 | 1 | +| System.DTSubString | [DefaultMemberAttribute(...)] | 0 | Item | +| System.DTSubString | [ObsoleteAttribute(...)] | 0 | Types with embedded references are not supported in this version of your compiler. | +| System.DTSubString | [ObsoleteAttribute(...)] | 1 | True | +| System.DataMisalignedException | [NullableAttribute(...)] | 0 | 0 | +| System.DataMisalignedException | [NullableContextAttribute(...)] | 0 | 2 | +| System.DataMisalignedException | [TypeForwardedFromAttribute(...)] | 0 | mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 | +| System.DateTime | [NullableAttribute(...)] | 0 | 0 | +| System.DateTime | [NullableContextAttribute(...)] | 0 | 1 | +| System.DateTime | [TypeForwardedFromAttribute(...)] | 0 | mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 | +| System.DateTimeOffset | [TypeForwardedFromAttribute(...)] | 0 | mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 | +| System.DateTimeResult | [ObsoleteAttribute(...)] | 0 | Types with embedded references are not supported in this version of your compiler. | +| System.DateTimeResult | [ObsoleteAttribute(...)] | 1 | True | +| System.Delegate | [ClassInterfaceAttribute(...)] | 0 | 0 | +| System.Delegate | [ComVisibleAttribute(...)] | 0 | True | +| System.Delegate | [NullableAttribute(...)] | 0 | 0 | +| System.Delegate | [NullableContextAttribute(...)] | 0 | 1 | +| System.Diagnostics.CodeAnalysis.AllowNullAttribute | [AttributeUsageAttribute(...)] | 0 | 2432 | +| System.Diagnostics.CodeAnalysis.DisallowNullAttribute | [AttributeUsageAttribute(...)] | 0 | 2432 | +| System.Diagnostics.CodeAnalysis.DoesNotReturnAttribute | [AttributeUsageAttribute(...)] | 0 | 64 | +| System.Diagnostics.CodeAnalysis.DoesNotReturnIfAttribute | [AttributeUsageAttribute(...)] | 0 | 2048 | +| System.Diagnostics.CodeAnalysis.MaybeNullAttribute | [AttributeUsageAttribute(...)] | 0 | 10624 | +| System.Diagnostics.CodeAnalysis.MaybeNullWhenAttribute | [AttributeUsageAttribute(...)] | 0 | 2048 | +| System.Diagnostics.CodeAnalysis.NotNullAttribute | [AttributeUsageAttribute(...)] | 0 | 10624 | +| System.Diagnostics.CodeAnalysis.NotNullIfNotNullAttribute | [AttributeUsageAttribute(...)] | 0 | 10368 | +| System.Diagnostics.CodeAnalysis.NotNullIfNotNullAttribute | [NullableAttribute(...)] | 0 | 0 | +| System.Diagnostics.CodeAnalysis.NotNullIfNotNullAttribute | [NullableContextAttribute(...)] | 0 | 1 | +| System.Diagnostics.CodeAnalysis.NotNullWhenAttribute | [AttributeUsageAttribute(...)] | 0 | 2048 | +| System.Diagnostics.CodeAnalysis.SuppressMessageAttribute | [AttributeUsageAttribute(...)] | 0 | 32767 | +| System.Diagnostics.CodeAnalysis.SuppressMessageAttribute | [ConditionalAttribute(...)] | 0 | CODE_ANALYSIS | +| System.Diagnostics.CodeAnalysis.SuppressMessageAttribute | [NullableAttribute(...)] | 0 | 0 | +| System.Diagnostics.CodeAnalysis.SuppressMessageAttribute | [NullableContextAttribute(...)] | 0 | 2 | +| System.Diagnostics.ConditionalAttribute | [AttributeUsageAttribute(...)] | 0 | 68 | +| System.Diagnostics.ConditionalAttribute | [NullableAttribute(...)] | 0 | 0 | +| System.Diagnostics.ConditionalAttribute | [NullableContextAttribute(...)] | 0 | 1 | +| System.Diagnostics.Contracts.Contract | [NullableAttribute(...)] | 0 | 0 | +| System.Diagnostics.Contracts.Contract | [NullableContextAttribute(...)] | 0 | 1 | +| System.Diagnostics.Contracts.Contract.ContractFailed | [NullableAttribute(...)] | 0 | [2,1] | +| System.Diagnostics.Contracts.ContractAbbreviatorAttribute | [AttributeUsageAttribute(...)] | 0 | 64 | +| System.Diagnostics.Contracts.ContractAbbreviatorAttribute | [ConditionalAttribute(...)] | 0 | CONTRACTS_FULL | +| System.Diagnostics.Contracts.ContractArgumentValidatorAttribute | [AttributeUsageAttribute(...)] | 0 | 64 | +| System.Diagnostics.Contracts.ContractArgumentValidatorAttribute | [ConditionalAttribute(...)] | 0 | CONTRACTS_FULL | +| System.Diagnostics.Contracts.ContractClassAttribute | [AttributeUsageAttribute(...)] | 0 | 5124 | +| System.Diagnostics.Contracts.ContractClassAttribute | [ConditionalAttribute(...)] | 0 | CONTRACTS_FULL | +| System.Diagnostics.Contracts.ContractClassAttribute | [ConditionalAttribute(...)] | 0 | DEBUG | +| System.Diagnostics.Contracts.ContractClassAttribute | [NullableAttribute(...)] | 0 | 0 | +| System.Diagnostics.Contracts.ContractClassAttribute | [NullableContextAttribute(...)] | 0 | 1 | +| System.Diagnostics.Contracts.ContractClassForAttribute | [AttributeUsageAttribute(...)] | 0 | 4 | +| System.Diagnostics.Contracts.ContractClassForAttribute | [ConditionalAttribute(...)] | 0 | CONTRACTS_FULL | +| System.Diagnostics.Contracts.ContractClassForAttribute | [NullableAttribute(...)] | 0 | 0 | +| System.Diagnostics.Contracts.ContractClassForAttribute | [NullableContextAttribute(...)] | 0 | 1 | +| System.Diagnostics.Contracts.ContractException | [NullableAttribute(...)] | 0 | 0 | +| System.Diagnostics.Contracts.ContractException | [NullableContextAttribute(...)] | 0 | 2 | +| System.Diagnostics.Contracts.ContractException | [TypeForwardedFromAttribute(...)] | 0 | mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 | +| System.Diagnostics.Contracts.ContractFailedEventArgs | [NullableAttribute(...)] | 0 | 0 | +| System.Diagnostics.Contracts.ContractFailedEventArgs | [NullableContextAttribute(...)] | 0 | 2 | +| System.Diagnostics.Contracts.ContractFailureKind | [TypeForwardedFromAttribute(...)] | 0 | mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 | +| System.Diagnostics.Contracts.ContractInvariantMethodAttribute | [AttributeUsageAttribute(...)] | 0 | 64 | +| System.Diagnostics.Contracts.ContractInvariantMethodAttribute | [ConditionalAttribute(...)] | 0 | CONTRACTS_FULL | +| System.Diagnostics.Contracts.ContractOptionAttribute | [AttributeUsageAttribute(...)] | 0 | 32767 | +| System.Diagnostics.Contracts.ContractOptionAttribute | [ConditionalAttribute(...)] | 0 | CONTRACTS_FULL | +| System.Diagnostics.Contracts.ContractOptionAttribute | [NullableAttribute(...)] | 0 | 0 | +| System.Diagnostics.Contracts.ContractOptionAttribute | [NullableContextAttribute(...)] | 0 | 1 | +| System.Diagnostics.Contracts.ContractPublicPropertyNameAttribute | [AttributeUsageAttribute(...)] | 0 | 256 | +| System.Diagnostics.Contracts.ContractPublicPropertyNameAttribute | [ConditionalAttribute(...)] | 0 | CONTRACTS_FULL | +| System.Diagnostics.Contracts.ContractPublicPropertyNameAttribute | [NullableAttribute(...)] | 0 | 0 | +| System.Diagnostics.Contracts.ContractPublicPropertyNameAttribute | [NullableContextAttribute(...)] | 0 | 1 | +| System.Diagnostics.Contracts.ContractReferenceAssemblyAttribute | [AttributeUsageAttribute(...)] | 0 | 1 | +| System.Diagnostics.Contracts.ContractRuntimeIgnoredAttribute | [AttributeUsageAttribute(...)] | 0 | 192 | +| System.Diagnostics.Contracts.ContractRuntimeIgnoredAttribute | [ConditionalAttribute(...)] | 0 | CONTRACTS_FULL | +| System.Diagnostics.Contracts.ContractVerificationAttribute | [AttributeUsageAttribute(...)] | 0 | 237 | +| System.Diagnostics.Contracts.ContractVerificationAttribute | [ConditionalAttribute(...)] | 0 | CONTRACTS_FULL | +| System.Diagnostics.Contracts.PureAttribute | [AttributeUsageAttribute(...)] | 0 | 6884 | +| System.Diagnostics.Contracts.PureAttribute | [ConditionalAttribute(...)] | 0 | CONTRACTS_FULL | +| System.Diagnostics.Debug | [NullableAttribute(...)] | 0 | 0 | +| System.Diagnostics.Debug | [NullableContextAttribute(...)] | 0 | 2 | +| System.Diagnostics.DebugProvider | [NullableAttribute(...)] | 0 | 0 | +| System.Diagnostics.DebugProvider | [NullableContextAttribute(...)] | 0 | 2 | +| System.Diagnostics.DebuggableAttribute | [AttributeUsageAttribute(...)] | 0 | 3 | +| System.Diagnostics.Debugger | [NullableAttribute(...)] | 0 | 0 | +| System.Diagnostics.Debugger | [NullableContextAttribute(...)] | 0 | 2 | +| System.Diagnostics.DebuggerBrowsableAttribute | [AttributeUsageAttribute(...)] | 0 | 384 | +| System.Diagnostics.DebuggerDisplayAttribute | [AttributeUsageAttribute(...)] | 0 | 4509 | +| System.Diagnostics.DebuggerDisplayAttribute | [NullableAttribute(...)] | 0 | 0 | +| System.Diagnostics.DebuggerDisplayAttribute | [NullableContextAttribute(...)] | 0 | 2 | +| System.Diagnostics.DebuggerHiddenAttribute | [AttributeUsageAttribute(...)] | 0 | 224 | +| System.Diagnostics.DebuggerNonUserCodeAttribute | [AttributeUsageAttribute(...)] | 0 | 236 | +| System.Diagnostics.DebuggerStepThroughAttribute | [AttributeUsageAttribute(...)] | 0 | 108 | +| System.Diagnostics.DebuggerStepperBoundaryAttribute | [AttributeUsageAttribute(...)] | 0 | 96 | +| System.Diagnostics.DebuggerTypeProxyAttribute | [AttributeUsageAttribute(...)] | 0 | 13 | +| System.Diagnostics.DebuggerTypeProxyAttribute | [NullableAttribute(...)] | 0 | 0 | +| System.Diagnostics.DebuggerTypeProxyAttribute | [NullableContextAttribute(...)] | 0 | 2 | +| System.Diagnostics.DebuggerVisualizerAttribute | [AttributeUsageAttribute(...)] | 0 | 13 | +| System.Diagnostics.DebuggerVisualizerAttribute | [NullableAttribute(...)] | 0 | 0 | +| System.Diagnostics.DebuggerVisualizerAttribute | [NullableContextAttribute(...)] | 0 | 2 | +| System.Diagnostics.StackFrame | [NullableAttribute(...)] | 0 | 0 | +| System.Diagnostics.StackFrame | [NullableContextAttribute(...)] | 0 | 2 | +| System.Diagnostics.StackTrace | [NullableAttribute(...)] | 0 | 0 | +| System.Diagnostics.StackTrace | [NullableContextAttribute(...)] | 0 | 1 | +| System.Diagnostics.StackTraceHiddenAttribute | [AttributeUsageAttribute(...)] | 0 | 108 | +| System.Diagnostics.SymbolStore.ISymbolDocumentWriter | [NullableContextAttribute(...)] | 0 | 1 | +| System.Diagnostics.Tracing.DiagnosticCounter | [NullableAttribute(...)] | 0 | 0 | +| System.Diagnostics.Tracing.DiagnosticCounter | [NullableContextAttribute(...)] | 0 | 1 | +| System.Diagnostics.Tracing.EventAttribute | [AttributeUsageAttribute(...)] | 0 | 64 | +| System.Diagnostics.Tracing.EventAttribute | [NullableAttribute(...)] | 0 | 0 | +| System.Diagnostics.Tracing.EventAttribute | [NullableContextAttribute(...)] | 0 | 2 | +| System.Diagnostics.Tracing.EventChannelAttribute | [AttributeUsageAttribute(...)] | 0 | 256 | +| System.Diagnostics.Tracing.EventCounter | [NullableAttribute(...)] | 0 | 0 | +| System.Diagnostics.Tracing.EventCounter | [NullableContextAttribute(...)] | 0 | 1 | +| System.Diagnostics.Tracing.EventDataAttribute | [AttributeUsageAttribute(...)] | 0 | 12 | +| System.Diagnostics.Tracing.EventDataAttribute | [NullableAttribute(...)] | 0 | 0 | +| System.Diagnostics.Tracing.EventDataAttribute | [NullableContextAttribute(...)] | 0 | 2 | +| System.Diagnostics.Tracing.EventFieldAttribute | [AttributeUsageAttribute(...)] | 0 | 128 | +| System.Diagnostics.Tracing.EventIgnoreAttribute | [AttributeUsageAttribute(...)] | 0 | 128 | +| System.Diagnostics.Tracing.EventListener | [NullableAttribute(...)] | 0 | 0 | +| System.Diagnostics.Tracing.EventListener | [NullableContextAttribute(...)] | 0 | 1 | +| System.Diagnostics.Tracing.EventListener.EventSourceCreated | [NullableAttribute(...)] | 0 | [2,1] | +| System.Diagnostics.Tracing.EventListener.EventWritten | [NullableAttribute(...)] | 0 | [2,1] | +| System.Diagnostics.Tracing.EventPayload | [DefaultMemberAttribute(...)] | 0 | Item | +| System.Diagnostics.Tracing.EventSource | [NullableAttribute(...)] | 0 | 0 | +| System.Diagnostics.Tracing.EventSource | [NullableContextAttribute(...)] | 0 | 2 | +| System.Diagnostics.Tracing.EventSource System.Diagnostics.Tracing.EventWrittenEventArgs.EventSource | [NullableAttribute(...)] | 0 | 1 | +| System.Diagnostics.Tracing.EventSource.EventCommandExecuted | [NullableAttribute(...)] | 0 | [2,1] | +| System.Diagnostics.Tracing.EventSource.EventData | [NullableContextAttribute(...)] | 0 | 0 | +| System.Diagnostics.Tracing.EventSourceAttribute | [AttributeUsageAttribute(...)] | 0 | 4 | +| System.Diagnostics.Tracing.EventSourceAttribute | [NullableAttribute(...)] | 0 | 0 | +| System.Diagnostics.Tracing.EventSourceAttribute | [NullableContextAttribute(...)] | 0 | 2 | +| System.Diagnostics.Tracing.EventSourceCreatedEventArgs | [NullableAttribute(...)] | 0 | 0 | +| System.Diagnostics.Tracing.EventSourceCreatedEventArgs | [NullableContextAttribute(...)] | 0 | 2 | +| System.Diagnostics.Tracing.EventSourceException | [NullableAttribute(...)] | 0 | 0 | +| System.Diagnostics.Tracing.EventSourceException | [NullableContextAttribute(...)] | 0 | 2 | +| System.Diagnostics.Tracing.EventWrittenEventArgs | [NullableAttribute(...)] | 0 | 0 | +| System.Diagnostics.Tracing.EventWrittenEventArgs | [NullableContextAttribute(...)] | 0 | 2 | +| System.Diagnostics.Tracing.IncrementingEventCounter | [NullableAttribute(...)] | 0 | 0 | +| System.Diagnostics.Tracing.IncrementingEventCounter | [NullableContextAttribute(...)] | 0 | 1 | +| System.Diagnostics.Tracing.IncrementingPollingCounter | [NullableAttribute(...)] | 0 | 0 | +| System.Diagnostics.Tracing.IncrementingPollingCounter | [NullableContextAttribute(...)] | 0 | 1 | +| System.Diagnostics.Tracing.NonEventAttribute | [AttributeUsageAttribute(...)] | 0 | 64 | +| System.Diagnostics.Tracing.PollingCounter | [NullableAttribute(...)] | 0 | 0 | +| System.Diagnostics.Tracing.PollingCounter | [NullableContextAttribute(...)] | 0 | 1 | +| System.Diagnostics.Tracing.SessionMask | [DefaultMemberAttribute(...)] | 0 | Item | +| System.Diagnostics.Tracing.TraceLoggingEventHandleTable | [DefaultMemberAttribute(...)] | 0 | Item | +| System.DivideByZeroException | [NullableAttribute(...)] | 0 | 0 | +| System.DivideByZeroException | [NullableContextAttribute(...)] | 0 | 2 | +| System.DivideByZeroException | [TypeForwardedFromAttribute(...)] | 0 | mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 | +| System.DllNotFoundException | [NullableAttribute(...)] | 0 | 0 | +| System.DllNotFoundException | [NullableContextAttribute(...)] | 0 | 2 | +| System.DllNotFoundException | [TypeForwardedFromAttribute(...)] | 0 | mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 | +| System.DuplicateWaitObjectException | [NullableAttribute(...)] | 0 | 0 | +| System.DuplicateWaitObjectException | [NullableContextAttribute(...)] | 0 | 2 | +| System.DuplicateWaitObjectException | [TypeForwardedFromAttribute(...)] | 0 | mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 | +| System.EntryPointNotFoundException | [NullableAttribute(...)] | 0 | 0 | +| System.EntryPointNotFoundException | [NullableContextAttribute(...)] | 0 | 2 | +| System.EntryPointNotFoundException | [TypeForwardedFromAttribute(...)] | 0 | mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 | +| System.Enum | [NullableAttribute(...)] | 0 | 0 | +| System.Enum | [NullableContextAttribute(...)] | 0 | 1 | +| System.Enum | [TypeForwardedFromAttribute(...)] | 0 | mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 | +| System.Environment | [NullableAttribute(...)] | 0 | 0 | +| System.Environment | [NullableContextAttribute(...)] | 0 | 1 | +| System.Environment.SpecialFolder | [NullableContextAttribute(...)] | 0 | 0 | +| System.Environment.SpecialFolderOption | [NullableContextAttribute(...)] | 0 | 0 | +| System.EventArgs | [TypeForwardedFromAttribute(...)] | 0 | mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 | +| System.EventArgs.Empty | [NullableAttribute(...)] | 0 | 1 | +| System.Exception | [NullableAttribute(...)] | 0 | 0 | +| System.Exception | [NullableContextAttribute(...)] | 0 | 2 | +| System.Exception | [TypeForwardedFromAttribute(...)] | 0 | mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 | +| System.Exception.SerializeObjectState | [NullableAttribute(...)] | 0 | [2,1] | +| System.Exception[] System.Reflection.ReflectionTypeLoadException.LoaderExceptions | [NullableAttribute(...)] | 0 | 2 | +| System.ExecutionEngineException | [NullableAttribute(...)] | 0 | 0 | +| System.ExecutionEngineException | [NullableContextAttribute(...)] | 0 | 2 | +| System.ExecutionEngineException | [ObsoleteAttribute(...)] | 0 | This type previously indicated an unspecified fatal error in the runtime. The runtime no longer raises this exception so this type is obsolete. | +| System.ExecutionEngineException | [TypeForwardedFromAttribute(...)] | 0 | mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 | +| System.FieldAccessException | [NullableAttribute(...)] | 0 | 0 | +| System.FieldAccessException | [NullableContextAttribute(...)] | 0 | 2 | +| System.FieldAccessException | [TypeForwardedFromAttribute(...)] | 0 | mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 | +| System.FlagsAttribute | [AttributeUsageAttribute(...)] | 0 | 16 | +| System.FormatException | [NullableAttribute(...)] | 0 | 0 | +| System.FormatException | [NullableContextAttribute(...)] | 0 | 2 | +| System.FormatException | [TypeForwardedFromAttribute(...)] | 0 | mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 | +| System.FormattableString | [NullableAttribute(...)] | 0 | 0 | +| System.FormattableString | [NullableContextAttribute(...)] | 0 | 1 | +| System.Func`5 | [NullableAttribute(...)] | 0 | 0 | +| System.Func`5 | [NullableContextAttribute(...)] | 0 | 2 | +| System.Func`6 | [NullableAttribute(...)] | 0 | 0 | +| System.Func`6 | [NullableContextAttribute(...)] | 0 | 2 | +| System.Func`7 | [NullableAttribute(...)] | 0 | 0 | +| System.Func`7 | [NullableContextAttribute(...)] | 0 | 2 | +| System.Func`8 | [NullableAttribute(...)] | 0 | 0 | +| System.Func`8 | [NullableContextAttribute(...)] | 0 | 2 | +| System.Func`9 | [NullableAttribute(...)] | 0 | 0 | +| System.Func`9 | [NullableContextAttribute(...)] | 0 | 2 | +| System.Func`10 | [NullableAttribute(...)] | 0 | 0 | +| System.Func`10 | [NullableContextAttribute(...)] | 0 | 2 | +| System.Func`11 | [NullableAttribute(...)] | 0 | 0 | +| System.Func`11 | [NullableContextAttribute(...)] | 0 | 2 | +| System.Func`12 | [NullableAttribute(...)] | 0 | 0 | +| System.Func`12 | [NullableContextAttribute(...)] | 0 | 2 | +| System.Func`13 | [NullableAttribute(...)] | 0 | 0 | +| System.Func`13 | [NullableContextAttribute(...)] | 0 | 2 | +| System.Func`14 | [NullableAttribute(...)] | 0 | 0 | +| System.Func`14 | [NullableContextAttribute(...)] | 0 | 2 | +| System.Func`15 | [NullableAttribute(...)] | 0 | 0 | +| System.Func`15 | [NullableContextAttribute(...)] | 0 | 2 | +| System.Func`16 | [NullableAttribute(...)] | 0 | 0 | +| System.Func`16 | [NullableContextAttribute(...)] | 0 | 2 | +| System.Func`17 | [NullableAttribute(...)] | 0 | 0 | +| System.Func`17 | [NullableContextAttribute(...)] | 0 | 2 | +| System.GC | [NullableAttribute(...)] | 0 | 0 | +| System.GC | [NullableContextAttribute(...)] | 0 | 1 | +| System.Globalization.Calendar | [NullableAttribute(...)] | 0 | 0 | +| System.Globalization.Calendar | [NullableContextAttribute(...)] | 0 | 1 | +| System.Globalization.ChineseLunisolarCalendar | [NullableAttribute(...)] | 0 | 0 | +| System.Globalization.ChineseLunisolarCalendar | [NullableContextAttribute(...)] | 0 | 1 | +| System.Globalization.CompareInfo | [NullableAttribute(...)] | 0 | 0 | +| System.Globalization.CompareInfo | [NullableContextAttribute(...)] | 0 | 1 | +| System.Globalization.CompareInfo | [TypeForwardedFromAttribute(...)] | 0 | mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 | +| System.Globalization.CultureInfo | [NullableAttribute(...)] | 0 | 0 | +| System.Globalization.CultureInfo | [NullableContextAttribute(...)] | 0 | 1 | +| System.Globalization.CultureInfo System.Globalization.CultureInfo.DefaultThreadCurrentCulture | [NullableAttribute(...)] | 0 | 2 | +| System.Globalization.CultureInfo System.Globalization.CultureInfo.DefaultThreadCurrentUICulture | [NullableAttribute(...)] | 0 | 2 | +| System.Globalization.CultureNotFoundException | [NullableAttribute(...)] | 0 | 0 | +| System.Globalization.CultureNotFoundException | [NullableContextAttribute(...)] | 0 | 2 | +| System.Globalization.CultureNotFoundException | [TypeForwardedFromAttribute(...)] | 0 | mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 | +| System.Globalization.CultureTypes.FrameworkCultures | [ObsoleteAttribute(...)] | 0 | This value has been deprecated. Please use other values in CultureTypes. | +| System.Globalization.CultureTypes.WindowsOnlyCultures | [ObsoleteAttribute(...)] | 0 | This value has been deprecated. Please use other values in CultureTypes. | +| System.Globalization.DateTimeFormatInfo | [NullableAttribute(...)] | 0 | 0 | +| System.Globalization.DateTimeFormatInfo | [NullableContextAttribute(...)] | 0 | 1 | +| System.Globalization.EraInfo[] System.Globalization.ChineseLunisolarCalendar.CalEraInfo | [NullableAttribute(...)] | 0 | [2,1] | +| System.Globalization.EraInfo[] System.Globalization.EastAsianLunisolarCalendar.CalEraInfo | [NullableAttribute(...)] | 0 | [2,1] | +| System.Globalization.EraInfo[] System.Globalization.JapaneseLunisolarCalendar.CalEraInfo | [NullableAttribute(...)] | 0 | [2,1] | +| System.Globalization.EraInfo[] System.Globalization.KoreanLunisolarCalendar.CalEraInfo | [NullableAttribute(...)] | 0 | [2,1] | +| System.Globalization.EraInfo[] System.Globalization.TaiwanLunisolarCalendar.CalEraInfo | [NullableAttribute(...)] | 0 | [2,1] | +| System.Globalization.GregorianCalendar | [NullableAttribute(...)] | 0 | 0 | +| System.Globalization.GregorianCalendar | [NullableContextAttribute(...)] | 0 | 1 | +| System.Globalization.HebrewCalendar | [NullableAttribute(...)] | 0 | 0 | +| System.Globalization.HebrewCalendar | [NullableContextAttribute(...)] | 0 | 1 | +| System.Globalization.HijriCalendar | [NullableAttribute(...)] | 0 | 0 | +| System.Globalization.HijriCalendar | [NullableContextAttribute(...)] | 0 | 1 | +| System.Globalization.IdnMapping | [NullableAttribute(...)] | 0 | 0 | +| System.Globalization.IdnMapping | [NullableContextAttribute(...)] | 0 | 1 | +| System.Globalization.JapaneseCalendar | [NullableAttribute(...)] | 0 | 0 | +| System.Globalization.JapaneseCalendar | [NullableContextAttribute(...)] | 0 | 1 | +| System.Globalization.JapaneseLunisolarCalendar | [NullableAttribute(...)] | 0 | 0 | +| System.Globalization.JapaneseLunisolarCalendar | [NullableContextAttribute(...)] | 0 | 1 | +| System.Globalization.JulianCalendar | [NullableAttribute(...)] | 0 | 0 | +| System.Globalization.JulianCalendar | [NullableContextAttribute(...)] | 0 | 1 | +| System.Globalization.KoreanCalendar | [NullableAttribute(...)] | 0 | 0 | +| System.Globalization.KoreanCalendar | [NullableContextAttribute(...)] | 0 | 1 | +| System.Globalization.KoreanLunisolarCalendar | [NullableAttribute(...)] | 0 | 0 | +| System.Globalization.KoreanLunisolarCalendar | [NullableContextAttribute(...)] | 0 | 1 | +| System.Globalization.NumberFormatInfo | [NullableAttribute(...)] | 0 | 0 | +| System.Globalization.NumberFormatInfo | [NullableContextAttribute(...)] | 0 | 1 | +| System.Globalization.PersianCalendar | [NullableAttribute(...)] | 0 | 0 | +| System.Globalization.PersianCalendar | [NullableContextAttribute(...)] | 0 | 1 | +| System.Globalization.RegionInfo | [NullableAttribute(...)] | 0 | 0 | +| System.Globalization.RegionInfo | [NullableContextAttribute(...)] | 0 | 1 | +| System.Globalization.SortKey | [NullableAttribute(...)] | 0 | 0 | +| System.Globalization.SortKey | [NullableContextAttribute(...)] | 0 | 1 | +| System.Globalization.SortVersion | [NullableAttribute(...)] | 0 | 0 | +| System.Globalization.SortVersion | [NullableContextAttribute(...)] | 0 | 2 | +| System.Globalization.SortVersion | [TypeForwardedFromAttribute(...)] | 0 | mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 | +| System.Globalization.StringInfo | [NullableAttribute(...)] | 0 | 0 | +| System.Globalization.StringInfo | [NullableContextAttribute(...)] | 0 | 1 | +| System.Globalization.TaiwanCalendar | [NullableAttribute(...)] | 0 | 0 | +| System.Globalization.TaiwanCalendar | [NullableContextAttribute(...)] | 0 | 1 | +| System.Globalization.TaiwanLunisolarCalendar | [NullableAttribute(...)] | 0 | 0 | +| System.Globalization.TaiwanLunisolarCalendar | [NullableContextAttribute(...)] | 0 | 1 | +| System.Globalization.TextElementEnumerator | [NullableAttribute(...)] | 0 | 0 | +| System.Globalization.TextElementEnumerator | [NullableContextAttribute(...)] | 0 | 1 | +| System.Globalization.TextInfo | [NullableAttribute(...)] | 0 | 0 | +| System.Globalization.TextInfo | [NullableContextAttribute(...)] | 0 | 1 | +| System.Globalization.ThaiBuddhistCalendar | [NullableAttribute(...)] | 0 | 0 | +| System.Globalization.ThaiBuddhistCalendar | [NullableContextAttribute(...)] | 0 | 1 | +| System.Globalization.TimeSpanParse.StringParser | [ObsoleteAttribute(...)] | 0 | Types with embedded references are not supported in this version of your compiler. | +| System.Globalization.TimeSpanParse.StringParser | [ObsoleteAttribute(...)] | 1 | True | +| System.Globalization.TimeSpanParse.TimeSpanRawInfo | [ObsoleteAttribute(...)] | 0 | Types with embedded references are not supported in this version of your compiler. | +| System.Globalization.TimeSpanParse.TimeSpanRawInfo | [ObsoleteAttribute(...)] | 1 | True | +| System.Globalization.TimeSpanParse.TimeSpanResult | [ObsoleteAttribute(...)] | 0 | Types with embedded references are not supported in this version of your compiler. | +| System.Globalization.TimeSpanParse.TimeSpanResult | [ObsoleteAttribute(...)] | 1 | True | +| System.Globalization.TimeSpanParse.TimeSpanToken | [ObsoleteAttribute(...)] | 0 | Types with embedded references are not supported in this version of your compiler. | +| System.Globalization.TimeSpanParse.TimeSpanToken | [ObsoleteAttribute(...)] | 1 | True | +| System.Globalization.TimeSpanParse.TimeSpanTokenizer | [ObsoleteAttribute(...)] | 0 | Types with embedded references are not supported in this version of your compiler. | +| System.Globalization.TimeSpanParse.TimeSpanTokenizer | [ObsoleteAttribute(...)] | 1 | True | +| System.Globalization.UmAlQuraCalendar | [NullableAttribute(...)] | 0 | 0 | +| System.Globalization.UmAlQuraCalendar | [NullableContextAttribute(...)] | 0 | 1 | +| System.Guid | [TypeForwardedFromAttribute(...)] | 0 | mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 | +| System.HashCode | [NullableAttribute(...)] | 0 | 0 | +| System.HashCode | [NullableContextAttribute(...)] | 0 | 1 | +| System.IAsyncResult | [NullableContextAttribute(...)] | 0 | 1 | +| System.ICloneable | [NullableContextAttribute(...)] | 0 | 1 | +| System.IComparable | [NullableContextAttribute(...)] | 0 | 2 | +| System.IComparable`1 | [NullableContextAttribute(...)] | 0 | 1 | +| System.IConvertible | [CLSCompliantAttribute(...)] | 0 | False | +| System.IConvertible | [NullableContextAttribute(...)] | 0 | 2 | +| System.ICustomFormatter | [NullableContextAttribute(...)] | 0 | 2 | +| System.IEquatable`1 | [NullableContextAttribute(...)] | 0 | 1 | +| System.IFormatProvider | [NullableContextAttribute(...)] | 0 | 2 | +| System.IFormattable | [NullableContextAttribute(...)] | 0 | 2 | +| System.IO.BinaryReader | [NullableAttribute(...)] | 0 | 0 | +| System.IO.BinaryReader | [NullableContextAttribute(...)] | 0 | 1 | +| System.IO.BinaryWriter | [NullableAttribute(...)] | 0 | 0 | +| System.IO.BinaryWriter | [NullableContextAttribute(...)] | 0 | 1 | +| System.IO.DirectoryNotFoundException | [NullableAttribute(...)] | 0 | 0 | +| System.IO.DirectoryNotFoundException | [NullableContextAttribute(...)] | 0 | 2 | +| System.IO.DirectoryNotFoundException | [TypeForwardedFromAttribute(...)] | 0 | mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 | +| System.IO.EndOfStreamException | [NullableAttribute(...)] | 0 | 0 | +| System.IO.EndOfStreamException | [NullableContextAttribute(...)] | 0 | 2 | +| System.IO.EndOfStreamException | [TypeForwardedFromAttribute(...)] | 0 | mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 | +| System.IO.FileLoadException | [NullableAttribute(...)] | 0 | 0 | +| System.IO.FileLoadException | [NullableContextAttribute(...)] | 0 | 2 | +| System.IO.FileLoadException | [TypeForwardedFromAttribute(...)] | 0 | mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 | +| System.IO.FileNotFoundException | [NullableAttribute(...)] | 0 | 0 | +| System.IO.FileNotFoundException | [NullableContextAttribute(...)] | 0 | 2 | +| System.IO.FileNotFoundException | [TypeForwardedFromAttribute(...)] | 0 | mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 | +| System.IO.FileStream | [NullableAttribute(...)] | 0 | 0 | +| System.IO.FileStream | [NullableContextAttribute(...)] | 0 | 1 | +| System.IO.IOException | [NullableAttribute(...)] | 0 | 0 | +| System.IO.IOException | [NullableContextAttribute(...)] | 0 | 2 | +| System.IO.IOException | [TypeForwardedFromAttribute(...)] | 0 | mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 | +| System.IO.MemoryStream | [NullableAttribute(...)] | 0 | 0 | +| System.IO.MemoryStream | [NullableContextAttribute(...)] | 0 | 1 | +| System.IO.Path.<>c.<>9__37_0 | [TupleElementNamesAttribute(...)] | 0 | [First,FirstLength,Second,SecondLength,HasSeparator] | +| System.IO.Path.<>c.<>9__38_0 | [TupleElementNamesAttribute(...)] | 0 | [First,FirstLength,Second,SecondLength,Third,ThirdLength,FirstHasSeparator,ThirdHasSeparator,null] | +| System.IO.Path.<>c.<>9__39_0 | [TupleElementNamesAttribute(...)] | 0 | [First,FirstLength,Second,SecondLength,Third,ThirdLength,Fourth,FourthLength,FirstHasSeparator,ThirdHasSeparator,FourthHasSeparator,null,null,null,null] | +| System.IO.Path.InvalidPathChars | [NullableAttribute(...)] | 0 | 1 | +| System.IO.Path.InvalidPathChars | [ObsoleteAttribute(...)] | 0 | Please use GetInvalidPathChars or GetInvalidFileNameChars instead. | +| System.IO.PathTooLongException | [NullableAttribute(...)] | 0 | 0 | +| System.IO.PathTooLongException | [NullableContextAttribute(...)] | 0 | 2 | +| System.IO.PathTooLongException | [TypeForwardedFromAttribute(...)] | 0 | mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 | +| System.IO.Stream | [NullableAttribute(...)] | 0 | 0 | +| System.IO.Stream | [NullableContextAttribute(...)] | 0 | 1 | +| System.IO.StreamReader | [NullableAttribute(...)] | 0 | 0 | +| System.IO.StreamReader | [NullableContextAttribute(...)] | 0 | 1 | +| System.IO.StreamWriter | [NullableAttribute(...)] | 0 | 0 | +| System.IO.StreamWriter | [NullableContextAttribute(...)] | 0 | 1 | +| System.IO.TextReader | [NullableAttribute(...)] | 0 | 0 | +| System.IO.TextReader | [NullableContextAttribute(...)] | 0 | 1 | +| System.IO.TextWriter | [NullableAttribute(...)] | 0 | 0 | +| System.IO.TextWriter | [NullableContextAttribute(...)] | 0 | 1 | +| System.IObservable`1 | [NullableContextAttribute(...)] | 0 | 1 | +| System.IObserver`1 | [NullableContextAttribute(...)] | 0 | 1 | +| System.IProgress`1 | [NullableContextAttribute(...)] | 0 | 1 | +| System.IndexOutOfRangeException | [NullableAttribute(...)] | 0 | 0 | +| System.IndexOutOfRangeException | [NullableContextAttribute(...)] | 0 | 2 | +| System.IndexOutOfRangeException | [TypeForwardedFromAttribute(...)] | 0 | mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 | +| System.InsufficientExecutionStackException | [NullableAttribute(...)] | 0 | 0 | +| System.InsufficientExecutionStackException | [NullableContextAttribute(...)] | 0 | 2 | +| System.InsufficientExecutionStackException | [TypeForwardedFromAttribute(...)] | 0 | mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 | +| System.InsufficientMemoryException | [NullableAttribute(...)] | 0 | 0 | +| System.InsufficientMemoryException | [NullableContextAttribute(...)] | 0 | 2 | +| System.InsufficientMemoryException | [TypeForwardedFromAttribute(...)] | 0 | mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 | +| System.IntPtr | [TypeForwardedFromAttribute(...)] | 0 | mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 | +| System.IntPtr System.IO.FileStream.Handle | [ObsoleteAttribute(...)] | 0 | This property has been deprecated. Please use FileStream's SafeFileHandle property instead. https://go.microsoft.com/fwlink/?linkid=14202 | +| System.IntPtr System.Threading.WaitHandle.Handle | [ObsoleteAttribute(...)] | 0 | Use the SafeWaitHandle property instead. | +| System.InvalidCastException | [NullableAttribute(...)] | 0 | 0 | +| System.InvalidCastException | [NullableContextAttribute(...)] | 0 | 2 | +| System.InvalidCastException | [TypeForwardedFromAttribute(...)] | 0 | mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 | +| System.InvalidOperationException | [NullableAttribute(...)] | 0 | 0 | +| System.InvalidOperationException | [NullableContextAttribute(...)] | 0 | 2 | +| System.InvalidOperationException | [TypeForwardedFromAttribute(...)] | 0 | mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 | +| System.InvalidProgramException | [NullableAttribute(...)] | 0 | 0 | +| System.InvalidProgramException | [NullableContextAttribute(...)] | 0 | 2 | +| System.InvalidProgramException | [TypeForwardedFromAttribute(...)] | 0 | mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 | +| System.InvalidTimeZoneException | [NullableAttribute(...)] | 0 | 0 | +| System.InvalidTimeZoneException | [NullableContextAttribute(...)] | 0 | 2 | +| System.InvalidTimeZoneException | [TypeForwardedFromAttribute(...)] | 0 | System.Core, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 | +| System.Lazy`1 | [DebuggerDisplayAttribute(...)] | 0 | ThreadSafetyMode={Mode}, IsValueCreated={IsValueCreated}, IsValueFaulted={IsValueFaulted}, Value={ValueForDebugDisplay} | +| System.Lazy`1 | [DebuggerTypeProxyAttribute(...)] | 0 | System.LazyDebugView`1 | +| System.Lazy`1 | [NullableAttribute(...)] | 0 | 0 | +| System.Lazy`1 | [NullableContextAttribute(...)] | 0 | 1 | +| System.Lazy`2 | [NullableAttribute(...)] | 0 | [0,1] | +| System.Lazy`2 | [NullableContextAttribute(...)] | 0 | 1 | +| System.MTAThreadAttribute | [AttributeUsageAttribute(...)] | 0 | 64 | +| System.MarshalByRefObject | [ClassInterfaceAttribute(...)] | 0 | 1 | +| System.MarshalByRefObject | [ComVisibleAttribute(...)] | 0 | True | +| System.MarshalByRefObject | [NullableAttribute(...)] | 0 | 0 | +| System.MarshalByRefObject | [NullableContextAttribute(...)] | 0 | 1 | +| System.MemberAccessException | [NullableAttribute(...)] | 0 | 0 | +| System.MemberAccessException | [NullableContextAttribute(...)] | 0 | 2 | +| System.MemberAccessException | [TypeForwardedFromAttribute(...)] | 0 | mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 | +| System.Memory<!0> System.Buffers.IMemoryOwner`1.Memory | [NullableAttribute(...)] | 0 | [0,1] | +| System.Memory<!0> System.Buffers.MemoryManager`1.Memory | [NullableAttribute(...)] | 0 | [0,1] | +| System.Memory<!0> System.Memory`1.Empty | [NullableAttribute(...)] | 0 | [0,1] | +| System.Memory`1 | [DebuggerDisplayAttribute(...)] | 0 | {ToString(),raw} | +| System.Memory`1 | [DebuggerTypeProxyAttribute(...)] | 0 | System.MemoryDebugView`1 | +| System.Memory`1 | [NullableAttribute(...)] | 0 | 0 | +| System.Memory`1 | [NullableContextAttribute(...)] | 0 | 1 | +| System.MethodAccessException | [NullableAttribute(...)] | 0 | 0 | +| System.MethodAccessException | [NullableContextAttribute(...)] | 0 | 2 | +| System.MethodAccessException | [TypeForwardedFromAttribute(...)] | 0 | mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 | +| System.MissingFieldException | [NullableAttribute(...)] | 0 | 0 | +| System.MissingFieldException | [NullableContextAttribute(...)] | 0 | 1 | +| System.MissingFieldException | [TypeForwardedFromAttribute(...)] | 0 | mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 | +| System.MissingMemberException | [NullableAttribute(...)] | 0 | 0 | +| System.MissingMemberException | [NullableContextAttribute(...)] | 0 | 2 | +| System.MissingMemberException | [TypeForwardedFromAttribute(...)] | 0 | mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 | +| System.MissingMethodException | [NullableAttribute(...)] | 0 | 0 | +| System.MissingMethodException | [NullableContextAttribute(...)] | 0 | 1 | +| System.MissingMethodException | [TypeForwardedFromAttribute(...)] | 0 | mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 | +| System.ModuleHandle | [NullableAttribute(...)] | 0 | 0 | +| System.ModuleHandle | [NullableContextAttribute(...)] | 0 | 2 | +| System.MulticastDelegate | [ClassInterfaceAttribute(...)] | 0 | 0 | +| System.MulticastDelegate | [ComVisibleAttribute(...)] | 0 | True | +| System.MulticastDelegate | [NullableAttribute(...)] | 0 | 0 | +| System.MulticastDelegate | [NullableContextAttribute(...)] | 0 | 1 | +| System.MulticastNotSupportedException | [NullableAttribute(...)] | 0 | 0 | +| System.MulticastNotSupportedException | [NullableContextAttribute(...)] | 0 | 2 | +| System.MulticastNotSupportedException | [TypeForwardedFromAttribute(...)] | 0 | mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 | +| System.NonSerializedAttribute | [AttributeUsageAttribute(...)] | 0 | 256 | +| System.NotFiniteNumberException | [NullableAttribute(...)] | 0 | 0 | +| System.NotFiniteNumberException | [NullableContextAttribute(...)] | 0 | 2 | +| System.NotFiniteNumberException | [TypeForwardedFromAttribute(...)] | 0 | mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 | +| System.NotImplementedException | [NullableAttribute(...)] | 0 | 0 | +| System.NotImplementedException | [NullableContextAttribute(...)] | 0 | 2 | +| System.NotImplementedException | [TypeForwardedFromAttribute(...)] | 0 | mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 | +| System.NotSupportedException | [NullableAttribute(...)] | 0 | 0 | +| System.NotSupportedException | [NullableContextAttribute(...)] | 0 | 2 | +| System.NotSupportedException | [TypeForwardedFromAttribute(...)] | 0 | mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 | +| System.NullReferenceException | [NullableAttribute(...)] | 0 | 0 | +| System.NullReferenceException | [NullableContextAttribute(...)] | 0 | 2 | +| System.NullReferenceException | [TypeForwardedFromAttribute(...)] | 0 | mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 | +| System.Nullable`1 | [TypeForwardedFromAttribute(...)] | 0 | mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 | +| System.Number.BigInteger | [ObsoleteAttribute(...)] | 0 | Types with embedded references are not supported in this version of your compiler. | +| System.Number.BigInteger | [ObsoleteAttribute(...)] | 1 | True | +| System.Number.BigInteger._blocks | [FixedBufferAttribute(...)] | 0 | System.UInt32 | +| System.Number.BigInteger._blocks | [FixedBufferAttribute(...)] | 1 | 115 | +| System.Number.DiyFp | [ObsoleteAttribute(...)] | 0 | Types with embedded references are not supported in this version of your compiler. | +| System.Number.DiyFp | [ObsoleteAttribute(...)] | 1 | True | +| System.Number.NumberBuffer | [ObsoleteAttribute(...)] | 0 | Types with embedded references are not supported in this version of your compiler. | +| System.Number.NumberBuffer | [ObsoleteAttribute(...)] | 1 | True | +| System.Numerics.Vector`1 | [DefaultMemberAttribute(...)] | 0 | Item | +| System.ObjectDisposedException | [NullableAttribute(...)] | 0 | 0 | +| System.ObjectDisposedException | [NullableContextAttribute(...)] | 0 | 1 | +| System.ObjectDisposedException | [TypeForwardedFromAttribute(...)] | 0 | mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 | +| System.ObsoleteAttribute | [AttributeUsageAttribute(...)] | 0 | 6140 | +| System.ObsoleteAttribute | [NullableAttribute(...)] | 0 | 0 | +| System.ObsoleteAttribute | [NullableContextAttribute(...)] | 0 | 2 | +| System.OperatingSystem | [NullableAttribute(...)] | 0 | 0 | +| System.OperatingSystem | [NullableContextAttribute(...)] | 0 | 1 | +| System.OperationCanceledException | [NullableAttribute(...)] | 0 | 0 | +| System.OperationCanceledException | [NullableContextAttribute(...)] | 0 | 2 | +| System.OperationCanceledException | [TypeForwardedFromAttribute(...)] | 0 | mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 | +| System.OrdinalComparer | [NullableAttribute(...)] | 0 | 0 | +| System.OrdinalComparer | [NullableContextAttribute(...)] | 0 | 2 | +| System.OrdinalComparer | [TypeForwardedFromAttribute(...)] | 0 | mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 | +| System.OutOfMemoryException | [NullableAttribute(...)] | 0 | 0 | +| System.OutOfMemoryException | [NullableContextAttribute(...)] | 0 | 2 | +| System.OutOfMemoryException | [TypeForwardedFromAttribute(...)] | 0 | mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 | +| System.OverflowException | [NullableAttribute(...)] | 0 | 0 | +| System.OverflowException | [NullableContextAttribute(...)] | 0 | 2 | +| System.OverflowException | [TypeForwardedFromAttribute(...)] | 0 | mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 | +| System.ParamArrayAttribute | [AttributeUsageAttribute(...)] | 0 | 2048 | +| System.ParamsArray | [DefaultMemberAttribute(...)] | 0 | Item | +| System.PlatformID.MacOSX | [EditorBrowsableAttribute(...)] | 0 | 1 | +| System.PlatformID.Win32S | [EditorBrowsableAttribute(...)] | 0 | 1 | +| System.PlatformID.Win32Windows | [EditorBrowsableAttribute(...)] | 0 | 1 | +| System.PlatformID.WinCE | [EditorBrowsableAttribute(...)] | 0 | 1 | +| System.PlatformID.Xbox | [EditorBrowsableAttribute(...)] | 0 | 1 | +| System.PlatformNotSupportedException | [NullableAttribute(...)] | 0 | 0 | +| System.PlatformNotSupportedException | [NullableContextAttribute(...)] | 0 | 2 | +| System.PlatformNotSupportedException | [TypeForwardedFromAttribute(...)] | 0 | mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 | +| System.Progress`1 | [NullableAttribute(...)] | 0 | 0 | +| System.Progress`1 | [NullableContextAttribute(...)] | 0 | 1 | +| System.Progress`1.ProgressChanged | [NullableAttribute(...)] | 0 | [2,1] | +| System.RankException | [NullableAttribute(...)] | 0 | 0 | +| System.RankException | [NullableContextAttribute(...)] | 0 | 2 | +| System.RankException | [TypeForwardedFromAttribute(...)] | 0 | mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 | +| System.ReadOnlyMemory<!0> System.ReadOnlyMemory`1.Empty | [NullableAttribute(...)] | 0 | [0,1] | +| System.ReadOnlyMemory`1 | [DebuggerDisplayAttribute(...)] | 0 | {ToString(),raw} | +| System.ReadOnlyMemory`1 | [DebuggerTypeProxyAttribute(...)] | 0 | System.MemoryDebugView`1 | +| System.ReadOnlyMemory`1 | [NullableAttribute(...)] | 0 | 0 | +| System.ReadOnlyMemory`1 | [NullableContextAttribute(...)] | 0 | 1 | +| System.ReadOnlySpan<!0> System.ReadOnlyMemory`1.Span | [NullableAttribute(...)] | 0 | [0,1] | +| System.ReadOnlySpan<!0> System.ReadOnlySpan`1.Empty | [NullableAttribute(...)] | 0 | [0,1] | +| System.ReadOnlySpan<System.Byte> System.Text.Encoding.Preamble | [NullableAttribute(...)] | 0 | 0 | +| System.ReadOnlySpan<System.Byte> System.Text.UTF32Encoding.Preamble | [NullableAttribute(...)] | 0 | 0 | +| System.ReadOnlySpan<System.Byte> System.Text.UnicodeEncoding.Preamble | [NullableAttribute(...)] | 0 | 0 | +| System.ReadOnlySpan<System.Byte> char.CategoryForLatin1 | [NullableAttribute(...)] | 0 | 0 | +| System.ReadOnlySpan`1 | [DebuggerDisplayAttribute(...)] | 0 | {ToString(),raw} | +| System.ReadOnlySpan`1 | [DebuggerTypeProxyAttribute(...)] | 0 | System.SpanDebugView`1 | +| System.ReadOnlySpan`1 | [DefaultMemberAttribute(...)] | 0 | Item | +| System.ReadOnlySpan`1 | [NullableAttribute(...)] | 0 | 0 | +| System.ReadOnlySpan`1 | [NullableContextAttribute(...)] | 0 | 1 | +| System.ReadOnlySpan`1 | [ObsoleteAttribute(...)] | 0 | Types with embedded references are not supported in this version of your compiler. | +| System.ReadOnlySpan`1 | [ObsoleteAttribute(...)] | 1 | True | +| System.ReadOnlySpan`1.Enumerator | [NullableAttribute(...)] | 0 | 0 | +| System.ReadOnlySpan`1.Enumerator | [ObsoleteAttribute(...)] | 0 | Types with embedded references are not supported in this version of your compiler. | +| System.ReadOnlySpan`1.Enumerator | [ObsoleteAttribute(...)] | 1 | True | +| System.Reflection.AmbiguousMatchException | [NullableAttribute(...)] | 0 | 0 | +| System.Reflection.AmbiguousMatchException | [NullableContextAttribute(...)] | 0 | 2 | +| System.Reflection.AmbiguousMatchException | [TypeForwardedFromAttribute(...)] | 0 | mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 | +| System.Reflection.Assembly | [NullableAttribute(...)] | 0 | 0 | +| System.Reflection.Assembly | [NullableContextAttribute(...)] | 0 | 1 | +| System.Reflection.Assembly.ModuleResolve | [NullableAttribute(...)] | 0 | 2 | +| System.Reflection.AssemblyAlgorithmIdAttribute | [AttributeUsageAttribute(...)] | 0 | 1 | +| System.Reflection.AssemblyCompanyAttribute | [AttributeUsageAttribute(...)] | 0 | 1 | +| System.Reflection.AssemblyCompanyAttribute | [NullableAttribute(...)] | 0 | 0 | +| System.Reflection.AssemblyCompanyAttribute | [NullableContextAttribute(...)] | 0 | 1 | +| System.Reflection.AssemblyConfigurationAttribute | [AttributeUsageAttribute(...)] | 0 | 1 | +| System.Reflection.AssemblyConfigurationAttribute | [NullableAttribute(...)] | 0 | 0 | +| System.Reflection.AssemblyConfigurationAttribute | [NullableContextAttribute(...)] | 0 | 1 | +| System.Reflection.AssemblyCopyrightAttribute | [AttributeUsageAttribute(...)] | 0 | 1 | +| System.Reflection.AssemblyCopyrightAttribute | [NullableAttribute(...)] | 0 | 0 | +| System.Reflection.AssemblyCopyrightAttribute | [NullableContextAttribute(...)] | 0 | 1 | +| System.Reflection.AssemblyCultureAttribute | [AttributeUsageAttribute(...)] | 0 | 1 | +| System.Reflection.AssemblyCultureAttribute | [NullableAttribute(...)] | 0 | 0 | +| System.Reflection.AssemblyCultureAttribute | [NullableContextAttribute(...)] | 0 | 1 | +| System.Reflection.AssemblyDefaultAliasAttribute | [AttributeUsageAttribute(...)] | 0 | 1 | +| System.Reflection.AssemblyDefaultAliasAttribute | [NullableAttribute(...)] | 0 | 0 | +| System.Reflection.AssemblyDefaultAliasAttribute | [NullableContextAttribute(...)] | 0 | 1 | +| System.Reflection.AssemblyDelaySignAttribute | [AttributeUsageAttribute(...)] | 0 | 1 | +| System.Reflection.AssemblyDescriptionAttribute | [AttributeUsageAttribute(...)] | 0 | 1 | +| System.Reflection.AssemblyDescriptionAttribute | [NullableAttribute(...)] | 0 | 0 | +| System.Reflection.AssemblyDescriptionAttribute | [NullableContextAttribute(...)] | 0 | 1 | +| System.Reflection.AssemblyFileVersionAttribute | [AttributeUsageAttribute(...)] | 0 | 1 | +| System.Reflection.AssemblyFileVersionAttribute | [NullableAttribute(...)] | 0 | 0 | +| System.Reflection.AssemblyFileVersionAttribute | [NullableContextAttribute(...)] | 0 | 1 | +| System.Reflection.AssemblyFlagsAttribute | [AttributeUsageAttribute(...)] | 0 | 1 | +| System.Reflection.AssemblyInformationalVersionAttribute | [AttributeUsageAttribute(...)] | 0 | 1 | +| System.Reflection.AssemblyInformationalVersionAttribute | [NullableAttribute(...)] | 0 | 0 | +| System.Reflection.AssemblyInformationalVersionAttribute | [NullableContextAttribute(...)] | 0 | 1 | +| System.Reflection.AssemblyKeyFileAttribute | [AttributeUsageAttribute(...)] | 0 | 1 | +| System.Reflection.AssemblyKeyFileAttribute | [NullableAttribute(...)] | 0 | 0 | +| System.Reflection.AssemblyKeyFileAttribute | [NullableContextAttribute(...)] | 0 | 1 | +| System.Reflection.AssemblyKeyNameAttribute | [AttributeUsageAttribute(...)] | 0 | 1 | +| System.Reflection.AssemblyKeyNameAttribute | [NullableAttribute(...)] | 0 | 0 | +| System.Reflection.AssemblyKeyNameAttribute | [NullableContextAttribute(...)] | 0 | 1 | +| System.Reflection.AssemblyMetadataAttribute | [AttributeUsageAttribute(...)] | 0 | 1 | +| System.Reflection.AssemblyMetadataAttribute | [NullableAttribute(...)] | 0 | 0 | +| System.Reflection.AssemblyMetadataAttribute | [NullableContextAttribute(...)] | 0 | 1 | +| System.Reflection.AssemblyName | [NullableAttribute(...)] | 0 | 0 | +| System.Reflection.AssemblyName | [NullableContextAttribute(...)] | 0 | 2 | +| System.Reflection.AssemblyProductAttribute | [AttributeUsageAttribute(...)] | 0 | 1 | +| System.Reflection.AssemblyProductAttribute | [NullableAttribute(...)] | 0 | 0 | +| System.Reflection.AssemblyProductAttribute | [NullableContextAttribute(...)] | 0 | 1 | +| System.Reflection.AssemblySignatureKeyAttribute | [AttributeUsageAttribute(...)] | 0 | 1 | +| System.Reflection.AssemblySignatureKeyAttribute | [NullableAttribute(...)] | 0 | 0 | +| System.Reflection.AssemblySignatureKeyAttribute | [NullableContextAttribute(...)] | 0 | 1 | +| System.Reflection.AssemblyTitleAttribute | [AttributeUsageAttribute(...)] | 0 | 1 | +| System.Reflection.AssemblyTitleAttribute | [NullableAttribute(...)] | 0 | 0 | +| System.Reflection.AssemblyTitleAttribute | [NullableContextAttribute(...)] | 0 | 1 | +| System.Reflection.AssemblyTrademarkAttribute | [AttributeUsageAttribute(...)] | 0 | 1 | +| System.Reflection.AssemblyTrademarkAttribute | [NullableAttribute(...)] | 0 | 0 | +| System.Reflection.AssemblyTrademarkAttribute | [NullableContextAttribute(...)] | 0 | 1 | +| System.Reflection.AssemblyVersionAttribute | [AttributeUsageAttribute(...)] | 0 | 1 | +| System.Reflection.AssemblyVersionAttribute | [NullableAttribute(...)] | 0 | 0 | +| System.Reflection.AssemblyVersionAttribute | [NullableContextAttribute(...)] | 0 | 1 | +| System.Reflection.Binder | [NullableAttribute(...)] | 0 | 0 | +| System.Reflection.Binder | [NullableContextAttribute(...)] | 0 | 1 | +| System.Reflection.CerHashtable`2 | [DefaultMemberAttribute(...)] | 0 | Item | +| System.Reflection.ConstArray | [DefaultMemberAttribute(...)] | 0 | Item | +| System.Reflection.ConstructorInfo | [NullableAttribute(...)] | 0 | 0 | +| System.Reflection.ConstructorInfo | [NullableContextAttribute(...)] | 0 | 2 | +| System.Reflection.ConstructorInfo System.Type.TypeInitializer | [NullableAttribute(...)] | 0 | 2 | +| System.Reflection.ConstructorInfo.ConstructorName | [NullableAttribute(...)] | 0 | 1 | +| System.Reflection.ConstructorInfo.TypeConstructorName | [NullableAttribute(...)] | 0 | 1 | +| System.Reflection.CustomAttributeData | [NullableAttribute(...)] | 0 | 0 | +| System.Reflection.CustomAttributeData | [NullableContextAttribute(...)] | 0 | 1 | +| System.Reflection.CustomAttributeExtensions | [NullableAttribute(...)] | 0 | 0 | +| System.Reflection.CustomAttributeExtensions | [NullableContextAttribute(...)] | 0 | 1 | +| System.Reflection.CustomAttributeFormatException | [NullableAttribute(...)] | 0 | 0 | +| System.Reflection.CustomAttributeFormatException | [NullableContextAttribute(...)] | 0 | 2 | +| System.Reflection.CustomAttributeFormatException | [TypeForwardedFromAttribute(...)] | 0 | mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 | +| System.Reflection.CustomAttributeNamedArgument | [NullableAttribute(...)] | 0 | 0 | +| System.Reflection.CustomAttributeNamedArgument | [NullableContextAttribute(...)] | 0 | 1 | +| System.Reflection.CustomAttributeTypedArgument | [NullableAttribute(...)] | 0 | 0 | +| System.Reflection.CustomAttributeTypedArgument | [NullableContextAttribute(...)] | 0 | 1 | +| System.Reflection.DefaultMemberAttribute | [AttributeUsageAttribute(...)] | 0 | 1036 | +| System.Reflection.DefaultMemberAttribute | [NullableAttribute(...)] | 0 | 0 | +| System.Reflection.DefaultMemberAttribute | [NullableContextAttribute(...)] | 0 | 1 | +| System.Reflection.Emit.AssemblyBuilder | [NullableAttribute(...)] | 0 | 0 | +| System.Reflection.Emit.AssemblyBuilder | [NullableContextAttribute(...)] | 0 | 1 | +| System.Reflection.Emit.ConstructorBuilder | [NullableAttribute(...)] | 0 | 0 | +| System.Reflection.Emit.ConstructorBuilder | [NullableContextAttribute(...)] | 0 | 1 | +| System.Reflection.Emit.CustomAttributeBuilder | [NullableAttribute(...)] | 0 | 0 | +| System.Reflection.Emit.CustomAttributeBuilder | [NullableContextAttribute(...)] | 0 | 1 | +| System.Reflection.Emit.DynamicILInfo | [NullableAttribute(...)] | 0 | 0 | +| System.Reflection.Emit.DynamicILInfo | [NullableContextAttribute(...)] | 0 | 1 | +| System.Reflection.Emit.DynamicMethod | [NullableAttribute(...)] | 0 | 0 | +| System.Reflection.Emit.DynamicMethod | [NullableContextAttribute(...)] | 0 | 1 | +| System.Reflection.Emit.DynamicScope | [DefaultMemberAttribute(...)] | 0 | Item | +| System.Reflection.Emit.EnumBuilder | [NullableAttribute(...)] | 0 | 0 | +| System.Reflection.Emit.EnumBuilder | [NullableContextAttribute(...)] | 0 | 1 | +| System.Reflection.Emit.EventBuilder | [NullableAttribute(...)] | 0 | 0 | +| System.Reflection.Emit.EventBuilder | [NullableContextAttribute(...)] | 0 | 1 | +| System.Reflection.Emit.FieldBuilder | [NullableAttribute(...)] | 0 | 0 | +| System.Reflection.Emit.FieldBuilder | [NullableContextAttribute(...)] | 0 | 1 | +| System.Reflection.Emit.FlowControl.Phi | [ObsoleteAttribute(...)] | 0 | This API has been deprecated. https://go.microsoft.com/fwlink/?linkid=14202 | +| System.Reflection.Emit.GenericTypeParameterBuilder | [NullableAttribute(...)] | 0 | 0 | +| System.Reflection.Emit.GenericTypeParameterBuilder | [NullableContextAttribute(...)] | 0 | 1 | +| System.Reflection.Emit.ILGenerator | [NullableAttribute(...)] | 0 | 0 | +| System.Reflection.Emit.ILGenerator | [NullableContextAttribute(...)] | 0 | 1 | +| System.Reflection.Emit.LocalBuilder | [NullableAttribute(...)] | 0 | 0 | +| System.Reflection.Emit.LocalBuilder | [NullableContextAttribute(...)] | 0 | 1 | +| System.Reflection.Emit.MethodBuilder | [NullableAttribute(...)] | 0 | 0 | +| System.Reflection.Emit.MethodBuilder | [NullableContextAttribute(...)] | 0 | 1 | +| System.Reflection.Emit.ModuleBuilder | [NullableAttribute(...)] | 0 | 0 | +| System.Reflection.Emit.ModuleBuilder | [NullableContextAttribute(...)] | 0 | 1 | +| System.Reflection.Emit.OpCode | [NullableAttribute(...)] | 0 | 0 | +| System.Reflection.Emit.OpCode | [NullableContextAttribute(...)] | 0 | 2 | +| System.Reflection.Emit.OpCodeType.Annotation | [ObsoleteAttribute(...)] | 0 | This API has been deprecated. https://go.microsoft.com/fwlink/?linkid=14202 | +| System.Reflection.Emit.OperandType.InlinePhi | [ObsoleteAttribute(...)] | 0 | This API has been deprecated. https://go.microsoft.com/fwlink/?linkid=14202 | +| System.Reflection.Emit.ParameterBuilder | [NullableAttribute(...)] | 0 | 0 | +| System.Reflection.Emit.ParameterBuilder | [NullableContextAttribute(...)] | 0 | 2 | +| System.Reflection.Emit.PropertyBuilder | [NullableAttribute(...)] | 0 | 0 | +| System.Reflection.Emit.PropertyBuilder | [NullableContextAttribute(...)] | 0 | 1 | +| System.Reflection.Emit.SignatureHelper | [NullableAttribute(...)] | 0 | 0 | +| System.Reflection.Emit.SignatureHelper | [NullableContextAttribute(...)] | 0 | 1 | +| System.Reflection.Emit.TypeBuilder | [NullableAttribute(...)] | 0 | 0 | +| System.Reflection.Emit.TypeBuilder | [NullableContextAttribute(...)] | 0 | 1 | +| System.Reflection.EventInfo | [NullableAttribute(...)] | 0 | 0 | +| System.Reflection.EventInfo | [NullableContextAttribute(...)] | 0 | 2 | +| System.Reflection.ExceptionHandlingClause | [NullableAttribute(...)] | 0 | 0 | +| System.Reflection.ExceptionHandlingClause | [NullableContextAttribute(...)] | 0 | 2 | +| System.Reflection.FieldInfo | [NullableAttribute(...)] | 0 | 0 | +| System.Reflection.FieldInfo | [NullableContextAttribute(...)] | 0 | 2 | +| System.Reflection.ICustomAttributeProvider | [NullableContextAttribute(...)] | 0 | 1 | +| System.Reflection.IReflect | [NullableContextAttribute(...)] | 0 | 1 | +| System.Reflection.IReflectableType | [NullableContextAttribute(...)] | 0 | 1 | +| System.Reflection.InterfaceMapping | [NullableAttribute(...)] | 0 | 0 | +| System.Reflection.InterfaceMapping | [NullableContextAttribute(...)] | 0 | 1 | +| System.Reflection.InvalidFilterCriteriaException | [NullableAttribute(...)] | 0 | 0 | +| System.Reflection.InvalidFilterCriteriaException | [NullableContextAttribute(...)] | 0 | 2 | +| System.Reflection.InvalidFilterCriteriaException | [TypeForwardedFromAttribute(...)] | 0 | mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 | +| System.Reflection.LocalVariableInfo | [NullableAttribute(...)] | 0 | 0 | +| System.Reflection.LocalVariableInfo | [NullableContextAttribute(...)] | 0 | 1 | +| System.Reflection.ManifestResourceInfo | [NullableAttribute(...)] | 0 | 0 | +| System.Reflection.ManifestResourceInfo | [NullableContextAttribute(...)] | 0 | 1 | +| System.Reflection.MemberInfo | [NullableAttribute(...)] | 0 | 0 | +| System.Reflection.MemberInfo | [NullableContextAttribute(...)] | 0 | 1 | +| System.Reflection.MetadataEnumResult | [DefaultMemberAttribute(...)] | 0 | Item | +| System.Reflection.MetadataEnumResult.smallResult | [FixedBufferAttribute(...)] | 0 | System.Int32 | +| System.Reflection.MetadataEnumResult.smallResult | [FixedBufferAttribute(...)] | 1 | 16 | +| System.Reflection.MethodBase | [NullableAttribute(...)] | 0 | 0 | +| System.Reflection.MethodBase | [NullableContextAttribute(...)] | 0 | 2 | +| System.Reflection.MethodBase System.Reflection.Emit.GenericTypeParameterBuilder.DeclaringMethod | [NullableAttribute(...)] | 0 | 2 | +| System.Reflection.MethodBase System.Reflection.Emit.TypeBuilder.DeclaringMethod | [NullableAttribute(...)] | 0 | 2 | +| System.Reflection.MethodBase System.Type.DeclaringMethod | [NullableAttribute(...)] | 0 | 2 | +| System.Reflection.MethodBody | [NullableAttribute(...)] | 0 | 0 | +| System.Reflection.MethodBody | [NullableContextAttribute(...)] | 0 | 1 | +| System.Reflection.MethodInfo | [NullableAttribute(...)] | 0 | 0 | +| System.Reflection.MethodInfo | [NullableContextAttribute(...)] | 0 | 1 | +| System.Reflection.MethodInfo System.Reflection.Assembly.EntryPoint | [NullableAttribute(...)] | 0 | 2 | +| System.Reflection.MethodInfo System.Reflection.Emit.AssemblyBuilder.EntryPoint | [NullableAttribute(...)] | 0 | 2 | +| System.Reflection.Missing.Value | [NullableAttribute(...)] | 0 | 1 | +| System.Reflection.Module | [NullableAttribute(...)] | 0 | 0 | +| System.Reflection.Module | [NullableContextAttribute(...)] | 0 | 1 | +| System.Reflection.ObfuscateAssemblyAttribute | [AttributeUsageAttribute(...)] | 0 | 1 | +| System.Reflection.ObfuscationAttribute | [AttributeUsageAttribute(...)] | 0 | 8157 | +| System.Reflection.ObfuscationAttribute | [NullableAttribute(...)] | 0 | 0 | +| System.Reflection.ObfuscationAttribute | [NullableContextAttribute(...)] | 0 | 2 | +| System.Reflection.ParameterInfo | [NullableAttribute(...)] | 0 | 0 | +| System.Reflection.ParameterInfo | [NullableContextAttribute(...)] | 0 | 1 | +| System.Reflection.ParameterInfo.ClassImpl | [NullableAttribute(...)] | 0 | 2 | +| System.Reflection.ParameterInfo.DefaultValueImpl | [NullableAttribute(...)] | 0 | 2 | +| System.Reflection.ParameterInfo.NameImpl | [NullableAttribute(...)] | 0 | 2 | +| System.Reflection.ParameterModifier | [DefaultMemberAttribute(...)] | 0 | Item | +| System.Reflection.Pointer | [CLSCompliantAttribute(...)] | 0 | False | +| System.Reflection.PropertyInfo | [NullableAttribute(...)] | 0 | 0 | +| System.Reflection.PropertyInfo | [NullableContextAttribute(...)] | 0 | 2 | +| System.Reflection.ReflectionContext | [NullableAttribute(...)] | 0 | 0 | +| System.Reflection.ReflectionContext | [NullableContextAttribute(...)] | 0 | 1 | +| System.Reflection.ReflectionTypeLoadException | [NullableAttribute(...)] | 0 | 0 | +| System.Reflection.ReflectionTypeLoadException | [NullableContextAttribute(...)] | 0 | 1 | +| System.Reflection.ReflectionTypeLoadException | [TypeForwardedFromAttribute(...)] | 0 | mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 | +| System.Reflection.RuntimeReflectionExtensions | [NullableAttribute(...)] | 0 | 0 | +| System.Reflection.RuntimeReflectionExtensions | [NullableContextAttribute(...)] | 0 | 1 | +| System.Reflection.StrongNameKeyPair | [NullableAttribute(...)] | 0 | 0 | +| System.Reflection.StrongNameKeyPair | [NullableContextAttribute(...)] | 0 | 1 | +| System.Reflection.TargetException | [NullableAttribute(...)] | 0 | 0 | +| System.Reflection.TargetException | [NullableContextAttribute(...)] | 0 | 2 | +| System.Reflection.TargetException | [TypeForwardedFromAttribute(...)] | 0 | mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 | +| System.Reflection.TargetInvocationException | [NullableAttribute(...)] | 0 | 0 | +| System.Reflection.TargetInvocationException | [NullableContextAttribute(...)] | 0 | 2 | +| System.Reflection.TargetInvocationException | [TypeForwardedFromAttribute(...)] | 0 | mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 | +| System.Reflection.TargetParameterCountException | [NullableAttribute(...)] | 0 | 0 | +| System.Reflection.TargetParameterCountException | [NullableContextAttribute(...)] | 0 | 2 | +| System.Reflection.TargetParameterCountException | [TypeForwardedFromAttribute(...)] | 0 | mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 | +| System.Reflection.TypeDelegator | [NullableAttribute(...)] | 0 | 0 | +| System.Reflection.TypeDelegator | [NullableContextAttribute(...)] | 0 | 1 | +| System.Reflection.TypeInfo | [NullableAttribute(...)] | 0 | 0 | +| System.Reflection.TypeInfo | [NullableContextAttribute(...)] | 0 | 1 | +| System.ResolveEventArgs | [NullableAttribute(...)] | 0 | 0 | +| System.ResolveEventArgs | [NullableContextAttribute(...)] | 0 | 2 | +| System.Resources.MissingManifestResourceException | [NullableAttribute(...)] | 0 | 0 | +| System.Resources.MissingManifestResourceException | [NullableContextAttribute(...)] | 0 | 2 | +| System.Resources.MissingManifestResourceException | [TypeForwardedFromAttribute(...)] | 0 | mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 | +| System.Resources.MissingSatelliteAssemblyException | [NullableAttribute(...)] | 0 | 0 | +| System.Resources.MissingSatelliteAssemblyException | [NullableContextAttribute(...)] | 0 | 2 | +| System.Resources.MissingSatelliteAssemblyException | [TypeForwardedFromAttribute(...)] | 0 | mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 | +| System.Resources.NeutralResourcesLanguageAttribute | [AttributeUsageAttribute(...)] | 0 | 1 | +| System.Resources.NeutralResourcesLanguageAttribute | [NullableAttribute(...)] | 0 | 0 | +| System.Resources.NeutralResourcesLanguageAttribute | [NullableContextAttribute(...)] | 0 | 1 | +| System.Resources.ResourceManager | [NullableAttribute(...)] | 0 | 0 | +| System.Resources.ResourceManager | [NullableContextAttribute(...)] | 0 | 1 | +| System.Resources.ResourceManager.MainAssembly | [NullableAttribute(...)] | 0 | 2 | +| System.Resources.ResourceSet | [NullableAttribute(...)] | 0 | 0 | +| System.Resources.ResourceSet | [NullableContextAttribute(...)] | 0 | 1 | +| System.Resources.SatelliteContractVersionAttribute | [AttributeUsageAttribute(...)] | 0 | 1 | +| System.Resources.SatelliteContractVersionAttribute | [NullableAttribute(...)] | 0 | 0 | +| System.Resources.SatelliteContractVersionAttribute | [NullableContextAttribute(...)] | 0 | 1 | +| System.Runtime.AmbiguousImplementationException | [NullableAttribute(...)] | 0 | 0 | +| System.Runtime.AmbiguousImplementationException | [NullableContextAttribute(...)] | 0 | 2 | +| System.Runtime.AmbiguousImplementationException | [TypeForwardedFromAttribute(...)] | 0 | System.Runtime, Version=4.2.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a | +| System.Runtime.AssemblyTargetedPatchBandAttribute | [AttributeUsageAttribute(...)] | 0 | 1 | +| System.Runtime.AssemblyTargetedPatchBandAttribute | [NullableAttribute(...)] | 0 | 0 | +| System.Runtime.AssemblyTargetedPatchBandAttribute | [NullableContextAttribute(...)] | 0 | 1 | +| System.Runtime.CompilerServices.AccessedThroughPropertyAttribute | [AttributeUsageAttribute(...)] | 0 | 256 | +| System.Runtime.CompilerServices.AccessedThroughPropertyAttribute | [NullableAttribute(...)] | 0 | 0 | +| System.Runtime.CompilerServices.AccessedThroughPropertyAttribute | [NullableContextAttribute(...)] | 0 | 1 | +| System.Runtime.CompilerServices.AsyncIteratorMethodBuilder | [NullableAttribute(...)] | 0 | 0 | +| System.Runtime.CompilerServices.AsyncIteratorMethodBuilder | [NullableContextAttribute(...)] | 0 | 1 | +| System.Runtime.CompilerServices.AsyncIteratorStateMachineAttribute | [AttributeUsageAttribute(...)] | 0 | 64 | +| System.Runtime.CompilerServices.AsyncMethodBuilderAttribute | [AttributeUsageAttribute(...)] | 0 | 5148 | +| System.Runtime.CompilerServices.AsyncMethodBuilderAttribute | [NullableAttribute(...)] | 0 | 0 | +| System.Runtime.CompilerServices.AsyncMethodBuilderAttribute | [NullableContextAttribute(...)] | 0 | 1 | +| System.Runtime.CompilerServices.AsyncStateMachineAttribute | [AttributeUsageAttribute(...)] | 0 | 64 | +| System.Runtime.CompilerServices.AsyncTaskMethodBuilder | [NullableAttribute(...)] | 0 | 0 | +| System.Runtime.CompilerServices.AsyncTaskMethodBuilder | [NullableContextAttribute(...)] | 0 | 1 | +| System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1 | [NullableAttribute(...)] | 0 | 0 | +| System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1 | [NullableContextAttribute(...)] | 0 | 1 | +| System.Runtime.CompilerServices.AsyncValueTaskMethodBuilder | [NullableAttribute(...)] | 0 | 0 | +| System.Runtime.CompilerServices.AsyncValueTaskMethodBuilder | [NullableContextAttribute(...)] | 0 | 1 | +| System.Runtime.CompilerServices.AsyncValueTaskMethodBuilder`1 | [NullableAttribute(...)] | 0 | 0 | +| System.Runtime.CompilerServices.AsyncValueTaskMethodBuilder`1 | [NullableContextAttribute(...)] | 0 | 1 | +| System.Runtime.CompilerServices.AsyncVoidMethodBuilder | [NullableAttribute(...)] | 0 | 0 | +| System.Runtime.CompilerServices.AsyncVoidMethodBuilder | [NullableContextAttribute(...)] | 0 | 1 | +| System.Runtime.CompilerServices.CallerArgumentExpressionAttribute | [AttributeUsageAttribute(...)] | 0 | 2048 | +| System.Runtime.CompilerServices.CallerArgumentExpressionAttribute | [NullableAttribute(...)] | 0 | 0 | +| System.Runtime.CompilerServices.CallerArgumentExpressionAttribute | [NullableContextAttribute(...)] | 0 | 1 | +| System.Runtime.CompilerServices.CallerFilePathAttribute | [AttributeUsageAttribute(...)] | 0 | 2048 | +| System.Runtime.CompilerServices.CallerLineNumberAttribute | [AttributeUsageAttribute(...)] | 0 | 2048 | +| System.Runtime.CompilerServices.CallerMemberNameAttribute | [AttributeUsageAttribute(...)] | 0 | 2048 | +| System.Runtime.CompilerServices.CompilationRelaxationsAttribute | [AttributeUsageAttribute(...)] | 0 | 71 | +| System.Runtime.CompilerServices.CompilerGeneratedAttribute | [AttributeUsageAttribute(...)] | 0 | 32767 | +| System.Runtime.CompilerServices.CompilerGlobalScopeAttribute | [AttributeUsageAttribute(...)] | 0 | 4 | +| System.Runtime.CompilerServices.ConditionalWeakTable`2 | [NullableAttribute(...)] | 0 | 0 | +| System.Runtime.CompilerServices.ConditionalWeakTable`2 | [NullableContextAttribute(...)] | 0 | 1 | +| System.Runtime.CompilerServices.ConditionalWeakTable`2.CreateValueCallback | [NullableContextAttribute(...)] | 0 | 0 | +| System.Runtime.CompilerServices.ContractHelper | [NullableAttribute(...)] | 0 | 0 | +| System.Runtime.CompilerServices.ContractHelper | [NullableContextAttribute(...)] | 0 | 2 | +| System.Runtime.CompilerServices.ContractHelper.InternalContractFailed | [NullableAttribute(...)] | 0 | [2,1] | +| System.Runtime.CompilerServices.CustomConstantAttribute | [AttributeUsageAttribute(...)] | 0 | 2304 | +| System.Runtime.CompilerServices.CustomConstantAttribute | [NullableAttribute(...)] | 0 | 0 | +| System.Runtime.CompilerServices.CustomConstantAttribute | [NullableContextAttribute(...)] | 0 | 2 | +| System.Runtime.CompilerServices.DateTimeConstantAttribute | [AttributeUsageAttribute(...)] | 0 | 2304 | +| System.Runtime.CompilerServices.DateTimeConstantAttribute | [NullableAttribute(...)] | 0 | 0 | +| System.Runtime.CompilerServices.DateTimeConstantAttribute | [NullableContextAttribute(...)] | 0 | 1 | +| System.Runtime.CompilerServices.DecimalConstantAttribute | [AttributeUsageAttribute(...)] | 0 | 2304 | +| System.Runtime.CompilerServices.DefaultDependencyAttribute | [AttributeUsageAttribute(...)] | 0 | 1 | +| System.Runtime.CompilerServices.DependencyAttribute | [AttributeUsageAttribute(...)] | 0 | 1 | +| System.Runtime.CompilerServices.DependencyAttribute | [NullableAttribute(...)] | 0 | 0 | +| System.Runtime.CompilerServices.DependencyAttribute | [NullableContextAttribute(...)] | 0 | 1 | +| System.Runtime.CompilerServices.DisablePrivateReflectionAttribute | [AttributeUsageAttribute(...)] | 0 | 1 | +| System.Runtime.CompilerServices.EnumeratorCancellationAttribute | [AttributeUsageAttribute(...)] | 0 | 2048 | +| System.Runtime.CompilerServices.ExtensionAttribute | [AttributeUsageAttribute(...)] | 0 | 69 | +| System.Runtime.CompilerServices.FixedAddressValueTypeAttribute | [AttributeUsageAttribute(...)] | 0 | 256 | +| System.Runtime.CompilerServices.FixedBufferAttribute | [AttributeUsageAttribute(...)] | 0 | 256 | +| System.Runtime.CompilerServices.FixedBufferAttribute | [NullableAttribute(...)] | 0 | 0 | +| System.Runtime.CompilerServices.FixedBufferAttribute | [NullableContextAttribute(...)] | 0 | 1 | +| System.Runtime.CompilerServices.IAsyncStateMachine | [NullableContextAttribute(...)] | 0 | 1 | +| System.Runtime.CompilerServices.ICastable | [NullableContextAttribute(...)] | 0 | 2 | +| System.Runtime.CompilerServices.INotifyCompletion | [NullableContextAttribute(...)] | 0 | 1 | +| System.Runtime.CompilerServices.IStrongBox | [NullableContextAttribute(...)] | 0 | 2 | +| System.Runtime.CompilerServices.ITuple | [DefaultMemberAttribute(...)] | 0 | Item | +| System.Runtime.CompilerServices.ITuple | [NullableContextAttribute(...)] | 0 | 2 | +| System.Runtime.CompilerServices.IndexerNameAttribute | [AttributeUsageAttribute(...)] | 0 | 128 | +| System.Runtime.CompilerServices.InternalsVisibleToAttribute | [AttributeUsageAttribute(...)] | 0 | 1 | +| System.Runtime.CompilerServices.InternalsVisibleToAttribute | [NullableAttribute(...)] | 0 | 0 | +| System.Runtime.CompilerServices.InternalsVisibleToAttribute | [NullableContextAttribute(...)] | 0 | 1 | +| System.Runtime.CompilerServices.IntrinsicAttribute | [AttributeUsageAttribute(...)] | 0 | 364 | +| System.Runtime.CompilerServices.IsByRefLikeAttribute | [AttributeUsageAttribute(...)] | 0 | 8 | +| System.Runtime.CompilerServices.IsByRefLikeAttribute | [EditorBrowsableAttribute(...)] | 0 | 1 | +| System.Runtime.CompilerServices.IsReadOnlyAttribute | [AttributeUsageAttribute(...)] | 0 | 32767 | +| System.Runtime.CompilerServices.IsReadOnlyAttribute | [EditorBrowsableAttribute(...)] | 0 | 1 | +| System.Runtime.CompilerServices.IteratorStateMachineAttribute | [AttributeUsageAttribute(...)] | 0 | 64 | +| System.Runtime.CompilerServices.MethodImplAttribute | [AttributeUsageAttribute(...)] | 0 | 96 | +| System.Runtime.CompilerServices.NullableAttribute | [AttributeUsageAttribute(...)] | 0 | 27524 | +| System.Runtime.CompilerServices.NullableContextAttribute | [AttributeUsageAttribute(...)] | 0 | 5198 | +| System.Runtime.CompilerServices.NullablePublicOnlyAttribute | [AttributeUsageAttribute(...)] | 0 | 2 | +| System.Runtime.CompilerServices.ReferenceAssemblyAttribute | [AttributeUsageAttribute(...)] | 0 | 1 | +| System.Runtime.CompilerServices.ReferenceAssemblyAttribute | [NullableAttribute(...)] | 0 | 0 | +| System.Runtime.CompilerServices.ReferenceAssemblyAttribute | [NullableContextAttribute(...)] | 0 | 2 | +| System.Runtime.CompilerServices.RuntimeCompatibilityAttribute | [AttributeUsageAttribute(...)] | 0 | 1 | +| System.Runtime.CompilerServices.RuntimeFeature | [NullableAttribute(...)] | 0 | 0 | +| System.Runtime.CompilerServices.RuntimeFeature | [NullableContextAttribute(...)] | 0 | 1 | +| System.Runtime.CompilerServices.RuntimeHelpers | [NullableAttribute(...)] | 0 | 0 | +| System.Runtime.CompilerServices.RuntimeHelpers | [NullableContextAttribute(...)] | 0 | 1 | +| System.Runtime.CompilerServices.RuntimeHelpers.CleanupCode | [NullableContextAttribute(...)] | 0 | 0 | +| System.Runtime.CompilerServices.RuntimeHelpers.TryCode | [NullableContextAttribute(...)] | 0 | 0 | +| System.Runtime.CompilerServices.RuntimeWrappedException | [NullableAttribute(...)] | 0 | 0 | +| System.Runtime.CompilerServices.RuntimeWrappedException | [NullableContextAttribute(...)] | 0 | 1 | +| System.Runtime.CompilerServices.RuntimeWrappedException | [TypeForwardedFromAttribute(...)] | 0 | mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 | +| System.Runtime.CompilerServices.SpecialNameAttribute | [AttributeUsageAttribute(...)] | 0 | 972 | +| System.Runtime.CompilerServices.StateMachineAttribute | [AttributeUsageAttribute(...)] | 0 | 64 | +| System.Runtime.CompilerServices.StateMachineAttribute | [NullableAttribute(...)] | 0 | 0 | +| System.Runtime.CompilerServices.StateMachineAttribute | [NullableContextAttribute(...)] | 0 | 1 | +| System.Runtime.CompilerServices.StringFreezingAttribute | [AttributeUsageAttribute(...)] | 0 | 1 | +| System.Runtime.CompilerServices.StrongBox`1.Value | [NullableAttribute(...)] | 0 | 1 | +| System.Runtime.CompilerServices.SuppressIldasmAttribute | [AttributeUsageAttribute(...)] | 0 | 3 | +| System.Runtime.CompilerServices.TupleElementNamesAttribute | [AttributeUsageAttribute(...)] | 0 | 11148 | +| System.Runtime.CompilerServices.TupleElementNamesAttribute | [CLSCompliantAttribute(...)] | 0 | False | +| System.Runtime.CompilerServices.TypeDependencyAttribute | [AttributeUsageAttribute(...)] | 0 | 1036 | +| System.Runtime.CompilerServices.TypeForwardedFromAttribute | [AttributeUsageAttribute(...)] | 0 | 5148 | +| System.Runtime.CompilerServices.TypeForwardedFromAttribute | [NullableAttribute(...)] | 0 | 0 | +| System.Runtime.CompilerServices.TypeForwardedFromAttribute | [NullableContextAttribute(...)] | 0 | 1 | +| System.Runtime.CompilerServices.TypeForwardedToAttribute | [AttributeUsageAttribute(...)] | 0 | 1 | +| System.Runtime.CompilerServices.TypeForwardedToAttribute | [NullableAttribute(...)] | 0 | 0 | +| System.Runtime.CompilerServices.TypeForwardedToAttribute | [NullableContextAttribute(...)] | 0 | 1 | +| System.Runtime.CompilerServices.UnsafeValueTypeAttribute | [AttributeUsageAttribute(...)] | 0 | 8 | +| System.Runtime.ConstrainedExecution.PrePrepareMethodAttribute | [AttributeUsageAttribute(...)] | 0 | 96 | +| System.Runtime.ConstrainedExecution.ReliabilityContractAttribute | [AttributeUsageAttribute(...)] | 0 | 1133 | +| System.Runtime.ExceptionServices.ExceptionDispatchInfo | [NullableAttribute(...)] | 0 | 0 | +| System.Runtime.ExceptionServices.ExceptionDispatchInfo | [NullableContextAttribute(...)] | 0 | 1 | +| System.Runtime.ExceptionServices.FirstChanceExceptionEventArgs | [NullableAttribute(...)] | 0 | 0 | +| System.Runtime.ExceptionServices.FirstChanceExceptionEventArgs | [NullableContextAttribute(...)] | 0 | 1 | +| System.Runtime.ExceptionServices.HandleProcessCorruptedStateExceptionsAttribute | [AttributeUsageAttribute(...)] | 0 | 64 | +| System.Runtime.InteropServices.AllowReversePInvokeCallsAttribute | [AttributeUsageAttribute(...)] | 0 | 64 | +| System.Runtime.InteropServices.ArrayWithOffset | [NullableAttribute(...)] | 0 | 0 | +| System.Runtime.InteropServices.ArrayWithOffset | [NullableContextAttribute(...)] | 0 | 2 | +| System.Runtime.InteropServices.BStrWrapper | [NullableAttribute(...)] | 0 | 0 | +| System.Runtime.InteropServices.BStrWrapper | [NullableContextAttribute(...)] | 0 | 2 | +| System.Runtime.InteropServices.BestFitMappingAttribute | [AttributeUsageAttribute(...)] | 0 | 1037 | +| System.Runtime.InteropServices.COMException | [NullableAttribute(...)] | 0 | 0 | +| System.Runtime.InteropServices.COMException | [NullableContextAttribute(...)] | 0 | 2 | +| System.Runtime.InteropServices.COMException | [TypeForwardedFromAttribute(...)] | 0 | mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 | +| System.Runtime.InteropServices.ClassInterfaceAttribute | [AttributeUsageAttribute(...)] | 0 | 5 | +| System.Runtime.InteropServices.CoClassAttribute | [AttributeUsageAttribute(...)] | 0 | 1024 | +| System.Runtime.InteropServices.CoClassAttribute | [NullableAttribute(...)] | 0 | 0 | +| System.Runtime.InteropServices.CoClassAttribute | [NullableContextAttribute(...)] | 0 | 1 | +| System.Runtime.InteropServices.ComDefaultInterfaceAttribute | [AttributeUsageAttribute(...)] | 0 | 4 | +| System.Runtime.InteropServices.ComDefaultInterfaceAttribute | [NullableAttribute(...)] | 0 | 0 | +| System.Runtime.InteropServices.ComDefaultInterfaceAttribute | [NullableContextAttribute(...)] | 0 | 1 | +| System.Runtime.InteropServices.ComEventInterfaceAttribute | [AttributeUsageAttribute(...)] | 0 | 1024 | +| System.Runtime.InteropServices.ComEventInterfaceAttribute | [NullableAttribute(...)] | 0 | 0 | +| System.Runtime.InteropServices.ComEventInterfaceAttribute | [NullableContextAttribute(...)] | 0 | 1 | +| System.Runtime.InteropServices.ComEventsHelper | [NullableAttribute(...)] | 0 | 0 | +| System.Runtime.InteropServices.ComEventsHelper | [NullableContextAttribute(...)] | 0 | 1 | +| System.Runtime.InteropServices.ComImportAttribute | [AttributeUsageAttribute(...)] | 0 | 1028 | +| System.Runtime.InteropServices.ComSourceInterfacesAttribute | [AttributeUsageAttribute(...)] | 0 | 4 | +| System.Runtime.InteropServices.ComSourceInterfacesAttribute | [NullableAttribute(...)] | 0 | 0 | +| System.Runtime.InteropServices.ComSourceInterfacesAttribute | [NullableContextAttribute(...)] | 0 | 1 | +| System.Runtime.InteropServices.ComTypes.CONNECTDATA.pUnk | [NullableAttribute(...)] | 0 | 1 | +| System.Runtime.InteropServices.ComTypes.EXCEPINFO | [NullableAttribute(...)] | 0 | 0 | +| System.Runtime.InteropServices.ComTypes.EXCEPINFO | [NullableContextAttribute(...)] | 0 | 1 | +| System.Runtime.InteropServices.ComTypes.IBindCtx | [GuidAttribute(...)] | 0 | 0000000e-0000-0000-C000-000000000046 | +| System.Runtime.InteropServices.ComTypes.IBindCtx | [InterfaceTypeAttribute(...)] | 0 | 1 | +| System.Runtime.InteropServices.ComTypes.IBindCtx | [NullableContextAttribute(...)] | 0 | 1 | +| System.Runtime.InteropServices.ComTypes.IConnectionPoint | [GuidAttribute(...)] | 0 | B196B286-BAB4-101A-B69C-00AA00341D07 | +| System.Runtime.InteropServices.ComTypes.IConnectionPoint | [InterfaceTypeAttribute(...)] | 0 | 1 | +| System.Runtime.InteropServices.ComTypes.IConnectionPoint | [NullableContextAttribute(...)] | 0 | 1 | +| System.Runtime.InteropServices.ComTypes.IConnectionPointContainer | [GuidAttribute(...)] | 0 | B196B284-BAB4-101A-B69C-00AA00341D07 | +| System.Runtime.InteropServices.ComTypes.IConnectionPointContainer | [InterfaceTypeAttribute(...)] | 0 | 1 | +| System.Runtime.InteropServices.ComTypes.IConnectionPointContainer | [NullableContextAttribute(...)] | 0 | 1 | +| System.Runtime.InteropServices.ComTypes.IEnumConnectionPoints | [GuidAttribute(...)] | 0 | B196B285-BAB4-101A-B69C-00AA00341D07 | +| System.Runtime.InteropServices.ComTypes.IEnumConnectionPoints | [InterfaceTypeAttribute(...)] | 0 | 1 | +| System.Runtime.InteropServices.ComTypes.IEnumConnectionPoints | [NullableContextAttribute(...)] | 0 | 1 | +| System.Runtime.InteropServices.ComTypes.IEnumConnections | [GuidAttribute(...)] | 0 | B196B287-BAB4-101A-B69C-00AA00341D07 | +| System.Runtime.InteropServices.ComTypes.IEnumConnections | [InterfaceTypeAttribute(...)] | 0 | 1 | +| System.Runtime.InteropServices.ComTypes.IEnumConnections | [NullableContextAttribute(...)] | 0 | 1 | +| System.Runtime.InteropServices.ComTypes.IEnumMoniker | [GuidAttribute(...)] | 0 | 00000102-0000-0000-C000-000000000046 | +| System.Runtime.InteropServices.ComTypes.IEnumMoniker | [InterfaceTypeAttribute(...)] | 0 | 1 | +| System.Runtime.InteropServices.ComTypes.IEnumMoniker | [NullableContextAttribute(...)] | 0 | 1 | +| System.Runtime.InteropServices.ComTypes.IEnumString | [GuidAttribute(...)] | 0 | 00000101-0000-0000-C000-000000000046 | +| System.Runtime.InteropServices.ComTypes.IEnumString | [InterfaceTypeAttribute(...)] | 0 | 1 | +| System.Runtime.InteropServices.ComTypes.IEnumString | [NullableContextAttribute(...)] | 0 | 1 | +| System.Runtime.InteropServices.ComTypes.IEnumVARIANT | [GuidAttribute(...)] | 0 | 00020404-0000-0000-C000-000000000046 | +| System.Runtime.InteropServices.ComTypes.IEnumVARIANT | [InterfaceTypeAttribute(...)] | 0 | 1 | +| System.Runtime.InteropServices.ComTypes.IEnumVARIANT | [NullableContextAttribute(...)] | 0 | 1 | +| System.Runtime.InteropServices.ComTypes.IEnumerable | [GuidAttribute(...)] | 0 | 496B0ABE-CDEE-11d3-88E8-00902754C43A | +| System.Runtime.InteropServices.ComTypes.IMoniker | [GuidAttribute(...)] | 0 | 0000000f-0000-0000-C000-000000000046 | +| System.Runtime.InteropServices.ComTypes.IMoniker | [InterfaceTypeAttribute(...)] | 0 | 1 | +| System.Runtime.InteropServices.ComTypes.IMoniker | [NullableContextAttribute(...)] | 0 | 1 | +| System.Runtime.InteropServices.ComTypes.IPersistFile | [GuidAttribute(...)] | 0 | 0000010b-0000-0000-C000-000000000046 | +| System.Runtime.InteropServices.ComTypes.IPersistFile | [InterfaceTypeAttribute(...)] | 0 | 1 | +| System.Runtime.InteropServices.ComTypes.IPersistFile | [NullableContextAttribute(...)] | 0 | 1 | +| System.Runtime.InteropServices.ComTypes.IRunningObjectTable | [GuidAttribute(...)] | 0 | 00000010-0000-0000-C000-000000000046 | +| System.Runtime.InteropServices.ComTypes.IRunningObjectTable | [InterfaceTypeAttribute(...)] | 0 | 1 | +| System.Runtime.InteropServices.ComTypes.IRunningObjectTable | [NullableContextAttribute(...)] | 0 | 1 | +| System.Runtime.InteropServices.ComTypes.IStream | [GuidAttribute(...)] | 0 | 0000000c-0000-0000-C000-000000000046 | +| System.Runtime.InteropServices.ComTypes.IStream | [InterfaceTypeAttribute(...)] | 0 | 1 | +| System.Runtime.InteropServices.ComTypes.IStream | [NullableContextAttribute(...)] | 0 | 1 | +| System.Runtime.InteropServices.ComTypes.ITypeComp | [GuidAttribute(...)] | 0 | 00020403-0000-0000-C000-000000000046 | +| System.Runtime.InteropServices.ComTypes.ITypeComp | [InterfaceTypeAttribute(...)] | 0 | 1 | +| System.Runtime.InteropServices.ComTypes.ITypeComp | [NullableContextAttribute(...)] | 0 | 1 | +| System.Runtime.InteropServices.ComTypes.ITypeInfo | [GuidAttribute(...)] | 0 | 00020401-0000-0000-C000-000000000046 | +| System.Runtime.InteropServices.ComTypes.ITypeInfo | [InterfaceTypeAttribute(...)] | 0 | 1 | +| System.Runtime.InteropServices.ComTypes.ITypeInfo | [NullableContextAttribute(...)] | 0 | 1 | +| System.Runtime.InteropServices.ComTypes.ITypeInfo2 | [GuidAttribute(...)] | 0 | 00020412-0000-0000-C000-000000000046 | +| System.Runtime.InteropServices.ComTypes.ITypeInfo2 | [InterfaceTypeAttribute(...)] | 0 | 1 | +| System.Runtime.InteropServices.ComTypes.ITypeInfo2 | [NullableContextAttribute(...)] | 0 | 1 | +| System.Runtime.InteropServices.ComTypes.ITypeLib | [GuidAttribute(...)] | 0 | 00020402-0000-0000-C000-000000000046 | +| System.Runtime.InteropServices.ComTypes.ITypeLib | [InterfaceTypeAttribute(...)] | 0 | 1 | +| System.Runtime.InteropServices.ComTypes.ITypeLib | [NullableContextAttribute(...)] | 0 | 1 | +| System.Runtime.InteropServices.ComTypes.ITypeLib2 | [GuidAttribute(...)] | 0 | 00020411-0000-0000-C000-000000000046 | +| System.Runtime.InteropServices.ComTypes.ITypeLib2 | [InterfaceTypeAttribute(...)] | 0 | 1 | +| System.Runtime.InteropServices.ComTypes.ITypeLib2 | [NullableContextAttribute(...)] | 0 | 1 | +| System.Runtime.InteropServices.ComTypes.STATSTG.pwcsName | [NullableAttribute(...)] | 0 | 1 | +| System.Runtime.InteropServices.ComTypes.VARDESC.lpstrSchema | [NullableAttribute(...)] | 0 | 1 | +| System.Runtime.InteropServices.ComVisibleAttribute | [AttributeUsageAttribute(...)] | 0 | 5597 | +| System.Runtime.InteropServices.DefaultCharSetAttribute | [AttributeUsageAttribute(...)] | 0 | 2 | +| System.Runtime.InteropServices.DefaultDllImportSearchPathsAttribute | [AttributeUsageAttribute(...)] | 0 | 65 | +| System.Runtime.InteropServices.DefaultParameterValueAttribute | [AttributeUsageAttribute(...)] | 0 | 2048 | +| System.Runtime.InteropServices.DefaultParameterValueAttribute | [NullableAttribute(...)] | 0 | 0 | +| System.Runtime.InteropServices.DefaultParameterValueAttribute | [NullableContextAttribute(...)] | 0 | 2 | +| System.Runtime.InteropServices.DispIdAttribute | [AttributeUsageAttribute(...)] | 0 | 960 | +| System.Runtime.InteropServices.DispatchWrapper | [NullableAttribute(...)] | 0 | 0 | +| System.Runtime.InteropServices.DispatchWrapper | [NullableContextAttribute(...)] | 0 | 2 | +| System.Runtime.InteropServices.DllImportAttribute | [AttributeUsageAttribute(...)] | 0 | 64 | +| System.Runtime.InteropServices.DllImportAttribute | [NullableAttribute(...)] | 0 | 0 | +| System.Runtime.InteropServices.DllImportAttribute | [NullableContextAttribute(...)] | 0 | 1 | +| System.Runtime.InteropServices.DllImportAttribute.EntryPoint | [NullableAttribute(...)] | 0 | 2 | +| System.Runtime.InteropServices.ErrorWrapper | [NullableAttribute(...)] | 0 | 0 | +| System.Runtime.InteropServices.ErrorWrapper | [NullableContextAttribute(...)] | 0 | 1 | +| System.Runtime.InteropServices.Expando.IExpando | [GuidAttribute(...)] | 0 | AFBF15E6-C37C-11d2-B88E-00A0C9B471B8 | +| System.Runtime.InteropServices.ExternalException | [NullableAttribute(...)] | 0 | 0 | +| System.Runtime.InteropServices.ExternalException | [NullableContextAttribute(...)] | 0 | 2 | +| System.Runtime.InteropServices.ExternalException | [TypeForwardedFromAttribute(...)] | 0 | mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 | +| System.Runtime.InteropServices.FieldOffsetAttribute | [AttributeUsageAttribute(...)] | 0 | 256 | +| System.Runtime.InteropServices.GCHandle | [NullableAttribute(...)] | 0 | 0 | +| System.Runtime.InteropServices.GCHandle | [NullableContextAttribute(...)] | 0 | 2 | +| System.Runtime.InteropServices.GuidAttribute | [AttributeUsageAttribute(...)] | 0 | 5149 | +| System.Runtime.InteropServices.GuidAttribute | [NullableAttribute(...)] | 0 | 0 | +| System.Runtime.InteropServices.GuidAttribute | [NullableContextAttribute(...)] | 0 | 1 | +| System.Runtime.InteropServices.HandleRef | [NullableAttribute(...)] | 0 | 0 | +| System.Runtime.InteropServices.HandleRef | [NullableContextAttribute(...)] | 0 | 2 | +| System.Runtime.InteropServices.ICustomAdapter | [NullableContextAttribute(...)] | 0 | 1 | +| System.Runtime.InteropServices.ICustomFactory | [NullableContextAttribute(...)] | 0 | 1 | +| System.Runtime.InteropServices.ICustomMarshaler | [NullableContextAttribute(...)] | 0 | 1 | +| System.Runtime.InteropServices.InAttribute | [AttributeUsageAttribute(...)] | 0 | 2048 | +| System.Runtime.InteropServices.InterfaceTypeAttribute | [AttributeUsageAttribute(...)] | 0 | 1024 | +| System.Runtime.InteropServices.InvalidComObjectException | [NullableAttribute(...)] | 0 | 0 | +| System.Runtime.InteropServices.InvalidComObjectException | [NullableContextAttribute(...)] | 0 | 2 | +| System.Runtime.InteropServices.InvalidComObjectException | [TypeForwardedFromAttribute(...)] | 0 | mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 | +| System.Runtime.InteropServices.InvalidOleVariantTypeException | [NullableAttribute(...)] | 0 | 0 | +| System.Runtime.InteropServices.InvalidOleVariantTypeException | [NullableContextAttribute(...)] | 0 | 2 | +| System.Runtime.InteropServices.InvalidOleVariantTypeException | [TypeForwardedFromAttribute(...)] | 0 | mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 | +| System.Runtime.InteropServices.LCIDConversionAttribute | [AttributeUsageAttribute(...)] | 0 | 64 | +| System.Runtime.InteropServices.Marshal | [NullableAttribute(...)] | 0 | 0 | +| System.Runtime.InteropServices.Marshal | [NullableContextAttribute(...)] | 0 | 1 | +| System.Runtime.InteropServices.MarshalAsAttribute | [AttributeUsageAttribute(...)] | 0 | 10496 | +| System.Runtime.InteropServices.MarshalAsAttribute | [NullableAttribute(...)] | 0 | 0 | +| System.Runtime.InteropServices.MarshalAsAttribute | [NullableContextAttribute(...)] | 0 | 2 | +| System.Runtime.InteropServices.MarshalDirectiveException | [NullableAttribute(...)] | 0 | 0 | +| System.Runtime.InteropServices.MarshalDirectiveException | [NullableContextAttribute(...)] | 0 | 2 | +| System.Runtime.InteropServices.MarshalDirectiveException | [TypeForwardedFromAttribute(...)] | 0 | mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 | +| System.Runtime.InteropServices.NativeCallableAttribute | [AttributeUsageAttribute(...)] | 0 | 64 | +| System.Runtime.InteropServices.NativeCallableAttribute.EntryPoint | [NullableAttribute(...)] | 0 | 2 | +| System.Runtime.InteropServices.NativeLibrary | [NullableAttribute(...)] | 0 | 0 | +| System.Runtime.InteropServices.NativeLibrary | [NullableContextAttribute(...)] | 0 | 1 | +| System.Runtime.InteropServices.OptionalAttribute | [AttributeUsageAttribute(...)] | 0 | 2048 | +| System.Runtime.InteropServices.OutAttribute | [AttributeUsageAttribute(...)] | 0 | 2048 | +| System.Runtime.InteropServices.PreserveSigAttribute | [AttributeUsageAttribute(...)] | 0 | 64 | +| System.Runtime.InteropServices.ProgIdAttribute | [AttributeUsageAttribute(...)] | 0 | 4 | +| System.Runtime.InteropServices.ProgIdAttribute | [NullableAttribute(...)] | 0 | 0 | +| System.Runtime.InteropServices.ProgIdAttribute | [NullableContextAttribute(...)] | 0 | 1 | +| System.Runtime.InteropServices.SEHException | [NullableAttribute(...)] | 0 | 0 | +| System.Runtime.InteropServices.SEHException | [NullableContextAttribute(...)] | 0 | 2 | +| System.Runtime.InteropServices.SEHException | [TypeForwardedFromAttribute(...)] | 0 | mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 | +| System.Runtime.InteropServices.SafeArrayRankMismatchException | [NullableAttribute(...)] | 0 | 0 | +| System.Runtime.InteropServices.SafeArrayRankMismatchException | [NullableContextAttribute(...)] | 0 | 2 | +| System.Runtime.InteropServices.SafeArrayRankMismatchException | [TypeForwardedFromAttribute(...)] | 0 | mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 | +| System.Runtime.InteropServices.SafeArrayTypeMismatchException | [NullableAttribute(...)] | 0 | 0 | +| System.Runtime.InteropServices.SafeArrayTypeMismatchException | [NullableContextAttribute(...)] | 0 | 2 | +| System.Runtime.InteropServices.SafeArrayTypeMismatchException | [TypeForwardedFromAttribute(...)] | 0 | mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 | +| System.Runtime.InteropServices.SafeHandle System.Threading.ThreadPoolBoundHandle.Handle | [NullableAttribute(...)] | 0 | 1 | +| System.Runtime.InteropServices.StructLayoutAttribute | [AttributeUsageAttribute(...)] | 0 | 12 | +| System.Runtime.InteropServices.StructLayoutAttribute System.Type.StructLayoutAttribute | [NullableAttribute(...)] | 0 | 2 | +| System.Runtime.InteropServices.TypeIdentifierAttribute | [AttributeUsageAttribute(...)] | 0 | 5144 | +| System.Runtime.InteropServices.TypeIdentifierAttribute | [NullableAttribute(...)] | 0 | 0 | +| System.Runtime.InteropServices.TypeIdentifierAttribute | [NullableContextAttribute(...)] | 0 | 2 | +| System.Runtime.InteropServices.UnknownWrapper | [NullableAttribute(...)] | 0 | 0 | +| System.Runtime.InteropServices.UnknownWrapper | [NullableContextAttribute(...)] | 0 | 2 | +| System.Runtime.InteropServices.UnmanagedFunctionPointerAttribute | [AttributeUsageAttribute(...)] | 0 | 4096 | +| System.Runtime.InteropServices.VariantWrapper | [NullableAttribute(...)] | 0 | 0 | +| System.Runtime.InteropServices.VariantWrapper | [NullableContextAttribute(...)] | 0 | 2 | +| System.Runtime.Intrinsics.Arm.Arm64.Aes | [CLSCompliantAttribute(...)] | 0 | False | +| System.Runtime.Intrinsics.Arm.Arm64.Base | [CLSCompliantAttribute(...)] | 0 | False | +| System.Runtime.Intrinsics.Arm.Arm64.Sha1 | [CLSCompliantAttribute(...)] | 0 | False | +| System.Runtime.Intrinsics.Arm.Arm64.Sha256 | [CLSCompliantAttribute(...)] | 0 | False | +| System.Runtime.Intrinsics.Arm.Arm64.Simd | [CLSCompliantAttribute(...)] | 0 | False | +| System.Runtime.Intrinsics.Vector64`1 | [DebuggerDisplayAttribute(...)] | 0 | {DisplayString,nq} | +| System.Runtime.Intrinsics.Vector64`1 | [DebuggerTypeProxyAttribute(...)] | 0 | System.Runtime.Intrinsics.Vector64DebugView`1 | +| System.Runtime.Intrinsics.Vector128`1 | [DebuggerDisplayAttribute(...)] | 0 | {DisplayString,nq} | +| System.Runtime.Intrinsics.Vector128`1 | [DebuggerTypeProxyAttribute(...)] | 0 | System.Runtime.Intrinsics.Vector128DebugView`1 | +| System.Runtime.Intrinsics.Vector256`1 | [DebuggerDisplayAttribute(...)] | 0 | {DisplayString,nq} | +| System.Runtime.Intrinsics.Vector256`1 | [DebuggerTypeProxyAttribute(...)] | 0 | System.Runtime.Intrinsics.Vector256DebugView`1 | +| System.Runtime.Intrinsics.X86.Aes | [CLSCompliantAttribute(...)] | 0 | False | +| System.Runtime.Intrinsics.X86.Avx | [CLSCompliantAttribute(...)] | 0 | False | +| System.Runtime.Intrinsics.X86.Avx2 | [CLSCompliantAttribute(...)] | 0 | False | +| System.Runtime.Intrinsics.X86.Bmi1 | [CLSCompliantAttribute(...)] | 0 | False | +| System.Runtime.Intrinsics.X86.Bmi2 | [CLSCompliantAttribute(...)] | 0 | False | +| System.Runtime.Intrinsics.X86.Fma | [CLSCompliantAttribute(...)] | 0 | False | +| System.Runtime.Intrinsics.X86.Lzcnt | [CLSCompliantAttribute(...)] | 0 | False | +| System.Runtime.Intrinsics.X86.Pclmulqdq | [CLSCompliantAttribute(...)] | 0 | False | +| System.Runtime.Intrinsics.X86.Popcnt | [CLSCompliantAttribute(...)] | 0 | False | +| System.Runtime.Intrinsics.X86.Sse | [CLSCompliantAttribute(...)] | 0 | False | +| System.Runtime.Intrinsics.X86.Sse2 | [CLSCompliantAttribute(...)] | 0 | False | +| System.Runtime.Intrinsics.X86.Sse3 | [CLSCompliantAttribute(...)] | 0 | False | +| System.Runtime.Intrinsics.X86.Sse41 | [CLSCompliantAttribute(...)] | 0 | False | +| System.Runtime.Intrinsics.X86.Sse42 | [CLSCompliantAttribute(...)] | 0 | False | +| System.Runtime.Intrinsics.X86.Ssse3 | [CLSCompliantAttribute(...)] | 0 | False | +| System.Runtime.Loader.AssemblyDependencyResolver | [NullableAttribute(...)] | 0 | 0 | +| System.Runtime.Loader.AssemblyDependencyResolver | [NullableContextAttribute(...)] | 0 | 1 | +| System.Runtime.Loader.AssemblyLoadContext | [NullableAttribute(...)] | 0 | 0 | +| System.Runtime.Loader.AssemblyLoadContext | [NullableContextAttribute(...)] | 0 | 1 | +| System.Runtime.Loader.AssemblyLoadContext System.Runtime.Loader.AssemblyLoadContext.CurrentContextualReflectionContext | [NullableAttribute(...)] | 0 | 2 | +| System.Runtime.Loader.AssemblyLoadContext.AssemblyLoad | [NullableAttribute(...)] | 0 | 2 | +| System.Runtime.Loader.AssemblyLoadContext.AssemblyResolve | [NullableAttribute(...)] | 0 | 2 | +| System.Runtime.Loader.AssemblyLoadContext.ContextualReflectionScope | [EditorBrowsableAttribute(...)] | 0 | 1 | +| System.Runtime.Loader.AssemblyLoadContext.ContextualReflectionScope | [NullableContextAttribute(...)] | 0 | 0 | +| System.Runtime.Loader.AssemblyLoadContext.Resolving | [NullableAttribute(...)] | 0 | [2,1,1,2] | +| System.Runtime.Loader.AssemblyLoadContext.ResolvingUnmanagedDll | [NullableAttribute(...)] | 0 | [2,1,1] | +| System.Runtime.Loader.AssemblyLoadContext.ResourceResolve | [NullableAttribute(...)] | 0 | 2 | +| System.Runtime.Loader.AssemblyLoadContext.TypeResolve | [NullableAttribute(...)] | 0 | 2 | +| System.Runtime.Loader.AssemblyLoadContext.Unloading | [NullableAttribute(...)] | 0 | [2,1] | +| System.Runtime.Loader.AssemblyLoadContext._resolving | [NullableAttribute(...)] | 0 | [2,1,1,1] | +| System.Runtime.Loader.AssemblyLoadContext._resolvingUnmanagedDll | [NullableAttribute(...)] | 0 | [2,1,1] | +| System.Runtime.Loader.AssemblyLoadContext._unloading | [NullableAttribute(...)] | 0 | [2,1] | +| System.Runtime.Remoting.ObjectHandle | [NullableAttribute(...)] | 0 | 0 | +| System.Runtime.Remoting.ObjectHandle | [NullableContextAttribute(...)] | 0 | 2 | +| System.Runtime.Serialization.IDeserializationCallback | [NullableContextAttribute(...)] | 0 | 2 | +| System.Runtime.Serialization.IFormatterConverter | [CLSCompliantAttribute(...)] | 0 | False | +| System.Runtime.Serialization.IFormatterConverter | [NullableContextAttribute(...)] | 0 | 1 | +| System.Runtime.Serialization.IObjectReference | [NullableContextAttribute(...)] | 0 | 1 | +| System.Runtime.Serialization.ISafeSerializationData | [NullableContextAttribute(...)] | 0 | 1 | +| System.Runtime.Serialization.ISerializable | [NullableContextAttribute(...)] | 0 | 1 | +| System.Runtime.Serialization.OnDeserializedAttribute | [AttributeUsageAttribute(...)] | 0 | 64 | +| System.Runtime.Serialization.OnDeserializingAttribute | [AttributeUsageAttribute(...)] | 0 | 64 | +| System.Runtime.Serialization.OnSerializedAttribute | [AttributeUsageAttribute(...)] | 0 | 64 | +| System.Runtime.Serialization.OnSerializingAttribute | [AttributeUsageAttribute(...)] | 0 | 64 | +| System.Runtime.Serialization.OptionalFieldAttribute | [AttributeUsageAttribute(...)] | 0 | 256 | +| System.Runtime.Serialization.SerializationEntry | [NullableAttribute(...)] | 0 | 0 | +| System.Runtime.Serialization.SerializationEntry | [NullableContextAttribute(...)] | 0 | 1 | +| System.Runtime.Serialization.SerializationException | [NullableAttribute(...)] | 0 | 0 | +| System.Runtime.Serialization.SerializationException | [NullableContextAttribute(...)] | 0 | 2 | +| System.Runtime.Serialization.SerializationException | [TypeForwardedFromAttribute(...)] | 0 | mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 | +| System.Runtime.Serialization.SerializationInfo | [NullableAttribute(...)] | 0 | 0 | +| System.Runtime.Serialization.SerializationInfo | [NullableContextAttribute(...)] | 0 | 1 | +| System.Runtime.Serialization.SerializationInfoEnumerator | [NullableAttribute(...)] | 0 | 0 | +| System.Runtime.Serialization.SerializationInfoEnumerator | [NullableContextAttribute(...)] | 0 | 1 | +| System.Runtime.Serialization.StreamingContext | [NullableAttribute(...)] | 0 | 0 | +| System.Runtime.Serialization.StreamingContext | [NullableContextAttribute(...)] | 0 | 2 | +| System.Runtime.TargetedPatchingOptOutAttribute | [AttributeUsageAttribute(...)] | 0 | 96 | +| System.Runtime.TargetedPatchingOptOutAttribute | [NullableAttribute(...)] | 0 | 0 | +| System.Runtime.TargetedPatchingOptOutAttribute | [NullableContextAttribute(...)] | 0 | 1 | +| System.Runtime.Versioning.NonVersionableAttribute | [AttributeUsageAttribute(...)] | 0 | 108 | +| System.Runtime.Versioning.TargetFrameworkAttribute | [AttributeUsageAttribute(...)] | 0 | 1 | +| System.Runtime.Versioning.TargetFrameworkAttribute | [NullableAttribute(...)] | 0 | 0 | +| System.Runtime.Versioning.TargetFrameworkAttribute | [NullableContextAttribute(...)] | 0 | 1 | +| System.RuntimeType.ListBuilder`1 | [DefaultMemberAttribute(...)] | 0 | Item | +| System.RuntimeTypeHandle | [NullableAttribute(...)] | 0 | 0 | +| System.RuntimeTypeHandle | [NullableContextAttribute(...)] | 0 | 2 | +| System.STAThreadAttribute | [AttributeUsageAttribute(...)] | 0 | 64 | +| System.Security.AllowPartiallyTrustedCallersAttribute | [AttributeUsageAttribute(...)] | 0 | 1 | +| System.Security.Cryptography.CryptographicException | [NullableAttribute(...)] | 0 | 0 | +| System.Security.Cryptography.CryptographicException | [NullableContextAttribute(...)] | 0 | 1 | +| System.Security.Cryptography.CryptographicException | [TypeForwardedFromAttribute(...)] | 0 | mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 | +| System.Security.IPermission | [NullableContextAttribute(...)] | 0 | 2 | +| System.Security.ISecurityEncodable | [NullableContextAttribute(...)] | 0 | 1 | +| System.Security.PermissionSet | [NullableAttribute(...)] | 0 | 0 | +| System.Security.PermissionSet | [NullableContextAttribute(...)] | 0 | 2 | +| System.Security.PermissionSet System.AppDomain.PermissionSet | [NullableAttribute(...)] | 0 | 1 | +| System.Security.Principal.IIdentity | [NullableContextAttribute(...)] | 0 | 2 | +| System.Security.Principal.IPrincipal | [NullableContextAttribute(...)] | 0 | 2 | +| System.Security.Principal.IPrincipal System.Threading.Thread.CurrentPrincipal | [NullableAttribute(...)] | 0 | 2 | +| System.Security.SecurityCriticalAttribute | [AttributeUsageAttribute(...)] | 0 | 5501 | +| System.Security.SecurityCriticalScope | [ObsoleteAttribute(...)] | 0 | SecurityCriticalScope is only used for .NET 2.0 transparency compatibility. | +| System.Security.SecurityCriticalScope System.Security.SecurityCriticalAttribute.Scope | [ObsoleteAttribute(...)] | 0 | SecurityCriticalScope is only used for .NET 2.0 transparency compatibility. | +| System.Security.SecurityElement | [NullableAttribute(...)] | 0 | 0 | +| System.Security.SecurityElement | [NullableContextAttribute(...)] | 0 | 2 | +| System.Security.SecurityException | [NullableAttribute(...)] | 0 | 0 | +| System.Security.SecurityException | [NullableContextAttribute(...)] | 0 | 2 | +| System.Security.SecurityException | [TypeForwardedFromAttribute(...)] | 0 | mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 | +| System.Security.SecurityRulesAttribute | [AttributeUsageAttribute(...)] | 0 | 1 | +| System.Security.SecuritySafeCriticalAttribute | [AttributeUsageAttribute(...)] | 0 | 5500 | +| System.Security.SecurityTransparentAttribute | [AttributeUsageAttribute(...)] | 0 | 1 | +| System.Security.SecurityTreatAsSafeAttribute | [AttributeUsageAttribute(...)] | 0 | 5501 | +| System.Security.SecurityTreatAsSafeAttribute | [ObsoleteAttribute(...)] | 0 | SecurityTreatAsSafe is only used for .NET 2.0 transparency compatibility. Please use the SecuritySafeCriticalAttribute instead. | +| System.Security.SuppressUnmanagedCodeSecurityAttribute | [AttributeUsageAttribute(...)] | 0 | 5188 | +| System.Security.UnverifiableCodeAttribute | [AttributeUsageAttribute(...)] | 0 | 2 | +| System.Security.VerificationException | [NullableAttribute(...)] | 0 | 0 | +| System.Security.VerificationException | [NullableContextAttribute(...)] | 0 | 2 | +| System.Security.VerificationException | [TypeForwardedFromAttribute(...)] | 0 | mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 | +| System.SerializableAttribute | [AttributeUsageAttribute(...)] | 0 | 4124 | +| System.Span<!0> System.Memory`1.Span | [NullableAttribute(...)] | 0 | [0,1] | +| System.Span<!0> System.Span`1.Empty | [NullableAttribute(...)] | 0 | [0,1] | +| System.Span<System.Char> System.Text.StringBuilder.RemainingCurrentChunk | [NullableAttribute(...)] | 0 | 0 | +| System.Span`1 | [DebuggerDisplayAttribute(...)] | 0 | {ToString(),raw} | +| System.Span`1 | [DebuggerTypeProxyAttribute(...)] | 0 | System.SpanDebugView`1 | +| System.Span`1 | [DefaultMemberAttribute(...)] | 0 | Item | +| System.Span`1 | [NullableAttribute(...)] | 0 | 0 | +| System.Span`1 | [NullableContextAttribute(...)] | 0 | 1 | +| System.Span`1 | [ObsoleteAttribute(...)] | 0 | Types with embedded references are not supported in this version of your compiler. | +| System.Span`1 | [ObsoleteAttribute(...)] | 1 | True | +| System.Span`1.Enumerator | [NullableAttribute(...)] | 0 | 0 | +| System.Span`1.Enumerator | [ObsoleteAttribute(...)] | 0 | Types with embedded references are not supported in this version of your compiler. | +| System.Span`1.Enumerator | [ObsoleteAttribute(...)] | 1 | True | +| System.StackOverflowException | [NullableAttribute(...)] | 0 | 0 | +| System.StackOverflowException | [NullableContextAttribute(...)] | 0 | 2 | +| System.StackOverflowException | [TypeForwardedFromAttribute(...)] | 0 | mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 | +| System.StringComparer | [NullableAttribute(...)] | 0 | 0 | +| System.StringComparer | [NullableContextAttribute(...)] | 0 | 1 | +| System.StringComparer | [TypeForwardedFromAttribute(...)] | 0 | mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 | +| System.SystemException | [NullableAttribute(...)] | 0 | 0 | +| System.SystemException | [NullableContextAttribute(...)] | 0 | 2 | +| System.SystemException | [TypeForwardedFromAttribute(...)] | 0 | mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 | +| System.Text.DecoderFallback | [NullableAttribute(...)] | 0 | 0 | +| System.Text.DecoderFallback | [NullableContextAttribute(...)] | 0 | 1 | +| System.Text.DecoderFallback System.Text.Decoder.Fallback | [NullableAttribute(...)] | 0 | 2 | +| System.Text.DecoderFallbackBuffer System.Text.Decoder.FallbackBuffer | [NullableAttribute(...)] | 0 | 1 | +| System.Text.DecoderFallbackException | [NullableAttribute(...)] | 0 | 0 | +| System.Text.DecoderFallbackException | [NullableContextAttribute(...)] | 0 | 2 | +| System.Text.DecoderFallbackException | [TypeForwardedFromAttribute(...)] | 0 | mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 | +| System.Text.DecoderReplacementFallback | [NullableAttribute(...)] | 0 | 0 | +| System.Text.DecoderReplacementFallback | [NullableContextAttribute(...)] | 0 | 1 | +| System.Text.DecoderReplacementFallbackBuffer | [NullableAttribute(...)] | 0 | 0 | +| System.Text.DecoderReplacementFallbackBuffer | [NullableContextAttribute(...)] | 0 | 1 | +| System.Text.EncoderFallback | [NullableAttribute(...)] | 0 | 0 | +| System.Text.EncoderFallback | [NullableContextAttribute(...)] | 0 | 1 | +| System.Text.EncoderFallback System.Text.Encoder.Fallback | [NullableAttribute(...)] | 0 | 2 | +| System.Text.EncoderFallbackBuffer System.Text.Encoder.FallbackBuffer | [NullableAttribute(...)] | 0 | 1 | +| System.Text.EncoderFallbackException | [NullableAttribute(...)] | 0 | 0 | +| System.Text.EncoderFallbackException | [NullableContextAttribute(...)] | 0 | 2 | +| System.Text.EncoderFallbackException | [TypeForwardedFromAttribute(...)] | 0 | mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 | +| System.Text.EncoderReplacementFallback | [NullableAttribute(...)] | 0 | 0 | +| System.Text.EncoderReplacementFallback | [NullableContextAttribute(...)] | 0 | 1 | +| System.Text.Encoding | [NullableAttribute(...)] | 0 | 0 | +| System.Text.Encoding | [NullableContextAttribute(...)] | 0 | 1 | +| System.Text.EncodingInfo | [NullableAttribute(...)] | 0 | 0 | +| System.Text.EncodingInfo | [NullableContextAttribute(...)] | 0 | 1 | +| System.Text.EncodingProvider | [NullableAttribute(...)] | 0 | 0 | +| System.Text.EncodingProvider | [NullableContextAttribute(...)] | 0 | 1 | +| System.Text.Rune | [DebuggerDisplayAttribute(...)] | 0 | {DebuggerDisplay,nq} | +| System.Text.SpanRuneEnumerator | [ObsoleteAttribute(...)] | 0 | Types with embedded references are not supported in this version of your compiler. | +| System.Text.SpanRuneEnumerator | [ObsoleteAttribute(...)] | 1 | True | +| System.Text.StringBuilder | [DefaultMemberAttribute(...)] | 0 | Chars | +| System.Text.StringBuilder | [NullableAttribute(...)] | 0 | 0 | +| System.Text.StringBuilder | [NullableContextAttribute(...)] | 0 | 1 | +| System.Text.StringBuilder | [TypeForwardedFromAttribute(...)] | 0 | mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 | +| System.Text.StringBuilder.ChunkEnumerator | [NullableContextAttribute(...)] | 0 | 0 | +| System.Text.UTF7Encoding | [NullableAttribute(...)] | 0 | 0 | +| System.Text.UTF7Encoding | [NullableContextAttribute(...)] | 0 | 1 | +| System.Text.UTF32Encoding | [NullableAttribute(...)] | 0 | 0 | +| System.Text.UTF32Encoding | [NullableContextAttribute(...)] | 0 | 1 | +| System.Text.UnicodeEncoding | [NullableAttribute(...)] | 0 | 0 | +| System.Text.UnicodeEncoding | [NullableContextAttribute(...)] | 0 | 1 | +| System.Text.ValueStringBuilder | [DefaultMemberAttribute(...)] | 0 | Item | +| System.Text.ValueStringBuilder | [ObsoleteAttribute(...)] | 0 | Types with embedded references are not supported in this version of your compiler. | +| System.Text.ValueStringBuilder | [ObsoleteAttribute(...)] | 1 | True | +| System.ThreadStaticAttribute | [AttributeUsageAttribute(...)] | 0 | 256 | +| System.Threading.AbandonedMutexException | [NullableAttribute(...)] | 0 | 0 | +| System.Threading.AbandonedMutexException | [NullableContextAttribute(...)] | 0 | 2 | +| System.Threading.AbandonedMutexException | [TypeForwardedFromAttribute(...)] | 0 | mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 | +| System.Threading.ApartmentState System.Threading.Thread.ApartmentState | [ObsoleteAttribute(...)] | 0 | The ApartmentState property has been deprecated. Use GetApartmentState, SetApartmentState or TrySetApartmentState instead. | +| System.Threading.ApartmentState System.Threading.Thread.ApartmentState | [ObsoleteAttribute(...)] | 1 | False | +| System.Threading.AsyncLocalValueChangedArgs`1 | [NullableAttribute(...)] | 0 | 0 | +| System.Threading.AsyncLocalValueChangedArgs`1 | [NullableContextAttribute(...)] | 0 | 1 | +| System.Threading.AsyncLocal`1 | [NullableAttribute(...)] | 0 | 0 | +| System.Threading.AsyncLocal`1 | [NullableContextAttribute(...)] | 0 | 1 | +| System.Threading.CancellationToken | [DebuggerDisplayAttribute(...)] | 0 | IsCancellationRequested = {IsCancellationRequested} | +| System.Threading.CancellationToken | [NullableAttribute(...)] | 0 | 0 | +| System.Threading.CancellationToken | [NullableContextAttribute(...)] | 0 | 1 | +| System.Threading.CancellationTokenSource | [NullableAttribute(...)] | 0 | 0 | +| System.Threading.CancellationTokenSource | [NullableContextAttribute(...)] | 0 | 1 | +| System.Threading.CompressedStack | [NullableAttribute(...)] | 0 | 0 | +| System.Threading.CompressedStack | [NullableContextAttribute(...)] | 0 | 1 | +| System.Threading.EventWaitHandle | [NullableAttribute(...)] | 0 | 0 | +| System.Threading.EventWaitHandle | [NullableContextAttribute(...)] | 0 | 1 | +| System.Threading.ExecutionContext System.Threading.Tasks.Task.CapturedContext | [NullableAttribute(...)] | 0 | 2 | +| System.Threading.ExecutionContext System.Threading.Thread.ExecutionContext | [NullableAttribute(...)] | 0 | 2 | +| System.Threading.IOCompletionCallback | [CLSCompliantAttribute(...)] | 0 | False | +| System.Threading.Interlocked | [NullableAttribute(...)] | 0 | 0 | +| System.Threading.Interlocked | [NullableContextAttribute(...)] | 0 | 1 | +| System.Threading.LazyInitializer | [NullableAttribute(...)] | 0 | 0 | +| System.Threading.LazyInitializer | [NullableContextAttribute(...)] | 0 | 1 | +| System.Threading.LockRecursionException | [NullableAttribute(...)] | 0 | 0 | +| System.Threading.LockRecursionException | [NullableContextAttribute(...)] | 0 | 2 | +| System.Threading.LockRecursionException | [TypeForwardedFromAttribute(...)] | 0 | System.Core, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 | +| System.Threading.ManualResetEventSlim | [DebuggerDisplayAttribute(...)] | 0 | Set = {IsSet} | +| System.Threading.Monitor | [NullableAttribute(...)] | 0 | 0 | +| System.Threading.Monitor | [NullableContextAttribute(...)] | 0 | 1 | +| System.Threading.Mutex | [NullableAttribute(...)] | 0 | 0 | +| System.Threading.Mutex | [NullableContextAttribute(...)] | 0 | 1 | +| System.Threading.Overlapped | [NullableAttribute(...)] | 0 | 0 | +| System.Threading.Overlapped | [NullableContextAttribute(...)] | 0 | 2 | +| System.Threading.Semaphore | [NullableAttribute(...)] | 0 | 0 | +| System.Threading.Semaphore | [NullableContextAttribute(...)] | 0 | 1 | +| System.Threading.SemaphoreFullException | [NullableAttribute(...)] | 0 | 0 | +| System.Threading.SemaphoreFullException | [NullableContextAttribute(...)] | 0 | 2 | +| System.Threading.SemaphoreFullException | [TypeForwardedFromAttribute(...)] | 0 | System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 | +| System.Threading.SemaphoreSlim | [DebuggerDisplayAttribute(...)] | 0 | Current Count = {m_currentCount} | +| System.Threading.SemaphoreSlim | [NullableAttribute(...)] | 0 | 0 | +| System.Threading.SemaphoreSlim | [NullableContextAttribute(...)] | 0 | 1 | +| System.Threading.SpinLock | [DebuggerDisplayAttribute(...)] | 0 | IsHeld = {IsHeld} | +| System.Threading.SpinLock | [DebuggerTypeProxyAttribute(...)] | 0 | System.Threading.SpinLock.SystemThreading_SpinLockDebugView | +| System.Threading.SpinWait | [NullableAttribute(...)] | 0 | 0 | +| System.Threading.SpinWait | [NullableContextAttribute(...)] | 0 | 1 | +| System.Threading.SynchronizationContext | [NullableAttribute(...)] | 0 | 0 | +| System.Threading.SynchronizationContext | [NullableContextAttribute(...)] | 0 | 1 | +| System.Threading.SynchronizationContext System.Threading.SynchronizationContext.Current | [NullableAttribute(...)] | 0 | 2 | +| System.Threading.SynchronizationContext.<>c.<>9__8_0 | [TupleElementNamesAttribute(...)] | 0 | [d,state] | +| System.Threading.SynchronizationLockException | [NullableAttribute(...)] | 0 | 0 | +| System.Threading.SynchronizationLockException | [NullableContextAttribute(...)] | 0 | 2 | +| System.Threading.SynchronizationLockException | [TypeForwardedFromAttribute(...)] | 0 | mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 | +| System.Threading.Tasks.ConcurrentExclusiveSchedulerPair | [DebuggerDisplayAttribute(...)] | 0 | Concurrent={ConcurrentTaskCountForDebugger}, Exclusive={ExclusiveTaskCountForDebugger}, Mode={ModeForDebugger} | +| System.Threading.Tasks.ConcurrentExclusiveSchedulerPair | [DebuggerTypeProxyAttribute(...)] | 0 | System.Threading.Tasks.ConcurrentExclusiveSchedulerPair.DebugView | +| System.Threading.Tasks.ConcurrentExclusiveSchedulerPair | [NullableAttribute(...)] | 0 | 0 | +| System.Threading.Tasks.ConcurrentExclusiveSchedulerPair | [NullableContextAttribute(...)] | 0 | 1 | +| System.Threading.Tasks.ConcurrentExclusiveSchedulerPair.ConcurrentExclusiveTaskScheduler | [DebuggerDisplayAttribute(...)] | 0 | Count={CountForDebugger}, MaxConcurrencyLevel={m_maxConcurrencyLevel}, Id={Id} | +| System.Threading.Tasks.ConcurrentExclusiveSchedulerPair.ConcurrentExclusiveTaskScheduler | [DebuggerTypeProxyAttribute(...)] | 0 | System.Threading.Tasks.ConcurrentExclusiveSchedulerPair.ConcurrentExclusiveTaskScheduler.DebugView | +| System.Threading.Tasks.MultiProducerMultiConsumerQueue`1 | [DebuggerDisplayAttribute(...)] | 0 | Count = {Count} | +| System.Threading.Tasks.SingleProducerSingleConsumerQueue`1 | [DebuggerDisplayAttribute(...)] | 0 | Count = {Count} | +| System.Threading.Tasks.SingleProducerSingleConsumerQueue`1 | [DebuggerTypeProxyAttribute(...)] | 0 | System.Threading.Tasks.SingleProducerSingleConsumerQueue`1.SingleProducerSingleConsumerQueue_DebugView | +| System.Threading.Tasks.Sources.IValueTaskSource | [NullableContextAttribute(...)] | 0 | 2 | +| System.Threading.Tasks.Sources.IValueTaskSource`1 | [NullableContextAttribute(...)] | 0 | 2 | +| System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore`1 | [NullableAttribute(...)] | 0 | 0 | +| System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore`1 | [NullableContextAttribute(...)] | 0 | 1 | +| System.Threading.Tasks.Task | [DebuggerDisplayAttribute(...)] | 0 | Id = {Id}, Status = {Status}, Method = {DebuggerDisplayMethodDescription} | +| System.Threading.Tasks.Task | [DebuggerTypeProxyAttribute(...)] | 0 | System.Threading.Tasks.SystemThreadingTasks_TaskDebugView | +| System.Threading.Tasks.Task | [NullableAttribute(...)] | 0 | 0 | +| System.Threading.Tasks.Task | [NullableContextAttribute(...)] | 0 | 1 | +| System.Threading.Tasks.Task System.Threading.Tasks.Task.InternalCurrent | [NullableAttribute(...)] | 0 | 2 | +| System.Threading.Tasks.Task System.Threading.Tasks.Task.ParentForDebugger | [NullableAttribute(...)] | 0 | 2 | +| System.Threading.Tasks.TaskAsyncEnumerableExtensions | [NullableAttribute(...)] | 0 | 0 | +| System.Threading.Tasks.TaskAsyncEnumerableExtensions | [NullableContextAttribute(...)] | 0 | 1 | +| System.Threading.Tasks.TaskCanceledException | [NullableAttribute(...)] | 0 | 0 | +| System.Threading.Tasks.TaskCanceledException | [NullableContextAttribute(...)] | 0 | 2 | +| System.Threading.Tasks.TaskCanceledException | [TypeForwardedFromAttribute(...)] | 0 | mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 | +| System.Threading.Tasks.TaskCompletionSource`1 | [NullableAttribute(...)] | 0 | 0 | +| System.Threading.Tasks.TaskCompletionSource`1 | [NullableContextAttribute(...)] | 0 | 1 | +| System.Threading.Tasks.TaskExtensions | [NullableAttribute(...)] | 0 | 0 | +| System.Threading.Tasks.TaskExtensions | [NullableContextAttribute(...)] | 0 | 1 | +| System.Threading.Tasks.TaskFactory | [NullableAttribute(...)] | 0 | 0 | +| System.Threading.Tasks.TaskFactory | [NullableContextAttribute(...)] | 0 | 1 | +| System.Threading.Tasks.TaskFactory`1 | [NullableAttribute(...)] | 0 | 0 | +| System.Threading.Tasks.TaskFactory`1 | [NullableContextAttribute(...)] | 0 | 1 | +| System.Threading.Tasks.TaskScheduler | [DebuggerDisplayAttribute(...)] | 0 | Id={Id} | +| System.Threading.Tasks.TaskScheduler | [DebuggerTypeProxyAttribute(...)] | 0 | System.Threading.Tasks.TaskScheduler.SystemThreadingTasks_TaskSchedulerDebugView | +| System.Threading.Tasks.TaskScheduler | [NullableAttribute(...)] | 0 | 0 | +| System.Threading.Tasks.TaskScheduler | [NullableContextAttribute(...)] | 0 | 1 | +| System.Threading.Tasks.TaskScheduler System.Threading.Tasks.Task.ExecutingTaskScheduler | [NullableAttribute(...)] | 0 | 2 | +| System.Threading.Tasks.TaskScheduler System.Threading.Tasks.TaskFactory.Scheduler | [NullableAttribute(...)] | 0 | 2 | +| System.Threading.Tasks.TaskScheduler System.Threading.Tasks.TaskFactory`1.Scheduler | [NullableAttribute(...)] | 0 | 2 | +| System.Threading.Tasks.TaskScheduler System.Threading.Tasks.TaskScheduler.InternalCurrent | [NullableAttribute(...)] | 0 | 2 | +| System.Threading.Tasks.TaskScheduler.UnobservedTaskException | [NullableAttribute(...)] | 0 | [2,1] | +| System.Threading.Tasks.TaskSchedulerException | [NullableAttribute(...)] | 0 | 0 | +| System.Threading.Tasks.TaskSchedulerException | [NullableContextAttribute(...)] | 0 | 2 | +| System.Threading.Tasks.TaskSchedulerException | [TypeForwardedFromAttribute(...)] | 0 | mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 | +| System.Threading.Tasks.Task`1 | [DebuggerDisplayAttribute(...)] | 0 | Id = {Id}, Status = {Status}, Method = {DebuggerDisplayMethodDescription}, Result = {DebuggerDisplayResultDescription} | +| System.Threading.Tasks.Task`1 | [DebuggerTypeProxyAttribute(...)] | 0 | System.Threading.Tasks.SystemThreadingTasks_FutureDebugView`1 | +| System.Threading.Tasks.Task`1 | [NullableAttribute(...)] | 0 | 0 | +| System.Threading.Tasks.Task`1 | [NullableContextAttribute(...)] | 0 | 1 | +| System.Threading.Tasks.UnobservedTaskExceptionEventArgs | [NullableAttribute(...)] | 0 | 0 | +| System.Threading.Tasks.UnobservedTaskExceptionEventArgs | [NullableContextAttribute(...)] | 0 | 2 | +| System.Threading.Tasks.ValueTask | [AsyncMethodBuilderAttribute(...)] | 0 | System.Runtime.CompilerServices.AsyncValueTaskMethodBuilder | +| System.Threading.Tasks.ValueTask | [NullableAttribute(...)] | 0 | 0 | +| System.Threading.Tasks.ValueTask | [NullableContextAttribute(...)] | 0 | 1 | +| System.Threading.Tasks.ValueTask<!0> System.Runtime.CompilerServices.AsyncValueTaskMethodBuilder`1.Task | [NullableAttribute(...)] | 0 | [0,1] | +| System.Threading.Tasks.ValueTask`1 | [AsyncMethodBuilderAttribute(...)] | 0 | System.Runtime.CompilerServices.AsyncValueTaskMethodBuilder`1 | +| System.Threading.Tasks.ValueTask`1 | [NullableAttribute(...)] | 0 | 0 | +| System.Threading.Tasks.ValueTask`1 | [NullableContextAttribute(...)] | 0 | 1 | +| System.Threading.Thread | [NullableAttribute(...)] | 0 | 0 | +| System.Threading.Thread | [NullableContextAttribute(...)] | 0 | 1 | +| System.Threading.ThreadAbortException | [NullableAttribute(...)] | 0 | 0 | +| System.Threading.ThreadAbortException | [NullableContextAttribute(...)] | 0 | 2 | +| System.Threading.ThreadAbortException | [TypeForwardedFromAttribute(...)] | 0 | mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 | +| System.Threading.ThreadInterruptedException | [NullableAttribute(...)] | 0 | 0 | +| System.Threading.ThreadInterruptedException | [NullableContextAttribute(...)] | 0 | 2 | +| System.Threading.ThreadInterruptedException | [TypeForwardedFromAttribute(...)] | 0 | mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 | +| System.Threading.ThreadLocal<System.Object> System.LocalDataStoreSlot.Data | [NullableAttribute(...)] | 0 | [1,2] | +| System.Threading.ThreadLocal`1 | [DebuggerDisplayAttribute(...)] | 0 | IsValueCreated={IsValueCreated}, Value={ValueForDebugDisplay}, Count={ValuesCountForDebugDisplay} | +| System.Threading.ThreadLocal`1 | [DebuggerTypeProxyAttribute(...)] | 0 | System.Threading.SystemThreading_ThreadLocalDebugView`1 | +| System.Threading.ThreadLocal`1 | [NullableAttribute(...)] | 0 | 0 | +| System.Threading.ThreadLocal`1 | [NullableContextAttribute(...)] | 0 | 1 | +| System.Threading.ThreadPool | [NullableAttribute(...)] | 0 | 0 | +| System.Threading.ThreadPool | [NullableContextAttribute(...)] | 0 | 1 | +| System.Threading.ThreadStartException | [TypeForwardedFromAttribute(...)] | 0 | mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 | +| System.Threading.ThreadStateException | [NullableAttribute(...)] | 0 | 0 | +| System.Threading.ThreadStateException | [NullableContextAttribute(...)] | 0 | 2 | +| System.Threading.ThreadStateException | [TypeForwardedFromAttribute(...)] | 0 | mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 | +| System.Threading.Timer | [NullableAttribute(...)] | 0 | 0 | +| System.Threading.Timer | [NullableContextAttribute(...)] | 0 | 1 | +| System.Threading.Volatile | [NullableAttribute(...)] | 0 | 0 | +| System.Threading.Volatile | [NullableContextAttribute(...)] | 0 | 1 | +| System.Threading.WaitHandle | [NullableAttribute(...)] | 0 | 0 | +| System.Threading.WaitHandle | [NullableContextAttribute(...)] | 0 | 1 | +| System.Threading.WaitHandle System.Threading.ManualResetEventSlim.WaitHandle | [NullableAttribute(...)] | 0 | 1 | +| System.Threading.WaitHandleCannotBeOpenedException | [NullableAttribute(...)] | 0 | 0 | +| System.Threading.WaitHandleCannotBeOpenedException | [NullableContextAttribute(...)] | 0 | 2 | +| System.Threading.WaitHandleCannotBeOpenedException | [TypeForwardedFromAttribute(...)] | 0 | mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 | +| System.Threading.WaitHandleExtensions | [NullableAttribute(...)] | 0 | 0 | +| System.Threading.WaitHandleExtensions | [NullableContextAttribute(...)] | 0 | 1 | +| System.TimeZone | [NullableAttribute(...)] | 0 | 0 | +| System.TimeZone | [NullableContextAttribute(...)] | 0 | 1 | +| System.TimeZone | [ObsoleteAttribute(...)] | 0 | System.TimeZone has been deprecated. Please investigate the use of System.TimeZoneInfo instead. | +| System.TimeZoneInfo | [NullableAttribute(...)] | 0 | 0 | +| System.TimeZoneInfo | [NullableContextAttribute(...)] | 0 | 1 | +| System.TimeZoneInfo | [TypeForwardedFromAttribute(...)] | 0 | System.Core, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 | +| System.TimeZoneInfo.AdjustmentRule | [NullableContextAttribute(...)] | 0 | 0 | +| System.TimeZoneInfo.TransitionTime | [NullableContextAttribute(...)] | 0 | 0 | +| System.TimeZoneNotFoundException | [NullableAttribute(...)] | 0 | 0 | +| System.TimeZoneNotFoundException | [NullableContextAttribute(...)] | 0 | 2 | +| System.TimeZoneNotFoundException | [TypeForwardedFromAttribute(...)] | 0 | System.Core, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 | +| System.TimeoutException | [NullableAttribute(...)] | 0 | 0 | +| System.TimeoutException | [NullableContextAttribute(...)] | 0 | 2 | +| System.TimeoutException | [TypeForwardedFromAttribute(...)] | 0 | mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 | +| System.Tuple | [NullableAttribute(...)] | 0 | 0 | +| System.Tuple | [NullableContextAttribute(...)] | 0 | 1 | +| System.TupleExtensions | [NullableAttribute(...)] | 0 | 0 | +| System.TupleExtensions | [NullableContextAttribute(...)] | 0 | 2 | +| System.Tuple`1 | [TypeForwardedFromAttribute(...)] | 0 | mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 | +| System.Tuple`2 | [TypeForwardedFromAttribute(...)] | 0 | mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 | +| System.Tuple`3 | [NullableAttribute(...)] | 0 | 0 | +| System.Tuple`3 | [NullableContextAttribute(...)] | 0 | 1 | +| System.Tuple`3 | [TypeForwardedFromAttribute(...)] | 0 | mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 | +| System.Tuple`4 | [NullableAttribute(...)] | 0 | 0 | +| System.Tuple`4 | [NullableContextAttribute(...)] | 0 | 1 | +| System.Tuple`4 | [TypeForwardedFromAttribute(...)] | 0 | mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 | +| System.Tuple`5 | [NullableAttribute(...)] | 0 | 0 | +| System.Tuple`5 | [NullableContextAttribute(...)] | 0 | 1 | +| System.Tuple`5 | [TypeForwardedFromAttribute(...)] | 0 | mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 | +| System.Tuple`6 | [NullableAttribute(...)] | 0 | 0 | +| System.Tuple`6 | [NullableContextAttribute(...)] | 0 | 1 | +| System.Tuple`6 | [TypeForwardedFromAttribute(...)] | 0 | mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 | +| System.Tuple`7 | [NullableAttribute(...)] | 0 | 0 | +| System.Tuple`7 | [NullableContextAttribute(...)] | 0 | 1 | +| System.Tuple`7 | [TypeForwardedFromAttribute(...)] | 0 | mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 | +| System.Tuple`8 | [NullableAttribute(...)] | 0 | 0 | +| System.Tuple`8 | [NullableContextAttribute(...)] | 0 | 1 | +| System.Tuple`8 | [TypeForwardedFromAttribute(...)] | 0 | mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 | +| System.Type | [NullableAttribute(...)] | 0 | 0 | +| System.Type | [NullableContextAttribute(...)] | 0 | 1 | +| System.Type System.Reflection.Emit.ConstructorBuilder.DeclaringType | [NullableAttribute(...)] | 0 | 2 | +| System.Type System.Reflection.Emit.ConstructorBuilder.ReflectedType | [NullableAttribute(...)] | 0 | 2 | +| System.Type System.Reflection.Emit.DynamicMethod.DeclaringType | [NullableAttribute(...)] | 0 | 2 | +| System.Type System.Reflection.Emit.DynamicMethod.ReflectedType | [NullableAttribute(...)] | 0 | 2 | +| System.Type System.Reflection.Emit.EnumBuilder.BaseType | [NullableAttribute(...)] | 0 | 2 | +| System.Type System.Reflection.Emit.EnumBuilder.DeclaringType | [NullableAttribute(...)] | 0 | 2 | +| System.Type System.Reflection.Emit.EnumBuilder.ReflectedType | [NullableAttribute(...)] | 0 | 2 | +| System.Type System.Reflection.Emit.FieldBuilder.DeclaringType | [NullableAttribute(...)] | 0 | 2 | +| System.Type System.Reflection.Emit.FieldBuilder.ReflectedType | [NullableAttribute(...)] | 0 | 2 | +| System.Type System.Reflection.Emit.GenericTypeParameterBuilder.BaseType | [NullableAttribute(...)] | 0 | 2 | +| System.Type System.Reflection.Emit.GenericTypeParameterBuilder.DeclaringType | [NullableAttribute(...)] | 0 | 2 | +| System.Type System.Reflection.Emit.GenericTypeParameterBuilder.ReflectedType | [NullableAttribute(...)] | 0 | 2 | +| System.Type System.Reflection.Emit.MethodBuilder.DeclaringType | [NullableAttribute(...)] | 0 | 2 | +| System.Type System.Reflection.Emit.MethodBuilder.ReflectedType | [NullableAttribute(...)] | 0 | 2 | +| System.Type System.Reflection.Emit.PropertyBuilder.DeclaringType | [NullableAttribute(...)] | 0 | 2 | +| System.Type System.Reflection.Emit.PropertyBuilder.ReflectedType | [NullableAttribute(...)] | 0 | 2 | +| System.Type System.Reflection.Emit.TypeBuilder.BaseType | [NullableAttribute(...)] | 0 | 2 | +| System.Type System.Reflection.Emit.TypeBuilder.DeclaringType | [NullableAttribute(...)] | 0 | 2 | +| System.Type System.Reflection.Emit.TypeBuilder.ReflectedType | [NullableAttribute(...)] | 0 | 2 | +| System.Type System.Reflection.FieldInfo.FieldType | [NullableAttribute(...)] | 0 | 1 | +| System.Type System.Reflection.MemberInfo.DeclaringType | [NullableAttribute(...)] | 0 | 2 | +| System.Type System.Reflection.MemberInfo.ReflectedType | [NullableAttribute(...)] | 0 | 2 | +| System.Type System.Reflection.PropertyInfo.PropertyType | [NullableAttribute(...)] | 0 | 1 | +| System.Type System.Reflection.TypeDelegator.BaseType | [NullableAttribute(...)] | 0 | 2 | +| System.Type System.Type.BaseType | [NullableAttribute(...)] | 0 | 2 | +| System.Type System.Type.DeclaringType | [NullableAttribute(...)] | 0 | 2 | +| System.Type System.Type.ReflectedType | [NullableAttribute(...)] | 0 | 2 | +| System.TypeAccessException | [NullableAttribute(...)] | 0 | 0 | +| System.TypeAccessException | [NullableContextAttribute(...)] | 0 | 2 | +| System.TypeAccessException | [TypeForwardedFromAttribute(...)] | 0 | mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 | +| System.TypeInitializationException | [NullableAttribute(...)] | 0 | 0 | +| System.TypeInitializationException | [NullableContextAttribute(...)] | 0 | 1 | +| System.TypeInitializationException | [TypeForwardedFromAttribute(...)] | 0 | mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 | +| System.TypeLoadException | [NullableAttribute(...)] | 0 | 0 | +| System.TypeLoadException | [NullableContextAttribute(...)] | 0 | 1 | +| System.TypeLoadException | [TypeForwardedFromAttribute(...)] | 0 | mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 | +| System.TypeUnloadedException | [NullableAttribute(...)] | 0 | 0 | +| System.TypeUnloadedException | [NullableContextAttribute(...)] | 0 | 2 | +| System.TypeUnloadedException | [TypeForwardedFromAttribute(...)] | 0 | mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 | +| System.Type[] System.Reflection.ReflectionTypeLoadException.Types | [NullableAttribute(...)] | 0 | [2,1] | +| System.TypedReference | [CLSCompliantAttribute(...)] | 0 | False | +| System.TypedReference | [NullableAttribute(...)] | 0 | 0 | +| System.TypedReference | [NullableContextAttribute(...)] | 0 | 1 | +| System.UIntPtr | [CLSCompliantAttribute(...)] | 0 | False | +| System.UIntPtr | [TypeForwardedFromAttribute(...)] | 0 | mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 | +| System.UnauthorizedAccessException | [NullableAttribute(...)] | 0 | 0 | +| System.UnauthorizedAccessException | [NullableContextAttribute(...)] | 0 | 2 | +| System.UnauthorizedAccessException | [TypeForwardedFromAttribute(...)] | 0 | mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 | +| System.UnhandledExceptionEventArgs | [NullableAttribute(...)] | 0 | 0 | +| System.UnhandledExceptionEventArgs | [NullableContextAttribute(...)] | 0 | 1 | +| System.ValueTuple | [NullableAttribute(...)] | 0 | 0 | +| System.ValueTuple | [NullableContextAttribute(...)] | 0 | 1 | +| System.ValueTuple | [TypeForwardedFromAttribute(...)] | 0 | mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 | +| System.ValueTuple`1 | [TypeForwardedFromAttribute(...)] | 0 | mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 | +| System.ValueTuple`1.Item1 | [NullableAttribute(...)] | 0 | 1 | +| System.ValueTuple`2 | [TypeForwardedFromAttribute(...)] | 0 | mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 | +| System.ValueTuple`2.Item1 | [NullableAttribute(...)] | 0 | 1 | +| System.ValueTuple`2.Item2 | [NullableAttribute(...)] | 0 | 1 | +| System.ValueTuple`3 | [TypeForwardedFromAttribute(...)] | 0 | mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 | +| System.ValueTuple`3.Item1 | [NullableAttribute(...)] | 0 | 1 | +| System.ValueTuple`3.Item2 | [NullableAttribute(...)] | 0 | 1 | +| System.ValueTuple`3.Item3 | [NullableAttribute(...)] | 0 | 1 | +| System.ValueTuple`4 | [TypeForwardedFromAttribute(...)] | 0 | mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 | +| System.ValueTuple`4.Item1 | [NullableAttribute(...)] | 0 | 1 | +| System.ValueTuple`4.Item2 | [NullableAttribute(...)] | 0 | 1 | +| System.ValueTuple`4.Item3 | [NullableAttribute(...)] | 0 | 1 | +| System.ValueTuple`4.Item4 | [NullableAttribute(...)] | 0 | 1 | +| System.ValueTuple`5 | [NullableAttribute(...)] | 0 | 0 | +| System.ValueTuple`5 | [NullableContextAttribute(...)] | 0 | 1 | +| System.ValueTuple`5 | [TypeForwardedFromAttribute(...)] | 0 | mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 | +| System.ValueTuple`6 | [NullableAttribute(...)] | 0 | 0 | +| System.ValueTuple`6 | [NullableContextAttribute(...)] | 0 | 1 | +| System.ValueTuple`6 | [TypeForwardedFromAttribute(...)] | 0 | mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 | +| System.ValueTuple`7 | [NullableAttribute(...)] | 0 | 0 | +| System.ValueTuple`7 | [NullableContextAttribute(...)] | 0 | 1 | +| System.ValueTuple`7 | [TypeForwardedFromAttribute(...)] | 0 | mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 | +| System.ValueTuple`8 | [NullableAttribute(...)] | 0 | 0 | +| System.ValueTuple`8 | [NullableContextAttribute(...)] | 0 | 1 | +| System.ValueTuple`8 | [TypeForwardedFromAttribute(...)] | 0 | mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 | +| System.ValueTuple`8.Rest | [NullableAttribute(...)] | 0 | 0 | +| System.ValueType | [NullableAttribute(...)] | 0 | 0 | +| System.ValueType | [NullableContextAttribute(...)] | 0 | 2 | +| System.ValueType | [TypeForwardedFromAttribute(...)] | 0 | mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 | +| System.Version | [NullableAttribute(...)] | 0 | 0 | +| System.Version | [NullableContextAttribute(...)] | 0 | 2 | +| System.Version | [TypeForwardedFromAttribute(...)] | 0 | mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 | +| System.WeakReference | [NullableAttribute(...)] | 0 | 0 | +| System.WeakReference | [NullableContextAttribute(...)] | 0 | 2 | +| System.WeakReference | [TypeForwardedFromAttribute(...)] | 0 | mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 | +| System.WeakReference`1 | [NullableAttribute(...)] | 0 | 0 | +| System.WeakReference`1 | [NullableContextAttribute(...)] | 0 | 1 | +| System.WeakReference`1 | [TypeForwardedFromAttribute(...)] | 0 | mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 | +| System.__Canon | [ClassInterfaceAttribute(...)] | 0 | 0 | +| System.__Canon | [ComVisibleAttribute(...)] | 0 | True | +| System.__DTString | [ObsoleteAttribute(...)] | 0 | Types with embedded references are not supported in this version of your compiler. | +| System.__DTString | [ObsoleteAttribute(...)] | 1 | True | +| bool | [TypeForwardedFromAttribute(...)] | 0 | mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 | +| bool.FalseString | [NullableAttribute(...)] | 0 | 1 | +| bool.TrueString | [NullableAttribute(...)] | 0 | 1 | +| byte | [TypeForwardedFromAttribute(...)] | 0 | mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 | +| byte* System.IO.UnmanagedMemoryStream.PositionPointer | [CLSCompliantAttribute(...)] | 0 | False | +| char | [NullableAttribute(...)] | 0 | 0 | +| char | [NullableContextAttribute(...)] | 0 | 1 | +| char | [TypeForwardedFromAttribute(...)] | 0 | mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 | +| decimal | [TypeForwardedFromAttribute(...)] | 0 | mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 | +| decimal.MaxValue | [DecimalConstantAttribute(...)] | 0 | 0 | +| decimal.MaxValue | [DecimalConstantAttribute(...)] | 1 | 0 | +| decimal.MaxValue | [DecimalConstantAttribute(...)] | 2 | 4294967295 | +| decimal.MaxValue | [DecimalConstantAttribute(...)] | 3 | 4294967295 | +| decimal.MaxValue | [DecimalConstantAttribute(...)] | 4 | 4294967295 | +| decimal.MinValue | [DecimalConstantAttribute(...)] | 0 | 0 | +| decimal.MinValue | [DecimalConstantAttribute(...)] | 1 | 128 | +| decimal.MinValue | [DecimalConstantAttribute(...)] | 2 | 4294967295 | +| decimal.MinValue | [DecimalConstantAttribute(...)] | 3 | 4294967295 | +| decimal.MinValue | [DecimalConstantAttribute(...)] | 4 | 4294967295 | +| decimal.MinusOne | [DecimalConstantAttribute(...)] | 0 | 0 | +| decimal.MinusOne | [DecimalConstantAttribute(...)] | 1 | 128 | +| decimal.MinusOne | [DecimalConstantAttribute(...)] | 2 | 0 | +| decimal.MinusOne | [DecimalConstantAttribute(...)] | 3 | 0 | +| decimal.MinusOne | [DecimalConstantAttribute(...)] | 4 | 1 | +| decimal.One | [DecimalConstantAttribute(...)] | 0 | 0 | +| decimal.One | [DecimalConstantAttribute(...)] | 1 | 0 | +| decimal.One | [DecimalConstantAttribute(...)] | 2 | 0 | +| decimal.One | [DecimalConstantAttribute(...)] | 3 | 0 | +| decimal.One | [DecimalConstantAttribute(...)] | 4 | 1 | +| decimal.Zero | [DecimalConstantAttribute(...)] | 0 | 0 | +| decimal.Zero | [DecimalConstantAttribute(...)] | 1 | 0 | +| decimal.Zero | [DecimalConstantAttribute(...)] | 2 | 0 | +| decimal.Zero | [DecimalConstantAttribute(...)] | 3 | 0 | +| decimal.Zero | [DecimalConstantAttribute(...)] | 4 | 0 | +| double | [TypeForwardedFromAttribute(...)] | 0 | mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 | +| float | [TypeForwardedFromAttribute(...)] | 0 | mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 | +| int | [TypeForwardedFromAttribute(...)] | 0 | mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 | +| int System.Threading.Overlapped.EventHandle | [ObsoleteAttribute(...)] | 0 | This property is not 64-bit compatible. Use EventHandleIntPtr instead. http://go.microsoft.com/fwlink/?linkid=14202 | +| int[] System.Globalization.StringInfo.Indexes | [NullableAttribute(...)] | 0 | 2 | +| long | [TypeForwardedFromAttribute(...)] | 0 | mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 | +| object | [ClassInterfaceAttribute(...)] | 0 | 1 | +| object | [ComVisibleAttribute(...)] | 0 | True | +| object | [NullableContextAttribute(...)] | 0 | 2 | +| object | [TypeForwardedFromAttribute(...)] | 0 | mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 | +| object System.Array.Item | [NullableAttribute(...)] | 0 | 2 | +| object System.ArraySegment`1.Enumerator.Current | [NullableAttribute(...)] | 0 | 2 | +| object System.CharEnumerator.Current | [NullableAttribute(...)] | 0 | 2 | +| object System.Collections.ArrayList.Item | [NullableAttribute(...)] | 0 | 2 | +| object System.Collections.DictionaryEntry.Value | [NullableAttribute(...)] | 0 | 2 | +| object System.Collections.Generic.Dictionary`2.Enumerator.Current | [NullableAttribute(...)] | 0 | 2 | +| object System.Collections.Generic.Dictionary`2.Enumerator.Key | [NullableAttribute(...)] | 0 | 1 | +| object System.Collections.Generic.Dictionary`2.Enumerator.Value | [NullableAttribute(...)] | 0 | 2 | +| object System.Collections.Generic.Dictionary`2.Item | [NullableAttribute(...)] | 0 | 2 | +| object System.Collections.Generic.Dictionary`2.KeyCollection.Enumerator.Current | [NullableAttribute(...)] | 0 | 2 | +| object System.Collections.Generic.Dictionary`2.KeyCollection.SyncRoot | [NullableAttribute(...)] | 0 | 1 | +| object System.Collections.Generic.Dictionary`2.ValueCollection.Enumerator.Current | [NullableAttribute(...)] | 0 | 2 | +| object System.Collections.Generic.Dictionary`2.ValueCollection.SyncRoot | [NullableAttribute(...)] | 0 | 1 | +| object System.Collections.Generic.List`1.Enumerator.Current | [NullableAttribute(...)] | 0 | 2 | +| object System.Collections.Generic.List`1.Item | [NullableAttribute(...)] | 0 | 2 | +| object System.Collections.Hashtable.Item | [NullableAttribute(...)] | 0 | 2 | +| object System.Collections.IDictionary.Item | [NullableAttribute(...)] | 0 | 2 | +| object System.Collections.IDictionaryEnumerator.Value | [NullableAttribute(...)] | 0 | 2 | +| object System.Collections.ListDictionaryInternal.Item | [NullableAttribute(...)] | 0 | 2 | +| object System.Collections.ObjectModel.Collection`1.Item | [NullableAttribute(...)] | 0 | 2 | +| object System.Collections.ObjectModel.ReadOnlyCollection`1.Item | [NullableAttribute(...)] | 0 | 2 | +| object System.Delegate.Target | [NullableAttribute(...)] | 0 | 2 | +| object System.IAsyncResult.AsyncState | [NullableAttribute(...)] | 0 | 2 | +| object System.Reflection.CustomAttributeTypedArgument.Value | [NullableAttribute(...)] | 0 | 2 | +| object System.Reflection.ParameterInfo.DefaultValue | [NullableAttribute(...)] | 0 | 2 | +| object System.Reflection.ParameterInfo.RawDefaultValue | [NullableAttribute(...)] | 0 | 2 | +| object System.Runtime.CompilerServices.StrongBox`1.Value | [NullableAttribute(...)] | 0 | 2 | +| object System.Runtime.Serialization.SerializationEntry.Value | [NullableAttribute(...)] | 0 | 2 | +| object System.Runtime.Serialization.SerializationInfoEnumerator.Current | [NullableAttribute(...)] | 0 | 2 | +| object System.Runtime.Serialization.SerializationInfoEnumerator.Value | [NullableAttribute(...)] | 0 | 2 | +| object System.Security.PermissionSet.SyncRoot | [NullableAttribute(...)] | 0 | 1 | +| object System.Text.StringRuneEnumerator.Current | [NullableAttribute(...)] | 0 | 2 | +| object System.Threading.Tasks.Task.AsyncState | [NullableAttribute(...)] | 0 | 2 | +| object System.Tuple`1.Item | [NullableAttribute(...)] | 0 | 2 | +| object System.Tuple`2.Item | [NullableAttribute(...)] | 0 | 2 | +| object System.Tuple`3.Item | [NullableAttribute(...)] | 0 | 2 | +| object System.Tuple`4.Item | [NullableAttribute(...)] | 0 | 2 | +| object System.Tuple`5.Item | [NullableAttribute(...)] | 0 | 2 | +| object System.Tuple`6.Item | [NullableAttribute(...)] | 0 | 2 | +| object System.Tuple`7.Item | [NullableAttribute(...)] | 0 | 2 | +| object System.Tuple`8.Item | [NullableAttribute(...)] | 0 | 2 | +| object System.ValueTuple.Item | [NullableAttribute(...)] | 0 | 2 | +| object System.ValueTuple`1.Item | [NullableAttribute(...)] | 0 | 2 | +| object System.ValueTuple`2.Item | [NullableAttribute(...)] | 0 | 2 | +| object System.ValueTuple`3.Item | [NullableAttribute(...)] | 0 | 2 | +| object System.ValueTuple`4.Item | [NullableAttribute(...)] | 0 | 2 | +| object System.ValueTuple`5.Item | [NullableAttribute(...)] | 0 | 2 | +| object System.ValueTuple`6.Item | [NullableAttribute(...)] | 0 | 2 | +| object System.ValueTuple`7.Item | [NullableAttribute(...)] | 0 | 2 | +| object System.ValueTuple`8.Item | [NullableAttribute(...)] | 0 | 2 | +| object[] System.Collections.ArrayList.ArrayListDebugView.Items | [DebuggerBrowsableAttribute(...)] | 0 | 3 | +| sbyte | [CLSCompliantAttribute(...)] | 0 | False | +| sbyte | [TypeForwardedFromAttribute(...)] | 0 | mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 | +| short | [TypeForwardedFromAttribute(...)] | 0 | mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 | +| string | [DefaultMemberAttribute(...)] | 0 | Chars | +| string | [NullableAttribute(...)] | 0 | 0 | +| string | [NullableContextAttribute(...)] | 0 | 1 | +| string | [TypeForwardedFromAttribute(...)] | 0 | mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 | +| string System.AppContext.BaseDirectory | [NullableAttribute(...)] | 0 | 1 | +| string System.AppDomain.FriendlyName | [NullableAttribute(...)] | 0 | 1 | +| string System.ArgumentException.Message | [NullableAttribute(...)] | 0 | 1 | +| string System.ArgumentOutOfRangeException.Message | [NullableAttribute(...)] | 0 | 1 | +| string System.BadImageFormatException.Message | [NullableAttribute(...)] | 0 | 1 | +| string System.Diagnostics.CodeAnalysis.SuppressMessageAttribute.Category | [NullableAttribute(...)] | 0 | 1 | +| string System.Diagnostics.CodeAnalysis.SuppressMessageAttribute.CheckId | [NullableAttribute(...)] | 0 | 1 | +| string System.Diagnostics.Contracts.ContractException.Failure | [NullableAttribute(...)] | 0 | 1 | +| string System.Diagnostics.Contracts.ContractOptionAttribute.Value | [NullableAttribute(...)] | 0 | 2 | +| string System.Diagnostics.DebuggerDisplayAttribute.Value | [NullableAttribute(...)] | 0 | 1 | +| string System.Diagnostics.DebuggerTypeProxyAttribute.ProxyTypeName | [NullableAttribute(...)] | 0 | 1 | +| string System.Diagnostics.DebuggerVisualizerAttribute.VisualizerTypeName | [NullableAttribute(...)] | 0 | 1 | +| string System.Diagnostics.Tracing.EventFieldAttribute.Name | [NullableAttribute(...)] | 0 | 2 | +| string System.Diagnostics.Tracing.EventSource.Name | [NullableAttribute(...)] | 0 | 1 | +| string System.Diagnostics.Tracing.TraceLoggingEventTypes.Name | [NullableAttribute(...)] | 0 | 1 | +| string System.Exception.Message | [NullableAttribute(...)] | 0 | 1 | +| string System.Globalization.CultureNotFoundException.DefaultMessage | [NullableAttribute(...)] | 0 | 1 | +| string System.Globalization.CultureNotFoundException.Message | [NullableAttribute(...)] | 0 | 1 | +| string System.IO.FileLoadException.Message | [NullableAttribute(...)] | 0 | 1 | +| string System.IO.FileNotFoundException.Message | [NullableAttribute(...)] | 0 | 1 | +| string System.MissingMemberException.Message | [NullableAttribute(...)] | 0 | 1 | +| string System.Reflection.Assembly.CodeBase | [NullableAttribute(...)] | 0 | 2 | +| string System.Reflection.Assembly.FullName | [NullableAttribute(...)] | 0 | 2 | +| string System.Reflection.AssemblyMetadataAttribute.Value | [NullableAttribute(...)] | 0 | 2 | +| string System.Reflection.AssemblyName.FullName | [NullableAttribute(...)] | 0 | 1 | +| string System.Reflection.Emit.AssemblyBuilder.CodeBase | [NullableAttribute(...)] | 0 | 2 | +| string System.Reflection.Emit.AssemblyBuilder.FullName | [NullableAttribute(...)] | 0 | 2 | +| string System.Reflection.Emit.EnumBuilder.AssemblyQualifiedName | [NullableAttribute(...)] | 0 | 2 | +| string System.Reflection.Emit.EnumBuilder.FullName | [NullableAttribute(...)] | 0 | 2 | +| string System.Reflection.Emit.EnumBuilder.Namespace | [NullableAttribute(...)] | 0 | 2 | +| string System.Reflection.Emit.GenericTypeParameterBuilder.AssemblyQualifiedName | [NullableAttribute(...)] | 0 | 2 | +| string System.Reflection.Emit.GenericTypeParameterBuilder.FullName | [NullableAttribute(...)] | 0 | 2 | +| string System.Reflection.Emit.GenericTypeParameterBuilder.Namespace | [NullableAttribute(...)] | 0 | 2 | +| string System.Reflection.Emit.TypeBuilder.AssemblyQualifiedName | [NullableAttribute(...)] | 0 | 2 | +| string System.Reflection.Emit.TypeBuilder.FullName | [NullableAttribute(...)] | 0 | 2 | +| string System.Reflection.Emit.TypeBuilder.Namespace | [NullableAttribute(...)] | 0 | 2 | +| string System.Reflection.ParameterInfo.Name | [NullableAttribute(...)] | 0 | 2 | +| string System.Reflection.TypeDelegator.AssemblyQualifiedName | [NullableAttribute(...)] | 0 | 2 | +| string System.Reflection.TypeDelegator.FullName | [NullableAttribute(...)] | 0 | 2 | +| string System.Reflection.TypeDelegator.Namespace | [NullableAttribute(...)] | 0 | 2 | +| string System.Runtime.Intrinsics.Vector64`1.DisplayString | [NullableAttribute(...)] | 0 | 1 | +| string System.Runtime.Intrinsics.Vector128`1.DisplayString | [NullableAttribute(...)] | 0 | 1 | +| string System.Runtime.Intrinsics.Vector256`1.DisplayString | [NullableAttribute(...)] | 0 | 1 | +| string System.Runtime.Loader.AssemblyLoadContext.Name | [NullableAttribute(...)] | 0 | 2 | +| string System.Runtime.Versioning.TargetFrameworkAttribute.FrameworkDisplayName | [NullableAttribute(...)] | 0 | 2 | +| string System.Security.SecurityElement.Tag | [NullableAttribute(...)] | 0 | 1 | +| string System.Text.Rune.DebuggerDisplay | [NullableAttribute(...)] | 0 | 1 | +| string System.Threading.Thread.Name | [NullableAttribute(...)] | 0 | 2 | +| string System.Type.AssemblyQualifiedName | [NullableAttribute(...)] | 0 | 2 | +| string System.Type.FullName | [NullableAttribute(...)] | 0 | 2 | +| string System.Type.Namespace | [NullableAttribute(...)] | 0 | 2 | +| uint | [CLSCompliantAttribute(...)] | 0 | False | +| uint | [TypeForwardedFromAttribute(...)] | 0 | mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 | +| uint System.Reflection.AssemblyAlgorithmIdAttribute.AlgorithmId | [CLSCompliantAttribute(...)] | 0 | False | +| uint System.Reflection.AssemblyFlagsAttribute.Flags | [CLSCompliantAttribute(...)] | 0 | False | +| uint System.Reflection.AssemblyFlagsAttribute.Flags | [ObsoleteAttribute(...)] | 0 | This property has been deprecated. Please use AssemblyFlags instead. https://go.microsoft.com/fwlink/?linkid=14202 | +| ulong | [CLSCompliantAttribute(...)] | 0 | False | +| ulong | [TypeForwardedFromAttribute(...)] | 0 | mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 | +| ulong System.Runtime.InteropServices.SafeBuffer.ByteLength | [CLSCompliantAttribute(...)] | 0 | False | +| ushort | [CLSCompliantAttribute(...)] | 0 | False | +| ushort | [TypeForwardedFromAttribute(...)] | 0 | mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 | +| void* System.Buffers.MemoryHandle.Pointer | [CLSCompliantAttribute(...)] | 0 | False | diff --git a/csharp/ql/test/library-tests/cil/attributes/attribute.ql b/csharp/ql/test/library-tests/cil/attributes/attribute.ql new file mode 100644 index 00000000000..a0e56a607bf --- /dev/null +++ b/csharp/ql/test/library-tests/cil/attributes/attribute.ql @@ -0,0 +1,32 @@ +import semmle.code.cil.Attribute +import semmle.code.cil.Declaration + +query predicate attrNoArg(string dec, string attr) { + exists(Declaration d, Attribute a | + a.getDeclaration() = d and + not exists(a.getAnArgument()) + | + dec = d.toStringWithTypes() and + attr = a.toStringWithTypes() + ) +} + +query predicate attrArgNamed(string dec, string attr, string name, string value) { + exists(Declaration d, Attribute a | + a.getDeclaration() = d and + a.getNamedArgument(name) = value + | + dec = d.toStringWithTypes() and + attr = a.toStringWithTypes() + ) +} + +query predicate attrArgPositional(string dec, string attr, int index, string value) { + exists(Declaration d, Attribute a | + a.getDeclaration() = d and + a.getArgument(index) = value + | + dec = d.toStringWithTypes() and + attr = a.toStringWithTypes() + ) +} diff --git a/csharp/ql/test/library-tests/cil/enums/Program.cs b/csharp/ql/test/library-tests/cil/enums/Program.cs new file mode 100644 index 00000000000..ea38187bdec --- /dev/null +++ b/csharp/ql/test/library-tests/cil/enums/Program.cs @@ -0,0 +1,10 @@ +// semmle-extractor-options: --cil + +using System; + +class Test +{ + static void Main(string[] args) + { + } +} diff --git a/csharp/ql/test/library-tests/cil/enums/enums.expected b/csharp/ql/test/library-tests/cil/enums/enums.expected new file mode 100644 index 00000000000..dd2907bc5d5 --- /dev/null +++ b/csharp/ql/test/library-tests/cil/enums/enums.expected @@ -0,0 +1,239 @@ +| Interop.Advapi32.ActivityControl | uint | +| Interop.BOOL | int | +| Interop.Error | int | +| Interop.Globalization.ResultCode | int | +| Interop.Globalization.TimeZoneDisplayNameType | int | +| Interop.Sys.AccessMode | int | +| Interop.Sys.ControlCharacterNames | int | +| Interop.Sys.CtrlCode | int | +| Interop.Sys.FileAdvice | int | +| Interop.Sys.FileStatusFlags | int | +| Interop.Sys.LockOperations | int | +| Interop.Sys.NodeType | int | +| Interop.Sys.OpenFlags | int | +| Interop.Sys.PollEvents | short | +| Interop.Sys.SeekWhence | int | +| Interop.Sys.SysConfName | int | +| Interop.Sys.SysLogPriority | int | +| System.AttributeTargets | int | +| System.Base64FormattingOptions | int | +| System.Buffers.ArrayPoolEventSource.BufferAllocatedReason | int | +| System.Buffers.OperationStatus | int | +| System.Buffers.Text.FormattingHelpers.HexCasing | uint | +| System.Buffers.Text.Utf8Parser.ComponentParseResult | byte | +| System.Buffers.Text.Utf8Parser.ParseNumberOptions | int | +| System.Buffers.TlsOverPerCoreLockedStacksArrayPool.MemoryPressure | int | +| System.Collections.Generic.InsertionBehavior | byte | +| System.ComponentModel.EditorBrowsableState | int | +| System.Configuration.Assemblies.AssemblyHashAlgorithm | int | +| System.Configuration.Assemblies.AssemblyVersionCompatibility | int | +| System.ConsoleColor | int | +| System.ConsoleKey | int | +| System.ConsoleModifiers | int | +| System.ConsoleSpecialKey | int | +| System.DTSubStringType | int | +| System.DateTimeKind | int | +| System.DateTimeParse.DS | int | +| System.DateTimeParse.DTT | int | +| System.DateTimeParse.TM | int | +| System.DayOfWeek | int | +| System.DefaultBinder.Primitives | int | +| System.DelegateBindingFlags | int | +| System.Diagnostics.Contracts.ContractFailureKind | int | +| System.Diagnostics.DebuggableAttribute.DebuggingModes | int | +| System.Diagnostics.DebuggerBrowsableState | int | +| System.Diagnostics.StackTrace.TraceFormat | int | +| System.Diagnostics.SymbolStore.SymAddressKind | int | +| System.Diagnostics.Tracing.ControllerCommand | int | +| System.Diagnostics.Tracing.EventActivityOptions | int | +| System.Diagnostics.Tracing.EventChannel | byte | +| System.Diagnostics.Tracing.EventChannelType | int | +| System.Diagnostics.Tracing.EventCommand | int | +| System.Diagnostics.Tracing.EventFieldFormat | int | +| System.Diagnostics.Tracing.EventFieldTags | int | +| System.Diagnostics.Tracing.EventKeywords | long | +| System.Diagnostics.Tracing.EventLevel | int | +| System.Diagnostics.Tracing.EventManifestOptions | int | +| System.Diagnostics.Tracing.EventOpcode | int | +| System.Diagnostics.Tracing.EventPipeSerializationFormat | int | +| System.Diagnostics.Tracing.EventProvider.WriteEventErrorCode | int | +| System.Diagnostics.Tracing.EventProviderType | int | +| System.Diagnostics.Tracing.EventSourceSettings | int | +| System.Diagnostics.Tracing.EventTags | int | +| System.Diagnostics.Tracing.EventTask | int | +| System.Diagnostics.Tracing.ManifestEnvelope.ManifestFormats | byte | +| System.Diagnostics.Tracing.TraceLoggingDataType | int | +| System.Environment.SpecialFolder | int | +| System.Environment.SpecialFolderOption | int | +| System.EnvironmentVariableTarget | int | +| System.Exception.ExceptionMessageKind | int | +| System.ExceptionArgument | int | +| System.ExceptionResource | int | +| System.GC.EndNoGCRegionStatus | int | +| System.GC.StartNoGCRegionStatus | int | +| System.GCCollectionMode | int | +| System.GCNotificationStatus | int | +| System.Globalization.BidiCategory | int | +| System.Globalization.CalendarAlgorithmType | int | +| System.Globalization.CalendarDataType | int | +| System.Globalization.CalendarId | ushort | +| System.Globalization.CalendarWeekRule | int | +| System.Globalization.CalendricalCalculationsHelper.CorrectionAlgorithm | int | +| System.Globalization.CompareOptions | int | +| System.Globalization.CultureData.LocaleGroupingData | uint | +| System.Globalization.CultureData.LocaleNumberData | uint | +| System.Globalization.CultureData.LocaleStringData | uint | +| System.Globalization.CultureTypes | int | +| System.Globalization.DateTimeFormatFlags | int | +| System.Globalization.DateTimeFormatInfoScanner.FoundDatePattern | int | +| System.Globalization.DateTimeStyles | int | +| System.Globalization.DigitShapes | int | +| System.Globalization.FORMATFLAGS | int | +| System.Globalization.GregorianCalendarTypes | int | +| System.Globalization.HebrewNumber.HS | sbyte | +| System.Globalization.HebrewNumber.HebrewToken | short | +| System.Globalization.HebrewNumberParsingState | int | +| System.Globalization.LocaleDataParts | int | +| System.Globalization.MonthNameStyles | int | +| System.Globalization.NumberStyles | int | +| System.Globalization.TextInfo.Tristate | byte | +| System.Globalization.TimeSpanFormat.StandardFormat | int | +| System.Globalization.TimeSpanParse.TTT | byte | +| System.Globalization.TimeSpanParse.TimeSpanStandardStyles | byte | +| System.Globalization.TimeSpanStyles | int | +| System.Globalization.UnicodeCategory | int | +| System.Guid.GuidParseThrowStyle | byte | +| System.IO.FileAccess | int | +| System.IO.FileAttributes | int | +| System.IO.FileMode | int | +| System.IO.FileOptions | int | +| System.IO.FileShare | int | +| System.IO.HandleInheritability | int | +| System.IO.SeekOrigin | int | +| System.LazyState | int | +| System.MidpointRounding | int | +| System.Number.NumberBufferKind | byte | +| System.Number.ParsingStatus | int | +| System.ParseFailureKind | int | +| System.ParseFlags | int | +| System.PlatformID | int | +| System.Reflection.AssemblyContentType | int | +| System.Reflection.AssemblyNameFlags | int | +| System.Reflection.Associates.Attributes | int | +| System.Reflection.BindingFlags | int | +| System.Reflection.CallingConventions | int | +| System.Reflection.CorElementType | byte | +| System.Reflection.CustomAttributeEncoding | int | +| System.Reflection.Emit.AssemblyBuilderAccess | int | +| System.Reflection.Emit.DynamicResolver.SecurityControlFlags | int | +| System.Reflection.Emit.FlowControl | int | +| System.Reflection.Emit.OpCodeType | int | +| System.Reflection.Emit.OpCodeValues | int | +| System.Reflection.Emit.OperandType | int | +| System.Reflection.Emit.PEFileKinds | int | +| System.Reflection.Emit.PackingSize | int | +| System.Reflection.Emit.ScopeAction | sbyte | +| System.Reflection.Emit.StackBehaviour | int | +| System.Reflection.Emit.TypeKind | int | +| System.Reflection.Emit.TypeNameBuilder.Format | int | +| System.Reflection.EventAttributes | int | +| System.Reflection.ExceptionHandlingClauseOptions | int | +| System.Reflection.FieldAttributes | int | +| System.Reflection.GenericParameterAttributes | int | +| System.Reflection.INVOCATION_FLAGS | uint | +| System.Reflection.ImageFileMachine | int | +| System.Reflection.MdSigCallingConvention | byte | +| System.Reflection.MemberTypes | int | +| System.Reflection.MetadataTokenType | int | +| System.Reflection.MethodAttributes | int | +| System.Reflection.MethodImplAttributes | int | +| System.Reflection.MethodSemanticsAttributes | int | +| System.Reflection.PInvokeAttributes | int | +| System.Reflection.ParameterAttributes | int | +| System.Reflection.PortableExecutableKinds | int | +| System.Reflection.ProcessorArchitecture | int | +| System.Reflection.PropertyAttributes | int | +| System.Reflection.ResourceAttributes | int | +| System.Reflection.ResourceLocation | int | +| System.Reflection.TypeAttributes | int | +| System.Resources.ResourceTypeCode | int | +| System.Resources.UltimateResourceFallbackLocation | int | +| System.Runtime.CompilerServices.CompilationRelaxations | int | +| System.Runtime.CompilerServices.LoadHint | int | +| System.Runtime.CompilerServices.MethodCodeType | int | +| System.Runtime.CompilerServices.MethodImplOptions | int | +| System.Runtime.ConstrainedExecution.Cer | int | +| System.Runtime.ConstrainedExecution.Consistency | int | +| System.Runtime.GCLargeObjectHeapCompactionMode | int | +| System.Runtime.GCLatencyMode | int | +| System.Runtime.GCSettings.SetLatencyModeStatus | int | +| System.Runtime.InteropServices.CallingConvention | int | +| System.Runtime.InteropServices.CharSet | int | +| System.Runtime.InteropServices.ClassInterfaceType | int | +| System.Runtime.InteropServices.ComInterfaceType | int | +| System.Runtime.InteropServices.ComMemberType | int | +| System.Runtime.InteropServices.ComTypes.CALLCONV | int | +| System.Runtime.InteropServices.ComTypes.DESCKIND | int | +| System.Runtime.InteropServices.ComTypes.FUNCFLAGS | short | +| System.Runtime.InteropServices.ComTypes.FUNCKIND | int | +| System.Runtime.InteropServices.ComTypes.IDLFLAG | short | +| System.Runtime.InteropServices.ComTypes.IMPLTYPEFLAGS | int | +| System.Runtime.InteropServices.ComTypes.INVOKEKIND | int | +| System.Runtime.InteropServices.ComTypes.LIBFLAGS | short | +| System.Runtime.InteropServices.ComTypes.PARAMFLAG | short | +| System.Runtime.InteropServices.ComTypes.SYSKIND | int | +| System.Runtime.InteropServices.ComTypes.TYPEFLAGS | short | +| System.Runtime.InteropServices.ComTypes.TYPEKIND | int | +| System.Runtime.InteropServices.ComTypes.VARFLAGS | short | +| System.Runtime.InteropServices.ComTypes.VARKIND | int | +| System.Runtime.InteropServices.CustomQueryInterfaceMode | int | +| System.Runtime.InteropServices.CustomQueryInterfaceResult | int | +| System.Runtime.InteropServices.DllImportSearchPath | int | +| System.Runtime.InteropServices.GCHandleType | int | +| System.Runtime.InteropServices.LayoutKind | int | +| System.Runtime.InteropServices.UnmanagedType | int | +| System.Runtime.InteropServices.VarEnum | int | +| System.Runtime.Intrinsics.X86.FloatComparisonMode | byte | +| System.Runtime.Loader.AssemblyLoadContext.InternalState | int | +| System.Runtime.Serialization.StreamingContextStates | int | +| System.RuntimeType.MemberListType | int | +| System.RuntimeType.RuntimeTypeCache.CacheType | int | +| System.Security.PartialTrustVisibilityLevel | int | +| System.Security.Permissions.PermissionState | int | +| System.Security.Principal.PrincipalPolicy | int | +| System.Security.SecurityCriticalScope | int | +| System.Security.SecurityRuleSet | byte | +| System.String.TrimType | int | +| System.StringComparison | int | +| System.StringSplitOptions | int | +| System.StubHelpers.AsAnyMarshaler.BackPropAction | int | +| System.TermInfo.WellKnownNumbers | int | +| System.TermInfo.WellKnownStrings | int | +| System.Text.NormalizationForm | int | +| System.Threading.ApartmentState | int | +| System.Threading.EventResetMode | int | +| System.Threading.LazyThreadSafetyMode | int | +| System.Threading.LockRecursionPolicy | int | +| System.Threading.ReaderWriterLockSlim.EnterLockType | int | +| System.Threading.ReaderWriterLockSlim.EnterSpinLockReason | int | +| System.Threading.ReaderWriterLockSlim.WaiterStates | byte | +| System.Threading.StackCrawlMark | int | +| System.Threading.Tasks.ConcurrentExclusiveSchedulerPair.ProcessingMode | byte | +| System.Threading.Tasks.InternalTaskOptions | int | +| System.Threading.Tasks.Sources.ValueTaskSourceOnCompletedFlags | int | +| System.Threading.Tasks.Sources.ValueTaskSourceStatus | int | +| System.Threading.Tasks.TaskContinuationOptions | int | +| System.Threading.Tasks.TaskCreationOptions | int | +| System.Threading.Tasks.TaskStatus | int | +| System.Threading.Tasks.TplEventSource.TaskWaitBehavior | int | +| System.Threading.ThreadPriority | int | +| System.Threading.ThreadState | int | +| System.Threading.WaitHandle.OpenExistingResult | int | +| System.TimeZoneInfo.StringSerializer.State | int | +| System.TimeZoneInfo.TZVersion | byte | +| System.TimeZoneInfo.TimeZoneInfoResult | int | +| System.TimeZoneInfoOptions | int | +| System.TokenType | int | +| System.TypeCode | int | +| System.TypeNameFormatFlags | int | +| System.TypeNameKind | int | diff --git a/csharp/ql/test/library-tests/cil/enums/enums.ql b/csharp/ql/test/library-tests/cil/enums/enums.ql new file mode 100644 index 00000000000..280bee49921 --- /dev/null +++ b/csharp/ql/test/library-tests/cil/enums/enums.ql @@ -0,0 +1,5 @@ +import semmle.code.cil.Types + +from Enum e +where e.getQualifiedName() != "Interop.Sys.LockType" // doesn't exist on osx +select e.getQualifiedName(), e.getUnderlyingType().toStringWithTypes() diff --git a/csharp/ql/test/library-tests/cil/functionPointers/Class1.cs_ b/csharp/ql/test/library-tests/cil/functionPointers/Class1.cs_ new file mode 100644 index 00000000000..bd0ddc30906 --- /dev/null +++ b/csharp/ql/test/library-tests/cil/functionPointers/Class1.cs_ @@ -0,0 +1,52 @@ +using System; + +#nullable enable + +public class FnPointer +{ + public unsafe static class Program + { + static delegate*<int> pointer = &M0; + + public static int M0() + { + return 0; + } + + static void M1(delegate*<ref int, out object?, int> f) + { + int i = 42; + int j = f(ref i, out object? o); + } + + static void M2<T>(delegate* unmanaged[Stdcall/*, StdcallSuppressGCTransition*/]<ref int, out object?, T, void> f) where T : new() + { + int i = 42; + f(ref i, out object? o, new T()); + } + + static void M3(delegate* managed<ref int, out object?, in int, ref int> f) + { + int i = 42; + ref int j = ref f(ref i, out object? o, in i); + } + + static void M4<T>(delegate*<T, int> f) where T : new() + { + int j = f(new T()); + } + + static void M5(delegate*<B, A> f, delegate*<A, B> ff) + { + M5(ff, ff); // implicit conversion due to implicit reference conversion + } + + static void M6(delegate*<int*, void*> f, delegate*<void*, int*> ff) + { + M6(ff, ff); // implicit conversion due to implicit pointer conversion + } + + class A { } + class B : A { } + } +} \ No newline at end of file diff --git a/csharp/ql/test/library-tests/cil/functionPointers/Test.cs b/csharp/ql/test/library-tests/cil/functionPointers/Test.cs new file mode 100644 index 00000000000..c72cfe0b0b3 --- /dev/null +++ b/csharp/ql/test/library-tests/cil/functionPointers/Test.cs @@ -0,0 +1,7 @@ +// semmle-extractor-options: --cil + +using System; + +class Test +{ +} \ No newline at end of file diff --git a/csharp/ql/test/library-tests/cil/functionPointers/fnptr.dll b/csharp/ql/test/library-tests/cil/functionPointers/fnptr.dll new file mode 100644 index 00000000000..c63b9dcc254 Binary files /dev/null and b/csharp/ql/test/library-tests/cil/functionPointers/fnptr.dll differ diff --git a/csharp/ql/test/library-tests/cil/functionPointers/functionPointers.expected b/csharp/ql/test/library-tests/cil/functionPointers/functionPointers.expected new file mode 100644 index 00000000000..0e26dc0592c --- /dev/null +++ b/csharp/ql/test/library-tests/cil/functionPointers/functionPointers.expected @@ -0,0 +1,29 @@ +fnptr +| delegate* managed<!0,Int32> | 1 | Int32 | 0 | +| delegate* managed<A,B> | 1 | B | 0 | +| delegate* managed<B,A> | 1 | A | 0 | +| delegate* managed<Int32&,Object& modreq(OutAttribute),Int32& modreq(InAttribute),Int32&> | 3 | Int32& | 0 | +| delegate* managed<Int32&,Object& modreq(OutAttribute),Int32> | 2 | Int32 | 0 | +| delegate* managed<Int32*,Void*> | 1 | Void* | 0 | +| delegate* managed<Int32> | 0 | Int32 | 0 | +| delegate* managed<Void*,Int32*> | 1 | Int32* | 0 | +| delegate* unmanaged[StdCall]<Int32&,Object& modreq(OutAttribute),!0,Void> | 3 | void | 2 | +params +| delegate* managed<!0,Int32> | 0 | Parameter 0 of delegate* managed<!0,Int32> | !0 | +| delegate* managed<A,B> | 0 | Parameter 0 of delegate* managed<A,B> | A | +| delegate* managed<B,A> | 0 | Parameter 0 of delegate* managed<B,A> | B | +| delegate* managed<Int32&,Object& modreq(OutAttribute),Int32& modreq(InAttribute),Int32&> | 0 | Parameter 0 of delegate* managed<Int32&,Object& modreq(OutAttribute),Int32& modreq(InAttribute),Int32&> | Int32& | +| delegate* managed<Int32&,Object& modreq(OutAttribute),Int32& modreq(InAttribute),Int32&> | 1 | Parameter 1 of delegate* managed<Int32&,Object& modreq(OutAttribute),Int32& modreq(InAttribute),Int32&> | Object& | +| delegate* managed<Int32&,Object& modreq(OutAttribute),Int32& modreq(InAttribute),Int32&> | 2 | Parameter 2 of delegate* managed<Int32&,Object& modreq(OutAttribute),Int32& modreq(InAttribute),Int32&> | Int32& | +| delegate* managed<Int32&,Object& modreq(OutAttribute),Int32> | 0 | Parameter 0 of delegate* managed<Int32&,Object& modreq(OutAttribute),Int32> | Int32& | +| delegate* managed<Int32&,Object& modreq(OutAttribute),Int32> | 1 | Parameter 1 of delegate* managed<Int32&,Object& modreq(OutAttribute),Int32> | Object& | +| delegate* managed<Int32*,Void*> | 0 | Parameter 0 of delegate* managed<Int32*,Void*> | Int32* | +| delegate* managed<Void*,Int32*> | 0 | Parameter 0 of delegate* managed<Void*,Int32*> | Void* | +| delegate* unmanaged[StdCall]<Int32&,Object& modreq(OutAttribute),!0,Void> | 0 | Parameter 0 of delegate* unmanaged[StdCall]<Int32&,Object& modreq(OutAttribute),!0,Void> | Int32& | +| delegate* unmanaged[StdCall]<Int32&,Object& modreq(OutAttribute),!0,Void> | 1 | Parameter 1 of delegate* unmanaged[StdCall]<Int32&,Object& modreq(OutAttribute),!0,Void> | Object& | +| delegate* unmanaged[StdCall]<Int32&,Object& modreq(OutAttribute),!0,Void> | 2 | Parameter 2 of delegate* unmanaged[StdCall]<Int32&,Object& modreq(OutAttribute),!0,Void> | !0 | +modifiers +| delegate* managed<Int32&,Object& modreq(OutAttribute),Int32& modreq(InAttribute),Int32&> | System.Runtime.InteropServices.InAttribute | modreq | +| delegate* managed<Int32&,Object& modreq(OutAttribute),Int32& modreq(InAttribute),Int32&> | System.Runtime.InteropServices.OutAttribute | modreq | +| delegate* managed<Int32&,Object& modreq(OutAttribute),Int32> | System.Runtime.InteropServices.OutAttribute | modreq | +| delegate* unmanaged[StdCall]<Int32&,Object& modreq(OutAttribute),!0,Void> | System.Runtime.InteropServices.OutAttribute | modreq | diff --git a/csharp/ql/test/library-tests/cil/functionPointers/functionPointers.ql b/csharp/ql/test/library-tests/cil/functionPointers/functionPointers.ql new file mode 100644 index 00000000000..ddc6671d358 --- /dev/null +++ b/csharp/ql/test/library-tests/cil/functionPointers/functionPointers.ql @@ -0,0 +1,34 @@ +import cil +import semmle.code.cil.Type + +bindingset[kind] +private string getKind(int kind) { if kind = 1 then result = "modreq" else result = "modopt" } + +bindingset[t, e] +private string getAnnotatedType(Type t, Element e) { + cil_type_annotation(e, 32) and result = t.toString() + "&" + or + not cil_type_annotation(e, 32) and result = t.toString() +} + +query predicate fnptr(string fnptr, int paramCount, string returnType, int callingConvention) { + exists(FunctionPointerType fn | fnptr = fn.toString() | + paramCount = fn.getNumberOfParameters() and + returnType = getAnnotatedType(fn.getReturnType(), fn) and + callingConvention = fn.getCallingConvention() + ) +} + +query predicate params(string fnptr, int i, string param, string t) { + exists(FunctionPointerType fn, Parameter p | fnptr = fn.toString() and param = p.toString() | + fn.getParameter(i) = p and t = getAnnotatedType(p.getType(), p) + ) +} + +query predicate modifiers(string fnptr, string modifier, string sKind) { + exists(Type modType, int kind, FunctionPointerType fn | fnptr = fn.toString() | + cil_custom_modifiers(fn, modType, kind) and + modType.getQualifiedName() = modifier and + sKind = getKind(kind) + ) +} diff --git a/csharp/ql/test/library-tests/cil/init-only-prop/Program.cs b/csharp/ql/test/library-tests/cil/init-only-prop/Program.cs new file mode 100644 index 00000000000..ea38187bdec --- /dev/null +++ b/csharp/ql/test/library-tests/cil/init-only-prop/Program.cs @@ -0,0 +1,10 @@ +// semmle-extractor-options: --cil + +using System; + +class Test +{ + static void Main(string[] args) + { + } +} diff --git a/csharp/ql/test/library-tests/cil/init-only-prop/Test.cs_ b/csharp/ql/test/library-tests/cil/init-only-prop/Test.cs_ new file mode 100644 index 00000000000..d39b5a82926 --- /dev/null +++ b/csharp/ql/test/library-tests/cil/init-only-prop/Test.cs_ @@ -0,0 +1,13 @@ +namespace System.Runtime.CompilerServices +{ + class IsExternalInit { } +} + +namespace cil_init_prop +{ + class SomeClass + { + public int Prop1 { get; set; } + public int Prop2 { get; init; } + } +} diff --git a/csharp/ql/test/library-tests/cil/init-only-prop/cil-init-prop.dll b/csharp/ql/test/library-tests/cil/init-only-prop/cil-init-prop.dll new file mode 100644 index 00000000000..dceff38f487 Binary files /dev/null and b/csharp/ql/test/library-tests/cil/init-only-prop/cil-init-prop.dll differ diff --git a/csharp/ql/test/library-tests/cil/init-only-prop/customModifiers.expected b/csharp/ql/test/library-tests/cil/init-only-prop/customModifiers.expected new file mode 100644 index 00000000000..8845c0e76f4 --- /dev/null +++ b/csharp/ql/test/library-tests/cil/init-only-prop/customModifiers.expected @@ -0,0 +1,107 @@ +| AsRef | System.Runtime.InteropServices.InAttribute | modreq | +| BeginInvoke | System.Runtime.InteropServices.InAttribute | modreq | +| EndInvoke | System.Runtime.InteropServices.InAttribute | modreq | +| EventWriteTransfer | System.Runtime.InteropServices.InAttribute | modreq | +| GetPinnableReference | System.Runtime.InteropServices.InAttribute | modreq | +| Invoke | System.Runtime.InteropServices.InAttribute | modreq | +| Max | System.Runtime.InteropServices.InAttribute | modreq | +| Min | System.Runtime.InteropServices.InAttribute | modreq | +| Value | System.Runtime.CompilerServices.IsVolatile | modreq | +| _bufferedValues | System.Runtime.CompilerServices.IsVolatile | modreq | +| _bufferedValuesIndex | System.Runtime.CompilerServices.IsVolatile | modreq | +| _callbackPartitions | System.Runtime.CompilerServices.IsVolatile | modreq | +| _canceled | System.Runtime.CompilerServices.IsVolatile | modreq | +| _container | System.Runtime.CompilerServices.IsVolatile | modreq | +| _fullyInitialized | System.Runtime.CompilerServices.IsVolatile | modreq | +| _head | System.Runtime.CompilerServices.IsVolatile | modreq | +| _initialized | System.Runtime.CompilerServices.IsVolatile | modreq | +| _isFullyInitialized | System.Runtime.CompilerServices.IsVolatile | modreq | +| _isWriterInProgress | System.Runtime.CompilerServices.IsVolatile | modreq | +| _kernelEvent | System.Runtime.CompilerServices.IsVolatile | modreq | +| _localTimeZone | System.Runtime.CompilerServices.IsVolatile | modreq | +| _next | System.Runtime.CompilerServices.IsVolatile | modreq | +| _notifyWhenNoCallbacksRunning | System.Runtime.CompilerServices.IsVolatile | modreq | +| _oldKeepAlive | System.Runtime.CompilerServices.IsVolatile | modreq | +| _owner | System.Runtime.CompilerServices.IsVolatile | modreq | +| _pauseTicks | System.Runtime.CompilerServices.IsVolatile | modreq | +| _previous | System.Runtime.CompilerServices.IsVolatile | modreq | +| _queues | System.Runtime.CompilerServices.IsVolatile | modreq | +| _saDurationFormats | System.Runtime.CompilerServices.IsVolatile | modreq | +| _saLongTimes | System.Runtime.CompilerServices.IsVolatile | modreq | +| _saShortTimes | System.Runtime.CompilerServices.IsVolatile | modreq | +| _slotArray | System.Runtime.CompilerServices.IsVolatile | modreq | +| _state | System.Runtime.CompilerServices.IsVolatile | modreq | +| _tail | System.Runtime.CompilerServices.IsVolatile | modreq | +| _threadIDExecutingCallbacks | System.Runtime.CompilerServices.IsVolatile | modreq | +| _timer | System.Runtime.CompilerServices.IsVolatile | modreq | +| _version | System.Runtime.CompilerServices.IsVolatile | modreq | +| _waCalendars | System.Runtime.CompilerServices.IsVolatile | modreq | +| currentTimeZone | System.Runtime.CompilerServices.IsVolatile | modreq | +| g_nameCache | System.Runtime.CompilerServices.IsVolatile | modreq | +| get_Current | System.Runtime.InteropServices.InAttribute | modreq | +| get_Item | System.Runtime.InteropServices.InAttribute | modreq | +| m_Dispatchers | System.Runtime.CompilerServices.IsVolatile | modreq | +| m_Next | System.Runtime.CompilerServices.IsVolatile | modreq | +| m_array | System.Runtime.CompilerServices.IsVolatile | modreq | +| m_channelData | System.Runtime.CompilerServices.IsVolatile | modreq | +| m_combinedState | System.Runtime.CompilerServices.IsVolatile | modreq | +| m_completionCountdown | System.Runtime.CompilerServices.IsVolatile | modreq | +| m_completionEvent | System.Runtime.CompilerServices.IsVolatile | modreq | +| m_continuationObject | System.Runtime.CompilerServices.IsVolatile | modreq | +| m_currentCount | System.Runtime.CompilerServices.IsVolatile | modreq | +| m_declaringType | System.Runtime.CompilerServices.IsVolatile | modreq | +| m_etwProvider | System.Runtime.CompilerServices.IsVolatile | modreq | +| m_eventData | System.Runtime.CompilerServices.IsVolatile | modreq | +| m_eventObj | System.Runtime.CompilerServices.IsVolatile | modreq | +| m_eventPipeProvider | System.Runtime.CompilerServices.IsVolatile | modreq | +| m_exceptionalChildren | System.Runtime.CompilerServices.IsVolatile | modreq | +| m_exceptionsHolder | System.Runtime.CompilerServices.IsVolatile | modreq | +| m_faultExceptions | System.Runtime.CompilerServices.IsVolatile | modreq | +| m_first | System.Runtime.CompilerServices.IsVolatile | modreq | +| m_head | System.Runtime.CompilerServices.IsVolatile | modreq | +| m_headIndex | System.Runtime.CompilerServices.IsVolatile | modreq | +| m_internalCancellationRequested | System.Runtime.CompilerServices.IsVolatile | modreq | +| m_isHandled | System.Runtime.CompilerServices.IsVolatile | modreq | +| m_last | System.Runtime.CompilerServices.IsVolatile | modreq | +| m_lock | System.Runtime.CompilerServices.IsVolatile | modreq | +| m_mask | System.Runtime.CompilerServices.IsVolatile | modreq | +| m_nameIsCached | System.Runtime.CompilerServices.IsVolatile | modreq | +| m_rawManifest | System.Runtime.CompilerServices.IsVolatile | modreq | +| m_signature | System.Runtime.CompilerServices.IsVolatile | modreq | +| m_stateFlags | System.Runtime.CompilerServices.IsVolatile | modreq | +| m_tail | System.Runtime.CompilerServices.IsVolatile | modreq | +| m_tailIndex | System.Runtime.CompilerServices.IsVolatile | modreq | +| m_taskId | System.Runtime.CompilerServices.IsVolatile | modreq | +| m_taskSchedulerId | System.Runtime.CompilerServices.IsVolatile | modreq | +| m_waitHandle | System.Runtime.CompilerServices.IsVolatile | modreq | +| numOutstandingThreadRequests | System.Runtime.CompilerServices.IsVolatile | modreq | +| property Current | System.Runtime.InteropServices.InAttribute | modreq | +| property Item | System.Runtime.InteropServices.InAttribute | modreq | +| s_DefaultThreadCurrentCulture | System.Runtime.CompilerServices.IsVolatile | modreq | +| s_DefaultThreadCurrentUICulture | System.Runtime.CompilerServices.IsVolatile | modreq | +| s_Invariant | System.Runtime.CompilerServices.IsVolatile | modreq | +| s_LcidCachedCultures | System.Runtime.CompilerServices.IsVolatile | modreq | +| s_NameCachedCultures | System.Runtime.CompilerServices.IsVolatile | modreq | +| s_anonymouslyHostedDynamicMethodsModule | System.Runtime.CompilerServices.IsVolatile | modreq | +| s_cachedCultures | System.Runtime.CompilerServices.IsVolatile | modreq | +| s_cachedRegions | System.Runtime.CompilerServices.IsVolatile | modreq | +| s_currentRegionInfo | System.Runtime.CompilerServices.IsVolatile | modreq | +| s_defaultBinder | System.Runtime.CompilerServices.IsVolatile | modreq | +| s_defaultInstance | System.Runtime.CompilerServices.IsVolatile | modreq | +| s_indentSize | System.Runtime.CompilerServices.IsVolatile | modreq | +| s_initialized | System.Runtime.CompilerServices.IsVolatile | modreq | +| s_invariant | System.Runtime.CompilerServices.IsVolatile | modreq | +| s_invariantInfo | System.Runtime.CompilerServices.IsVolatile | modreq | +| s_jajpDTFI | System.Runtime.CompilerServices.IsVolatile | modreq | +| s_japaneseEraInfo | System.Runtime.CompilerServices.IsVolatile | modreq | +| s_knownWords | System.Runtime.CompilerServices.IsVolatile | modreq | +| s_lastProcessorCountRefreshTicks | System.Runtime.CompilerServices.IsVolatile | modreq | +| s_processorCount | System.Runtime.CompilerServices.IsVolatile | modreq | +| s_provider | System.Runtime.CompilerServices.IsVolatile | modreq | +| s_providers | System.Runtime.CompilerServices.IsVolatile | modreq | +| s_regionNames | System.Runtime.CompilerServices.IsVolatile | modreq | +| s_userDefaultCulture | System.Runtime.CompilerServices.IsVolatile | modreq | +| s_userDefaultUICulture | System.Runtime.CompilerServices.IsVolatile | modreq | +| s_zhtwDTFI | System.Runtime.CompilerServices.IsVolatile | modreq | +| set_Prop2 | System.Runtime.CompilerServices.IsExternalInit | modreq | +| threadPoolInitialized | System.Runtime.CompilerServices.IsVolatile | modreq | diff --git a/csharp/ql/test/library-tests/cil/init-only-prop/customModifiers.ql b/csharp/ql/test/library-tests/cil/init-only-prop/customModifiers.ql new file mode 100644 index 00000000000..3366bef35ce --- /dev/null +++ b/csharp/ql/test/library-tests/cil/init-only-prop/customModifiers.ql @@ -0,0 +1,13 @@ +import semmle.code.cil.Type + +bindingset[kind] +private string getKind(int kind) { if kind = 1 then result = "modreq" else result = "modopt" } + +from string receiver, string modifier, int kind +where + exists(Type modType, CustomModifierReceiver cmr | + receiver = cmr.toString() and + cil_custom_modifiers(cmr, modType, kind) and + modType.getQualifiedName() = modifier + ) +select receiver, modifier, getKind(kind) diff --git a/csharp/ql/test/library-tests/cil/init-only-prop/setters.expected b/csharp/ql/test/library-tests/cil/init-only-prop/setters.expected new file mode 100644 index 00000000000..49f58c1113d --- /dev/null +++ b/csharp/ql/test/library-tests/cil/init-only-prop/setters.expected @@ -0,0 +1,2 @@ +| cil-init-prop.dll:0:0:0:0 | set_Prop1 | set | +| cil-init-prop.dll:0:0:0:0 | set_Prop2 | init | diff --git a/csharp/ql/test/library-tests/cil/init-only-prop/setters.ql b/csharp/ql/test/library-tests/cil/init-only-prop/setters.ql new file mode 100644 index 00000000000..b5721e243dd --- /dev/null +++ b/csharp/ql/test/library-tests/cil/init-only-prop/setters.ql @@ -0,0 +1,8 @@ +import semmle.code.cil.Method +import semmle.code.csharp.Location + +private string getType(Setter s) { if s.isInitOnly() then result = "init" else result = "set" } + +from Setter s +where s.getLocation().(Assembly).getName() = "cil-init-prop" +select s, getType(s) diff --git a/csharp/ql/test/library-tests/cil/typeAnnotations/Program.cs b/csharp/ql/test/library-tests/cil/typeAnnotations/Program.cs new file mode 100644 index 00000000000..ea38187bdec --- /dev/null +++ b/csharp/ql/test/library-tests/cil/typeAnnotations/Program.cs @@ -0,0 +1,10 @@ +// semmle-extractor-options: --cil + +using System; + +class Test +{ + static void Main(string[] args) + { + } +} diff --git a/csharp/ql/test/library-tests/cil/typeAnnotations/typeAnnotations.expected b/csharp/ql/test/library-tests/cil/typeAnnotations/typeAnnotations.expected new file mode 100644 index 00000000000..c2a2d3a76fe --- /dev/null +++ b/csharp/ql/test/library-tests/cil/typeAnnotations/typeAnnotations.expected @@ -0,0 +1,1747 @@ +| Add | method | 32 | +| AddByteOffset | method | 32 | +| As | method | 32 | +| AsMutable | method | 32 | +| AsRef | method | 32 | +| GetNonNullPinnableReference | method | 32 | +| GetPinnableReference | method | 32 | +| GetRawArrayData | method | 32 | +| GetRawArrayGeometry | method | 32 | +| GetRawData | method | 32 | +| GetRawStringData | method | 32 | +| GetRawSzArrayData | method | 32 | +| GetReference | method | 32 | +| Local variable 0 of method <GetUpper>g__SoftwareFallback\|66_0 | local | 32 | +| Local variable 0 of method Add | local | 32 | +| Local variable 0 of method Clear | local | 32 | +| Local variable 0 of method EnumCalendarInfoCallback | local | 32 | +| Local variable 0 of method GetElement | local | 32 | +| Local variable 0 of method GetHashCode | local | 32 | +| Local variable 0 of method GetPinnableReference | local | 32 | +| Local variable 0 of method GetUpper | local | 32 | +| Local variable 0 of method GetValue | local | 32 | +| Local variable 0 of method LinkTimer | local | 32 | +| Local variable 0 of method Memmove | local | 32 | +| Local variable 0 of method MoveNext | local | 32 | +| Local variable 0 of method Multiply | local | 32 | +| Local variable 0 of method RemoveIndex | local | 32 | +| Local variable 0 of method Reverse | local | 32 | +| Local variable 0 of method RunOrScheduleAction | local | 32 | +| Local variable 0 of method ToUInt64 | local | 32 | +| Local variable 0 of method TryDecodeFromUtf16 | local | 32 | +| Local variable 0 of method TryParseExactD | local | 32 | +| Local variable 0 of method TryParseExactN | local | 32 | +| Local variable 0 of method ValueToHexString | local | 32 | +| Local variable 0 of method ValueToString | local | 32 | +| Local variable 1 of method .ctor | local | 32 | +| Local variable 1 of method <Create>g__SoftwareFallback\|32_0 | local | 32 | +| Local variable 1 of method <Create>g__SoftwareFallback\|33_0 | local | 32 | +| Local variable 1 of method <Create>g__SoftwareFallback\|34_0 | local | 32 | +| Local variable 1 of method <Create>g__SoftwareFallback\|35_0 | local | 32 | +| Local variable 1 of method <Create>g__SoftwareFallback\|36_0 | local | 32 | +| Local variable 1 of method <Create>g__SoftwareFallback\|37_0 | local | 32 | +| Local variable 1 of method <Create>g__SoftwareFallback\|38_0 | local | 32 | +| Local variable 1 of method <Create>g__SoftwareFallback\|39_0 | local | 32 | +| Local variable 1 of method <Create>g__SoftwareFallback\|40_0 | local | 32 | +| Local variable 1 of method <Create>g__SoftwareFallback\|41_0 | local | 32 | +| Local variable 1 of method <GetCalendarInfo>b__32_0 | local | 32 | +| Local variable 1 of method <GetDisplayName>b__113_0 | local | 32 | +| Local variable 1 of method <WithUpper>g__SoftwareFallback\|67_0 | local | 32 | +| Local variable 1 of method Add | local | 32 | +| Local variable 1 of method Append | local | 32 | +| Local variable 1 of method AppendHelper | local | 32 | +| Local variable 1 of method AppendJoin | local | 32 | +| Local variable 1 of method CompareString | local | 32 | +| Local variable 1 of method CompareStringOrdinalIgnoreCase | local | 32 | +| Local variable 1 of method Convert | local | 32 | +| Local variable 1 of method Create | local | 32 | +| Local variable 1 of method CreateActivityPathGuid | local | 32 | +| Local variable 1 of method EndsWith | local | 32 | +| Local variable 1 of method FillStringChecked | local | 32 | +| Local variable 1 of method FromBase64CharArray | local | 32 | +| Local variable 1 of method FromBase64String | local | 32 | +| Local variable 1 of method FromUtf16 | local | 32 | +| Local variable 1 of method GetAscii | local | 32 | +| Local variable 1 of method GetByteCount | local | 32 | +| Local variable 1 of method GetByteCountWithFallback | local | 32 | +| Local variable 1 of method GetBytes | local | 32 | +| Local variable 1 of method GetBytesFromEncoding | local | 32 | +| Local variable 1 of method GetBytesWithFallback | local | 32 | +| Local variable 1 of method GetCharCount | local | 32 | +| Local variable 1 of method GetCharCountWithFallback | local | 32 | +| Local variable 1 of method GetChars | local | 32 | +| Local variable 1 of method GetCharsWithFallback | local | 32 | +| Local variable 1 of method GetEnvironmentVariable | local | 32 | +| Local variable 1 of method GetHashCode | local | 32 | +| Local variable 1 of method GetNonRandomizedHashCode | local | 32 | +| Local variable 1 of method GetString | local | 32 | +| Local variable 1 of method GetUnicode | local | 32 | +| Local variable 1 of method IndexOf | local | 32 | +| Local variable 1 of method IndexOfCore | local | 32 | +| Local variable 1 of method IndexOfOrdinalHelper | local | 32 | +| Local variable 1 of method IndexOfOrdinalIgnoreCaseHelper | local | 32 | +| Local variable 1 of method Insert | local | 32 | +| Local variable 1 of method InternalCopy | local | 32 | +| Local variable 1 of method InvariantIndexOf | local | 32 | +| Local variable 1 of method InvariantLastIndexOf | local | 32 | +| Local variable 1 of method IsAscii | local | 32 | +| Local variable 1 of method IsSortable | local | 32 | +| Local variable 1 of method Join | local | 32 | +| Local variable 1 of method LastIndexOf | local | 32 | +| Local variable 1 of method MatchChars | local | 32 | +| Local variable 1 of method Memmove | local | 32 | +| Local variable 1 of method Pow10 | local | 32 | +| Local variable 1 of method ReplaceAllInChunk | local | 32 | +| Local variable 1 of method Reverse | local | 32 | +| Local variable 1 of method StartsWith | local | 32 | +| Local variable 1 of method TZif_ToInt32 | local | 32 | +| Local variable 1 of method TZif_ToInt64 | local | 32 | +| Local variable 1 of method ThreadSafeCopy | local | 32 | +| Local variable 1 of method ToLowerAsciiInvariant | local | 32 | +| Local variable 1 of method ToUpperAsciiInvariant | local | 32 | +| Local variable 1 of method ToUtf16 | local | 32 | +| Local variable 1 of method Trim | local | 32 | +| Local variable 1 of method TrimEnd | local | 32 | +| Local variable 1 of method TrimStart | local | 32 | +| Local variable 1 of method TryDecodeFromUtf16 | local | 32 | +| Local variable 1 of method TryStringToNumber | local | 32 | +| Local variable 1 of method WaitMultipleIgnoringSyncContext | local | 32 | +| Local variable 1 of method WithElement | local | 32 | +| Local variable 1 of method WithUpper | local | 32 | +| Local variable 1 of method WriteEvent | local | 32 | +| Local variable 1 of method WriteImpl | local | 32 | +| Local variable 1 of method WriteMultiMerge | local | 32 | +| Local variable 1 of method WriteNative | local | 32 | +| Local variable 1 of method get_Item | local | 32 | +| Local variable 2 of method .ctor | local | 32 | +| Local variable 2 of method ChangeCaseCommon | local | 32 | +| Local variable 2 of method CompareOrdinalHelper | local | 32 | +| Local variable 2 of method CompareOrdinalIgnoreCase | local | 32 | +| Local variable 2 of method CopyTo | local | 32 | +| Local variable 2 of method CreateSortKey | local | 32 | +| Local variable 2 of method Ctor | local | 32 | +| Local variable 2 of method DoAnsiConversion | local | 32 | +| Local variable 2 of method EndsWithOrdinalHelper | local | 32 | +| Local variable 2 of method EndsWithOrdinalIgnoreCaseHelper | local | 32 | +| Local variable 2 of method EqualStartingCharacterCount | local | 32 | +| Local variable 2 of method GetByteCount | local | 32 | +| Local variable 2 of method GetBytes | local | 32 | +| Local variable 2 of method GetChars | local | 32 | +| Local variable 2 of method GetValue | local | 32 | +| Local variable 2 of method IndexOfCore | local | 32 | +| Local variable 2 of method IndexOfOrdinalCore | local | 32 | +| Local variable 2 of method Insert | local | 32 | +| Local variable 2 of method InternalGetNumericValue | local | 32 | +| Local variable 2 of method InternalSubString | local | 32 | +| Local variable 2 of method InvariantCreateSortKey | local | 32 | +| Local variable 2 of method LastIndexOfCore | local | 32 | +| Local variable 2 of method LastIndexOfOrdinalCore | local | 32 | +| Local variable 2 of method Multiply | local | 32 | +| Local variable 2 of method ReadNative | local | 32 | +| Local variable 2 of method SetValue | local | 32 | +| Local variable 2 of method StartsWithOrdinalHelper | local | 32 | +| Local variable 2 of method StartsWithOrdinalIgnoreCaseHelper | local | 32 | +| Local variable 2 of method StringToAnsiString | local | 32 | +| Local variable 2 of method TryInt32ToHexStr | local | 32 | +| Local variable 2 of method TryInt64ToHexStr | local | 32 | +| Local variable 2 of method TryJoin | local | 32 | +| Local variable 2 of method TryNegativeInt32ToDecStr | local | 32 | +| Local variable 2 of method TryUInt32ToDecStr | local | 32 | +| Local variable 2 of method TryUInt64ToDecStr | local | 32 | +| Local variable 2 of method Write | local | 32 | +| Local variable 3 of method AddCustomAttributes | local | 32 | +| Local variable 3 of method CompareOrdinalIgnoreCase | local | 32 | +| Local variable 3 of method CompareString | local | 32 | +| Local variable 3 of method CompareStringOrdinalIgnoreCase | local | 32 | +| Local variable 3 of method Convert | local | 32 | +| Local variable 3 of method Copy | local | 32 | +| Local variable 3 of method CreateInstance | local | 32 | +| Local variable 3 of method CreateStringFromEncoding | local | 32 | +| Local variable 3 of method Ctor | local | 32 | +| Local variable 3 of method EndsWith | local | 32 | +| Local variable 3 of method Fill | local | 32 | +| Local variable 3 of method FillStringChecked | local | 32 | +| Local variable 3 of method FindSection | local | 32 | +| Local variable 3 of method FromUtf16 | local | 32 | +| Local variable 3 of method GetBytes | local | 32 | +| Local variable 3 of method GetBytesWithFallback | local | 32 | +| Local variable 3 of method GetChars | local | 32 | +| Local variable 3 of method GetCharsWithFallback | local | 32 | +| Local variable 3 of method IndexOfCharArray | local | 32 | +| Local variable 3 of method IndexOfCore | local | 32 | +| Local variable 3 of method IndexOfOrdinalHelper | local | 32 | +| Local variable 3 of method IndexOfOrdinalIgnoreCaseHelper | local | 32 | +| Local variable 3 of method Int32ToHexStr | local | 32 | +| Local variable 3 of method Int64ToHexStr | local | 32 | +| Local variable 3 of method InternalLoad | local | 32 | +| Local variable 3 of method InvariantIndexOf | local | 32 | +| Local variable 3 of method InvariantLastIndexOf | local | 32 | +| Local variable 3 of method JoinInternal | local | 32 | +| Local variable 3 of method LastIndexOfCharArray | local | 32 | +| Local variable 3 of method NegativeInt32ToDecStr | local | 32 | +| Local variable 3 of method Pin | local | 32 | +| Local variable 3 of method Populate | local | 32 | +| Local variable 3 of method Pow10 | local | 32 | +| Local variable 3 of method Replace | local | 32 | +| Local variable 3 of method Resize | local | 32 | +| Local variable 3 of method StartsWith | local | 32 | +| Local variable 3 of method StringToCoTaskMemUni | local | 32 | +| Local variable 3 of method StringToHGlobalUni | local | 32 | +| Local variable 3 of method ThreadSafeCopy | local | 32 | +| Local variable 3 of method ToBase64String | local | 32 | +| Local variable 3 of method ToCharArray | local | 32 | +| Local variable 3 of method ToString | local | 32 | +| Local variable 3 of method ToUtf16 | local | 32 | +| Local variable 3 of method TryNegativeInt64ToDecStr | local | 32 | +| Local variable 3 of method TryToBase64Chars | local | 32 | +| Local variable 3 of method UInt32ToDecStr | local | 32 | +| Local variable 3 of method UInt64ToDecStr | local | 32 | +| Local variable 3 of method Write | local | 32 | +| Local variable 3 of method WriteEvent | local | 32 | +| Local variable 3 of method WriteStdoutAnsiString | local | 32 | +| Local variable 3 of method get_Item | local | 32 | +| Local variable 4 of method .ctor | local | 32 | +| Local variable 4 of method AddDivisor | local | 32 | +| Local variable 4 of method AddNullTerminatedString | local | 32 | +| Local variable 4 of method ChangeCaseCommon | local | 32 | +| Local variable 4 of method CompareOrdinalHelper | local | 32 | +| Local variable 4 of method Copy | local | 32 | +| Local variable 4 of method EndsWithOrdinalHelper | local | 32 | +| Local variable 4 of method EndsWithOrdinalIgnoreCaseHelper | local | 32 | +| Local variable 4 of method EqualStartingCharacterCount | local | 32 | +| Local variable 4 of method EscapeString | local | 32 | +| Local variable 4 of method FormatPrintF | local | 32 | +| Local variable 4 of method GetBytes | local | 32 | +| Local variable 4 of method GetChars | local | 32 | +| Local variable 4 of method GetMessage | local | 32 | +| Local variable 4 of method GetUnicodeCore | local | 32 | +| Local variable 4 of method IndexOfCore | local | 32 | +| Local variable 4 of method IndexOfOrdinalCore | local | 32 | +| Local variable 4 of method InternalLoad | local | 32 | +| Local variable 4 of method InternalSubString | local | 32 | +| Local variable 4 of method JoinInternal | local | 32 | +| Local variable 4 of method LastIndexOfCore | local | 32 | +| Local variable 4 of method MakeRoom | local | 32 | +| Local variable 4 of method NegativeInt64ToDecStr | local | 32 | +| Local variable 4 of method PadLeft | local | 32 | +| Local variable 4 of method PadRight | local | 32 | +| Local variable 4 of method Remove | local | 32 | +| Local variable 4 of method StartsWithOrdinalHelper | local | 32 | +| Local variable 4 of method StartsWithOrdinalIgnoreCaseHelper | local | 32 | +| Local variable 4 of method ToCharArray | local | 32 | +| Local variable 4 of method TryInsert | local | 32 | +| Local variable 4 of method Write | local | 32 | +| Local variable 4 of method WriteCore | local | 32 | +| Local variable 4 of method WriteEvent | local | 32 | +| Local variable 5 of method Append | local | 32 | +| Local variable 5 of method ConvertToNative | local | 32 | +| Local variable 5 of method CreateInstance | local | 32 | +| Local variable 5 of method GetAttributeUsage | local | 32 | +| Local variable 5 of method GetBytes | local | 32 | +| Local variable 5 of method GetBytesWithFallback | local | 32 | +| Local variable 5 of method GetCharsWithFallback | local | 32 | +| Local variable 5 of method GetCwd | local | 32 | +| Local variable 5 of method GetHomeDirectory | local | 32 | +| Local variable 5 of method Insert | local | 32 | +| Local variable 5 of method JoinInternal | local | 32 | +| Local variable 5 of method Pow10 | local | 32 | +| Local variable 5 of method Read | local | 32 | +| Local variable 5 of method ReadArray | local | 32 | +| Local variable 5 of method ReadCore | local | 32 | +| Local variable 5 of method Replace | local | 32 | +| Local variable 5 of method StringToCoTaskMemUTF8 | local | 32 | +| Local variable 5 of method StringToHGlobalUTF8 | local | 32 | +| Local variable 5 of method SubtractDivisor | local | 32 | +| Local variable 5 of method ToBase64String | local | 32 | +| Local variable 5 of method ToLowerAsciiInvariant | local | 32 | +| Local variable 5 of method ToUpperAsciiInvariant | local | 32 | +| Local variable 5 of method TryToBase64Chars | local | 32 | +| Local variable 5 of method WriteArray | local | 32 | +| Local variable 5 of method WriteEvent | local | 32 | +| Local variable 5 of method get_Item | local | 32 | +| Local variable 5 of method get_UserName | local | 32 | +| Local variable 6 of method .ctor | local | 32 | +| Local variable 6 of method Clear | local | 32 | +| Local variable 6 of method ConvertToBase64Array | local | 32 | +| Local variable 6 of method GenerateMetadataForProperty | local | 32 | +| Local variable 6 of method GetAsciiCore | local | 32 | +| Local variable 6 of method IndexOfOrdinalCore | local | 32 | +| Local variable 6 of method InternalCopy | local | 32 | +| Local variable 6 of method JoinInternal | local | 32 | +| Local variable 6 of method PadRight | local | 32 | +| Local variable 6 of method Remove | local | 32 | +| Local variable 6 of method Replace | local | 32 | +| Local variable 6 of method Resize | local | 32 | +| Local variable 6 of method SetConstantValue | local | 32 | +| Local variable 6 of method ToBase64CharArray | local | 32 | +| Local variable 6 of method TryDecodeFromUtf16 | local | 32 | +| Local variable 6 of method TryFormat | local | 32 | +| Local variable 6 of method Write | local | 32 | +| Local variable 7 of method .ctor | local | 32 | +| Local variable 7 of method Append | local | 32 | +| Local variable 7 of method GenerateMetadata | local | 32 | +| Local variable 7 of method GetBytesWithFallback | local | 32 | +| Local variable 7 of method GetCharsWithFallback | local | 32 | +| Local variable 7 of method GetHashCodeOfStringCore | local | 32 | +| Local variable 7 of method Insert | local | 32 | +| Local variable 7 of method JoinInternal | local | 32 | +| Local variable 7 of method PadLeft | local | 32 | +| Local variable 7 of method Populate | local | 32 | +| Local variable 7 of method Pow10 | local | 32 | +| Local variable 7 of method Remove | local | 32 | +| Local variable 7 of method Resize | local | 32 | +| Local variable 7 of method WriteEventString | local | 32 | +| Local variable 7 of method get_Item | local | 32 | +| Local variable 8 of method JoinInternal | local | 32 | +| Local variable 8 of method Pow10 | local | 32 | +| Local variable 8 of method Replace | local | 32 | +| Local variable 8 of method SetConstantValue | local | 32 | +| Local variable 8 of method ToBase64CharArray | local | 32 | +| Local variable 8 of method ToString | local | 32 | +| Local variable 8 of method TryInsert | local | 32 | +| Local variable 8 of method Write | local | 32 | +| Local variable 9 of method GenerateMetadataForProperty | local | 32 | +| Local variable 9 of method GetHashCodeOfStringCore | local | 32 | +| Local variable 9 of method Insert | local | 32 | +| Local variable 9 of method JoinInternal | local | 32 | +| Local variable 9 of method TrimExcess | local | 32 | +| Local variable 9 of method get_Item | local | 32 | +| Local variable 10 of method .ctor | local | 32 | +| Local variable 10 of method FormatFixed | local | 32 | +| Local variable 10 of method IntToString | local | 32 | +| Local variable 10 of method JoinInternal | local | 32 | +| Local variable 10 of method LongToString | local | 32 | +| Local variable 10 of method ReplaceAllInChunk | local | 32 | +| Local variable 11 of method GenerateMetadata | local | 32 | +| Local variable 11 of method GetHashCodeOfStringCore | local | 32 | +| Local variable 11 of method InternalReadChars | local | 32 | +| Local variable 11 of method Resize | local | 32 | +| Local variable 11 of method get_Item | local | 32 | +| Local variable 12 of method JoinCore | local | 32 | +| Local variable 13 of method .ctor | local | 32 | +| Local variable 13 of method ChangeCaseCommon | local | 32 | +| Local variable 13 of method get_Item | local | 32 | +| Local variable 14 of method .ctor | local | 32 | +| Local variable 14 of method Resize | local | 32 | +| Local variable 15 of method get_Item | local | 32 | +| Local variable 16 of method .ctor | local | 32 | +| Local variable 17 of method get_Item | local | 32 | +| Local variable 18 of method .ctor | local | 32 | +| Local variable 19 of method .ctor | local | 32 | +| Local variable 19 of method NumberToStringFormat | local | 32 | +| Local variable 19 of method get_Item | local | 32 | +| Local variable 22 of method .ctor | local | 32 | +| Local variable 23 of method WriteEvent | local | 32 | +| Local variable 24 of method WriteEvent | local | 32 | +| Local variable 25 of method .ctor | local | 32 | +| Local variable 25 of method WriteEvent | local | 32 | +| Local variable 26 of method .ctor | local | 32 | +| Local variable 26 of method WriteEvent | local | 32 | +| Local variable 27 of method WriteEvent | local | 32 | +| Local variable 28 of method .ctor | local | 32 | +| Local variable 28 of method WriteEvent | local | 32 | +| Local variable 29 of method WriteEvent | local | 32 | +| Local variable 30 of method .ctor | local | 32 | +| Local variable 30 of method WriteEvent | local | 32 | +| Local variable 31 of method .ctor | local | 32 | +| Local variable 31 of method NumberToStringFormat | local | 32 | +| Local variable 33 of method .ctor | local | 32 | +| Local variable 34 of method .ctor | local | 32 | +| Local variable 34 of method WriteEvent | local | 32 | +| Local variable 35 of method .ctor | local | 32 | +| Local variable 37 of method .ctor | local | 32 | +| Local variable 38 of method .ctor | local | 32 | +| Local variable 39 of method .ctor | local | 32 | +| Local variable 41 of method .ctor | local | 32 | +| Local variable 43 of method .ctor | local | 32 | +| Local variable 45 of method .ctor | local | 32 | +| Local variable 47 of method .ctor | local | 32 | +| Local variable 49 of method .ctor | local | 32 | +| Max | method | 32 | +| Min | method | 32 | +| Parameter 0 of <Equals>g__SoftwareFallback\|10_0 | parameter | 32 | +| Parameter 0 of <Equals>g__SoftwareFallback\|12_0 | parameter | 32 | +| Parameter 0 of <UpdatedCachedCursorPosition>g__IncrementX\|115_1 | parameter | 32 | +| Parameter 0 of <UpdatedCachedCursorPosition>g__IncrementY\|115_0 | parameter | 32 | +| Parameter 0 of Abs | parameter | 32 | +| Parameter 0 of AccumulateDecimalDigitsIntoBigInteger | parameter | 32 | +| Parameter 0 of Add | parameter | 32 | +| Parameter 0 of Add32To96 | parameter | 32 | +| Parameter 0 of AddByteOffset | parameter | 32 | +| Parameter 0 of AddCustomAttributes | parameter | 32 | +| Parameter 0 of AddDivisor | parameter | 32 | +| Parameter 0 of AddEventDescriptor | parameter | 32 | +| Parameter 0 of AddExceptionsForCompletedTask | parameter | 32 | +| Parameter 0 of AddNonLetter | parameter | 32 | +| Parameter 0 of AddToCleanupList | parameter | 32 | +| Parameter 0 of AdjustDaylightDeltaToExpectedRange | parameter | 32 | +| Parameter 0 of AdjustHour | parameter | 32 | +| Parameter 0 of AdjustTimeZoneToLocal | parameter | 32 | +| Parameter 0 of AdjustTimeZoneToUniversal | parameter | 32 | +| Parameter 0 of AppendParameters | parameter | 32 | +| Parameter 0 of AreSame | parameter | 32 | +| Parameter 0 of As | parameter | 32 | +| Parameter 0 of AsMutable | parameter | 32 | +| Parameter 0 of AsPointer | parameter | 32 | +| Parameter 0 of AsRef | parameter | 32 | +| Parameter 0 of AssembleFloatingPointBits | parameter | 32 | +| Parameter 0 of BinarySearch | parameter | 32 | +| Parameter 0 of Block | parameter | 32 | +| Parameter 0 of ByteOffset | parameter | 32 | +| Parameter 0 of CheckDefaultDateTime | parameter | 32 | +| Parameter 0 of CheckForAvailableMemory | parameter | 32 | +| Parameter 0 of CheckNewValue | parameter | 32 | +| Parameter 0 of CheckVMForIOPacket | parameter | 32 | +| Parameter 0 of ClearWithReferences | parameter | 32 | +| Parameter 0 of ClearWithoutReferences | parameter | 32 | +| Parameter 0 of Compare | parameter | 32 | +| Parameter 0 of CompareExchange | parameter | 32 | +| Parameter 0 of CompareOrdinalIgnoreCase | parameter | 32 | +| Parameter 0 of CompareStringOrdinalIgnoreCase | parameter | 32 | +| Parameter 0 of ComputeHash32 | parameter | 32 | +| Parameter 0 of ComputeHash32OrdinalIgnoreCase | parameter | 32 | +| Parameter 0 of ComputeHash32OrdinalIgnoreCaseSlow | parameter | 32 | +| Parameter 0 of ConfigureFormatOS | parameter | 32 | +| Parameter 0 of ConfigureFormatR | parameter | 32 | +| Parameter 0 of Contains | parameter | 32 | +| Parameter 0 of ConvertBigIntegerToFloatingPointBits | parameter | 32 | +| Parameter 0 of CountSignificantBits | parameter | 32 | +| Parameter 0 of CreateReadOnlySpan | parameter | 32 | +| Parameter 0 of CreateSpan | parameter | 32 | +| Parameter 0 of DateTimeOffsetTimeZonePostProcessing | parameter | 32 | +| Parameter 0 of DebugCheckEvent | parameter | 32 | +| Parameter 0 of DecAddSub | parameter | 32 | +| Parameter 0 of DecDivMod1E9 | parameter | 32 | +| Parameter 0 of DecimalToNumber | parameter | 32 | +| Parameter 0 of Decode | parameter | 32 | +| Parameter 0 of DecodePayload | parameter | 32 | +| Parameter 0 of Decrement | parameter | 32 | +| Parameter 0 of DestroyCleanupList | parameter | 32 | +| Parameter 0 of DetermineTimeZoneAdjustments | parameter | 32 | +| Parameter 0 of Div96By32 | parameter | 32 | +| Parameter 0 of Div96By64 | parameter | 32 | +| Parameter 0 of Div96ByConst | parameter | 32 | +| Parameter 0 of Div128By96 | parameter | 32 | +| Parameter 0 of DivRem | parameter | 32 | +| Parameter 0 of EncodeObject | parameter | 32 | +| Parameter 0 of EnsureInitialized | parameter | 32 | +| Parameter 0 of EnsureInitializedCore | parameter | 32 | +| Parameter 0 of EnsureLockInitialized | parameter | 32 | +| Parameter 0 of EqualsOrdinalIgnoreCase | parameter | 32 | +| Parameter 0 of EqualsOrdinalIgnoreCaseNonAscii | parameter | 32 | +| Parameter 0 of Exchange | parameter | 32 | +| Parameter 0 of ExchangeAdd | parameter | 32 | +| Parameter 0 of FormatCurrency | parameter | 32 | +| Parameter 0 of FormatDouble | parameter | 32 | +| Parameter 0 of FormatExponent | parameter | 32 | +| Parameter 0 of FormatFixed | parameter | 32 | +| Parameter 0 of FormatGeneral | parameter | 32 | +| Parameter 0 of FormatNumber | parameter | 32 | +| Parameter 0 of FormatPercent | parameter | 32 | +| Parameter 0 of FormatScientific | parameter | 32 | +| Parameter 0 of FormatSingle | parameter | 32 | +| Parameter 0 of GetAvailableThreads | parameter | 32 | +| Parameter 0 of GetAvailableThreadsNative | parameter | 32 | +| Parameter 0 of GetBytes | parameter | 32 | +| Parameter 0 of GetCpuUtilization | parameter | 32 | +| Parameter 0 of GetCurrentMethod | parameter | 32 | +| Parameter 0 of GetDateOfDSN | parameter | 32 | +| Parameter 0 of GetDateOfNDS | parameter | 32 | +| Parameter 0 of GetDateOfNNDS | parameter | 32 | +| Parameter 0 of GetDateTimeNow | parameter | 32 | +| Parameter 0 of GetDateTimeParseException | parameter | 32 | +| Parameter 0 of GetDayOfMN | parameter | 32 | +| Parameter 0 of GetDayOfMNN | parameter | 32 | +| Parameter 0 of GetDayOfNM | parameter | 32 | +| Parameter 0 of GetDayOfNN | parameter | 32 | +| Parameter 0 of GetDayOfNNN | parameter | 32 | +| Parameter 0 of GetDayOfNNY | parameter | 32 | +| Parameter 0 of GetDayOfYM | parameter | 32 | +| Parameter 0 of GetDayOfYMN | parameter | 32 | +| Parameter 0 of GetDayOfYN | parameter | 32 | +| Parameter 0 of GetDayOfYNN | parameter | 32 | +| Parameter 0 of GetDefaultLocaleName | parameter | 32 | +| Parameter 0 of GetDefaultYear | parameter | 32 | +| Parameter 0 of GetDirectoryEntryFullPath | parameter | 32 | +| Parameter 0 of GetExecutingAssembly | parameter | 32 | +| Parameter 0 of GetHashCode | parameter | 32 | +| Parameter 0 of GetHebrewDayOfNM | parameter | 32 | +| Parameter 0 of GetMaxThreads | parameter | 32 | +| Parameter 0 of GetMaxThreadsNative | parameter | 32 | +| Parameter 0 of GetMemoryInfo | parameter | 32 | +| Parameter 0 of GetMinThreads | parameter | 32 | +| Parameter 0 of GetMinThreadsNative | parameter | 32 | +| Parameter 0 of GetNextIntroducedMethod | parameter | 32 | +| Parameter 0 of GetObjectHandleOnStack | parameter | 32 | +| Parameter 0 of GetQCallAssemblyOnStack | parameter | 32 | +| Parameter 0 of GetQCallModuleOnStack | parameter | 32 | +| Parameter 0 of GetQCallTypeHandleOnStack | parameter | 32 | +| Parameter 0 of GetStackCrawlMarkHandle | parameter | 32 | +| Parameter 0 of GetStringHandleOnStack | parameter | 32 | +| Parameter 0 of GetSymbolOrDefault | parameter | 32 | +| Parameter 0 of GetThreadDeserializationTracker | parameter | 32 | +| Parameter 0 of GetTimeOfN | parameter | 32 | +| Parameter 0 of GetTimeOfNN | parameter | 32 | +| Parameter 0 of GetTimeOfNNN | parameter | 32 | +| Parameter 0 of GetTimeZoneName | parameter | 32 | +| Parameter 0 of GetWindowSize | parameter | 32 | +| Parameter 0 of HandleTimeZone | parameter | 32 | +| Parameter 0 of HeuristicDivide | parameter | 32 | +| Parameter 0 of IncreaseScale | parameter | 32 | +| Parameter 0 of IncreaseScale64 | parameter | 32 | +| Parameter 0 of Increment | parameter | 32 | +| Parameter 0 of IndexOf | parameter | 32 | +| Parameter 0 of IndexOfAny | parameter | 32 | +| Parameter 0 of InitBlockUnaligned | parameter | 32 | +| Parameter 0 of Initialize | parameter | 32 | +| Parameter 0 of InitializeVMTp | parameter | 32 | +| Parameter 0 of Int64DivMod1E9 | parameter | 32 | +| Parameter 0 of InternalGetCurrentMethod | parameter | 32 | +| Parameter 0 of InternalRound | parameter | 32 | +| Parameter 0 of IsAddressGreaterThan | parameter | 32 | +| Parameter 0 of IsAddressLessThan | parameter | 32 | +| Parameter 0 of IsUtf8ContinuationByte | parameter | 32 | +| Parameter 0 of LastIndexOf | parameter | 32 | +| Parameter 0 of LastIndexOfAny | parameter | 32 | +| Parameter 0 of LoadUIntPtr | parameter | 32 | +| Parameter 0 of LoadVector | parameter | 32 | +| Parameter 0 of LoadVector128 | parameter | 32 | +| Parameter 0 of LoadVector256 | parameter | 32 | +| Parameter 0 of MatchAbbreviatedDayName | parameter | 32 | +| Parameter 0 of MatchAbbreviatedMonthName | parameter | 32 | +| Parameter 0 of MatchAbbreviatedTimeMark | parameter | 32 | +| Parameter 0 of MatchDayName | parameter | 32 | +| Parameter 0 of MatchEraName | parameter | 32 | +| Parameter 0 of MatchHebrewDigits | parameter | 32 | +| Parameter 0 of MatchMonthName | parameter | 32 | +| Parameter 0 of MatchTimeMark | parameter | 32 | +| Parameter 0 of MatchWord | parameter | 32 | +| Parameter 0 of Max | parameter | 32 | +| Parameter 0 of Memmove | parameter | 32 | +| Parameter 0 of Min | parameter | 32 | +| Parameter 0 of Multiply | parameter | 32 | +| Parameter 0 of NarrowFourUtf16CharsToAsciiAndWriteToBuffer | parameter | 32 | +| Parameter 0 of NarrowTwoUtf16CharsToAsciiAndWriteToBuffer | parameter | 32 | +| Parameter 0 of NumberToDouble | parameter | 32 | +| Parameter 0 of NumberToFloatingPointBits | parameter | 32 | +| Parameter 0 of NumberToFloatingPointBitsSlow | parameter | 32 | +| Parameter 0 of NumberToSingle | parameter | 32 | +| Parameter 0 of NumberToString | parameter | 32 | +| Parameter 0 of NumberToStringFormat | parameter | 32 | +| Parameter 0 of OverflowUnscale | parameter | 32 | +| Parameter 0 of ParseByFormat | parameter | 32 | +| Parameter 0 of ParseDigits | parameter | 32 | +| Parameter 0 of ParseExactDigits | parameter | 32 | +| Parameter 0 of ParseExactLiteral | parameter | 32 | +| Parameter 0 of ParseFraction | parameter | 32 | +| Parameter 0 of ParseFractionExact | parameter | 32 | +| Parameter 0 of ParseISO8601 | parameter | 32 | +| Parameter 0 of ParseJapaneseEraStart | parameter | 32 | +| Parameter 0 of ParseSign | parameter | 32 | +| Parameter 0 of ParseTimeZone | parameter | 32 | +| Parameter 0 of ParseTimeZoneOffset | parameter | 32 | +| Parameter 0 of ProcessDateTimeSuffix | parameter | 32 | +| Parameter 0 of ProcessTerminalState | parameter | 32 | +| Parameter 0 of ProcessTerminal_D | parameter | 32 | +| Parameter 0 of ProcessTerminal_DHMSF | parameter | 32 | +| Parameter 0 of ProcessTerminal_HM | parameter | 32 | +| Parameter 0 of ProcessTerminal_HMS_F_D | parameter | 32 | +| Parameter 0 of ProcessTerminal_HM_S_D | parameter | 32 | +| Parameter 0 of Read | parameter | 32 | +| Parameter 0 of ReadUnaligned | parameter | 32 | +| Parameter 0 of RefreshColors | parameter | 32 | +| Parameter 0 of RemoveFirstArgIfRelatedActivityId | parameter | 32 | +| Parameter 0 of Resize | parameter | 32 | +| Parameter 0 of RhBulkMoveWithWriteBarrier | parameter | 32 | +| Parameter 0 of RhZeroMemory | parameter | 32 | +| Parameter 0 of Round | parameter | 32 | +| Parameter 0 of RoundNumber | parameter | 32 | +| Parameter 0 of SearchScale | parameter | 32 | +| Parameter 0 of SequenceCompareTo | parameter | 32 | +| Parameter 0 of SequenceEqual | parameter | 32 | +| Parameter 0 of SetDateDMY | parameter | 32 | +| Parameter 0 of SetDateMDY | parameter | 32 | +| Parameter 0 of SetDateYDM | parameter | 32 | +| Parameter 0 of SetDateYMD | parameter | 32 | +| Parameter 0 of Sign | parameter | 32 | +| Parameter 0 of Start | parameter | 32 | +| Parameter 0 of SubtractDivisor | parameter | 32 | +| Parameter 0 of TZif_GenerateAdjustmentRule | parameter | 32 | +| Parameter 0 of TZif_GenerateAdjustmentRules | parameter | 32 | +| Parameter 0 of TrimEventDescriptors | parameter | 32 | +| Parameter 0 of Truncate | parameter | 32 | +| Parameter 0 of TryAdjustYear | parameter | 32 | +| Parameter 0 of TryDigitGenCounted | parameter | 32 | +| Parameter 0 of TryDigitGenShortest | parameter | 32 | +| Parameter 0 of TryFormatDecimalE | parameter | 32 | +| Parameter 0 of TryFormatDecimalF | parameter | 32 | +| Parameter 0 of TryFormatDecimalG | parameter | 32 | +| Parameter 0 of TryFormatThrowFormatException | parameter | 32 | +| Parameter 0 of TryGetCachedCursorPosition | parameter | 32 | +| Parameter 0 of TryGetCursorPosition | parameter | 32 | +| Parameter 0 of TryGetLocalTzFile | parameter | 32 | +| Parameter 0 of TryNumberToDecimal | parameter | 32 | +| Parameter 0 of TryNumberToInt32 | parameter | 32 | +| Parameter 0 of TryNumberToInt64 | parameter | 32 | +| Parameter 0 of TryNumberToUInt32 | parameter | 32 | +| Parameter 0 of TryNumberToUInt64 | parameter | 32 | +| Parameter 0 of TryParseHebrewNumber | parameter | 32 | +| Parameter 0 of TryParseNumber | parameter | 32 | +| Parameter 0 of TryParseThrowFormatException | parameter | 32 | +| Parameter 0 of TryResolveStateMachineMethod | parameter | 32 | +| Parameter 0 of TryRunCounted | parameter | 32 | +| Parameter 0 of TryRunShortest | parameter | 32 | +| Parameter 0 of UnalignedCountVector | parameter | 32 | +| Parameter 0 of UnalignedCountVector128 | parameter | 32 | +| Parameter 0 of UnalignedCountVectorFromEnd | parameter | 32 | +| Parameter 0 of Unscale | parameter | 32 | +| Parameter 0 of UpdateStringBuilder | parameter | 32 | +| Parameter 0 of ValueAtReturn | parameter | 32 | +| Parameter 0 of VarCyFromDec | parameter | 32 | +| Parameter 0 of VarDecCmp | parameter | 32 | +| Parameter 0 of VarDecCmpSub | parameter | 32 | +| Parameter 0 of VarDecDiv | parameter | 32 | +| Parameter 0 of VarDecMod | parameter | 32 | +| Parameter 0 of VarDecModFull | parameter | 32 | +| Parameter 0 of VarDecMul | parameter | 32 | +| Parameter 0 of VarR4FromDec | parameter | 32 | +| Parameter 0 of VarR8FromDec | parameter | 32 | +| Parameter 0 of VerifyValidPunctuation | parameter | 32 | +| Parameter 0 of VolatileRead | parameter | 32 | +| Parameter 0 of VolatileWrite | parameter | 32 | +| Parameter 0 of WidenFourAsciiBytesToUtf16AndWriteToBuffer | parameter | 32 | +| Parameter 0 of Write | parameter | 32 | +| Parameter 0 of WriteFirstUtf16CharAsUtf8ThreeByteSequence | parameter | 32 | +| Parameter 0 of WriteNibble | parameter | 32 | +| Parameter 0 of WriteThreeLowOrderBytes | parameter | 32 | +| Parameter 0 of WriteTwoUtf16CharsAsTwoUtf8ThreeByteSequences | parameter | 32 | +| Parameter 0 of WriteUnaligned | parameter | 32 | +| Parameter 0 of _GetCurrentMethod | parameter | 32 | +| Parameter 0 of _Memmove | parameter | 32 | +| Parameter 1 of .ctor | parameter | 32 | +| Parameter 1 of <SignalCompletion>b__21_0 | parameter | 32 | +| Parameter 1 of AcquirePointer | parameter | 32 | +| Parameter 1 of Add | parameter | 32 | +| Parameter 1 of AddNonLetter | parameter | 32 | +| Parameter 1 of AddSpecialInterface | parameter | 32 | +| Parameter 1 of AddTitlecaseLetter | parameter | 32 | +| Parameter 1 of AddToList | parameter | 32 | +| Parameter 1 of AdjustDaylightDeltaToExpectedRange | parameter | 32 | +| Parameter 1 of AdjustTimeMark | parameter | 32 | +| Parameter 1 of AreSame | parameter | 32 | +| Parameter 1 of AwaitOnCompleted | parameter | 32 | +| Parameter 1 of AwaitUnsafeOnCompleted | parameter | 32 | +| Parameter 1 of BeginInvoke | parameter | 32 | +| Parameter 1 of Block | parameter | 32 | +| Parameter 1 of ByteOffset | parameter | 32 | +| Parameter 1 of ChangeCaseCommon | parameter | 32 | +| Parameter 1 of CheckDefaultDateTime | parameter | 32 | +| Parameter 1 of CheckForAvailableMemory | parameter | 32 | +| Parameter 1 of CheckVMForIOPacket | parameter | 32 | +| Parameter 1 of ClearManaged | parameter | 32 | +| Parameter 1 of ClearNative | parameter | 32 | +| Parameter 1 of Clone | parameter | 32 | +| Parameter 1 of Compare | parameter | 32 | +| Parameter 1 of ConfigureFormatOS | parameter | 32 | +| Parameter 1 of ConfigureFormatR | parameter | 32 | +| Parameter 1 of ConstructName | parameter | 32 | +| Parameter 1 of ConvertBigIntegerToFloatingPointBits | parameter | 32 | +| Parameter 1 of ConvertContentsToManaged | parameter | 32 | +| Parameter 1 of ConvertContentsToNative | parameter | 32 | +| Parameter 1 of ConvertGregorianToHijri | parameter | 32 | +| Parameter 1 of ConvertSpaceToManaged | parameter | 32 | +| Parameter 1 of ConvertSpaceToNative | parameter | 32 | +| Parameter 1 of CopyRuntimeTypeHandles | parameter | 32 | +| Parameter 1 of CountDecimalTrailingZeros | parameter | 32 | +| Parameter 1 of CreateActivityPathGuid | parameter | 32 | +| Parameter 1 of CreateAndGetBoundaries | parameter | 32 | +| Parameter 1 of CreationOptionsFromContinuationOptions | parameter | 32 | +| Parameter 1 of DangerousAddRef | parameter | 32 | +| Parameter 1 of DecAddSub | parameter | 32 | +| Parameter 1 of DecimalToNumber | parameter | 32 | +| Parameter 1 of Decode | parameter | 32 | +| Parameter 1 of DecodeFromUtf8 | parameter | 32 | +| Parameter 1 of DecodeFromUtf16 | parameter | 32 | +| Parameter 1 of DecodeLastFromUtf8 | parameter | 32 | +| Parameter 1 of DecodeLastFromUtf16 | parameter | 32 | +| Parameter 1 of Deconstruct | parameter | 32 | +| Parameter 1 of Div96ByConst | parameter | 32 | +| Parameter 1 of Div128By96 | parameter | 32 | +| Parameter 1 of DivRem | parameter | 32 | +| Parameter 1 of EatWhiteSpace | parameter | 32 | +| Parameter 1 of Encode | parameter | 32 | +| Parameter 1 of EncodeObject | parameter | 32 | +| Parameter 1 of EncodeTags | parameter | 32 | +| Parameter 1 of EndInvoke | parameter | 32 | +| Parameter 1 of EnsureInitialized | parameter | 32 | +| Parameter 1 of EnsureInitializedCore | parameter | 32 | +| Parameter 1 of Enter | parameter | 32 | +| Parameter 1 of EnumConnectionPoints | parameter | 32 | +| Parameter 1 of EnumConnections | parameter | 32 | +| Parameter 1 of EnumObjectParam | parameter | 32 | +| Parameter 1 of EnumRunning | parameter | 32 | +| Parameter 1 of EqualsOrdinalIgnoreCase | parameter | 32 | +| Parameter 1 of EqualsOrdinalIgnoreCaseNonAscii | parameter | 32 | +| Parameter 1 of EtwEnableCallBack | parameter | 32 | +| Parameter 1 of EvaluateInternal | parameter | 32 | +| Parameter 1 of EventActivityIdControl | parameter | 32 | +| Parameter 1 of ExecuteWithThreadLocal | parameter | 32 | +| Parameter 1 of ExpandPredefinedFormat | parameter | 32 | +| Parameter 1 of ExtractFractionAndBiasedExponent | parameter | 32 | +| Parameter 1 of FStat | parameter | 32 | +| Parameter 1 of FilterCustomAttributeRecord | parameter | 32 | +| Parameter 1 of FilterHelper | parameter | 32 | +| Parameter 1 of FindAndParseNextNumber | parameter | 32 | +| Parameter 1 of FindConnectionPoint | parameter | 32 | +| Parameter 1 of FormatCurrency | parameter | 32 | +| Parameter 1 of FormatFixed | parameter | 32 | +| Parameter 1 of FormatGeneral | parameter | 32 | +| Parameter 1 of FormatNumber | parameter | 32 | +| Parameter 1 of FormatPercent | parameter | 32 | +| Parameter 1 of FormatScientific | parameter | 32 | +| Parameter 1 of GetAvailableThreads | parameter | 32 | +| Parameter 1 of GetAvailableThreadsNative | parameter | 32 | +| Parameter 1 of GetBindOptions | parameter | 32 | +| Parameter 1 of GetBoolValue | parameter | 32 | +| Parameter 1 of GetCachedSwitchValue | parameter | 32 | +| Parameter 1 of GetCachedSwitchValueInternal | parameter | 32 | +| Parameter 1 of GetClassID | parameter | 32 | +| Parameter 1 of GetCodeInfo | parameter | 32 | +| Parameter 1 of GetCombinedList | parameter | 32 | +| Parameter 1 of GetConfigBoolValue | parameter | 32 | +| Parameter 1 of GetConnectionInterface | parameter | 32 | +| Parameter 1 of GetConnectionPointContainer | parameter | 32 | +| Parameter 1 of GetContainingTypeLib | parameter | 32 | +| Parameter 1 of GetCurFile | parameter | 32 | +| Parameter 1 of GetCustData | parameter | 32 | +| Parameter 1 of GetDateOfDSN | parameter | 32 | +| Parameter 1 of GetDateOfNDS | parameter | 32 | +| Parameter 1 of GetDateOfNNDS | parameter | 32 | +| Parameter 1 of GetDatePart | parameter | 32 | +| Parameter 1 of GetDateTimeNow | parameter | 32 | +| Parameter 1 of GetDateTimeNowUtcOffsetFromUtc | parameter | 32 | +| Parameter 1 of GetDayOfMN | parameter | 32 | +| Parameter 1 of GetDayOfMNN | parameter | 32 | +| Parameter 1 of GetDayOfNM | parameter | 32 | +| Parameter 1 of GetDayOfNN | parameter | 32 | +| Parameter 1 of GetDayOfNNN | parameter | 32 | +| Parameter 1 of GetDayOfNNY | parameter | 32 | +| Parameter 1 of GetDayOfYM | parameter | 32 | +| Parameter 1 of GetDayOfYMN | parameter | 32 | +| Parameter 1 of GetDayOfYN | parameter | 32 | +| Parameter 1 of GetDayOfYNN | parameter | 32 | +| Parameter 1 of GetDefaultYear | parameter | 32 | +| Parameter 1 of GetDelegateTarget | parameter | 32 | +| Parameter 1 of GetDynamicOrStaticVariables | parameter | 32 | +| Parameter 1 of GetEnumData | parameter | 32 | +| Parameter 1 of GetFloatingPointMaxDigitsAndPrecision | parameter | 32 | +| Parameter 1 of GetGUID | parameter | 32 | +| Parameter 1 of GetHebrewDayOfNM | parameter | 32 | +| Parameter 1 of GetInterface | parameter | 32 | +| Parameter 1 of GetJapaneseEraStartDate | parameter | 32 | +| Parameter 1 of GetJitContext | parameter | 32 | +| Parameter 1 of GetLibAttr | parameter | 32 | +| Parameter 1 of GetLocalSignature | parameter | 32 | +| Parameter 1 of GetLocaleName | parameter | 32 | +| Parameter 1 of GetMarshalAs | parameter | 32 | +| Parameter 1 of GetMaxThreads | parameter | 32 | +| Parameter 1 of GetMaxThreadsNative | parameter | 32 | +| Parameter 1 of GetMemberCache | parameter | 32 | +| Parameter 1 of GetMemberList | parameter | 32 | +| Parameter 1 of GetMemoryInfo | parameter | 32 | +| Parameter 1 of GetMetadata | parameter | 32 | +| Parameter 1 of GetMinThreads | parameter | 32 | +| Parameter 1 of GetMinThreadsNative | parameter | 32 | +| Parameter 1 of GetNeutralResourcesLanguage | parameter | 32 | +| Parameter 1 of GetObjectStartLength | parameter | 32 | +| Parameter 1 of GetPEKind | parameter | 32 | +| Parameter 1 of GetPrimaryAndSecondary | parameter | 32 | +| Parameter 1 of GetPropertyOrFieldData | parameter | 32 | +| Parameter 1 of GetPwUidR | parameter | 32 | +| Parameter 1 of GetRawArrayGeometry | parameter | 32 | +| Parameter 1 of GetRegularToken | parameter | 32 | +| Parameter 1 of GetRunningObjectTable | parameter | 32 | +| Parameter 1 of GetScopeProps | parameter | 32 | +| Parameter 1 of GetSizeMax | parameter | 32 | +| Parameter 1 of GetSortHandle | parameter | 32 | +| Parameter 1 of GetStackTracesDeepCopy | parameter | 32 | +| Parameter 1 of GetStateMachineBox | parameter | 32 | +| Parameter 1 of GetTimeOfN | parameter | 32 | +| Parameter 1 of GetTimeOfNN | parameter | 32 | +| Parameter 1 of GetTimeOfNNN | parameter | 32 | +| Parameter 1 of GetTypeAttr | parameter | 32 | +| Parameter 1 of GetTypeComp | parameter | 32 | +| Parameter 1 of GetTypeFlags | parameter | 32 | +| Parameter 1 of GetTypeInfoOfGuid | parameter | 32 | +| Parameter 1 of GetTypeKind | parameter | 32 | +| Parameter 1 of GetUtf16SurrogatesFromSupplementaryPlaneScalar | parameter | 32 | +| Parameter 1 of GetVersion | parameter | 32 | +| Parameter 1 of GetWindowSize | parameter | 32 | +| Parameter 1 of GrowTable | parameter | 32 | +| Parameter 1 of HandleTimeZone | parameter | 32 | +| Parameter 1 of Hash | parameter | 32 | +| Parameter 1 of HeuristicDivide | parameter | 32 | +| Parameter 1 of Initialize | parameter | 32 | +| Parameter 1 of Insert | parameter | 32 | +| Parameter 1 of Int32ToNumber | parameter | 32 | +| Parameter 1 of Int64ToNumber | parameter | 32 | +| Parameter 1 of InternalGetSignature | parameter | 32 | +| Parameter 1 of InternalLoad | parameter | 32 | +| Parameter 1 of InternalLoadAssemblyName | parameter | 32 | +| Parameter 1 of InternalTryGetRawMetadata | parameter | 32 | +| Parameter 1 of Inverse | parameter | 32 | +| Parameter 1 of Invoke | parameter | 32 | +| Parameter 1 of IsAddressGreaterThan | parameter | 32 | +| Parameter 1 of IsAddressLessThan | parameter | 32 | +| Parameter 1 of IsSystemMoniker | parameter | 32 | +| Parameter 1 of LStat | parameter | 32 | +| Parameter 1 of LazyCreateEvent | parameter | 32 | +| Parameter 1 of Lex | parameter | 32 | +| Parameter 1 of Load | parameter | 32 | +| Parameter 1 of MapBufferToConsoleKey | parameter | 32 | +| Parameter 1 of Max | parameter | 32 | +| Parameter 1 of Memmove | parameter | 32 | +| Parameter 1 of Min | parameter | 32 | +| Parameter 1 of MoveNext | parameter | 32 | +| Parameter 1 of Multiply | parameter | 32 | +| Parameter 1 of NormalizeAdjustmentRuleOffset | parameter | 32 | +| Parameter 1 of NormalizeCultureName | parameter | 32 | +| Parameter 1 of NumberToFloatingPointBits | parameter | 32 | +| Parameter 1 of NumberToFloatingPointBitsSlow | parameter | 32 | +| Parameter 1 of NumberToString | parameter | 32 | +| Parameter 1 of NumberToStringFormat | parameter | 32 | +| Parameter 1 of OpenExistingWorker | parameter | 32 | +| Parameter 1 of ParseAttributeArguments | parameter | 32 | +| Parameter 1 of ParseAttributeUsageAttribute | parameter | 32 | +| Parameter 1 of ParseByChar | parameter | 32 | +| Parameter 1 of ParseByFormat | parameter | 32 | +| Parameter 1 of ParseFormatO | parameter | 32 | +| Parameter 1 of ParseFormatR | parameter | 32 | +| Parameter 1 of ParseFormatSpecifier | parameter | 32 | +| Parameter 1 of ParseFraction | parameter | 32 | +| Parameter 1 of ParseHelper | parameter | 32 | +| Parameter 1 of ParseISO8601 | parameter | 32 | +| Parameter 1 of ParseSign | parameter | 32 | +| Parameter 1 of ParseTime | parameter | 32 | +| Parameter 1 of ParseTimeZone | parameter | 32 | +| Parameter 1 of Pow2 | parameter | 32 | +| Parameter 1 of Pow10 | parameter | 32 | +| Parameter 1 of ProcessDateTimeSuffix | parameter | 32 | +| Parameter 1 of ProcessHebrewTerminalState | parameter | 32 | +| Parameter 1 of ProcessTerminalState | parameter | 32 | +| Parameter 1 of ProcessToken | parameter | 32 | +| Parameter 1 of QueryInterface | parameter | 32 | +| Parameter 1 of ReadKey | parameter | 32 | +| Parameter 1 of ReliableEnter | parameter | 32 | +| Parameter 1 of ReorderArgumentArray | parameter | 32 | +| Parameter 1 of ReplaceInPlaceAtChunk | parameter | 32 | +| Parameter 1 of RestoreDispatchState | parameter | 32 | +| Parameter 1 of RhBulkMoveWithWriteBarrier | parameter | 32 | +| Parameter 1 of SafeHandleAddRef | parameter | 32 | +| Parameter 1 of SequenceEqual | parameter | 32 | +| Parameter 1 of SetBindOptions | parameter | 32 | +| Parameter 1 of SetCurrentThreadActivityId | parameter | 32 | +| Parameter 1 of SetValue | parameter | 32 | +| Parameter 1 of SkipWhitespace | parameter | 32 | +| Parameter 1 of SnapForObservation | parameter | 32 | +| Parameter 1 of SplitName | parameter | 32 | +| Parameter 1 of Start | parameter | 32 | +| Parameter 1 of Stat | parameter | 32 | +| Parameter 1 of Subtract | parameter | 32 | +| Parameter 1 of TZif_ParseJulianDay | parameter | 32 | +| Parameter 1 of TZif_ParseMDateRule | parameter | 32 | +| Parameter 1 of TZif_ParsePosixDate | parameter | 32 | +| Parameter 1 of TZif_ParsePosixDateTime | parameter | 32 | +| Parameter 1 of TZif_ParsePosixFormat | parameter | 32 | +| Parameter 1 of TZif_ParsePosixName | parameter | 32 | +| Parameter 1 of TZif_ParsePosixOffset | parameter | 32 | +| Parameter 1 of TZif_ParsePosixString | parameter | 32 | +| Parameter 1 of TZif_ParsePosixTime | parameter | 32 | +| Parameter 1 of TZif_ParseRaw | parameter | 32 | +| Parameter 1 of ThrowIfDeserializationInProgress | parameter | 32 | +| Parameter 1 of TryCreate | parameter | 32 | +| Parameter 1 of TryDequeue | parameter | 32 | +| Parameter 1 of TryDequeueSlow | parameter | 32 | +| Parameter 1 of TryDigitGenShortest | parameter | 32 | +| Parameter 1 of TryEnter | parameter | 32 | +| Parameter 1 of TryGetArray | parameter | 32 | +| Parameter 1 of TryGetBuffer | parameter | 32 | +| Parameter 1 of TryGetCachedCursorPosition | parameter | 32 | +| Parameter 1 of TryGetCursorPosition | parameter | 32 | +| Parameter 1 of TryGetLocalTzFile | parameter | 32 | +| Parameter 1 of TryGetMemoryManager | parameter | 32 | +| Parameter 1 of TryGetRawMetadata | parameter | 32 | +| Parameter 1 of TryGetString | parameter | 32 | +| Parameter 1 of TryGetSwitch | parameter | 32 | +| Parameter 1 of TryGetTarget | parameter | 32 | +| Parameter 1 of TryGetTimeZoneFromLocalMachine | parameter | 32 | +| Parameter 1 of TryGetTrailByte | parameter | 32 | +| Parameter 1 of TryLoad | parameter | 32 | +| Parameter 1 of TryLoadTzFile | parameter | 32 | +| Parameter 1 of TryNumberToDecimal | parameter | 32 | +| Parameter 1 of TryNumberToInt32 | parameter | 32 | +| Parameter 1 of TryNumberToInt64 | parameter | 32 | +| Parameter 1 of TryNumberToUInt32 | parameter | 32 | +| Parameter 1 of TryNumberToUInt64 | parameter | 32 | +| Parameter 1 of TryOpen | parameter | 32 | +| Parameter 1 of TryOpenExisting | parameter | 32 | +| Parameter 1 of TryParse | parameter | 32 | +| Parameter 1 of TryParseByteD | parameter | 32 | +| Parameter 1 of TryParseByteN | parameter | 32 | +| Parameter 1 of TryParseByteX | parameter | 32 | +| Parameter 1 of TryParseDateTimeG | parameter | 32 | +| Parameter 1 of TryParseDateTimeOffsetDefault | parameter | 32 | +| Parameter 1 of TryParseDateTimeOffsetO | parameter | 32 | +| Parameter 1 of TryParseExactB | parameter | 32 | +| Parameter 1 of TryParseExactD | parameter | 32 | +| Parameter 1 of TryParseExactN | parameter | 32 | +| Parameter 1 of TryParseExactP | parameter | 32 | +| Parameter 1 of TryParseExactX | parameter | 32 | +| Parameter 1 of TryParseGuid | parameter | 32 | +| Parameter 1 of TryParseGuidN | parameter | 32 | +| Parameter 1 of TryParseHebrewNumber | parameter | 32 | +| Parameter 1 of TryParseHex | parameter | 32 | +| Parameter 1 of TryParseInt16D | parameter | 32 | +| Parameter 1 of TryParseInt16N | parameter | 32 | +| Parameter 1 of TryParseInt32D | parameter | 32 | +| Parameter 1 of TryParseInt32N | parameter | 32 | +| Parameter 1 of TryParseInt64D | parameter | 32 | +| Parameter 1 of TryParseInt64N | parameter | 32 | +| Parameter 1 of TryParseNormalAsFloatingPoint | parameter | 32 | +| Parameter 1 of TryParseNumber | parameter | 32 | +| Parameter 1 of TryParseSByteD | parameter | 32 | +| Parameter 1 of TryParseSByteN | parameter | 32 | +| Parameter 1 of TryParseThrowFormatException | parameter | 32 | +| Parameter 1 of TryParseTimeSpanBigG | parameter | 32 | +| Parameter 1 of TryParseTimeSpanC | parameter | 32 | +| Parameter 1 of TryParseTimeSpanConstant | parameter | 32 | +| Parameter 1 of TryParseTimeSpanFraction | parameter | 32 | +| Parameter 1 of TryParseTimeSpanLittleG | parameter | 32 | +| Parameter 1 of TryParseUInt16D | parameter | 32 | +| Parameter 1 of TryParseUInt16N | parameter | 32 | +| Parameter 1 of TryParseUInt16X | parameter | 32 | +| Parameter 1 of TryParseUInt32D | parameter | 32 | +| Parameter 1 of TryParseUInt32N | parameter | 32 | +| Parameter 1 of TryParseUInt32X | parameter | 32 | +| Parameter 1 of TryParseUInt64D | parameter | 32 | +| Parameter 1 of TryParseUInt64N | parameter | 32 | +| Parameter 1 of TryParseUInt64X | parameter | 32 | +| Parameter 1 of TryPeek | parameter | 32 | +| Parameter 1 of TryRead | parameter | 32 | +| Parameter 1 of TryReadInt16BigEndian | parameter | 32 | +| Parameter 1 of TryReadInt16LittleEndian | parameter | 32 | +| Parameter 1 of TryReadInt32BigEndian | parameter | 32 | +| Parameter 1 of TryReadInt32LittleEndian | parameter | 32 | +| Parameter 1 of TryReadInt64BigEndian | parameter | 32 | +| Parameter 1 of TryReadInt64LittleEndian | parameter | 32 | +| Parameter 1 of TryReadUInt16BigEndian | parameter | 32 | +| Parameter 1 of TryReadUInt16LittleEndian | parameter | 32 | +| Parameter 1 of TryReadUInt32BigEndian | parameter | 32 | +| Parameter 1 of TryReadUInt32LittleEndian | parameter | 32 | +| Parameter 1 of TryReadUInt64BigEndian | parameter | 32 | +| Parameter 1 of TryReadUInt64LittleEndian | parameter | 32 | +| Parameter 1 of TryResolveStateMachineMethod | parameter | 32 | +| Parameter 1 of TryRunShortest | parameter | 32 | +| Parameter 1 of TrySteal | parameter | 32 | +| Parameter 1 of TryTake | parameter | 32 | +| Parameter 1 of TryWrite | parameter | 32 | +| Parameter 1 of UInt32ToNumber | parameter | 32 | +| Parameter 1 of UInt64ToNumber | parameter | 32 | +| Parameter 1 of Unscale | parameter | 32 | +| Parameter 1 of ValidateEventOpcodeForTransfer | parameter | 32 | +| Parameter 1 of ValidateVariableAndValue | parameter | 32 | +| Parameter 1 of VarDecCmp | parameter | 32 | +| Parameter 1 of VarDecCmpSub | parameter | 32 | +| Parameter 1 of VarDecDiv | parameter | 32 | +| Parameter 1 of VarDecFromR4 | parameter | 32 | +| Parameter 1 of VarDecFromR8 | parameter | 32 | +| Parameter 1 of VarDecMod | parameter | 32 | +| Parameter 1 of VarDecModFull | parameter | 32 | +| Parameter 1 of VarDecMul | parameter | 32 | +| Parameter 1 of Widen | parameter | 32 | +| Parameter 1 of Write | parameter | 32 | +| Parameter 1 of WriteEvent | parameter | 32 | +| Parameter 1 of WriteEventRaw | parameter | 32 | +| Parameter 1 of YearMonthAdjustment | parameter | 32 | +| Parameter 1 of _GetScopeProps | parameter | 32 | +| Parameter 1 of _Memmove | parameter | 32 | +| Parameter 1 of nCreateDynamicAssembly | parameter | 32 | +| Parameter 1 of nGetPrimaryAndSecondary | parameter | 32 | +| Parameter 2 of <TryGetCursorPosition>g__BufferUntil\|86_0 | parameter | 32 | +| Parameter 2 of Add | parameter | 32 | +| Parameter 2 of AddDivisor | parameter | 32 | +| Parameter 2 of AddNum | parameter | 32 | +| Parameter 2 of AddResourceSet | parameter | 32 | +| Parameter 2 of AddSep | parameter | 32 | +| Parameter 2 of AddTitlecaseLetter | parameter | 32 | +| Parameter 2 of Advise | parameter | 32 | +| Parameter 2 of AllocateStringForNameIndex | parameter | 32 | +| Parameter 2 of AttributeUsageCheck | parameter | 32 | +| Parameter 2 of AwaitOnCompleted | parameter | 32 | +| Parameter 2 of AwaitUnsafeOnCompleted | parameter | 32 | +| Parameter 2 of BiggestPowerTen | parameter | 32 | +| Parameter 2 of ChangeCaseCommon | parameter | 32 | +| Parameter 2 of CheckVMForIOPacket | parameter | 32 | +| Parameter 2 of CommonPrefixWith | parameter | 32 | +| Parameter 2 of CompareOrdinalIgnoreCase | parameter | 32 | +| Parameter 2 of CompareStringOrdinalIgnoreCase | parameter | 32 | +| Parameter 2 of ConfigureFormatR | parameter | 32 | +| Parameter 2 of ContinueTryEnter | parameter | 32 | +| Parameter 2 of ConvertGregorianToHijri | parameter | 32 | +| Parameter 2 of ConvertUtcToTimeZone | parameter | 32 | +| Parameter 2 of CopyToTempBufferWithoutWhiteSpace | parameter | 32 | +| Parameter 2 of CountOccurrences | parameter | 32 | +| Parameter 2 of CreateActivityPathGuid | parameter | 32 | +| Parameter 2 of CreateAndGetBoundaries | parameter | 32 | +| Parameter 2 of CreateInstance | parameter | 32 | +| Parameter 2 of CreationOptionsFromContinuationOptions | parameter | 32 | +| Parameter 2 of DecodeFirstRune | parameter | 32 | +| Parameter 2 of DecodeFromUtf8 | parameter | 32 | +| Parameter 2 of DecodeFromUtf16 | parameter | 32 | +| Parameter 2 of DecodeLastFromUtf8 | parameter | 32 | +| Parameter 2 of DecodeLastFromUtf16 | parameter | 32 | +| Parameter 2 of Deconstruct | parameter | 32 | +| Parameter 2 of Dequeue | parameter | 32 | +| Parameter 2 of DivByConst | parameter | 32 | +| Parameter 2 of DivMod | parameter | 32 | +| Parameter 2 of DivRem | parameter | 32 | +| Parameter 2 of DrainLeftoverDataForGetByteCount | parameter | 32 | +| Parameter 2 of DrainLeftoverDataForGetCharCount | parameter | 32 | +| Parameter 2 of EncodeObject | parameter | 32 | +| Parameter 2 of EndInvoke | parameter | 32 | +| Parameter 2 of EnqueueSlow | parameter | 32 | +| Parameter 2 of EnsureInitialized | parameter | 32 | +| Parameter 2 of EnsureInitializedCore | parameter | 32 | +| Parameter 2 of Enum | parameter | 32 | +| Parameter 2 of EnumCustomAttributes | parameter | 32 | +| Parameter 2 of EnumEvents | parameter | 32 | +| Parameter 2 of EnumFields | parameter | 32 | +| Parameter 2 of EnumNestedTypes | parameter | 32 | +| Parameter 2 of EnumParams | parameter | 32 | +| Parameter 2 of EnumProperties | parameter | 32 | +| Parameter 2 of EscapeAsciiChar | parameter | 32 | +| Parameter 2 of EventActivityIdControl | parameter | 32 | +| Parameter 2 of EventWriteTransfer | parameter | 32 | +| Parameter 2 of ExpandPredefinedFormat | parameter | 32 | +| Parameter 2 of FilterHelper | parameter | 32 | +| Parameter 2 of FindConnectionPoint | parameter | 32 | +| Parameter 2 of FindEntry | parameter | 32 | +| Parameter 2 of FmtClassUpdateNativeInternal | parameter | 32 | +| Parameter 2 of FromUtf16 | parameter | 32 | +| Parameter 2 of GenerateMetadata | parameter | 32 | +| Parameter 2 of GenerateMetadataForProperty | parameter | 32 | +| Parameter 2 of GetAdjustmentRuleForAmbiguousOffsets | parameter | 32 | +| Parameter 2 of GetAdjustmentRuleForTime | parameter | 32 | +| Parameter 2 of GetBoundaries | parameter | 32 | +| Parameter 2 of GetCachedPowerForBinaryExponentRange | parameter | 32 | +| Parameter 2 of GetClassLayout | parameter | 32 | +| Parameter 2 of GetCodeInfo | parameter | 32 | +| Parameter 2 of GetContainingTypeLib | parameter | 32 | +| Parameter 2 of GetCustData | parameter | 32 | +| Parameter 2 of GetCustomAttributeProps | parameter | 32 | +| Parameter 2 of GetCustomAttributes | parameter | 32 | +| Parameter 2 of GetDatePart | parameter | 32 | +| Parameter 2 of GetDayOfMN | parameter | 32 | +| Parameter 2 of GetDayOfNM | parameter | 32 | +| Parameter 2 of GetDayOfNN | parameter | 32 | +| Parameter 2 of GetDefaultValue | parameter | 32 | +| Parameter 2 of GetDisplayName | parameter | 32 | +| Parameter 2 of GetDocumentation | parameter | 32 | +| Parameter 2 of GetDocumentation2 | parameter | 32 | +| Parameter 2 of GetDynamicOrStaticVariables | parameter | 32 | +| Parameter 2 of GetElement | parameter | 32 | +| Parameter 2 of GetElementNoThrow | parameter | 32 | +| Parameter 2 of GetEnumData | parameter | 32 | +| Parameter 2 of GetEventProps | parameter | 32 | +| Parameter 2 of GetFieldDefProps | parameter | 32 | +| Parameter 2 of GetFuncCustData | parameter | 32 | +| Parameter 2 of GetFuncDesc | parameter | 32 | +| Parameter 2 of GetGenericParamProps | parameter | 32 | +| Parameter 2 of GetImplTypeCustData | parameter | 32 | +| Parameter 2 of GetImplTypeFlags | parameter | 32 | +| Parameter 2 of GetIndexOfNextTokenAfterSeconds | parameter | 32 | +| Parameter 2 of GetInterface | parameter | 32 | +| Parameter 2 of GetJapaneseEraStartDate | parameter | 32 | +| Parameter 2 of GetKeyFromCharValue | parameter | 32 | +| Parameter 2 of GetLibStatistics | parameter | 32 | +| Parameter 2 of GetLocaleInfoGroupingSizes | parameter | 32 | +| Parameter 2 of GetLocaleInfoInt | parameter | 32 | +| Parameter 2 of GetMarshalAs | parameter | 32 | +| Parameter 2 of GetMemoryInfo | parameter | 32 | +| Parameter 2 of GetMetadata | parameter | 32 | +| Parameter 2 of GetMonthDayOrder | parameter | 32 | +| Parameter 2 of GetMops | parameter | 32 | +| Parameter 2 of GetObject | parameter | 32 | +| Parameter 2 of GetObjectParam | parameter | 32 | +| Parameter 2 of GetObjectStartLength | parameter | 32 | +| Parameter 2 of GetPEKind | parameter | 32 | +| Parameter 2 of GetPInvokeMap | parameter | 32 | +| Parameter 2 of GetParamDefProps | parameter | 32 | +| Parameter 2 of GetPointerToFirstInvalidByte | parameter | 32 | +| Parameter 2 of GetPointerToFirstInvalidChar | parameter | 32 | +| Parameter 2 of GetPropertyProps | parameter | 32 | +| Parameter 2 of GetRawArrayGeometry | parameter | 32 | +| Parameter 2 of GetRefTypeInfo | parameter | 32 | +| Parameter 2 of GetRefTypeOfImplType | parameter | 32 | +| Parameter 2 of GetRegularToken | parameter | 32 | +| Parameter 2 of GetResource | parameter | 32 | +| Parameter 2 of GetResourceData | parameter | 32 | +| Parameter 2 of GetSeparatorToken | parameter | 32 | +| Parameter 2 of GetSessionInfo | parameter | 32 | +| Parameter 2 of GetSessionInfoCallback | parameter | 32 | +| Parameter 2 of GetStackTracesDeepCopy | parameter | 32 | +| Parameter 2 of GetTimeOfLastChange | parameter | 32 | +| Parameter 2 of GetTypeInfo | parameter | 32 | +| Parameter 2 of GetTypeInfoOfGuid | parameter | 32 | +| Parameter 2 of GetTypeInfoType | parameter | 32 | +| Parameter 2 of GetUnescapeSequence | parameter | 32 | +| Parameter 2 of GetUtcOffsetFromUniversalTime | parameter | 32 | +| Parameter 2 of GetUtcOffsetFromUtc | parameter | 32 | +| Parameter 2 of GetUtf16SurrogatesFromSupplementaryPlaneScalar | parameter | 32 | +| Parameter 2 of GetVarCustData | parameter | 32 | +| Parameter 2 of GetVarDesc | parameter | 32 | +| Parameter 2 of GetVarIndexOfMemId | parameter | 32 | +| Parameter 2 of GetVersion | parameter | 32 | +| Parameter 2 of GetYearMonthDayOrder | parameter | 32 | +| Parameter 2 of GetYearMonthOrder | parameter | 32 | +| Parameter 2 of GrabInts | parameter | 32 | +| Parameter 2 of GrabLongs | parameter | 32 | +| Parameter 2 of IndexOf | parameter | 32 | +| Parameter 2 of IndexOfAny | parameter | 32 | +| Parameter 2 of Initialize | parameter | 32 | +| Parameter 2 of InternalConvertToUtf32 | parameter | 32 | +| Parameter 2 of InternalDefineDynamicAssembly | parameter | 32 | +| Parameter 2 of InternalFallback | parameter | 32 | +| Parameter 2 of InternalFallbackGetByteCount | parameter | 32 | +| Parameter 2 of InternalGetUnicodeCategory | parameter | 32 | +| Parameter 2 of InternalTryGetRawMetadata | parameter | 32 | +| Parameter 2 of IsDigit | parameter | 32 | +| Parameter 2 of IsInstanceOfInterface | parameter | 32 | +| Parameter 2 of LastIndexOf | parameter | 32 | +| Parameter 2 of LastIndexOfAny | parameter | 32 | +| Parameter 2 of Lex | parameter | 32 | +| Parameter 2 of LoadObject | parameter | 32 | +| Parameter 2 of LoadObjectV2 | parameter | 32 | +| Parameter 2 of MakeSeparatorList | parameter | 32 | +| Parameter 2 of MapBufferToConsoleKey | parameter | 32 | +| Parameter 2 of MatchAbbreviatedDayName | parameter | 32 | +| Parameter 2 of MatchAbbreviatedMonthName | parameter | 32 | +| Parameter 2 of MatchAbbreviatedTimeMark | parameter | 32 | +| Parameter 2 of MatchDayName | parameter | 32 | +| Parameter 2 of MatchEraName | parameter | 32 | +| Parameter 2 of MatchHebrewDigits | parameter | 32 | +| Parameter 2 of MatchLongestWords | parameter | 32 | +| Parameter 2 of MatchMonthName | parameter | 32 | +| Parameter 2 of MatchTimeMark | parameter | 32 | +| Parameter 2 of Multiply | parameter | 32 | +| Parameter 2 of NormalizeDayOfWeek | parameter | 32 | +| Parameter 2 of NoteChangeTime | parameter | 32 | +| Parameter 2 of Overlaps | parameter | 32 | +| Parameter 2 of ParseAttributeArguments | parameter | 32 | +| Parameter 2 of ParseAttributeUsageAttribute | parameter | 32 | +| Parameter 2 of ParseByFormat | parameter | 32 | +| Parameter 2 of ParseComponent | parameter | 32 | +| Parameter 2 of ParseDigits | parameter | 32 | +| Parameter 2 of ParseExactDigits | parameter | 32 | +| Parameter 2 of ParseFormatO | parameter | 32 | +| Parameter 2 of ParseFormatR | parameter | 32 | +| Parameter 2 of ParseFractionExact | parameter | 32 | +| Parameter 2 of ParseInt | parameter | 32 | +| Parameter 2 of ParseTime | parameter | 32 | +| Parameter 2 of ParseTimeZoneOffset | parameter | 32 | +| Parameter 2 of ProcessDateTimeSuffix | parameter | 32 | +| Parameter 2 of ProcessHebrewTerminalState | parameter | 32 | +| Parameter 2 of ProcessTerminalState | parameter | 32 | +| Parameter 2 of ProcessTerminal_D | parameter | 32 | +| Parameter 2 of ProcessTerminal_DHMSF | parameter | 32 | +| Parameter 2 of ProcessTerminal_HM | parameter | 32 | +| Parameter 2 of ProcessTerminal_HMS_F_D | parameter | 32 | +| Parameter 2 of ProcessTerminal_HM_S_D | parameter | 32 | +| Parameter 2 of ProcessToken | parameter | 32 | +| Parameter 2 of QueryInterface | parameter | 32 | +| Parameter 2 of Read | parameter | 32 | +| Parameter 2 of ReadBuffer | parameter | 32 | +| Parameter 2 of RelativePathTo | parameter | 32 | +| Parameter 2 of ReleaseSemaphore | parameter | 32 | +| Parameter 2 of ReliableEnterTimeout | parameter | 32 | +| Parameter 2 of Remove | parameter | 32 | +| Parameter 2 of RemoveRelativeSegments | parameter | 32 | +| Parameter 2 of ReplaceInPlaceAtChunk | parameter | 32 | +| Parameter 2 of ResolveToken | parameter | 32 | +| Parameter 2 of RunForThreadPoolUnsafe | parameter | 32 | +| Parameter 2 of RunInternal | parameter | 32 | +| Parameter 2 of SequenceCompareTo | parameter | 32 | +| Parameter 2 of ShiftLeft | parameter | 32 | +| Parameter 2 of SnapForObservation | parameter | 32 | +| Parameter 2 of SplitName | parameter | 32 | +| Parameter 2 of SubtractDivisor | parameter | 32 | +| Parameter 2 of TZif_ParseJulianDay | parameter | 32 | +| Parameter 2 of TZif_ParseMDateRule | parameter | 32 | +| Parameter 2 of TZif_ParsePosixDateTime | parameter | 32 | +| Parameter 2 of TZif_ParsePosixFormat | parameter | 32 | +| Parameter 2 of TZif_ParseRaw | parameter | 32 | +| Parameter 2 of TimeToLunar | parameter | 32 | +| Parameter 2 of ToUtf16 | parameter | 32 | +| Parameter 2 of Tokenize | parameter | 32 | +| Parameter 2 of TryAddTicks | parameter | 32 | +| Parameter 2 of TryAdjustYear | parameter | 32 | +| Parameter 2 of TryCopyTo | parameter | 32 | +| Parameter 2 of TryCreate | parameter | 32 | +| Parameter 2 of TryDecodeFromUtf16 | parameter | 32 | +| Parameter 2 of TryDequeueSlow | parameter | 32 | +| Parameter 2 of TryDigitGenShortest | parameter | 32 | +| Parameter 2 of TryDrainRemainingDataForGetBytes | parameter | 32 | +| Parameter 2 of TryDrainRemainingDataForGetChars | parameter | 32 | +| Parameter 2 of TryEncodeToUtf8 | parameter | 32 | +| Parameter 2 of TryEncodeToUtf16 | parameter | 32 | +| Parameter 2 of TryEnter | parameter | 32 | +| Parameter 2 of TryFormat | parameter | 32 | +| Parameter 2 of TryFormatDateTimeL | parameter | 32 | +| Parameter 2 of TryFormatDateTimeR | parameter | 32 | +| Parameter 2 of TryFormatDecimalE | parameter | 32 | +| Parameter 2 of TryFormatDecimalF | parameter | 32 | +| Parameter 2 of TryFormatDecimalG | parameter | 32 | +| Parameter 2 of TryFormatFloatingPoint | parameter | 32 | +| Parameter 2 of TryFormatInt32MultipleDigits | parameter | 32 | +| Parameter 2 of TryFormatInt64Default | parameter | 32 | +| Parameter 2 of TryFormatInt64LessThanNegativeBillionMaxUInt | parameter | 32 | +| Parameter 2 of TryFormatInt64MoreThanNegativeBillionMaxUInt | parameter | 32 | +| Parameter 2 of TryFormatInt64MultipleDigits | parameter | 32 | +| Parameter 2 of TryFormatUInt32MultipleDigits | parameter | 32 | +| Parameter 2 of TryFormatUInt32SingleDigit | parameter | 32 | +| Parameter 2 of TryFormatUInt64 | parameter | 32 | +| Parameter 2 of TryFormatUInt64Default | parameter | 32 | +| Parameter 2 of TryFormatUInt64LessThanBillionMaxUInt | parameter | 32 | +| Parameter 2 of TryFormatUInt64MoreThanBillionMaxUInt | parameter | 32 | +| Parameter 2 of TryFormatUInt64MultipleDigits | parameter | 32 | +| Parameter 2 of TryFromBase64Chars | parameter | 32 | +| Parameter 2 of TryFromBase64String | parameter | 32 | +| Parameter 2 of TryGetByteCount | parameter | 32 | +| Parameter 2 of TryGetEntry | parameter | 32 | +| Parameter 2 of TryGetExport | parameter | 32 | +| Parameter 2 of TryGetHomeDirectoryFromPasswd | parameter | 32 | +| Parameter 2 of TryGetMemoryManager | parameter | 32 | +| Parameter 2 of TryGetRawMetadata | parameter | 32 | +| Parameter 2 of TryGetRuneAt | parameter | 32 | +| Parameter 2 of TryGetString | parameter | 32 | +| Parameter 2 of TryGetTimeZone | parameter | 32 | +| Parameter 2 of TryGetTimeZoneFromLocalMachine | parameter | 32 | +| Parameter 2 of TryGetUserNameFromPasswd | parameter | 32 | +| Parameter 2 of TryGetValue | parameter | 32 | +| Parameter 2 of TryGetValueWorker | parameter | 32 | +| Parameter 2 of TryLoadTzFile | parameter | 32 | +| Parameter 2 of TryParse | parameter | 32 | +| Parameter 2 of TryParseByteD | parameter | 32 | +| Parameter 2 of TryParseByteN | parameter | 32 | +| Parameter 2 of TryParseByteX | parameter | 32 | +| Parameter 2 of TryParseDateTimeG | parameter | 32 | +| Parameter 2 of TryParseDateTimeOffsetDefault | parameter | 32 | +| Parameter 2 of TryParseDateTimeOffsetO | parameter | 32 | +| Parameter 2 of TryParseDateTimeOffsetR | parameter | 32 | +| Parameter 2 of TryParseExact | parameter | 32 | +| Parameter 2 of TryParseGuidN | parameter | 32 | +| Parameter 2 of TryParseHebrewNumber | parameter | 32 | +| Parameter 2 of TryParseHex | parameter | 32 | +| Parameter 2 of TryParseInt16D | parameter | 32 | +| Parameter 2 of TryParseInt16N | parameter | 32 | +| Parameter 2 of TryParseInt32D | parameter | 32 | +| Parameter 2 of TryParseInt32N | parameter | 32 | +| Parameter 2 of TryParseInt64D | parameter | 32 | +| Parameter 2 of TryParseInt64N | parameter | 32 | +| Parameter 2 of TryParseNormalAsFloatingPoint | parameter | 32 | +| Parameter 2 of TryParseNumber | parameter | 32 | +| Parameter 2 of TryParseSByteD | parameter | 32 | +| Parameter 2 of TryParseSByteN | parameter | 32 | +| Parameter 2 of TryParseTimeSpanBigG | parameter | 32 | +| Parameter 2 of TryParseTimeSpanC | parameter | 32 | +| Parameter 2 of TryParseTimeSpanFraction | parameter | 32 | +| Parameter 2 of TryParseTimeSpanLittleG | parameter | 32 | +| Parameter 2 of TryParseUInt16D | parameter | 32 | +| Parameter 2 of TryParseUInt16N | parameter | 32 | +| Parameter 2 of TryParseUInt16X | parameter | 32 | +| Parameter 2 of TryParseUInt32D | parameter | 32 | +| Parameter 2 of TryParseUInt32HexNumberStyle | parameter | 32 | +| Parameter 2 of TryParseUInt32N | parameter | 32 | +| Parameter 2 of TryParseUInt32X | parameter | 32 | +| Parameter 2 of TryParseUInt64D | parameter | 32 | +| Parameter 2 of TryParseUInt64HexNumberStyle | parameter | 32 | +| Parameter 2 of TryParseUInt64N | parameter | 32 | +| Parameter 2 of TryParseUInt64X | parameter | 32 | +| Parameter 2 of TryRunDouble | parameter | 32 | +| Parameter 2 of TryRunShortest | parameter | 32 | +| Parameter 2 of TryRunSingle | parameter | 32 | +| Parameter 2 of TryStringToNumber | parameter | 32 | +| Parameter 2 of TryToBase64Chars | parameter | 32 | +| Parameter 2 of UInt64x64To128 | parameter | 32 | +| Parameter 2 of Unscale | parameter | 32 | +| Parameter 2 of WaitOnEvent | parameter | 32 | +| Parameter 2 of Widen | parameter | 32 | +| Parameter 2 of Write | parameter | 32 | +| Parameter 2 of WriteEventRaw | parameter | 32 | +| Parameter 2 of WriteImpl | parameter | 32 | +| Parameter 2 of WriteMultiMerge | parameter | 32 | +| Parameter 2 of WriteMultiMergeInner | parameter | 32 | +| Parameter 2 of WriteToAllListeners | parameter | 32 | +| Parameter 2 of WriteToBuffer | parameter | 32 | +| Parameter 2 of YearMonthAdjustment | parameter | 32 | +| Parameter 2 of _GetClassLayout | parameter | 32 | +| Parameter 2 of _GetCustomAttributeProps | parameter | 32 | +| Parameter 2 of _GetDefaultValue | parameter | 32 | +| Parameter 2 of _GetFieldDefProps | parameter | 32 | +| Parameter 2 of _GetFieldMarshal | parameter | 32 | +| Parameter 2 of _GetGenericParamProps | parameter | 32 | +| Parameter 2 of _GetMarshalAs | parameter | 32 | +| Parameter 2 of _GetMemberRefProps | parameter | 32 | +| Parameter 2 of _GetPInvokeMap | parameter | 32 | +| Parameter 2 of _GetParamDefProps | parameter | 32 | +| Parameter 2 of _GetParentToken | parameter | 32 | +| Parameter 2 of _GetSigOfFieldDef | parameter | 32 | +| Parameter 2 of _GetSigOfMethodDef | parameter | 32 | +| Parameter 2 of _GetSignatureFromToken | parameter | 32 | +| Parameter 2 of _LoadObjectV2 | parameter | 32 | +| Parameter 2 of _ParseAttributeUsageAttribute | parameter | 32 | +| Parameter 2 of ctor>g__TryConvertFromInvariantString\|2_0 | parameter | 32 | +| Parameter 3 of .ctor | parameter | 32 | +| Parameter 3 of <GetSessions>b__39_0 | parameter | 32 | +| Parameter 3 of <TryGetCursorPosition>g__AppendToStdInReaderUntil\|86_1 | parameter | 32 | +| Parameter 3 of <TryGetCursorPosition>g__BufferUntil\|86_0 | parameter | 32 | +| Parameter 3 of AccumulateDecimalDigitsIntoBigInteger | parameter | 32 | +| Parameter 3 of AddressOfMember | parameter | 32 | +| Parameter 3 of AtomicStateUpdate | parameter | 32 | +| Parameter 3 of BeginInvoke | parameter | 32 | +| Parameter 3 of BindToMethod | parameter | 32 | +| Parameter 3 of BindToObject | parameter | 32 | +| Parameter 3 of BindToStorage | parameter | 32 | +| Parameter 3 of BindType | parameter | 32 | +| Parameter 3 of CheckNewValue | parameter | 32 | +| Parameter 3 of CompareExchange | parameter | 32 | +| Parameter 3 of ComposeWith | parameter | 32 | +| Parameter 3 of ContinueTryEnterWithThreadTracking | parameter | 32 | +| Parameter 3 of ConvertGregorianToHijri | parameter | 32 | +| Parameter 3 of ConvertHijriToGregorian | parameter | 32 | +| Parameter 3 of ConvertToNative | parameter | 32 | +| Parameter 3 of CopyToTempBufferWithoutWhiteSpace | parameter | 32 | +| Parameter 3 of CreateCaObject | parameter | 32 | +| Parameter 3 of CreateInstance | parameter | 32 | +| Parameter 3 of CreateMutexCore | parameter | 32 | +| Parameter 3 of DecodeFirstRune | parameter | 32 | +| Parameter 3 of DecodeObject | parameter | 32 | +| Parameter 3 of Deconstruct | parameter | 32 | +| Parameter 3 of DefineDynamicModuleInternal | parameter | 32 | +| Parameter 3 of DefineDynamicModuleInternalNoLock | parameter | 32 | +| Parameter 3 of DivByConst | parameter | 32 | +| Parameter 3 of DivRem | parameter | 32 | +| Parameter 3 of DoAnsiConversion | parameter | 32 | +| Parameter 3 of Dragon4Double | parameter | 32 | +| Parameter 3 of Dragon4Single | parameter | 32 | +| Parameter 3 of DrainLeftoverDataForGetChars | parameter | 32 | +| Parameter 3 of EncodeObject | parameter | 32 | +| Parameter 3 of EncodeRune | parameter | 32 | +| Parameter 3 of EndInvoke | parameter | 32 | +| Parameter 3 of Enum | parameter | 32 | +| Parameter 3 of EnumCalendarInfo | parameter | 32 | +| Parameter 3 of EnumDatePatterns | parameter | 32 | +| Parameter 3 of EnumEraNames | parameter | 32 | +| Parameter 3 of EnumMonthNames | parameter | 32 | +| Parameter 3 of ExpandPredefinedFormat | parameter | 32 | +| Parameter 3 of FilterHelper | parameter | 32 | +| Parameter 3 of FromUtf16 | parameter | 32 | +| Parameter 3 of GetAdjustmentRuleForTime | parameter | 32 | +| Parameter 3 of GetBoundaries | parameter | 32 | +| Parameter 3 of GetCalendarInfo | parameter | 32 | +| Parameter 3 of GetClassLayout | parameter | 32 | +| Parameter 3 of GetCodeInfo | parameter | 32 | +| Parameter 3 of GetControlCharacters | parameter | 32 | +| Parameter 3 of GetCurrentTextElementLen | parameter | 32 | +| Parameter 3 of GetCustomAttributeProps | parameter | 32 | +| Parameter 3 of GetDataFromController | parameter | 32 | +| Parameter 3 of GetDatePart | parameter | 32 | +| Parameter 3 of GetDefaultValue | parameter | 32 | +| Parameter 3 of GetDisplayName | parameter | 32 | +| Parameter 3 of GetDocumentation | parameter | 32 | +| Parameter 3 of GetDocumentation2 | parameter | 32 | +| Parameter 3 of GetDynamicOrStaticVariables | parameter | 32 | +| Parameter 3 of GetEventProps | parameter | 32 | +| Parameter 3 of GetFieldOffset | parameter | 32 | +| Parameter 3 of GetFloatingPointMaxDigitsAndPrecision | parameter | 32 | +| Parameter 3 of GetFuncCustData | parameter | 32 | +| Parameter 3 of GetFuncIndexOfMemId | parameter | 32 | +| Parameter 3 of GetImplTypeCustData | parameter | 32 | +| Parameter 3 of GetJapaneseEraStartDate | parameter | 32 | +| Parameter 3 of GetKeyFromCharValue | parameter | 32 | +| Parameter 3 of GetLocaleInfoGroupingSizes | parameter | 32 | +| Parameter 3 of GetMarshalAs | parameter | 32 | +| Parameter 3 of GetMemoryInfo | parameter | 32 | +| Parameter 3 of GetMetadata | parameter | 32 | +| Parameter 3 of GetPInvokeMap | parameter | 32 | +| Parameter 3 of GetParamCustData | parameter | 32 | +| Parameter 3 of GetParamDefProps | parameter | 32 | +| Parameter 3 of GetParameters | parameter | 32 | +| Parameter 3 of GetPointerToFirstInvalidByte | parameter | 32 | +| Parameter 3 of GetPointerToFirstInvalidChar | parameter | 32 | +| Parameter 3 of GetPropertyOrFieldData | parameter | 32 | +| Parameter 3 of GetPropertyProps | parameter | 32 | +| Parameter 3 of GetRawArrayGeometry | parameter | 32 | +| Parameter 3 of GetResourceData | parameter | 32 | +| Parameter 3 of GetSeparatorToken | parameter | 32 | +| Parameter 3 of GetTimeOfLastChange | parameter | 32 | +| Parameter 3 of GetType | parameter | 32 | +| Parameter 3 of GetTypeByName | parameter | 32 | +| Parameter 3 of GetUtcOffsetFromUtc | parameter | 32 | +| Parameter 3 of GetVarCustData | parameter | 32 | +| Parameter 3 of GetVersion | parameter | 32 | +| Parameter 3 of InitHash | parameter | 32 | +| Parameter 3 of Initialize | parameter | 32 | +| Parameter 3 of InternalFallback | parameter | 32 | +| Parameter 3 of Invoke | parameter | 32 | +| Parameter 3 of Lex | parameter | 32 | +| Parameter 3 of MakeRoom | parameter | 32 | +| Parameter 3 of MakeSeparatorList | parameter | 32 | +| Parameter 3 of MapBufferToConsoleKey | parameter | 32 | +| Parameter 3 of MatchSpecifiedWords | parameter | 32 | +| Parameter 3 of Parse | parameter | 32 | +| Parameter 3 of ParseAttributeArguments | parameter | 32 | +| Parameter 3 of ParseAttributeUsageAttribute | parameter | 32 | +| Parameter 3 of ParseComponent | parameter | 32 | +| Parameter 3 of ParseDigits | parameter | 32 | +| Parameter 3 of ParseExactDigits | parameter | 32 | +| Parameter 3 of ParseISO8601 | parameter | 32 | +| Parameter 3 of ParseInt | parameter | 32 | +| Parameter 3 of Poll | parameter | 32 | +| Parameter 3 of PopulateLiteralFields | parameter | 32 | +| Parameter 3 of PopulateRtFields | parameter | 32 | +| Parameter 3 of ProcessHebrewTerminalState | parameter | 32 | +| Parameter 3 of ProcessTerminalState | parameter | 32 | +| Parameter 3 of ReadAsyncInternal | parameter | 32 | +| Parameter 3 of ReadDirR | parameter | 32 | +| Parameter 3 of Reduce | parameter | 32 | +| Parameter 3 of Remove | parameter | 32 | +| Parameter 3 of ResolveAssembly | parameter | 32 | +| Parameter 3 of ResolveToken | parameter | 32 | +| Parameter 3 of RunCallback | parameter | 32 | +| Parameter 3 of ScanRepeatChar | parameter | 32 | +| Parameter 3 of SnapForObservation | parameter | 32 | +| Parameter 3 of StringToInt | parameter | 32 | +| Parameter 3 of StringToLong | parameter | 32 | +| Parameter 3 of TZif_ParseMDateRule | parameter | 32 | +| Parameter 3 of TZif_ParsePosixDateTime | parameter | 32 | +| Parameter 3 of TZif_ParsePosixFormat | parameter | 32 | +| Parameter 3 of TZif_ParseRaw | parameter | 32 | +| Parameter 3 of TimeToLunar | parameter | 32 | +| Parameter 3 of ToUtf16 | parameter | 32 | +| Parameter 3 of Tokenize | parameter | 32 | +| Parameter 3 of TryDecodeFromUtf16 | parameter | 32 | +| Parameter 3 of TryDequeueSlow | parameter | 32 | +| Parameter 3 of TryDigitGenCounted | parameter | 32 | +| Parameter 3 of TryDrainLeftoverDataForGetBytes | parameter | 32 | +| Parameter 3 of TryFormat | parameter | 32 | +| Parameter 3 of TryFormatDateTimeG | parameter | 32 | +| Parameter 3 of TryFormatDateTimeO | parameter | 32 | +| Parameter 3 of TryFormatInt64 | parameter | 32 | +| Parameter 3 of TryFormatInt64D | parameter | 32 | +| Parameter 3 of TryFormatInt64N | parameter | 32 | +| Parameter 3 of TryFormatO | parameter | 32 | +| Parameter 3 of TryFormatR | parameter | 32 | +| Parameter 3 of TryGetEntry | parameter | 32 | +| Parameter 3 of TryGetMemoryManager | parameter | 32 | +| Parameter 3 of TryGetSpecialConsoleKey | parameter | 32 | +| Parameter 3 of TryGetString | parameter | 32 | +| Parameter 3 of TryGetTimeZone | parameter | 32 | +| Parameter 3 of TryGetTimeZoneFromLocalMachine | parameter | 32 | +| Parameter 3 of TryInternalFallbackGetBytes | parameter | 32 | +| Parameter 3 of TryJoin | parameter | 32 | +| Parameter 3 of TryLoad | parameter | 32 | +| Parameter 3 of TryParse | parameter | 32 | +| Parameter 3 of TryParseByFormat | parameter | 32 | +| Parameter 3 of TryParseComponent | parameter | 32 | +| Parameter 3 of TryParseDateTimeG | parameter | 32 | +| Parameter 3 of TryParseDateTimeOffsetO | parameter | 32 | +| Parameter 3 of TryParseDateTimeOffsetR | parameter | 32 | +| Parameter 3 of TryParseDecimal | parameter | 32 | +| Parameter 3 of TryParseDouble | parameter | 32 | +| Parameter 3 of TryParseExact | parameter | 32 | +| Parameter 3 of TryParseInt32 | parameter | 32 | +| Parameter 3 of TryParseInt32IntegerStyle | parameter | 32 | +| Parameter 3 of TryParseInt32Number | parameter | 32 | +| Parameter 3 of TryParseInt64 | parameter | 32 | +| Parameter 3 of TryParseInt64IntegerStyle | parameter | 32 | +| Parameter 3 of TryParseInt64Number | parameter | 32 | +| Parameter 3 of TryParseNumber | parameter | 32 | +| Parameter 3 of TryParseQuoteString | parameter | 32 | +| Parameter 3 of TryParseSingle | parameter | 32 | +| Parameter 3 of TryParseTimeSpan | parameter | 32 | +| Parameter 3 of TryParseUInt32 | parameter | 32 | +| Parameter 3 of TryParseUInt32IntegerStyle | parameter | 32 | +| Parameter 3 of TryParseUInt32Number | parameter | 32 | +| Parameter 3 of TryParseUInt64 | parameter | 32 | +| Parameter 3 of TryParseUInt64IntegerStyle | parameter | 32 | +| Parameter 3 of TryParseUInt64Number | parameter | 32 | +| Parameter 3 of TryRunCounted | parameter | 32 | +| Parameter 3 of TrySplitTimeSpan | parameter | 32 | +| Parameter 3 of TryUInt32ToDecStr | parameter | 32 | +| Parameter 3 of TryUInt64ToDecStr | parameter | 32 | +| Parameter 3 of UpdateDescriptor | parameter | 32 | +| Parameter 3 of ValidateTimeZoneInfo | parameter | 32 | +| Parameter 3 of Write | parameter | 32 | +| Parameter 3 of WriteFile | parameter | 32 | +| Parameter 3 of _Enum | parameter | 32 | +| Parameter 3 of _GetClassLayout | parameter | 32 | +| Parameter 3 of _GetCustomAttributeProps | parameter | 32 | +| Parameter 3 of _GetDefaultValue | parameter | 32 | +| Parameter 3 of _GetEventProps | parameter | 32 | +| Parameter 3 of _GetFieldOffset | parameter | 32 | +| Parameter 3 of _GetMarshalAs | parameter | 32 | +| Parameter 3 of _GetParamDefProps | parameter | 32 | +| Parameter 3 of _GetPropertyOrFieldData | parameter | 32 | +| Parameter 3 of _GetPropertyProps | parameter | 32 | +| Parameter 3 of _GetUserString | parameter | 32 | +| Parameter 3 of _ParseAttributeUsageAttribute | parameter | 32 | +| Parameter 3 of nLoad | parameter | 32 | +| Parameter 4 of .ctor | parameter | 32 | +| Parameter 4 of <TryGetCursorPosition>g__AppendToStdInReaderUntil\|86_1 | parameter | 32 | +| Parameter 4 of <TryGetCursorPosition>g__BufferUntil\|86_0 | parameter | 32 | +| Parameter 4 of <TryGetCursorPosition>g__ReadRowOrCol\|86_2 | parameter | 32 | +| Parameter 4 of AssignAssociates | parameter | 32 | +| Parameter 4 of BeginInvoke | parameter | 32 | +| Parameter 4 of Bind | parameter | 32 | +| Parameter 4 of BindToObject | parameter | 32 | +| Parameter 4 of BindToStorage | parameter | 32 | +| Parameter 4 of BindType | parameter | 32 | +| Parameter 4 of CallStringMethod | parameter | 32 | +| Parameter 4 of Convert | parameter | 32 | +| Parameter 4 of ConvertHijriToGregorian | parameter | 32 | +| Parameter 4 of CreateEventCore | parameter | 32 | +| Parameter 4 of CreateInstance | parameter | 32 | +| Parameter 4 of CreateSemaphoreCore | parameter | 32 | +| Parameter 4 of Deconstruct | parameter | 32 | +| Parameter 4 of DoStrictParse | parameter | 32 | +| Parameter 4 of EndInvoke | parameter | 32 | +| Parameter 4 of EnumMonthNames | parameter | 32 | +| Parameter 4 of EscapeString | parameter | 32 | +| Parameter 4 of EvaluateInternal | parameter | 32 | +| Parameter 4 of EventRegister | parameter | 32 | +| Parameter 4 of FilterHelper | parameter | 32 | +| Parameter 4 of GetByteCountFast | parameter | 32 | +| Parameter 4 of GetCharCountFast | parameter | 32 | +| Parameter 4 of GetCurrentTextElementLen | parameter | 32 | +| Parameter 4 of GetDataFromController | parameter | 32 | +| Parameter 4 of GetDefaultValue | parameter | 32 | +| Parameter 4 of GetDocumentation | parameter | 32 | +| Parameter 4 of GetDocumentation2 | parameter | 32 | +| Parameter 4 of GetMarshalAs | parameter | 32 | +| Parameter 4 of GetMemoryInfo | parameter | 32 | +| Parameter 4 of GetMetadata | parameter | 32 | +| Parameter 4 of GetNames | parameter | 32 | +| Parameter 4 of GetPInvokeMap | parameter | 32 | +| Parameter 4 of GetParamCustData | parameter | 32 | +| Parameter 4 of GetPropertyOrFieldData | parameter | 32 | +| Parameter 4 of GetPropertyProps | parameter | 32 | +| Parameter 4 of GetRawArrayGeometry | parameter | 32 | +| Parameter 4 of GetValue | parameter | 32 | +| Parameter 4 of GetVersion | parameter | 32 | +| Parameter 4 of GregorianToLunar | parameter | 32 | +| Parameter 4 of InitHash | parameter | 32 | +| Parameter 4 of Invoke | parameter | 32 | +| Parameter 4 of Lex | parameter | 32 | +| Parameter 4 of LunarToGregorian | parameter | 32 | +| Parameter 4 of MakeRoom | parameter | 32 | +| Parameter 4 of MapBufferToConsoleKey | parameter | 32 | +| Parameter 4 of OnStart | parameter | 32 | +| Parameter 4 of OnStop | parameter | 32 | +| Parameter 4 of ParseByFormat | parameter | 32 | +| Parameter 4 of ParseDisplayName | parameter | 32 | +| Parameter 4 of ParseExact | parameter | 32 | +| Parameter 4 of ParseExactDigits | parameter | 32 | +| Parameter 4 of ParseExactMultiple | parameter | 32 | +| Parameter 4 of PopulateEvents | parameter | 32 | +| Parameter 4 of ProcessHebrewTerminalState | parameter | 32 | +| Parameter 4 of ProcessTerminalState | parameter | 32 | +| Parameter 4 of Reduce | parameter | 32 | +| Parameter 4 of Remove | parameter | 32 | +| Parameter 4 of ResolveToken | parameter | 32 | +| Parameter 4 of SnapForObservation | parameter | 32 | +| Parameter 4 of TZif_ParsePosixFormat | parameter | 32 | +| Parameter 4 of TZif_ParseRaw | parameter | 32 | +| Parameter 4 of TimeToLunar | parameter | 32 | +| Parameter 4 of Tokenize | parameter | 32 | +| Parameter 4 of TranscodeToUtf8 | parameter | 32 | +| Parameter 4 of TranscodeToUtf16 | parameter | 32 | +| Parameter 4 of TryCreateDateTimeOffset | parameter | 32 | +| Parameter 4 of TryDigitGenCounted | parameter | 32 | +| Parameter 4 of TryDigitGenShortest | parameter | 32 | +| Parameter 4 of TryDrainLeftoverDataForGetBytes | parameter | 32 | +| Parameter 4 of TryFormatDecimal | parameter | 32 | +| Parameter 4 of TryFormatDouble | parameter | 32 | +| Parameter 4 of TryFormatInt32 | parameter | 32 | +| Parameter 4 of TryFormatInt64 | parameter | 32 | +| Parameter 4 of TryFormatSingle | parameter | 32 | +| Parameter 4 of TryFormatStandard | parameter | 32 | +| Parameter 4 of TryFormatUInt32 | parameter | 32 | +| Parameter 4 of TryFormatUInt64 | parameter | 32 | +| Parameter 4 of TryFormatUInt64D | parameter | 32 | +| Parameter 4 of TryFormatUInt64N | parameter | 32 | +| Parameter 4 of TryFormatUInt64X | parameter | 32 | +| Parameter 4 of TryGetSpecialConsoleKey | parameter | 32 | +| Parameter 4 of TryInt32ToHexStr | parameter | 32 | +| Parameter 4 of TryInt64ToHexStr | parameter | 32 | +| Parameter 4 of TryInternalFallbackGetBytes | parameter | 32 | +| Parameter 4 of TryInternalFallbackGetChars | parameter | 32 | +| Parameter 4 of TryJoin | parameter | 32 | +| Parameter 4 of TryNegativeInt32ToDecStr | parameter | 32 | +| Parameter 4 of TryNegativeInt64ToDecStr | parameter | 32 | +| Parameter 4 of TryParse | parameter | 32 | +| Parameter 4 of TryParseAsSpecialFloatingPoint | parameter | 32 | +| Parameter 4 of TryParseExact | parameter | 32 | +| Parameter 4 of TryParseExactMultiple | parameter | 32 | +| Parameter 4 of TryParseExactMultipleTimeSpan | parameter | 32 | +| Parameter 4 of TryParseExactTimeSpan | parameter | 32 | +| Parameter 4 of TryParseGuidCore | parameter | 32 | +| Parameter 4 of TryParseNumber | parameter | 32 | +| Parameter 4 of TryRunCounted | parameter | 32 | +| Parameter 4 of TryRunShortest | parameter | 32 | +| Parameter 4 of TrySZBinarySearch | parameter | 32 | +| Parameter 4 of TrySZIndexOf | parameter | 32 | +| Parameter 4 of TrySZLastIndexOf | parameter | 32 | +| Parameter 4 of UpdateDescriptor | parameter | 32 | +| Parameter 4 of Write | parameter | 32 | +| Parameter 4 of _GetDefaultValue | parameter | 32 | +| Parameter 4 of _GetMarshalAs | parameter | 32 | +| Parameter 4 of _GetPropertyOrFieldData | parameter | 32 | +| Parameter 4 of _GetPropertyProps | parameter | 32 | +| Parameter 4 of _ParseAttributeUsageAttribute | parameter | 32 | +| Parameter 5 of AssignAssociates | parameter | 32 | +| Parameter 5 of BeginInvoke | parameter | 32 | +| Parameter 5 of Bind | parameter | 32 | +| Parameter 5 of ConstructType | parameter | 32 | +| Parameter 5 of Convert | parameter | 32 | +| Parameter 5 of ConvertHijriToGregorian | parameter | 32 | +| Parameter 5 of CreateCaObject | parameter | 32 | +| Parameter 5 of CreateInstance | parameter | 32 | +| Parameter 5 of Deconstruct | parameter | 32 | +| Parameter 5 of EnsureDestinationSize | parameter | 32 | +| Parameter 5 of EvaluateInternal | parameter | 32 | +| Parameter 5 of FilterHelper | parameter | 32 | +| Parameter 5 of FindName | parameter | 32 | +| Parameter 5 of GetBytesFast | parameter | 32 | +| Parameter 5 of GetCharsFast | parameter | 32 | +| Parameter 5 of GetDataFromController | parameter | 32 | +| Parameter 5 of GetDocumentation | parameter | 32 | +| Parameter 5 of GetIsDaylightSavingsFromUtc | parameter | 32 | +| Parameter 5 of GetMarshalAs | parameter | 32 | +| Parameter 5 of GetMemoryInfo | parameter | 32 | +| Parameter 5 of GetPropertyOrFieldData | parameter | 32 | +| Parameter 5 of GetType | parameter | 32 | +| Parameter 5 of GregorianToLunar | parameter | 32 | +| Parameter 5 of Invoke | parameter | 32 | +| Parameter 5 of Lex | parameter | 32 | +| Parameter 5 of LunarToGregorian | parameter | 32 | +| Parameter 5 of MapBufferToConsoleKey | parameter | 32 | +| Parameter 5 of OnStart | parameter | 32 | +| Parameter 5 of ParseDisplayName | parameter | 32 | +| Parameter 5 of PopulateProperties | parameter | 32 | +| Parameter 5 of PopulateRtFields | parameter | 32 | +| Parameter 5 of ResolveType | parameter | 32 | +| Parameter 5 of TZif_ParsePosixFormat | parameter | 32 | +| Parameter 5 of TZif_ParseRaw | parameter | 32 | +| Parameter 5 of TranscodeToUtf8 | parameter | 32 | +| Parameter 5 of TranscodeToUtf16 | parameter | 32 | +| Parameter 5 of TryDigitGenShortest | parameter | 32 | +| Parameter 5 of TryParseAsSpecialFloatingPoint | parameter | 32 | +| Parameter 5 of TryParseByName | parameter | 32 | +| Parameter 5 of TryParseExact | parameter | 32 | +| Parameter 5 of TryParseExactMultiple | parameter | 32 | +| Parameter 5 of TryParseGuidCore | parameter | 32 | +| Parameter 5 of TryParseInt64Enum | parameter | 32 | +| Parameter 5 of TryParseRareEnum | parameter | 32 | +| Parameter 5 of TryParseUInt64Enum | parameter | 32 | +| Parameter 5 of TryRoundWeedCounted | parameter | 32 | +| Parameter 5 of TryRunShortest | parameter | 32 | +| Parameter 5 of Write | parameter | 32 | +| Parameter 5 of _GetMarshalAs | parameter | 32 | +| Parameter 5 of _GetPropertyOrFieldData | parameter | 32 | +| Parameter 6 of AssignAssociates | parameter | 32 | +| Parameter 6 of BeginInvoke | parameter | 32 | +| Parameter 6 of Bind | parameter | 32 | +| Parameter 6 of Convert | parameter | 32 | +| Parameter 6 of Deconstruct | parameter | 32 | +| Parameter 6 of FilterCustomAttributeRecord | parameter | 32 | +| Parameter 6 of GetMarshalAs | parameter | 32 | +| Parameter 6 of GetPropertyOrFieldData | parameter | 32 | +| Parameter 6 of GregorianToLunar | parameter | 32 | +| Parameter 6 of Invoke | parameter | 32 | +| Parameter 6 of LunarToGregorian | parameter | 32 | +| Parameter 6 of SetValue | parameter | 32 | +| Parameter 6 of TZif_ParsePosixFormat | parameter | 32 | +| Parameter 6 of TZif_ParseRaw | parameter | 32 | +| Parameter 6 of TryCreateTimeSpan | parameter | 32 | +| Parameter 6 of TryTimeToTicks | parameter | 32 | +| Parameter 6 of _GetMarshalAs | parameter | 32 | +| Parameter 6 of _GetPropertyOrFieldData | parameter | 32 | +| Parameter 7 of AssignAssociates | parameter | 32 | +| Parameter 7 of BindToMethod | parameter | 32 | +| Parameter 7 of Convert | parameter | 32 | +| Parameter 7 of Deconstruct | parameter | 32 | +| Parameter 7 of Dragon4 | parameter | 32 | +| Parameter 7 of FilterCustomAttributeRecord | parameter | 32 | +| Parameter 7 of GetMarshalAs | parameter | 32 | +| Parameter 7 of Invoke | parameter | 32 | +| Parameter 7 of TZif_ParsePosixFormat | parameter | 32 | +| Parameter 7 of TZif_ParseRaw | parameter | 32 | +| Parameter 7 of TryCreate | parameter | 32 | +| Parameter 7 of TryCreateDateTimeOffsetInterpretingDataAsLocalTime | parameter | 32 | +| Parameter 7 of TryParseUInt32Enum | parameter | 32 | +| Parameter 7 of _GetMarshalAs | parameter | 32 | +| Parameter 8 of AssignAssociates | parameter | 32 | +| Parameter 8 of Convert | parameter | 32 | +| Parameter 8 of CreateInstanceInternal | parameter | 32 | +| Parameter 8 of Deconstruct | parameter | 32 | +| Parameter 8 of FilterCustomAttributeRecord | parameter | 32 | +| Parameter 8 of GetMarshalAs | parameter | 32 | +| Parameter 8 of TZif_ParsePosixFormat | parameter | 32 | +| Parameter 8 of TZif_ParseRaw | parameter | 32 | +| Parameter 8 of TryCreateDateTime | parameter | 32 | +| Parameter 8 of TryParseInt32Enum | parameter | 32 | +| Parameter 8 of _GetMarshalAs | parameter | 32 | +| Parameter 9 of AssignAssociates | parameter | 32 | +| Parameter 9 of BeginInvoke | parameter | 32 | +| Parameter 9 of Convert | parameter | 32 | +| Parameter 9 of Deconstruct | parameter | 32 | +| Parameter 9 of FilterCustomAttributeRecord | parameter | 32 | +| Parameter 9 of GetMarshalAs | parameter | 32 | +| Parameter 9 of Invoke | parameter | 32 | +| Parameter 9 of TryToDateTime | parameter | 32 | +| Parameter 9 of _GetMarshalAs | parameter | 32 | +| Parameter 10 of AssignAssociates | parameter | 32 | +| Parameter 10 of BeginInvoke | parameter | 32 | +| Parameter 10 of Convert | parameter | 32 | +| Parameter 10 of Deconstruct | parameter | 32 | +| Parameter 10 of FilterCustomAttributeRecord | parameter | 32 | +| Parameter 10 of Invoke | parameter | 32 | +| Parameter 10 of TryCreateDateTimeOffset | parameter | 32 | +| Parameter 10 of _GetMarshalAs | parameter | 32 | +| Parameter 11 of AssignAssociates | parameter | 32 | +| Parameter 11 of BeginInvoke | parameter | 32 | +| Parameter 11 of Deconstruct | parameter | 32 | +| Parameter 11 of Invoke | parameter | 32 | +| Parameter 12 of Deconstruct | parameter | 32 | +| Parameter 13 of Deconstruct | parameter | 32 | +| Parameter 14 of Deconstruct | parameter | 32 | +| Parameter 15 of Deconstruct | parameter | 32 | +| Parameter 16 of Deconstruct | parameter | 32 | +| Parameter 17 of Deconstruct | parameter | 32 | +| Parameter 18 of Deconstruct | parameter | 32 | +| Parameter 19 of Deconstruct | parameter | 32 | +| Parameter 20 of Deconstruct | parameter | 32 | +| Parameter 21 of Deconstruct | parameter | 32 | +| get_Current | method | 32 | +| get_EventHandle | method | 32 | +| get_Item | method | 32 | +| get_OffsetHigh | method | 32 | +| get_OffsetLow | method | 32 | +| get_Value | method | 32 | +| property Current | property | 32 | +| property EventHandle | property | 32 | +| property Item | property | 32 | +| property OffsetHigh | property | 32 | +| property OffsetLow | property | 32 | +| property Value | property | 32 | diff --git a/csharp/ql/test/library-tests/cil/typeAnnotations/typeAnnotations.ql b/csharp/ql/test/library-tests/cil/typeAnnotations/typeAnnotations.ql new file mode 100644 index 00000000000..6544f049f7c --- /dev/null +++ b/csharp/ql/test/library-tests/cil/typeAnnotations/typeAnnotations.ql @@ -0,0 +1,25 @@ +import cil +import semmle.code.cil.Type + +private string elementType(Element e) { + e instanceof Method and result = "method" + or + e instanceof Property and result = "property" + or + e instanceof Parameter and result = "parameter" + or + e instanceof LocalVariable and result = "local" + or + e instanceof FunctionPointerType and result = "fnptr" + or + not e instanceof Method and + not e instanceof Property and + not e instanceof Parameter and + not e instanceof LocalVariable and + not e instanceof FunctionPointerType and + result = "other" +} + +from Element e, int i +where cil_type_annotation(e, i) +select e.toString(), elementType(e), i diff --git a/csharp/ql/test/library-tests/comments/BindingAfter.expected b/csharp/ql/test/library-tests/comments/BindingAfter.expected index 44c01d79239..59b784aa196 100644 --- a/csharp/ql/test/library-tests/comments/BindingAfter.expected +++ b/csharp/ql/test/library-tests/comments/BindingAfter.expected @@ -55,3 +55,6 @@ | comments2.cs:118:5:118:21 | // ... | comments2.cs:119:11:119:25 | GenericClass<> | GenericClass<> | | comments2.cs:124:5:124:16 | // ... | comments2.cs:125:9:125:20 | GenericFn | GenericFn | | comments2.cs:127:20:127:23 | // ... | comments2.cs:128:9:128:17 | return ...; | x | +| trivia.cs:1:1:3:15 | // ... | trivia.cs:14:7:14:9 | Tr1 | | +| trivia.cs:13:89:13:103 | // ... | trivia.cs:14:7:14:9 | Tr1 | New checksum | +| trivia.cs:25:14:25:38 | // ... | trivia.cs:26:9:26:17 | ... ...; | numbering not affected | diff --git a/csharp/ql/test/library-tests/comments/BindingBefore.expected b/csharp/ql/test/library-tests/comments/BindingBefore.expected index 4d41ea94864..9cb36b9e7cc 100644 --- a/csharp/ql/test/library-tests/comments/BindingBefore.expected +++ b/csharp/ql/test/library-tests/comments/BindingBefore.expected @@ -48,3 +48,4 @@ | comments2.cs:124:5:124:16 | // ... | comments2.cs:119:11:119:25 | GenericClass<> | GenericFn | | comments2.cs:127:20:127:23 | // ... | comments2.cs:127:9:127:18 | ... ...; | x | | comments2.cs:132:1:132:21 | // ... | comments2.cs:11:7:11:8 | C2 | End of comment2.cs | +| trivia.cs:25:14:25:38 | // ... | trivia.cs:24:9:24:16 | ... ...; | numbering not affected | diff --git a/csharp/ql/test/library-tests/comments/BindingParent.expected b/csharp/ql/test/library-tests/comments/BindingParent.expected index de8fed3666b..d9c8f24d48d 100644 --- a/csharp/ql/test/library-tests/comments/BindingParent.expected +++ b/csharp/ql/test/library-tests/comments/BindingParent.expected @@ -47,3 +47,13 @@ | comments2.cs:121:17:121:20 | // ... | comments2.cs:119:11:119:25 | GenericClass<> | f | | comments2.cs:124:5:124:16 | // ... | comments2.cs:11:7:11:8 | C2 | GenericFn | | comments2.cs:127:20:127:23 | // ... | comments2.cs:126:5:129:5 | {...} | x | +| trivia.cs:25:14:25:38 | // ... | trivia.cs:17:5:29:5 | {...} | numbering not affected | +| trivia.cs:49:18:49:82 | // ... | trivia.cs:48:5:58:5 | {...} | Sets the nullable annotation and warning contexts to disabled. | +| trivia.cs:50:17:50:80 | // ... | trivia.cs:48:5:58:5 | {...} | Sets the nullable annotation and warning contexts to enabled. | +| trivia.cs:51:18:51:94 | // ... | trivia.cs:48:5:58:5 | {...} | Restores the nullable annotation and warning contexts to project settings. | +| trivia.cs:52:30:52:81 | // ... | trivia.cs:48:5:58:5 | {...} | Sets the nullable annotation context to disabled. | +| trivia.cs:53:29:53:79 | // ... | trivia.cs:48:5:58:5 | {...} | Sets the nullable annotation context to enabled. | +| trivia.cs:54:30:54:93 | // ... | trivia.cs:48:5:58:5 | {...} | Restores the nullable annotation context to project settings. | +| trivia.cs:55:27:55:75 | // ... | trivia.cs:48:5:58:5 | {...} | Sets the nullable warning context to disabled. | +| trivia.cs:56:26:56:73 | // ... | trivia.cs:48:5:58:5 | {...} | Sets the nullable warning context to enabled. | +| trivia.cs:57:27:57:87 | // ... | trivia.cs:48:5:58:5 | {...} | Restores the nullable warning context to project settings. | diff --git a/csharp/ql/test/library-tests/comments/Bindings.expected b/csharp/ql/test/library-tests/comments/Bindings.expected index b241ed56b55..6822c9411a6 100644 --- a/csharp/ql/test/library-tests/comments/Bindings.expected +++ b/csharp/ql/test/library-tests/comments/Bindings.expected @@ -49,3 +49,14 @@ | comments2.cs:121:17:121:20 | // ... | comments2.cs:121:13:121:13 | f | f | | comments2.cs:124:5:124:16 | // ... | comments2.cs:125:9:125:20 | GenericFn | GenericFn | | comments2.cs:127:20:127:23 | // ... | comments2.cs:127:9:127:18 | ... ...; | x | +| trivia.cs:13:89:13:103 | // ... | trivia.cs:14:7:14:9 | Tr1 | New checksum | +| trivia.cs:25:14:25:38 | // ... | trivia.cs:17:5:29:5 | {...} | numbering not affected | +| trivia.cs:49:18:49:82 | // ... | trivia.cs:48:5:58:5 | {...} | Sets the nullable annotation and warning contexts to disabled. | +| trivia.cs:50:17:50:80 | // ... | trivia.cs:48:5:58:5 | {...} | Sets the nullable annotation and warning contexts to enabled. | +| trivia.cs:51:18:51:94 | // ... | trivia.cs:48:5:58:5 | {...} | Restores the nullable annotation and warning contexts to project settings. | +| trivia.cs:52:30:52:81 | // ... | trivia.cs:48:5:58:5 | {...} | Sets the nullable annotation context to disabled. | +| trivia.cs:53:29:53:79 | // ... | trivia.cs:48:5:58:5 | {...} | Sets the nullable annotation context to enabled. | +| trivia.cs:54:30:54:93 | // ... | trivia.cs:48:5:58:5 | {...} | Restores the nullable annotation context to project settings. | +| trivia.cs:55:27:55:75 | // ... | trivia.cs:48:5:58:5 | {...} | Sets the nullable warning context to disabled. | +| trivia.cs:56:26:56:73 | // ... | trivia.cs:48:5:58:5 | {...} | Sets the nullable warning context to enabled. | +| trivia.cs:57:27:57:87 | // ... | trivia.cs:48:5:58:5 | {...} | Restores the nullable warning context to project settings. | diff --git a/csharp/ql/test/library-tests/comments/Comments.expected b/csharp/ql/test/library-tests/comments/Comments.expected index 28cf81d9754..a0ff83a59be 100644 --- a/csharp/ql/test/library-tests/comments/Comments.expected +++ b/csharp/ql/test/library-tests/comments/Comments.expected @@ -1,83 +1,100 @@ -| comments1.cs:1:1:2:46 | // ... | 2 | comments1.cs:1:1:1:23 | // ... | Start of comment1.cs | // Start of comment1.cs | SinglelineComment | -| comments1.cs:1:1:2:46 | // ... | 2 | comments1.cs:2:1:2:46 | // ... | This tests the basic types of comment block | // This tests the basic types of comment block | SinglelineComment | -| comments1.cs:4:1:4:25 | // ... | 1 | comments1.cs:4:1:4:25 | // ... | 1) Basic comment types | // 1) Basic comment types | SinglelineComment | -| comments1.cs:6:1:6:24 | // ... | 1 | comments1.cs:6:1:6:24 | // ... | A single-line comment | // A single-line comment | SinglelineComment | -| comments1.cs:8:1:8:18 | /// ... | 1 | comments1.cs:8:1:8:18 | /// ... | An XML comment | /// An XML comment | XmlComment | -| comments1.cs:11:1:11:25 | /* ... */ | 1 | comments1.cs:11:1:11:25 | /* ... */ | A multiline comment | /* A multiline comment */ | MultilineComment | -| comments1.cs:14:1:14:20 | // ... | 1 | comments1.cs:14:1:14:20 | // ... | 2) Comment blocks | // 2) Comment blocks | SinglelineComment | -| comments1.cs:16:1:16:38 | // ... | 1 | comments1.cs:16:1:16:38 | // ... | A line on its own is a commentblock | // A line on its own is a commentblock | SinglelineComment | -| comments1.cs:18:1:19:31 | // ... | 2 | comments1.cs:18:1:18:21 | // ... | Two lines together | // Two lines together | SinglelineComment | -| comments1.cs:18:1:19:31 | // ... | 2 | comments1.cs:19:1:19:31 | // ... | are in the same commentblock | // are in the same commentblock | SinglelineComment | -| comments1.cs:21:1:23:15 | // ... | 3 | comments1.cs:21:1:21:14 | // ... | Three lines | // Three lines | SinglelineComment | -| comments1.cs:21:1:23:15 | // ... | 3 | comments1.cs:22:1:22:14 | // ... | in the same | // in the same | SinglelineComment | -| comments1.cs:21:1:23:15 | // ... | 3 | comments1.cs:23:1:23:15 | // ... | commentblock | // commentblock | SinglelineComment | -| comments1.cs:25:1:25:43 | /* ... */ | 2 | comments1.cs:25:1:25:15 | /* ... */ | This is a | /* This is a */ | MultilineComment | -| comments1.cs:25:1:25:43 | /* ... */ | 2 | comments1.cs:25:18:25:43 | /* ... */ | single comment block | /* single comment block */ | MultilineComment | -| comments1.cs:27:1:29:13 | /* ... */ | 3 | comments1.cs:27:1:27:12 | /* ... */ | This is a | /* This is a | MultilineComment | -| comments1.cs:27:1:29:13 | /* ... */ | 3 | comments1.cs:28:1:28:17 | /* ... */ | true multiline | true multiline | MultilineComment | -| comments1.cs:27:1:29:13 | /* ... */ | 3 | comments1.cs:29:1:29:13 | /* ... */ | comment | comment */ | MultilineComment | -| comments1.cs:31:1:33:30 | // ... | 3 | comments1.cs:31:1:31:21 | // ... | These three lines, | // These three lines, | SinglelineComment | -| comments1.cs:31:1:33:30 | // ... | 3 | comments1.cs:32:1:32:61 | /* ... */ | even though they are using different commenting styles, | /* even though they are using different commenting styles, */ | MultilineComment | -| comments1.cs:31:1:33:30 | // ... | 3 | comments1.cs:33:1:33:30 | /// ... | form a single commentblock | /// form a single commentblock | XmlComment | -| comments1.cs:37:5:39:41 | /* ... */ | 3 | comments1.cs:37:5:37:6 | /* ... */ | | /* | MultilineComment | -| comments1.cs:37:5:39:41 | /* ... */ | 3 | comments1.cs:38:1:38:6 | /* ... */ | | */ | MultilineComment | -| comments1.cs:37:5:39:41 | /* ... */ | 3 | comments1.cs:39:5:39:41 | // ... | This is not the same comment block | // This is not the same comment block | SinglelineComment | -| comments1.cs:40:13:41:51 | // ... | 2 | comments1.cs:40:13:40:27 | // ... | as this line | // as this line | SinglelineComment | -| comments1.cs:40:13:41:51 | // ... | 2 | comments1.cs:41:13:41:51 | // ... | because they are offset differently. | // because they are offset differently. | SinglelineComment | -| comments1.cs:43:15:43:36 | // ... | 1 | comments1.cs:43:15:43:36 | // ... | These are different | // These are different | SinglelineComment | -| comments1.cs:44:15:44:32 | // ... | 1 | comments1.cs:44:15:44:32 | // ... | comment blocks. | // comment blocks. | SinglelineComment | -| comments1.cs:47:1:47:21 | // ... | 1 | comments1.cs:47:1:47:21 | // ... | End of comment1.cs | // End of comment1.cs | SinglelineComment | -| comments2.cs:1:1:2:15 | // ... | 2 | comments2.cs:1:1:1:23 | // ... | Start of comment2.cs | // Start of comment2.cs | SinglelineComment | -| comments2.cs:1:1:2:15 | // ... | 2 | comments2.cs:2:1:2:15 | // ... | Unassociated | // Unassociated | SinglelineComment | -| comments2.cs:5:27:5:41 | // ... | 1 | comments2.cs:5:27:5:41 | // ... | Unassociated | // Unassociated | SinglelineComment | -| comments2.cs:8:1:8:15 | // ... | 1 | comments2.cs:8:1:8:15 | // ... | Unassociated | // Unassociated | SinglelineComment | -| comments2.cs:10:1:10:6 | /// ... | 1 | comments2.cs:10:1:10:6 | /// ... | C2 | /// C2 | XmlComment | -| comments2.cs:13:17:13:25 | // ... | 1 | comments2.cs:13:17:13:25 | // ... | field1 | // field1 | SinglelineComment | -| comments2.cs:14:17:14:25 | // ... | 1 | comments2.cs:14:17:14:25 | // ... | field2 | // field2 | SinglelineComment | -| comments2.cs:16:5:16:9 | // ... | 1 | comments2.cs:16:5:16:9 | // ... | C2 | // C2 | SinglelineComment | -| comments2.cs:18:5:18:8 | // ... | 1 | comments2.cs:18:5:18:8 | // ... | f | // f | SinglelineComment | -| comments2.cs:21:9:21:16 | // ... | 1 | comments2.cs:21:9:21:16 | // ... | {...} | // {...} | SinglelineComment | -| comments2.cs:23:15:23:21 | // ... | 1 | comments2.cs:23:15:23:21 | // ... | ...; | // ...; | SinglelineComment | -| comments2.cs:25:9:25:15 | // ... | 1 | comments2.cs:25:9:25:15 | // ... | ...; | // ...; | SinglelineComment | -| comments2.cs:31:9:31:15 | // ... | 1 | comments2.cs:31:9:31:15 | // ... | ...; | // ...; | SinglelineComment | -| comments2.cs:33:9:33:16 | // ... | 1 | comments2.cs:33:9:33:16 | // ... | {...} | // {...} | SinglelineComment | -| comments2.cs:36:9:36:16 | // ... | 1 | comments2.cs:36:9:36:16 | // ... | {...} | // {...} | SinglelineComment | -| comments2.cs:39:5:39:9 | // ... | 1 | comments2.cs:39:5:39:9 | // ... | C3 | // C3 | SinglelineComment | -| comments2.cs:42:9:42:13 | // ... | 1 | comments2.cs:42:9:42:13 | // ... | C3 | // C3 | SinglelineComment | -| comments2.cs:45:5:45:9 | // ... | 1 | comments2.cs:45:5:45:9 | // ... | C2 | // C2 | SinglelineComment | -| comments2.cs:47:5:47:9 | // ... | 1 | comments2.cs:47:5:47:9 | // ... | S1 | // S1 | SinglelineComment | -| comments2.cs:50:9:50:13 | // ... | 1 | comments2.cs:50:9:50:13 | // ... | S1 | // S1 | SinglelineComment | -| comments2.cs:52:28:52:35 | // ... | 1 | comments2.cs:52:28:52:35 | // ... | {...} | // {...} | SinglelineComment | -| comments2.cs:53:13:53:17 | // ... | 1 | comments2.cs:53:13:53:17 | // ... | S1 | // S1 | SinglelineComment | -| comments2.cs:55:13:55:20 | // ... | 1 | comments2.cs:55:13:55:20 | // ... | {...} | // {...} | SinglelineComment | -| comments2.cs:56:11:56:18 | // ... | 1 | comments2.cs:56:11:56:18 | // ... | {...} | // {...} | SinglelineComment | -| comments2.cs:58:5:58:9 | // ... | 1 | comments2.cs:58:5:58:9 | // ... | S1 | // S1 | SinglelineComment | -| comments2.cs:60:5:60:13 | // ... | 1 | comments2.cs:60:5:60:13 | // ... | Values | // Values | SinglelineComment | -| comments2.cs:63:9:63:17 | // ... | 1 | comments2.cs:63:9:63:17 | // ... | Values | // Values | SinglelineComment | -| comments2.cs:65:9:65:16 | // ... | 1 | comments2.cs:65:9:65:16 | // ... | First | // First | SinglelineComment | -| comments2.cs:66:17:66:24 | // ... | 1 | comments2.cs:66:17:66:24 | // ... | First | // First | SinglelineComment | -| comments2.cs:67:17:67:25 | // ... | 1 | comments2.cs:67:17:67:25 | // ... | Second | // Second | SinglelineComment | -| comments2.cs:69:9:70:10 | // ... | 2 | comments2.cs:69:9:69:17 | // ... | Values | // Values | SinglelineComment | -| comments2.cs:69:9:70:10 | // ... | 2 | comments2.cs:70:9:70:10 | // ... | | // | SinglelineComment | -| comments2.cs:72:9:72:16 | // ... | 1 | comments2.cs:72:9:72:16 | // ... | Third | // Third | SinglelineComment | -| comments2.cs:75:9:75:17 | // ... | 1 | comments2.cs:75:9:75:17 | // ... | Values | // Values | SinglelineComment | -| comments2.cs:78:5:78:21 | // ... | 1 | comments2.cs:78:5:78:21 | // ... | C2 Constructor | // C2 Constructor | SinglelineComment | -| comments2.cs:79:10:79:26 | // ... | 1 | comments2.cs:79:10:79:26 | // ... | C2 Constructor | // C2 Constructor | SinglelineComment | -| comments2.cs:81:9:81:16 | // ... | 1 | comments2.cs:81:9:81:16 | // ... | {...} | // {...} | SinglelineComment | -| comments2.cs:84:5:84:10 | // ... | 1 | comments2.cs:84:5:84:10 | // ... | ~C2 | // ~C2 | SinglelineComment | -| comments2.cs:85:11:85:16 | // ... | 1 | comments2.cs:85:11:85:16 | // ... | ~C2 | // ~C2 | SinglelineComment | -| comments2.cs:89:5:89:8 | // ... | 1 | comments2.cs:89:5:89:8 | // ... | + | // + | SinglelineComment | -| comments2.cs:90:46:90:49 | // ... | 1 | comments2.cs:90:46:90:49 | // ... | + | // + | SinglelineComment | -| comments2.cs:96:15:96:18 | // ... | 1 | comments2.cs:96:15:96:18 | // ... | x | // x | SinglelineComment | -| comments2.cs:97:13:97:16 | // ... | 1 | comments2.cs:97:13:97:16 | // ... | y | // y | SinglelineComment | -| comments2.cs:102:5:102:8 | // ... | 1 | comments2.cs:102:5:102:8 | // ... | D | // D | SinglelineComment | -| comments2.cs:103:31:104:34 | // ... | 2 | comments2.cs:103:31:103:34 | // ... | D | // D | SinglelineComment | -| comments2.cs:103:31:104:34 | // ... | 2 | comments2.cs:104:31:104:34 | // ... | D | // D | SinglelineComment | -| comments2.cs:106:5:106:8 | // ... | 1 | comments2.cs:106:5:106:8 | // ... | E | // E | SinglelineComment | -| comments2.cs:107:23:108:26 | // ... | 2 | comments2.cs:107:23:107:26 | // ... | E | // E | SinglelineComment | -| comments2.cs:107:23:108:26 | // ... | 2 | comments2.cs:108:23:108:26 | // ... | E | // E | SinglelineComment | -| comments2.cs:118:5:118:21 | // ... | 1 | comments2.cs:118:5:118:21 | // ... | GenericClass<> | // GenericClass<> | SinglelineComment | -| comments2.cs:121:17:121:20 | // ... | 1 | comments2.cs:121:17:121:20 | // ... | f | // f | SinglelineComment | -| comments2.cs:124:5:124:16 | // ... | 1 | comments2.cs:124:5:124:16 | // ... | GenericFn | // GenericFn | SinglelineComment | -| comments2.cs:127:20:127:23 | // ... | 1 | comments2.cs:127:20:127:23 | // ... | x | // x | SinglelineComment | -| comments2.cs:132:1:132:21 | // ... | 1 | comments2.cs:132:1:132:21 | // ... | End of comment2.cs | // End of comment2.cs | SinglelineComment | +singlelineComment +| comments1.cs:1:1:2:46 | // ... | comments1.cs:1:1:1:23 | // ... | 2 | Start of comment1.cs | // Start of comment1.cs | +| comments1.cs:1:1:2:46 | // ... | comments1.cs:2:1:2:46 | // ... | 2 | This tests the basic types of comment block | // This tests the basic types of comment block | +| comments1.cs:4:1:4:25 | // ... | comments1.cs:4:1:4:25 | // ... | 1 | 1) Basic comment types | // 1) Basic comment types | +| comments1.cs:6:1:6:24 | // ... | comments1.cs:6:1:6:24 | // ... | 1 | A single-line comment | // A single-line comment | +| comments1.cs:14:1:14:20 | // ... | comments1.cs:14:1:14:20 | // ... | 1 | 2) Comment blocks | // 2) Comment blocks | +| comments1.cs:16:1:16:38 | // ... | comments1.cs:16:1:16:38 | // ... | 1 | A line on its own is a commentblock | // A line on its own is a commentblock | +| comments1.cs:18:1:19:31 | // ... | comments1.cs:18:1:18:21 | // ... | 2 | Two lines together | // Two lines together | +| comments1.cs:18:1:19:31 | // ... | comments1.cs:19:1:19:31 | // ... | 2 | are in the same commentblock | // are in the same commentblock | +| comments1.cs:21:1:23:15 | // ... | comments1.cs:21:1:21:14 | // ... | 3 | Three lines | // Three lines | +| comments1.cs:21:1:23:15 | // ... | comments1.cs:22:1:22:14 | // ... | 3 | in the same | // in the same | +| comments1.cs:21:1:23:15 | // ... | comments1.cs:23:1:23:15 | // ... | 3 | commentblock | // commentblock | +| comments1.cs:31:1:33:30 | // ... | comments1.cs:31:1:31:21 | // ... | 3 | These three lines, | // These three lines, | +| comments1.cs:37:5:39:41 | /* ... */ | comments1.cs:39:5:39:41 | // ... | 3 | This is not the same comment block | // This is not the same comment block | +| comments1.cs:40:13:41:51 | // ... | comments1.cs:40:13:40:27 | // ... | 2 | as this line | // as this line | +| comments1.cs:40:13:41:51 | // ... | comments1.cs:41:13:41:51 | // ... | 2 | because they are offset differently. | // because they are offset differently. | +| comments1.cs:43:15:43:36 | // ... | comments1.cs:43:15:43:36 | // ... | 1 | These are different | // These are different | +| comments1.cs:44:15:44:32 | // ... | comments1.cs:44:15:44:32 | // ... | 1 | comment blocks. | // comment blocks. | +| comments1.cs:47:1:47:21 | // ... | comments1.cs:47:1:47:21 | // ... | 1 | End of comment1.cs | // End of comment1.cs | +| comments2.cs:1:1:2:15 | // ... | comments2.cs:1:1:1:23 | // ... | 2 | Start of comment2.cs | // Start of comment2.cs | +| comments2.cs:1:1:2:15 | // ... | comments2.cs:2:1:2:15 | // ... | 2 | Unassociated | // Unassociated | +| comments2.cs:5:27:5:41 | // ... | comments2.cs:5:27:5:41 | // ... | 1 | Unassociated | // Unassociated | +| comments2.cs:8:1:8:15 | // ... | comments2.cs:8:1:8:15 | // ... | 1 | Unassociated | // Unassociated | +| comments2.cs:13:17:13:25 | // ... | comments2.cs:13:17:13:25 | // ... | 1 | field1 | // field1 | +| comments2.cs:14:17:14:25 | // ... | comments2.cs:14:17:14:25 | // ... | 1 | field2 | // field2 | +| comments2.cs:16:5:16:9 | // ... | comments2.cs:16:5:16:9 | // ... | 1 | C2 | // C2 | +| comments2.cs:18:5:18:8 | // ... | comments2.cs:18:5:18:8 | // ... | 1 | f | // f | +| comments2.cs:21:9:21:16 | // ... | comments2.cs:21:9:21:16 | // ... | 1 | {...} | // {...} | +| comments2.cs:23:15:23:21 | // ... | comments2.cs:23:15:23:21 | // ... | 1 | ...; | // ...; | +| comments2.cs:25:9:25:15 | // ... | comments2.cs:25:9:25:15 | // ... | 1 | ...; | // ...; | +| comments2.cs:31:9:31:15 | // ... | comments2.cs:31:9:31:15 | // ... | 1 | ...; | // ...; | +| comments2.cs:33:9:33:16 | // ... | comments2.cs:33:9:33:16 | // ... | 1 | {...} | // {...} | +| comments2.cs:36:9:36:16 | // ... | comments2.cs:36:9:36:16 | // ... | 1 | {...} | // {...} | +| comments2.cs:39:5:39:9 | // ... | comments2.cs:39:5:39:9 | // ... | 1 | C3 | // C3 | +| comments2.cs:42:9:42:13 | // ... | comments2.cs:42:9:42:13 | // ... | 1 | C3 | // C3 | +| comments2.cs:45:5:45:9 | // ... | comments2.cs:45:5:45:9 | // ... | 1 | C2 | // C2 | +| comments2.cs:47:5:47:9 | // ... | comments2.cs:47:5:47:9 | // ... | 1 | S1 | // S1 | +| comments2.cs:50:9:50:13 | // ... | comments2.cs:50:9:50:13 | // ... | 1 | S1 | // S1 | +| comments2.cs:52:28:52:35 | // ... | comments2.cs:52:28:52:35 | // ... | 1 | {...} | // {...} | +| comments2.cs:53:13:53:17 | // ... | comments2.cs:53:13:53:17 | // ... | 1 | S1 | // S1 | +| comments2.cs:55:13:55:20 | // ... | comments2.cs:55:13:55:20 | // ... | 1 | {...} | // {...} | +| comments2.cs:56:11:56:18 | // ... | comments2.cs:56:11:56:18 | // ... | 1 | {...} | // {...} | +| comments2.cs:58:5:58:9 | // ... | comments2.cs:58:5:58:9 | // ... | 1 | S1 | // S1 | +| comments2.cs:60:5:60:13 | // ... | comments2.cs:60:5:60:13 | // ... | 1 | Values | // Values | +| comments2.cs:63:9:63:17 | // ... | comments2.cs:63:9:63:17 | // ... | 1 | Values | // Values | +| comments2.cs:65:9:65:16 | // ... | comments2.cs:65:9:65:16 | // ... | 1 | First | // First | +| comments2.cs:66:17:66:24 | // ... | comments2.cs:66:17:66:24 | // ... | 1 | First | // First | +| comments2.cs:67:17:67:25 | // ... | comments2.cs:67:17:67:25 | // ... | 1 | Second | // Second | +| comments2.cs:69:9:70:10 | // ... | comments2.cs:69:9:69:17 | // ... | 2 | Values | // Values | +| comments2.cs:69:9:70:10 | // ... | comments2.cs:70:9:70:10 | // ... | 2 | | // | +| comments2.cs:72:9:72:16 | // ... | comments2.cs:72:9:72:16 | // ... | 1 | Third | // Third | +| comments2.cs:75:9:75:17 | // ... | comments2.cs:75:9:75:17 | // ... | 1 | Values | // Values | +| comments2.cs:78:5:78:21 | // ... | comments2.cs:78:5:78:21 | // ... | 1 | C2 Constructor | // C2 Constructor | +| comments2.cs:79:10:79:26 | // ... | comments2.cs:79:10:79:26 | // ... | 1 | C2 Constructor | // C2 Constructor | +| comments2.cs:81:9:81:16 | // ... | comments2.cs:81:9:81:16 | // ... | 1 | {...} | // {...} | +| comments2.cs:84:5:84:10 | // ... | comments2.cs:84:5:84:10 | // ... | 1 | ~C2 | // ~C2 | +| comments2.cs:85:11:85:16 | // ... | comments2.cs:85:11:85:16 | // ... | 1 | ~C2 | // ~C2 | +| comments2.cs:89:5:89:8 | // ... | comments2.cs:89:5:89:8 | // ... | 1 | + | // + | +| comments2.cs:90:46:90:49 | // ... | comments2.cs:90:46:90:49 | // ... | 1 | + | // + | +| comments2.cs:96:15:96:18 | // ... | comments2.cs:96:15:96:18 | // ... | 1 | x | // x | +| comments2.cs:97:13:97:16 | // ... | comments2.cs:97:13:97:16 | // ... | 1 | y | // y | +| comments2.cs:102:5:102:8 | // ... | comments2.cs:102:5:102:8 | // ... | 1 | D | // D | +| comments2.cs:103:31:104:34 | // ... | comments2.cs:103:31:103:34 | // ... | 2 | D | // D | +| comments2.cs:103:31:104:34 | // ... | comments2.cs:104:31:104:34 | // ... | 2 | D | // D | +| comments2.cs:106:5:106:8 | // ... | comments2.cs:106:5:106:8 | // ... | 1 | E | // E | +| comments2.cs:107:23:108:26 | // ... | comments2.cs:107:23:107:26 | // ... | 2 | E | // E | +| comments2.cs:107:23:108:26 | // ... | comments2.cs:108:23:108:26 | // ... | 2 | E | // E | +| comments2.cs:118:5:118:21 | // ... | comments2.cs:118:5:118:21 | // ... | 1 | GenericClass<> | // GenericClass<> | +| comments2.cs:121:17:121:20 | // ... | comments2.cs:121:17:121:20 | // ... | 1 | f | // f | +| comments2.cs:124:5:124:16 | // ... | comments2.cs:124:5:124:16 | // ... | 1 | GenericFn | // GenericFn | +| comments2.cs:127:20:127:23 | // ... | comments2.cs:127:20:127:23 | // ... | 1 | x | // x | +| comments2.cs:132:1:132:21 | // ... | comments2.cs:132:1:132:21 | // ... | 1 | End of comment2.cs | // End of comment2.cs | +| trivia.cs:1:1:3:15 | // ... | trivia.cs:1:1:1:2 | // ... | 3 | | // | +| trivia.cs:1:1:3:15 | // ... | trivia.cs:2:1:2:21 | // ... | 3 | Start of trivia.cs | // Start of trivia.cs | +| trivia.cs:1:1:3:15 | // ... | trivia.cs:3:1:3:15 | // ... | 3 | Unassociated | // Unassociated | +| trivia.cs:13:89:13:103 | // ... | trivia.cs:13:89:13:103 | // ... | 1 | New checksum | // New checksum | +| trivia.cs:25:14:25:38 | // ... | trivia.cs:25:14:25:38 | // ... | 1 | numbering not affected | // numbering not affected | +| trivia.cs:49:18:49:82 | // ... | trivia.cs:49:18:49:82 | // ... | 1 | Sets the nullable annotation and warning contexts to disabled. | // Sets the nullable annotation and warning contexts to disabled. | +| trivia.cs:50:17:50:80 | // ... | trivia.cs:50:17:50:80 | // ... | 1 | Sets the nullable annotation and warning contexts to enabled. | // Sets the nullable annotation and warning contexts to enabled. | +| trivia.cs:51:18:51:94 | // ... | trivia.cs:51:18:51:94 | // ... | 1 | Restores the nullable annotation and warning contexts to project settings. | // Restores the nullable annotation and warning contexts to project settings. | +| trivia.cs:52:30:52:81 | // ... | trivia.cs:52:30:52:81 | // ... | 1 | Sets the nullable annotation context to disabled. | // Sets the nullable annotation context to disabled. | +| trivia.cs:53:29:53:79 | // ... | trivia.cs:53:29:53:79 | // ... | 1 | Sets the nullable annotation context to enabled. | // Sets the nullable annotation context to enabled. | +| trivia.cs:54:30:54:93 | // ... | trivia.cs:54:30:54:93 | // ... | 1 | Restores the nullable annotation context to project settings. | // Restores the nullable annotation context to project settings. | +| trivia.cs:55:27:55:75 | // ... | trivia.cs:55:27:55:75 | // ... | 1 | Sets the nullable warning context to disabled. | // Sets the nullable warning context to disabled. | +| trivia.cs:56:26:56:73 | // ... | trivia.cs:56:26:56:73 | // ... | 1 | Sets the nullable warning context to enabled. | // Sets the nullable warning context to enabled. | +| trivia.cs:57:27:57:87 | // ... | trivia.cs:57:27:57:87 | // ... | 1 | Restores the nullable warning context to project settings. | // Restores the nullable warning context to project settings. | +multilineComment +| comments1.cs:11:1:11:25 | /* ... */ | comments1.cs:11:1:11:25 | /* ... */ | 1 | A multiline comment | /* A multiline comment */ | +| comments1.cs:25:1:25:43 | /* ... */ | comments1.cs:25:1:25:15 | /* ... */ | 2 | This is a | /* This is a */ | +| comments1.cs:25:1:25:43 | /* ... */ | comments1.cs:25:18:25:43 | /* ... */ | 2 | single comment block | /* single comment block */ | +| comments1.cs:27:1:29:13 | /* ... */ | comments1.cs:27:1:27:12 | /* ... */ | 3 | This is a | /* This is a | +| comments1.cs:27:1:29:13 | /* ... */ | comments1.cs:28:1:28:17 | /* ... */ | 3 | true multiline | true multiline | +| comments1.cs:27:1:29:13 | /* ... */ | comments1.cs:29:1:29:13 | /* ... */ | 3 | comment | comment */ | +| comments1.cs:31:1:33:30 | // ... | comments1.cs:32:1:32:61 | /* ... */ | 3 | even though they are using different commenting styles, | /* even though they are using different commenting styles, */ | +| comments1.cs:37:5:39:41 | /* ... */ | comments1.cs:37:5:37:6 | /* ... */ | 3 | | /* | +| comments1.cs:37:5:39:41 | /* ... */ | comments1.cs:38:1:38:6 | /* ... */ | 3 | | */ | +xmlComment +| comments1.cs:8:1:8:18 | /// ... | comments1.cs:8:1:8:18 | /// ... | 1 | An XML comment | /// An XML comment | +| comments1.cs:31:1:33:30 | // ... | comments1.cs:33:1:33:30 | /// ... | 3 | form a single commentblock | /// form a single commentblock | +| comments2.cs:10:1:10:6 | /// ... | comments2.cs:10:1:10:6 | /// ... | 1 | C2 | /// C2 | diff --git a/csharp/ql/test/library-tests/comments/Comments.ql b/csharp/ql/test/library-tests/comments/Comments.ql index ab01b83572a..5ef8d3d75b9 100644 --- a/csharp/ql/test/library-tests/comments/Comments.ql +++ b/csharp/ql/test/library-tests/comments/Comments.ql @@ -1,5 +1,26 @@ import csharp -from CommentBlock c, CommentLine l -where l.getParent() = c -select c, c.getNumLines(), l, l.getText(), l.getRawText(), l.getAQlClass() +private predicate commentLine( + CommentBlock c, CommentLine l, int numLines, string text, string rawText +) { + l.getParent() = c and + numLines = c.getNumLines() and + text = l.getText() and + rawText = l.getRawText() +} + +query predicate singlelineComment( + CommentBlock c, SinglelineComment l, int numLines, string text, string rawText +) { + commentLine(c, l, numLines, text, rawText) +} + +query predicate multilineComment( + CommentBlock c, MultilineComment l, int numLines, string text, string rawText +) { + commentLine(c, l, numLines, text, rawText) +} + +query predicate xmlComment(CommentBlock c, XmlComment l, int numLines, string text, string rawText) { + commentLine(c, l, numLines, text, rawText) +} diff --git a/csharp/ql/test/library-tests/comments/DefineDirectives.expected b/csharp/ql/test/library-tests/comments/DefineDirectives.expected new file mode 100644 index 00000000000..e58b3859d58 --- /dev/null +++ b/csharp/ql/test/library-tests/comments/DefineDirectives.expected @@ -0,0 +1 @@ +| trivia.cs:4:1:4:13 | #define ... | DEBUG | diff --git a/csharp/ql/test/library-tests/comments/DefineDirectives.ql b/csharp/ql/test/library-tests/comments/DefineDirectives.ql new file mode 100644 index 00000000000..a27b18f9fbe --- /dev/null +++ b/csharp/ql/test/library-tests/comments/DefineDirectives.ql @@ -0,0 +1,4 @@ +import csharp + +from DefineDirective d +select d, d.getName() diff --git a/csharp/ql/test/library-tests/comments/Directives.expected b/csharp/ql/test/library-tests/comments/Directives.expected new file mode 100644 index 00000000000..c6d0a12ffb6 --- /dev/null +++ b/csharp/ql/test/library-tests/comments/Directives.expected @@ -0,0 +1,62 @@ +directives +| trivia.cs:4:1:4:13 | #define ... | trivia.cs:4:1:4:13 | trivia.cs:4:1:4:13 | active | +| trivia.cs:6:1:6:12 | #undef ... | trivia.cs:6:1:6:12 | trivia.cs:6:1:6:12 | active | +| trivia.cs:12:1:12:35 | #pragma warning ... | trivia.cs:12:1:12:35 | trivia.cs:12:1:12:35 | active | +| trivia.cs:13:1:13:103 | #pragma checksum ... | trivia.cs:13:1:13:103 | trivia.cs:13:1:13:103 | active | +| trivia.cs:18:1:18:22 | #line ... | trivia.cs:18:1:18:22 | trivia.cs:18:1:18:22 | active | +| trivia.cs:21:1:21:13 | #line default | trivia.cs:21:1:21:13 | trivia.cs:21:1:21:13 | active | +| trivia.cs:23:1:23:23 | #pragma warning ... | trivia.cs:23:1:23:23 | trivia.cs:23:1:23:23 | active | +| trivia.cs:25:1:25:38 | #line hidden | trivia.cs:25:1:25:38 | trivia.cs:25:1:25:38 | active | +| trivia.cs:27:1:27:7 | #line ... | trivia.cs:27:1:27:7 | trivia.cs:27:1:27:7 | active | +| trivia.cs:36:9:36:22 | #region ... | trivia.cs:36:9:36:22 | trivia.cs:36:9:36:22 | active | +| trivia.cs:38:9:38:22 | #region ... | trivia.cs:38:9:38:22 | trivia.cs:38:9:38:22 | active | +| trivia.cs:40:9:40:18 | #endregion | trivia.cs:40:9:40:18 | trivia.cs:40:9:40:18 | active | +| trivia.cs:41:9:41:18 | #endregion | trivia.cs:41:9:41:18 | trivia.cs:41:9:41:18 | active | +| trivia.cs:49:1:49:82 | #nullable ... | trivia.cs:49:1:49:82 | trivia.cs:49:1:49:82 | active | +| trivia.cs:50:1:50:80 | #nullable ... | trivia.cs:50:1:50:80 | trivia.cs:50:1:50:80 | active | +| trivia.cs:51:1:51:94 | #nullable ... | trivia.cs:51:1:51:94 | trivia.cs:51:1:51:94 | active | +| trivia.cs:52:1:52:81 | #nullable ... | trivia.cs:52:1:52:81 | trivia.cs:52:1:52:81 | active | +| trivia.cs:53:1:53:79 | #nullable ... | trivia.cs:53:1:53:79 | trivia.cs:53:1:53:79 | active | +| trivia.cs:54:1:54:93 | #nullable ... | trivia.cs:54:1:54:93 | trivia.cs:54:1:54:93 | active | +| trivia.cs:55:1:55:75 | #nullable ... | trivia.cs:55:1:55:75 | trivia.cs:55:1:55:75 | active | +| trivia.cs:56:1:56:73 | #nullable ... | trivia.cs:56:1:56:73 | trivia.cs:56:1:56:73 | active | +| trivia.cs:57:1:57:87 | #nullable ... | trivia.cs:57:1:57:87 | trivia.cs:57:1:57:87 | active | +| trivia.cs:65:1:65:9 | #if ... | trivia.cs:65:1:65:9 | trivia.cs:65:1:65:9 | active | +| trivia.cs:66:1:66:23 | #error ... | trivia.cs:66:1:66:23 | trivia.cs:66:1:66:23 | inactive | +| trivia.cs:68:1:68:10 | #if ... | trivia.cs:68:1:68:10 | trivia.cs:68:1:68:10 | inactive | +| trivia.cs:70:1:70:6 | #endif | trivia.cs:70:1:70:6 | trivia.cs:70:1:70:6 | inactive | +| trivia.cs:71:1:71:35 | #elif ... | trivia.cs:71:1:71:35 | trivia.cs:71:1:71:35 | active | +| trivia.cs:72:1:72:43 | #warning ... | trivia.cs:72:1:72:43 | trivia.cs:72:1:72:43 | active | +| trivia.cs:74:1:74:5 | #else | trivia.cs:74:1:74:5 | trivia.cs:74:1:74:5 | active | +| trivia.cs:76:1:76:6 | #endif | trivia.cs:76:1:76:6 | trivia.cs:76:1:76:6 | active | +comp +| trivia.cs:4:1:4:13 | #define ... | compilation | +| trivia.cs:6:1:6:12 | #undef ... | compilation | +| trivia.cs:12:1:12:35 | #pragma warning ... | compilation | +| trivia.cs:13:1:13:103 | #pragma checksum ... | compilation | +| trivia.cs:18:1:18:22 | #line ... | compilation | +| trivia.cs:21:1:21:13 | #line default | compilation | +| trivia.cs:23:1:23:23 | #pragma warning ... | compilation | +| trivia.cs:25:1:25:38 | #line hidden | compilation | +| trivia.cs:27:1:27:7 | #line ... | compilation | +| trivia.cs:36:9:36:22 | #region ... | compilation | +| trivia.cs:38:9:38:22 | #region ... | compilation | +| trivia.cs:40:9:40:18 | #endregion | compilation | +| trivia.cs:41:9:41:18 | #endregion | compilation | +| trivia.cs:49:1:49:82 | #nullable ... | compilation | +| trivia.cs:50:1:50:80 | #nullable ... | compilation | +| trivia.cs:51:1:51:94 | #nullable ... | compilation | +| trivia.cs:52:1:52:81 | #nullable ... | compilation | +| trivia.cs:53:1:53:79 | #nullable ... | compilation | +| trivia.cs:54:1:54:93 | #nullable ... | compilation | +| trivia.cs:55:1:55:75 | #nullable ... | compilation | +| trivia.cs:56:1:56:73 | #nullable ... | compilation | +| trivia.cs:57:1:57:87 | #nullable ... | compilation | +| trivia.cs:65:1:65:9 | #if ... | compilation | +| trivia.cs:66:1:66:23 | #error ... | compilation | +| trivia.cs:68:1:68:10 | #if ... | compilation | +| trivia.cs:70:1:70:6 | #endif | compilation | +| trivia.cs:71:1:71:35 | #elif ... | compilation | +| trivia.cs:72:1:72:43 | #warning ... | compilation | +| trivia.cs:74:1:74:5 | #else | compilation | +| trivia.cs:76:1:76:6 | #endif | compilation | diff --git a/csharp/ql/test/library-tests/comments/Directives.ql b/csharp/ql/test/library-tests/comments/Directives.ql new file mode 100644 index 00000000000..4811692a9fc --- /dev/null +++ b/csharp/ql/test/library-tests/comments/Directives.ql @@ -0,0 +1,9 @@ +import csharp +private import semmle.code.csharp.commons.Compilation + +query predicate directives(PreprocessorDirective d, Location l, string isActive) { + d.getALocation() = l and + if d.isActive() then isActive = "active" else isActive = "inactive" +} + +query predicate comp(PreprocessorDirective d, Compilation c) { d.getCompilation() = c } diff --git a/csharp/ql/test/library-tests/comments/ErrorDirectives.expected b/csharp/ql/test/library-tests/comments/ErrorDirectives.expected new file mode 100644 index 00000000000..e3fb9babaf0 --- /dev/null +++ b/csharp/ql/test/library-tests/comments/ErrorDirectives.expected @@ -0,0 +1 @@ +| trivia.cs:66:1:66:23 | #error ... | DEBUG is defined | diff --git a/csharp/ql/test/library-tests/comments/ErrorDirectives.ql b/csharp/ql/test/library-tests/comments/ErrorDirectives.ql new file mode 100644 index 00000000000..dbfbb986a4c --- /dev/null +++ b/csharp/ql/test/library-tests/comments/ErrorDirectives.ql @@ -0,0 +1,4 @@ +import csharp + +from ErrorDirective d +select d, d.getMessage() diff --git a/csharp/ql/test/library-tests/comments/IfDirectives.expected b/csharp/ql/test/library-tests/comments/IfDirectives.expected new file mode 100644 index 00000000000..3a3a24ef798 --- /dev/null +++ b/csharp/ql/test/library-tests/comments/IfDirectives.expected @@ -0,0 +1,19 @@ +ifDirectives +| trivia.cs:65:1:65:9 | #if ... | trivia.cs:76:1:76:6 | #endif | not taken | false | trivia.cs:65:5:65:9 | DEBUG | +| trivia.cs:68:1:68:10 | #if ... | trivia.cs:70:1:70:6 | #endif | not taken | false | trivia.cs:68:5:68:10 | NESTED | +siblings +| trivia.cs:65:1:65:9 | #if ... | trivia.cs:71:1:71:35 | #elif ... | 0 | taken | +| trivia.cs:65:1:65:9 | #if ... | trivia.cs:74:1:74:5 | #else | 1 | not taken | +conditionalDirectives +| trivia.cs:65:1:65:9 | #if ... | not taken | false | trivia.cs:65:5:65:9 | DEBUG | +| trivia.cs:68:1:68:10 | #if ... | not taken | false | trivia.cs:68:5:68:10 | NESTED | +| trivia.cs:71:1:71:35 | #elif ... | taken | true | trivia.cs:71:7:71:35 | ... \|\| ... | +expressions +| trivia.cs:65:5:65:9 | DEBUG | +| trivia.cs:68:5:68:10 | NESTED | +| trivia.cs:71:7:71:35 | ... \|\| ... | +| trivia.cs:71:8:71:15 | NOTDEBUG | +| trivia.cs:71:8:71:23 | ... == ... | +| trivia.cs:71:20:71:23 | true | +| trivia.cs:71:29:71:35 | !... | +| trivia.cs:71:31:71:34 | TEST | diff --git a/csharp/ql/test/library-tests/comments/IfDirectives.ql b/csharp/ql/test/library-tests/comments/IfDirectives.ql new file mode 100644 index 00000000000..d7e97d3abf8 --- /dev/null +++ b/csharp/ql/test/library-tests/comments/IfDirectives.ql @@ -0,0 +1,33 @@ +import csharp + +private string getConditionValue(ConditionalDirective d) { + if d.conditionMatched() then result = "true" else result = "false" +} + +private string getBranchValue(BranchDirective d) { + if d.branchTaken() then result = "taken" else result = "not taken" +} + +query predicate ifDirectives( + IfDirective d, EndifDirective endif, string taken, string condValue, Expr expr +) { + d.getEndifDirective() = endif and + d.getCondition() = expr and + taken = getBranchValue(d) and + condValue = getConditionValue(d) +} + +query predicate siblings(IfDirective d, BranchDirective sibling, int index, string taken) { + d.getSiblingDirective(index) = sibling and + taken = getBranchValue(sibling) +} + +query predicate conditionalDirectives( + ConditionalDirective cond, string taken, string condValue, Expr expr +) { + cond.getCondition() = expr and + taken = getBranchValue(cond) and + condValue = getConditionValue(cond) +} + +query predicate expressions(Expr e) { e.getParent+() instanceof ConditionalDirective } diff --git a/csharp/ql/test/library-tests/comments/LineDirectives.expected b/csharp/ql/test/library-tests/comments/LineDirectives.expected new file mode 100644 index 00000000000..13c3658fe82 --- /dev/null +++ b/csharp/ql/test/library-tests/comments/LineDirectives.expected @@ -0,0 +1,21 @@ +default +| trivia.cs:21:1:21:13 | #line default | +hidden +| trivia.cs:25:1:25:38 | #line hidden | +lines_file +| trivia.cs:18:1:18:22 | #line ... | 1 | comments1.cs:0:0:0:0 | comments1.cs | +lines_no_file +| trivia.cs:27:1:27:7 | #line ... | 5 | +succ +| trivia.cs:18:1:18:22 | #line ... | trivia.cs:21:1:21:13 | #line default | +| trivia.cs:21:1:21:13 | #line default | trivia.cs:25:1:25:38 | #line hidden | +| trivia.cs:25:1:25:38 | #line hidden | trivia.cs:27:1:27:7 | #line ... | +last +| trivia.cs:27:1:27:7 | #line ... | +mapped +| trivia.cs:19:9:19:11 | trivia.cs:19:9:19:11 | comments1.cs:1:9:1:11 | comments1.cs:1:9:1:11 | +| trivia.cs:19:9:19:14 | trivia.cs:19:9:19:14 | comments1.cs:1:9:1:14 | comments1.cs:1:9:1:14 | +| trivia.cs:19:13:19:13 | trivia.cs:19:13:19:13 | comments1.cs:1:13:1:13 | comments1.cs:1:13:1:13 | +| trivia.cs:20:9:20:11 | trivia.cs:20:9:20:11 | comments1.cs:2:9:2:11 | comments1.cs:2:9:2:11 | +| trivia.cs:20:9:20:14 | trivia.cs:20:9:20:14 | comments1.cs:2:9:2:14 | comments1.cs:2:9:2:14 | +| trivia.cs:20:13:20:13 | trivia.cs:20:13:20:13 | comments1.cs:2:13:2:13 | comments1.cs:2:13:2:13 | diff --git a/csharp/ql/test/library-tests/comments/LineDirectives.ql b/csharp/ql/test/library-tests/comments/LineDirectives.ql new file mode 100644 index 00000000000..5b009f0b4b8 --- /dev/null +++ b/csharp/ql/test/library-tests/comments/LineDirectives.ql @@ -0,0 +1,19 @@ +import csharp + +query predicate default(DefaultLineDirective line) { any() } + +query predicate hidden(HiddenLineDirective line) { any() } + +query predicate lines_file(NumericLineDirective line, int l, File file) { + line.getLine() = l and line.getReferencedFile() = file +} + +query predicate lines_no_file(NumericLineDirective line, int l) { + line.getLine() = l and not exists(line.getReferencedFile()) +} + +query predicate succ(LineDirective d, LineDirective succ) { d.getSuccLineDirective() = succ } + +query predicate last(LineDirective d) { not d.hasSuccLineDirective() } + +query predicate mapped(SourceLocation l1, Location l2) { l1.getMappedLocation() = l2 } diff --git a/csharp/ql/test/library-tests/comments/NullableDirectives.expected b/csharp/ql/test/library-tests/comments/NullableDirectives.expected new file mode 100644 index 00000000000..bbf13afa63b --- /dev/null +++ b/csharp/ql/test/library-tests/comments/NullableDirectives.expected @@ -0,0 +1,21 @@ +nullables +| trivia.cs:49:1:49:82 | #nullable ... | 0 | 0 | +| trivia.cs:50:1:50:80 | #nullable ... | 1 | 0 | +| trivia.cs:51:1:51:94 | #nullable ... | 2 | 0 | +| trivia.cs:52:1:52:81 | #nullable ... | 0 | 1 | +| trivia.cs:53:1:53:79 | #nullable ... | 1 | 1 | +| trivia.cs:54:1:54:93 | #nullable ... | 2 | 1 | +| trivia.cs:55:1:55:75 | #nullable ... | 0 | 2 | +| trivia.cs:56:1:56:73 | #nullable ... | 1 | 2 | +| trivia.cs:57:1:57:87 | #nullable ... | 2 | 2 | +succ +| trivia.cs:49:1:49:82 | #nullable ... | trivia.cs:50:1:50:80 | #nullable ... | +| trivia.cs:50:1:50:80 | #nullable ... | trivia.cs:51:1:51:94 | #nullable ... | +| trivia.cs:51:1:51:94 | #nullable ... | trivia.cs:52:1:52:81 | #nullable ... | +| trivia.cs:52:1:52:81 | #nullable ... | trivia.cs:53:1:53:79 | #nullable ... | +| trivia.cs:53:1:53:79 | #nullable ... | trivia.cs:54:1:54:93 | #nullable ... | +| trivia.cs:54:1:54:93 | #nullable ... | trivia.cs:55:1:55:75 | #nullable ... | +| trivia.cs:55:1:55:75 | #nullable ... | trivia.cs:56:1:56:73 | #nullable ... | +| trivia.cs:56:1:56:73 | #nullable ... | trivia.cs:57:1:57:87 | #nullable ... | +last +| trivia.cs:57:1:57:87 | #nullable ... | diff --git a/csharp/ql/test/library-tests/comments/NullableDirectives.ql b/csharp/ql/test/library-tests/comments/NullableDirectives.ql new file mode 100644 index 00000000000..a5312df39e9 --- /dev/null +++ b/csharp/ql/test/library-tests/comments/NullableDirectives.ql @@ -0,0 +1,11 @@ +import csharp + +query predicate nullables(NullableDirective d, int setting, int target) { + directive_nullables(d, setting, target) +} + +query predicate succ(NullableDirective d, NullableDirective succ) { + d.getSuccNullableDirective() = succ +} + +query predicate last(NullableDirective d) { not d.hasSuccNullableDirective() } diff --git a/csharp/ql/test/library-tests/comments/Orphans.expected b/csharp/ql/test/library-tests/comments/Orphans.expected index e57bc81990e..56e5af20cd2 100644 --- a/csharp/ql/test/library-tests/comments/Orphans.expected +++ b/csharp/ql/test/library-tests/comments/Orphans.expected @@ -14,3 +14,4 @@ | comments2.cs:5:27:5:41 | // ... | | comments2.cs:8:1:8:15 | // ... | | comments2.cs:132:1:132:21 | // ... | +| trivia.cs:1:1:3:15 | // ... | diff --git a/csharp/ql/test/library-tests/comments/PragmaChecksums.expected b/csharp/ql/test/library-tests/comments/PragmaChecksums.expected new file mode 100644 index 00000000000..d3700c13aa0 --- /dev/null +++ b/csharp/ql/test/library-tests/comments/PragmaChecksums.expected @@ -0,0 +1 @@ +| trivia.cs:13:1:13:103 | #pragma checksum ... | comments1.cs:0:0:0:0 | comments1.cs | "{406EA660-64CF-4C82-B6F0-42D48172A799}" | "ab007f1d23d9" | diff --git a/csharp/ql/test/library-tests/comments/PragmaChecksums.ql b/csharp/ql/test/library-tests/comments/PragmaChecksums.ql new file mode 100644 index 00000000000..8de177f5215 --- /dev/null +++ b/csharp/ql/test/library-tests/comments/PragmaChecksums.ql @@ -0,0 +1,4 @@ +import csharp + +from PragmaChecksumDirective p +select p, p.getReferencedFile(), p.getGuid(), p.getBytes() diff --git a/csharp/ql/test/library-tests/comments/PragmaWarnings.expected b/csharp/ql/test/library-tests/comments/PragmaWarnings.expected new file mode 100644 index 00000000000..ade1a86da1c --- /dev/null +++ b/csharp/ql/test/library-tests/comments/PragmaWarnings.expected @@ -0,0 +1,7 @@ +disable +| trivia.cs:12:1:12:35 | #pragma warning ... | +restore +| trivia.cs:23:1:23:23 | #pragma warning ... | +errorCodes +| trivia.cs:12:1:12:35 | #pragma warning ... | 414 | +| trivia.cs:12:1:12:35 | #pragma warning ... | CS3021 | diff --git a/csharp/ql/test/library-tests/comments/PragmaWarnings.ql b/csharp/ql/test/library-tests/comments/PragmaWarnings.ql new file mode 100644 index 00000000000..58ce589474e --- /dev/null +++ b/csharp/ql/test/library-tests/comments/PragmaWarnings.ql @@ -0,0 +1,9 @@ +import csharp + +query predicate disable(PragmaWarningDirective pragma) { pragma.isDisable() } + +query predicate restore(PragmaWarningDirective pragma) { pragma.isRestore() } + +query predicate errorCodes(PragmaWarningDirective pragma, string code) { + pragma.hasErrorCodes() and code = pragma.getAnErrorCode() +} diff --git a/csharp/ql/test/library-tests/comments/PrintAst.expected b/csharp/ql/test/library-tests/comments/PrintAst.expected new file mode 100644 index 00000000000..71d16cdf134 --- /dev/null +++ b/csharp/ql/test/library-tests/comments/PrintAst.expected @@ -0,0 +1,179 @@ +comments1.cs: +# 9| [Class] C +# 35| [Class] Foo +# 40| 5: [Field] x +# 40| -1: [TypeMention] int +# 43| 6: [Field] y +# 43| -1: [TypeMention] int +# 44| 7: [Field] z +# 44| -1: [TypeMention] int +comments2.cs: +# 11| [Class] C2 +# 13| 4: [Field] field1 +# 13| -1: [TypeMention] int +# 14| 5: [Field] field2 +# 14| -1: [TypeMention] int +# 19| 6: [Method] f +# 19| -1: [TypeMention] Void +# 20| 4: [BlockStmt] {...} +# 23| 0: [ExprStmt] ...; +# 23| 0: [MethodCall] call to method f +# 26| 1: [ExprStmt] ...; +# 26| 0: [MethodCall] call to method g +# 26| 0: [IntLiteral] 2 +# 29| 7: [Method] g +# 29| -1: [TypeMention] Void +#-----| 2: (Parameters) +# 29| 0: [Parameter] x +# 29| -1: [TypeMention] int +# 30| 4: [BlockStmt] {...} +# 32| 0: [LocalVariableDeclStmt] ... ...; +# 32| 0: [LocalVariableDeclAndInitExpr] Int32 y = ... +# 32| -1: [TypeMention] int +# 32| 0: [LocalVariableAccess] access to local variable y +# 32| 1: [IntLiteral] 0 +# 34| 1: [LocalVariableDeclStmt] ... ...; +# 34| 0: [LocalVariableDeclAndInitExpr] Int32 z = ... +# 34| -1: [TypeMention] int +# 34| 0: [LocalVariableAccess] access to local variable z +# 34| 1: [IntLiteral] 0 +# 40| 8: [Class] C3 +# 48| 9: [Property] S1 +# 48| -1: [TypeMention] string +# 52| 3: [Getter] get_S1 +# 52| 4: [BlockStmt] {...} +# 52| 0: [ReturnStmt] return ...; +# 52| 0: [StringLiteral] "" +# 53| 4: [Setter] set_S1 +#-----| 2: (Parameters) +# 53| 0: [Parameter] value +# 54| 4: [BlockStmt] {...} +# 61| 10: [Enum] Values +# 66| 5: [Field] First +# 67| 6: [Field] Second +# 73| 7: [Field] Third +# 79| 11: [InstanceConstructor] C2 +# 80| 4: [BlockStmt] {...} +# 85| 12: [Destructor] ~C2 +# 86| 4: [BlockStmt] {...} +# 90| 13: [AddOperator] + +# 90| -1: [TypeMention] int +#-----| 2: (Parameters) +# 90| 0: [Parameter] x +# 90| -1: [TypeMention] C2 +# 90| 1: [Parameter] b +# 90| -1: [TypeMention] C2 +# 91| 4: [BlockStmt] {...} +# 92| 0: [ReturnStmt] return ...; +# 92| 0: [IntLiteral] 2 +# 95| 14: [Method] f +# 95| -1: [TypeMention] Void +#-----| 2: (Parameters) +# 96| 0: [Parameter] x +# 96| -1: [TypeMention] int +# 97| 1: [Parameter] y +# 97| -1: [TypeMention] int +# 99| 4: [BlockStmt] {...} +# 103| 15: [DelegateType] D +# 107| 16: [Event] E +# 107| -1: [TypeMention] D +# 107| 3: [AddEventAccessor] add_E +#-----| 2: (Parameters) +# 107| 0: [Parameter] value +# 107| 4: [RemoveEventAccessor] remove_E +#-----| 2: (Parameters) +# 107| 0: [Parameter] value +# 110| 17: [Method] gen +# 110| -1: [TypeMention] Void +# 111| 4: [BlockStmt] {...} +# 112| 0: [LocalVariableDeclStmt] ... ...; +# 112| 0: [LocalVariableDeclAndInitExpr] GenericClass<Int32> t1 = ... +# 112| -1: [TypeMention] GenericClass<Int32> +# 112| 0: [LocalVariableAccess] access to local variable t1 +# 112| 1: [ObjectCreation] object creation of type GenericClass<Int32> +# 112| 0: [TypeMention] GenericClass<Int32> +# 112| 1: [TypeMention] int +# 113| 1: [LocalVariableDeclStmt] ... ...; +# 113| 0: [LocalVariableDeclAndInitExpr] Int32 t2 = ... +# 113| -1: [TypeMention] int +# 113| 0: [LocalVariableAccess] access to local variable t2 +# 113| 1: [MethodCall] call to method GenericFn +# 114| 2: [LocalVariableDeclStmt] ... ...; +# 114| 0: [LocalVariableDeclAndInitExpr] GenericClass<Double> t3 = ... +# 114| -1: [TypeMention] GenericClass<Double> +# 114| 0: [LocalVariableAccess] access to local variable t3 +# 114| 1: [ObjectCreation] object creation of type GenericClass<Double> +# 114| 0: [TypeMention] GenericClass<Double> +# 114| 1: [TypeMention] double +# 115| 3: [LocalVariableDeclStmt] ... ...; +# 115| 0: [LocalVariableDeclAndInitExpr] Int32 t4 = ... +# 115| -1: [TypeMention] int +# 115| 0: [LocalVariableAccess] access to local variable t4 +# 115| 1: [MethodCall] call to method GenericFn +# 119| 18: [Class] GenericClass<> +#-----| 1: (Type parameters) +# 119| 0: [TypeParameter] T +# 121| 5: [Field] f +# 121| -1: [TypeMention] int +# 125| 21: [Method] GenericFn +# 125| -1: [TypeMention] int +#-----| 1: (Type parameters) +# 125| 0: [TypeParameter] T +# 126| 4: [BlockStmt] {...} +# 127| 0: [LocalVariableDeclStmt] ... ...; +# 127| 0: [LocalVariableDeclAndInitExpr] Int32 x = ... +# 127| -1: [TypeMention] int +# 127| 0: [LocalVariableAccess] access to local variable x +# 127| 1: [IntLiteral] 0 +# 128| 1: [ReturnStmt] return ...; +# 128| 0: [IntLiteral] 0 +trivia.cs: +# 14| [Class] Tr1 +# 16| 5: [Method] M1 +# 16| -1: [TypeMention] Void +# 17| 4: [BlockStmt] {...} +comments1.cs: +# 1| 0: [LocalVariableDeclStmt] ... ...; +# 1| 0: [LocalVariableDeclExpr] Int32 i +trivia.cs: +# 19| 0: [TypeMention] int +comments1.cs: +# 2| 1: [LocalVariableDeclStmt] ... ...; +# 2| 0: [LocalVariableDeclExpr] Int32 j +trivia.cs: +# 20| 0: [TypeMention] int +# 22| 2: [LocalVariableDeclStmt] ... ...; +# 22| 0: [LocalVariableDeclExpr] Char c +# 22| 0: [TypeMention] char +# 24| 3: [LocalVariableDeclStmt] ... ...; +# 24| 0: [LocalVariableDeclExpr] Single f +# 24| 0: [TypeMention] float +# 26| 4: [LocalVariableDeclStmt] ... ...; +# 26| 0: [LocalVariableDeclExpr] String s +# 26| 0: [TypeMention] string +# 28| 5: [LocalVariableDeclStmt] ... ...; +# 28| 0: [LocalVariableDeclExpr] Double d +# 28| 0: [TypeMention] double +# 32| [Class] Tr2 +# 34| 5: [Method] M1 +# 34| -1: [TypeMention] Void +# 35| 4: [BlockStmt] {...} +# 37| 0: [LocalVariableDeclStmt] ... ...; +# 37| 0: [LocalVariableDeclExpr] Int32 i +# 37| 0: [TypeMention] int +# 39| 1: [LocalVariableDeclStmt] ... ...; +# 39| 0: [LocalVariableDeclExpr] Int32 j +# 39| 0: [TypeMention] int +# 45| [Class] Tr3 +# 47| 5: [Method] M1 +# 47| -1: [TypeMention] Void +# 48| 4: [BlockStmt] {...} +# 61| [Class] Tr4 +# 63| 5: [Method] M1 +# 63| -1: [TypeMention] Void +# 64| 4: [BlockStmt] {...} +# 73| 0: [LocalVariableDeclStmt] ... ...; +# 73| 0: [LocalVariableDeclAndInitExpr] Int32 i = ... +# 73| -1: [TypeMention] int +# 73| 0: [LocalVariableAccess] access to local variable i +# 73| 1: [IntLiteral] 1 diff --git a/csharp/ql/test/library-tests/comments/PrintAst.qlref b/csharp/ql/test/library-tests/comments/PrintAst.qlref new file mode 100644 index 00000000000..15af8b109dd --- /dev/null +++ b/csharp/ql/test/library-tests/comments/PrintAst.qlref @@ -0,0 +1 @@ +semmle/code/csharp/PrintAst.ql \ No newline at end of file diff --git a/csharp/ql/test/library-tests/comments/RegionDirectives.expected b/csharp/ql/test/library-tests/comments/RegionDirectives.expected new file mode 100644 index 00000000000..9ede79514b6 --- /dev/null +++ b/csharp/ql/test/library-tests/comments/RegionDirectives.expected @@ -0,0 +1,2 @@ +| trivia.cs:36:9:36:22 | #region ... | fields | trivia.cs:41:9:41:18 | #endregion | +| trivia.cs:38:9:38:22 | #region ... | nested | trivia.cs:40:9:40:18 | #endregion | diff --git a/csharp/ql/test/library-tests/comments/RegionDirectives.ql b/csharp/ql/test/library-tests/comments/RegionDirectives.ql new file mode 100644 index 00000000000..ea4c7cab4ec --- /dev/null +++ b/csharp/ql/test/library-tests/comments/RegionDirectives.ql @@ -0,0 +1,6 @@ +import csharp + +query predicate regionDirectives(RegionDirective d, string name, EndRegionDirective end) { + d.getName() = name and + d.getEnd() = end +} diff --git a/csharp/ql/test/library-tests/comments/UndefineDirectives.expected b/csharp/ql/test/library-tests/comments/UndefineDirectives.expected new file mode 100644 index 00000000000..016d2623f7d --- /dev/null +++ b/csharp/ql/test/library-tests/comments/UndefineDirectives.expected @@ -0,0 +1 @@ +| trivia.cs:6:1:6:12 | #undef ... | DEBUG | diff --git a/csharp/ql/test/library-tests/comments/UndefineDirectives.ql b/csharp/ql/test/library-tests/comments/UndefineDirectives.ql new file mode 100644 index 00000000000..72e992f9373 --- /dev/null +++ b/csharp/ql/test/library-tests/comments/UndefineDirectives.ql @@ -0,0 +1,4 @@ +import csharp + +from UndefineDirective d +select d, d.getName() diff --git a/csharp/ql/test/library-tests/comments/WarningDirectives.expected b/csharp/ql/test/library-tests/comments/WarningDirectives.expected new file mode 100644 index 00000000000..b4ed32ea179 --- /dev/null +++ b/csharp/ql/test/library-tests/comments/WarningDirectives.expected @@ -0,0 +1 @@ +| trivia.cs:72:1:72:43 | #warning ... | NOTDEBUG is defined or TEST is not | diff --git a/csharp/ql/test/library-tests/comments/WarningDirectives.ql b/csharp/ql/test/library-tests/comments/WarningDirectives.ql new file mode 100644 index 00000000000..0b1dedf1d77 --- /dev/null +++ b/csharp/ql/test/library-tests/comments/WarningDirectives.ql @@ -0,0 +1,4 @@ +import csharp + +from WarningDirective d +select d, d.getMessage() diff --git a/csharp/ql/test/library-tests/comments/trivia.cs b/csharp/ql/test/library-tests/comments/trivia.cs new file mode 100644 index 00000000000..be670eac1c4 --- /dev/null +++ b/csharp/ql/test/library-tests/comments/trivia.cs @@ -0,0 +1,78 @@ +// +// Start of trivia.cs +// Unassociated +#define DEBUG + +#undef DEBUG + +using System; +using System.Collections; +using System.Collections.Generic; + +#pragma warning disable 414, CS3021 +#pragma checksum "comments1.cs" "{406EA660-64CF-4C82-B6F0-42D48172A799}" "ab007f1d23d9" // New checksum +class Tr1 +{ + static void M1() + { +#line 1 "comments1.cs" + int i; + int j; +#line default + char c; +#pragma warning restore + float f; +#line hidden // numbering not affected + string s; +#line 5 + double d; + } +} + +class Tr2 +{ + static void M1() + { + #region fields + int i; + #region nested + int j; + #endregion + #endregion + } +} + +class Tr3 +{ + static void M1() + { +#nullable disable// Sets the nullable annotation and warning contexts to disabled. +#nullable enable// Sets the nullable annotation and warning contexts to enabled. +#nullable restore// Restores the nullable annotation and warning contexts to project settings. +#nullable disable annotations// Sets the nullable annotation context to disabled. +#nullable enable annotations// Sets the nullable annotation context to enabled. +#nullable restore annotations// Restores the nullable annotation context to project settings. +#nullable disable warnings// Sets the nullable warning context to disabled. +#nullable enable warnings// Sets the nullable warning context to enabled. +#nullable restore warnings// Restores the nullable warning context to project settings. + } +} + +class Tr4 +{ + static void M1() + { +#if DEBUG +#error DEBUG is defined + var i = 0; +#if NESTED + i--; +#endif +#elif (NOTDEBUG == true) || !(TEST) +#warning NOTDEBUG is defined or TEST is not + var i = 1; +#else + var i = 2; +#endif + } +} \ No newline at end of file diff --git a/csharp/ql/test/library-tests/compilations/Compilations.expected b/csharp/ql/test/library-tests/compilations/Compilations.expected index 92905087cc3..de6c72255ed 100644 --- a/csharp/ql/test/library-tests/compilations/Compilations.expected +++ b/csharp/ql/test/library-tests/compilations/Compilations.expected @@ -35,3 +35,5 @@ references | compilation | mscorlib.dll | timings | compilation | +assembly +| compilation | Program.dll:0:0:0:0 | Program, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null | diff --git a/csharp/ql/test/library-tests/compilations/Compilations.ql b/csharp/ql/test/library-tests/compilations/Compilations.ql index e54b36c4e10..c523dea5780 100644 --- a/csharp/ql/test/library-tests/compilations/Compilations.ql +++ b/csharp/ql/test/library-tests/compilations/Compilations.ql @@ -39,3 +39,5 @@ query predicate timings(Compilation c) { c.getCpuSeconds() > 0 and c.getElapsedSeconds() > 0 } + +query predicate assembly(Compilation c, Assembly a) { c.getOutputAssembly() = a } diff --git a/csharp/ql/test/library-tests/controlflow/graph/BasicBlock.expected b/csharp/ql/test/library-tests/controlflow/graph/BasicBlock.expected index 98e4b28801f..3936ebd12ae 100644 --- a/csharp/ql/test/library-tests/controlflow/graph/BasicBlock.expected +++ b/csharp/ql/test/library-tests/controlflow/graph/BasicBlock.expected @@ -370,95 +370,87 @@ | Conditions.cs:145:27:145:29 | [b (line 143): false] "b" | Conditions.cs:146:13:146:13 | [b (line 143): false] access to parameter b | 5 | | Conditions.cs:147:13:147:49 | ...; | Conditions.cs:147:13:147:48 | call to method WriteLine | 5 | | Conditions.cs:149:13:149:49 | ...; | Conditions.cs:149:13:149:48 | call to method WriteLine | 5 | -| ExitMethods.cs:7:10:7:11 | enter M1 | ExitMethods.cs:7:10:7:11 | exit M1 | 8 | -| ExitMethods.cs:13:10:13:11 | enter M2 | ExitMethods.cs:13:10:13:11 | exit M2 | 8 | -| ExitMethods.cs:19:10:19:11 | enter M3 | ExitMethods.cs:19:10:19:11 | exit M3 | 7 | -| ExitMethods.cs:25:10:25:11 | enter M4 | ExitMethods.cs:25:10:25:11 | exit M4 | 7 | -| ExitMethods.cs:31:10:31:11 | enter M5 | ExitMethods.cs:31:10:31:11 | exit M5 | 7 | -| ExitMethods.cs:37:10:37:11 | enter M6 | ExitMethods.cs:41:13:41:30 | call to method ErrorAlways | 7 | -| ExitMethods.cs:37:10:37:11 | exit M6 (normal) | ExitMethods.cs:37:10:37:11 | exit M6 | 2 | -| ExitMethods.cs:43:9:46:9 | [exception: ArgumentException] catch (...) {...} | ExitMethods.cs:43:9:46:9 | [exception: ArgumentException] catch (...) {...} | 1 | -| ExitMethods.cs:43:9:46:9 | [exception: Exception] catch (...) {...} | ExitMethods.cs:43:9:46:9 | [exception: Exception] catch (...) {...} | 1 | -| ExitMethods.cs:44:9:46:9 | {...} | ExitMethods.cs:45:13:45:19 | return ...; | 2 | -| ExitMethods.cs:47:9:50:9 | [exception: Exception] catch (...) {...} | ExitMethods.cs:47:9:50:9 | [exception: Exception] catch (...) {...} | 1 | -| ExitMethods.cs:48:9:50:9 | {...} | ExitMethods.cs:49:13:49:19 | return ...; | 2 | -| ExitMethods.cs:53:10:53:11 | enter M7 | ExitMethods.cs:53:10:53:11 | exit M7 | 6 | -| ExitMethods.cs:59:10:59:11 | enter M8 | ExitMethods.cs:59:10:59:11 | exit M8 | 6 | -| ExitMethods.cs:65:17:65:26 | enter ErrorMaybe | ExitMethods.cs:67:13:67:13 | access to parameter b | 4 | -| ExitMethods.cs:65:17:65:26 | exit ErrorMaybe | ExitMethods.cs:65:17:65:26 | exit ErrorMaybe | 1 | -| ExitMethods.cs:65:17:65:26 | exit ErrorMaybe (normal) | ExitMethods.cs:65:17:65:26 | exit ErrorMaybe (normal) | 1 | -| ExitMethods.cs:68:19:68:33 | object creation of type Exception | ExitMethods.cs:65:17:65:26 | exit ErrorMaybe (abnormal) | 3 | -| ExitMethods.cs:71:17:71:27 | enter ErrorAlways | ExitMethods.cs:73:13:73:13 | access to parameter b | 4 | -| ExitMethods.cs:71:17:71:27 | exit ErrorAlways (abnormal) | ExitMethods.cs:71:17:71:27 | exit ErrorAlways | 2 | -| ExitMethods.cs:74:19:74:33 | object creation of type Exception | ExitMethods.cs:74:13:74:34 | throw ...; | 2 | -| ExitMethods.cs:76:41:76:43 | "b" | ExitMethods.cs:76:13:76:45 | throw ...; | 3 | -| ExitMethods.cs:79:17:79:28 | enter ErrorAlways2 | ExitMethods.cs:79:17:79:28 | exit ErrorAlways2 | 6 | -| ExitMethods.cs:84:17:84:28 | enter ErrorAlways3 | ExitMethods.cs:84:17:84:28 | exit ErrorAlways3 | 5 | -| ExitMethods.cs:86:10:86:13 | enter Exit | ExitMethods.cs:86:10:86:13 | exit Exit | 7 | -| ExitMethods.cs:91:10:91:18 | enter ExitInTry | ExitMethods.cs:91:10:91:18 | exit ExitInTry | 9 | -| ExitMethods.cs:104:10:104:24 | enter ApplicationExit | ExitMethods.cs:104:10:104:24 | exit ApplicationExit | 6 | -| ExitMethods.cs:109:13:109:21 | enter ThrowExpr | ExitMethods.cs:111:16:111:25 | ... != ... | 6 | -| ExitMethods.cs:109:13:109:21 | exit ThrowExpr | ExitMethods.cs:109:13:109:21 | exit ThrowExpr | 1 | -| ExitMethods.cs:111:29:111:29 | 1 | ExitMethods.cs:109:13:109:21 | exit ThrowExpr (normal) | 7 | -| ExitMethods.cs:111:69:111:75 | "input" | ExitMethods.cs:109:13:109:21 | exit ThrowExpr (abnormal) | 4 | -| ExitMethods.cs:114:16:114:34 | enter ExtensionMethodCall | ExitMethods.cs:116:16:116:30 | call to method Contains | 5 | -| ExitMethods.cs:116:16:116:38 | ... ? ... : ... | ExitMethods.cs:114:16:114:34 | exit ExtensionMethodCall | 4 | -| ExitMethods.cs:116:34:116:34 | 0 | ExitMethods.cs:116:34:116:34 | 0 | 1 | -| ExitMethods.cs:116:38:116:38 | 1 | ExitMethods.cs:116:38:116:38 | 1 | 1 | -| ExitMethods.cs:119:17:119:32 | enter FailingAssertion | ExitMethods.cs:121:23:121:27 | false | 4 | -| ExitMethods.cs:121:9:121:28 | [assertion failure] call to method IsTrue | ExitMethods.cs:119:17:119:32 | exit FailingAssertion | 3 | -| ExitMethods.cs:125:17:125:33 | enter FailingAssertion2 | ExitMethods.cs:125:17:125:33 | exit FailingAssertion2 | 7 | -| ExitMethods.cs:131:10:131:20 | enter AssertFalse | ExitMethods.cs:131:48:131:48 | access to parameter b | 2 | -| ExitMethods.cs:131:10:131:20 | exit AssertFalse | ExitMethods.cs:131:10:131:20 | exit AssertFalse | 1 | -| ExitMethods.cs:131:33:131:49 | [assertion failure] call to method IsFalse | ExitMethods.cs:131:10:131:20 | exit AssertFalse (abnormal) | 2 | -| ExitMethods.cs:131:33:131:49 | [assertion success] call to method IsFalse | ExitMethods.cs:131:10:131:20 | exit AssertFalse (normal) | 2 | -| ExitMethods.cs:133:17:133:33 | enter FailingAssertion3 | ExitMethods.cs:135:21:135:24 | true | 5 | -| ExitMethods.cs:135:9:135:25 | [assertion failure] call to method AssertFalse | ExitMethods.cs:133:17:133:33 | exit FailingAssertion3 | 3 | +| ExitMethods.cs:8:10:8:11 | enter M1 | ExitMethods.cs:8:10:8:11 | exit M1 | 8 | +| ExitMethods.cs:14:10:14:11 | enter M2 | ExitMethods.cs:14:10:14:11 | exit M2 | 8 | +| ExitMethods.cs:20:10:20:11 | enter M3 | ExitMethods.cs:20:10:20:11 | exit M3 | 7 | +| ExitMethods.cs:26:10:26:11 | enter M4 | ExitMethods.cs:26:10:26:11 | exit M4 | 7 | +| ExitMethods.cs:32:10:32:11 | enter M5 | ExitMethods.cs:32:10:32:11 | exit M5 | 7 | +| ExitMethods.cs:38:10:38:11 | enter M6 | ExitMethods.cs:42:13:42:30 | call to method ErrorAlways | 7 | +| ExitMethods.cs:38:10:38:11 | exit M6 (normal) | ExitMethods.cs:38:10:38:11 | exit M6 | 2 | +| ExitMethods.cs:44:9:47:9 | [exception: ArgumentException] catch (...) {...} | ExitMethods.cs:44:9:47:9 | [exception: ArgumentException] catch (...) {...} | 1 | +| ExitMethods.cs:44:9:47:9 | [exception: Exception] catch (...) {...} | ExitMethods.cs:44:9:47:9 | [exception: Exception] catch (...) {...} | 1 | +| ExitMethods.cs:45:9:47:9 | {...} | ExitMethods.cs:46:13:46:19 | return ...; | 2 | +| ExitMethods.cs:48:9:51:9 | [exception: Exception] catch (...) {...} | ExitMethods.cs:48:9:51:9 | [exception: Exception] catch (...) {...} | 1 | +| ExitMethods.cs:49:9:51:9 | {...} | ExitMethods.cs:50:13:50:19 | return ...; | 2 | +| ExitMethods.cs:54:10:54:11 | enter M7 | ExitMethods.cs:54:10:54:11 | exit M7 | 6 | +| ExitMethods.cs:60:10:60:11 | enter M8 | ExitMethods.cs:60:10:60:11 | exit M8 | 6 | +| ExitMethods.cs:66:17:66:26 | enter ErrorMaybe | ExitMethods.cs:68:13:68:13 | access to parameter b | 4 | +| ExitMethods.cs:66:17:66:26 | exit ErrorMaybe | ExitMethods.cs:66:17:66:26 | exit ErrorMaybe | 1 | +| ExitMethods.cs:66:17:66:26 | exit ErrorMaybe (normal) | ExitMethods.cs:66:17:66:26 | exit ErrorMaybe (normal) | 1 | +| ExitMethods.cs:69:19:69:33 | object creation of type Exception | ExitMethods.cs:66:17:66:26 | exit ErrorMaybe (abnormal) | 3 | +| ExitMethods.cs:72:17:72:27 | enter ErrorAlways | ExitMethods.cs:74:13:74:13 | access to parameter b | 4 | +| ExitMethods.cs:72:17:72:27 | exit ErrorAlways (abnormal) | ExitMethods.cs:72:17:72:27 | exit ErrorAlways | 2 | +| ExitMethods.cs:75:19:75:33 | object creation of type Exception | ExitMethods.cs:75:13:75:34 | throw ...; | 2 | +| ExitMethods.cs:77:41:77:43 | "b" | ExitMethods.cs:77:13:77:45 | throw ...; | 3 | +| ExitMethods.cs:80:17:80:28 | enter ErrorAlways2 | ExitMethods.cs:80:17:80:28 | exit ErrorAlways2 | 6 | +| ExitMethods.cs:85:17:85:28 | enter ErrorAlways3 | ExitMethods.cs:85:17:85:28 | exit ErrorAlways3 | 5 | +| ExitMethods.cs:87:10:87:13 | enter Exit | ExitMethods.cs:87:10:87:13 | exit Exit | 7 | +| ExitMethods.cs:92:10:92:18 | enter ExitInTry | ExitMethods.cs:92:10:92:18 | exit ExitInTry | 9 | +| ExitMethods.cs:105:10:105:24 | enter ApplicationExit | ExitMethods.cs:105:10:105:24 | exit ApplicationExit | 6 | +| ExitMethods.cs:110:13:110:21 | enter ThrowExpr | ExitMethods.cs:112:16:112:25 | ... != ... | 6 | +| ExitMethods.cs:110:13:110:21 | exit ThrowExpr | ExitMethods.cs:110:13:110:21 | exit ThrowExpr | 1 | +| ExitMethods.cs:112:29:112:29 | 1 | ExitMethods.cs:110:13:110:21 | exit ThrowExpr (normal) | 7 | +| ExitMethods.cs:112:69:112:75 | "input" | ExitMethods.cs:110:13:110:21 | exit ThrowExpr (abnormal) | 4 | +| ExitMethods.cs:115:16:115:34 | enter ExtensionMethodCall | ExitMethods.cs:117:16:117:30 | call to method Contains | 5 | +| ExitMethods.cs:117:16:117:38 | ... ? ... : ... | ExitMethods.cs:115:16:115:34 | exit ExtensionMethodCall | 4 | +| ExitMethods.cs:117:34:117:34 | 0 | ExitMethods.cs:117:34:117:34 | 0 | 1 | +| ExitMethods.cs:117:38:117:38 | 1 | ExitMethods.cs:117:38:117:38 | 1 | 1 | +| ExitMethods.cs:120:17:120:32 | enter FailingAssertion | ExitMethods.cs:122:23:122:27 | false | 4 | +| ExitMethods.cs:122:9:122:28 | [assertion failure] call to method IsTrue | ExitMethods.cs:120:17:120:32 | exit FailingAssertion | 3 | +| ExitMethods.cs:126:17:126:33 | enter FailingAssertion2 | ExitMethods.cs:126:17:126:33 | exit FailingAssertion2 | 7 | +| ExitMethods.cs:132:10:132:20 | enter AssertFalse | ExitMethods.cs:132:48:132:48 | access to parameter b | 2 | +| ExitMethods.cs:132:10:132:20 | exit AssertFalse | ExitMethods.cs:132:10:132:20 | exit AssertFalse | 1 | +| ExitMethods.cs:132:33:132:49 | [assertion failure] call to method IsFalse | ExitMethods.cs:132:10:132:20 | exit AssertFalse (abnormal) | 2 | +| ExitMethods.cs:132:33:132:49 | [assertion success] call to method IsFalse | ExitMethods.cs:132:10:132:20 | exit AssertFalse (normal) | 2 | +| ExitMethods.cs:134:17:134:33 | enter FailingAssertion3 | ExitMethods.cs:136:21:136:24 | true | 5 | +| ExitMethods.cs:136:9:136:25 | [assertion failure] call to method AssertFalse | ExitMethods.cs:134:17:134:33 | exit FailingAssertion3 | 3 | +| ExitMethods.cs:140:17:140:42 | enter ExceptionDispatchInfoThrow | ExitMethods.cs:142:13:142:13 | access to parameter b | 4 | +| ExitMethods.cs:140:17:140:42 | exit ExceptionDispatchInfoThrow (abnormal) | ExitMethods.cs:140:17:140:42 | exit ExceptionDispatchInfoThrow | 2 | +| ExitMethods.cs:143:13:143:43 | ...; | ExitMethods.cs:143:13:143:42 | call to method Throw | 3 | +| ExitMethods.cs:145:13:145:53 | ...; | ExitMethods.cs:145:13:145:52 | call to method Throw | 4 | | Extensions.cs:5:23:5:29 | enter ToInt32 | Extensions.cs:5:23:5:29 | exit ToInt32 | 7 | | Extensions.cs:10:24:10:29 | enter ToBool | Extensions.cs:10:24:10:29 | exit ToBool | 8 | | Extensions.cs:15:23:15:33 | enter CallToInt32 | Extensions.cs:15:23:15:33 | exit CallToInt32 | 5 | | Extensions.cs:20:17:20:20 | enter Main | Extensions.cs:20:17:20:20 | exit Main | 20 | -| Finally.cs:7:10:7:11 | enter M1 | Finally.cs:11:31:11:36 | "Try1" | 6 | +| Finally.cs:7:10:7:11 | enter M1 | Finally.cs:11:13:11:37 | call to method WriteLine | 7 | | Finally.cs:7:10:7:11 | exit M1 | Finally.cs:7:10:7:11 | exit M1 | 1 | -| Finally.cs:7:10:7:11 | exit M1 (abnormal) | Finally.cs:7:10:7:11 | exit M1 (abnormal) | 1 | -| Finally.cs:11:13:11:37 | call to method WriteLine | Finally.cs:11:13:11:37 | call to method WriteLine | 1 | -| Finally.cs:14:9:16:9 | [finally: exception(Exception)] {...} | Finally.cs:15:13:15:40 | [finally: exception(Exception)] call to method WriteLine | 4 | -| Finally.cs:14:9:16:9 | [finally: exception(OutOfMemoryException)] {...} | Finally.cs:15:13:15:40 | [finally: exception(OutOfMemoryException)] call to method WriteLine | 4 | +| Finally.cs:14:9:16:9 | [finally: exception(Exception)] {...} | Finally.cs:7:10:7:11 | exit M1 (abnormal) | 5 | | Finally.cs:14:9:16:9 | {...} | Finally.cs:7:10:7:11 | exit M1 (normal) | 5 | -| Finally.cs:19:10:19:11 | enter M2 | Finally.cs:23:31:23:36 | "Try2" | 6 | +| Finally.cs:19:10:19:11 | enter M2 | Finally.cs:23:13:23:37 | call to method WriteLine | 7 | | Finally.cs:19:10:19:11 | exit M2 | Finally.cs:19:10:19:11 | exit M2 | 1 | | Finally.cs:19:10:19:11 | exit M2 (abnormal) | Finally.cs:19:10:19:11 | exit M2 (abnormal) | 1 | | Finally.cs:19:10:19:11 | exit M2 (normal) | Finally.cs:19:10:19:11 | exit M2 (normal) | 1 | -| Finally.cs:23:13:23:37 | call to method WriteLine | Finally.cs:23:13:23:37 | call to method WriteLine | 1 | | Finally.cs:24:13:24:19 | return ...; | Finally.cs:50:13:50:40 | [finally: return] call to method WriteLine | 5 | | Finally.cs:26:9:29:9 | [exception: Exception] catch (...) {...} | Finally.cs:26:9:29:9 | [exception: Exception] catch (...) {...} | 1 | -| Finally.cs:26:9:29:9 | [exception: OutOfMemoryException] catch (...) {...} | Finally.cs:26:9:29:9 | [exception: OutOfMemoryException] catch (...) {...} | 1 | | Finally.cs:26:38:26:39 | [exception: Exception] IOException ex | Finally.cs:26:48:26:51 | [exception: Exception] true | 2 | | Finally.cs:27:9:29:9 | {...} | Finally.cs:50:13:50:40 | [finally: exception(IOException)] call to method WriteLine | 6 | | Finally.cs:30:9:40:9 | [exception: Exception] catch (...) {...} | Finally.cs:30:9:40:9 | [exception: Exception] catch (...) {...} | 1 | -| Finally.cs:30:9:40:9 | [exception: OutOfMemoryException] catch (...) {...} | Finally.cs:30:9:40:9 | [exception: OutOfMemoryException] catch (...) {...} | 1 | | Finally.cs:30:41:30:42 | [exception: Exception] ArgumentException ex | Finally.cs:34:21:34:24 | true | 6 | | Finally.cs:34:27:34:32 | throw ...; | Finally.cs:50:13:50:40 | [finally: exception(Exception)] call to method WriteLine | 9 | | Finally.cs:41:9:43:9 | [exception: Exception] catch (...) {...} | Finally.cs:41:9:43:9 | [exception: Exception] catch (...) {...} | 1 | -| Finally.cs:41:9:43:9 | [exception: OutOfMemoryException] catch (...) {...} | Finally.cs:41:9:43:9 | [exception: OutOfMemoryException] catch (...) {...} | 1 | | Finally.cs:42:9:43:9 | {...} | Finally.cs:50:13:50:40 | call to method WriteLine | 5 | -| Finally.cs:54:10:54:11 | enter M3 | Finally.cs:58:31:58:36 | "Try3" | 6 | +| Finally.cs:54:10:54:11 | enter M3 | Finally.cs:58:13:58:37 | call to method WriteLine | 7 | | Finally.cs:54:10:54:11 | exit M3 | Finally.cs:54:10:54:11 | exit M3 | 1 | | Finally.cs:54:10:54:11 | exit M3 (abnormal) | Finally.cs:54:10:54:11 | exit M3 (abnormal) | 1 | | Finally.cs:54:10:54:11 | exit M3 (normal) | Finally.cs:54:10:54:11 | exit M3 (normal) | 1 | -| Finally.cs:58:13:58:37 | call to method WriteLine | Finally.cs:58:13:58:37 | call to method WriteLine | 1 | | Finally.cs:59:13:59:19 | return ...; | Finally.cs:70:13:70:40 | [finally: return] call to method WriteLine | 5 | | Finally.cs:61:9:64:9 | [exception: Exception] catch (...) {...} | Finally.cs:61:9:64:9 | [exception: Exception] catch (...) {...} | 1 | -| Finally.cs:61:9:64:9 | [exception: OutOfMemoryException] catch (...) {...} | Finally.cs:61:9:64:9 | [exception: OutOfMemoryException] catch (...) {...} | 1 | | Finally.cs:61:38:61:39 | [exception: Exception] IOException ex | Finally.cs:61:48:61:51 | [exception: Exception] true | 2 | | Finally.cs:62:9:64:9 | {...} | Finally.cs:70:13:70:40 | [finally: exception(IOException)] call to method WriteLine | 6 | | Finally.cs:65:9:67:9 | [exception: Exception] catch (...) {...} | Finally.cs:65:9:67:9 | [exception: Exception] catch (...) {...} | 1 | -| Finally.cs:65:9:67:9 | [exception: OutOfMemoryException] catch (...) {...} | Finally.cs:65:9:67:9 | [exception: OutOfMemoryException] catch (...) {...} | 1 | | Finally.cs:65:26:65:26 | [exception: Exception] Exception e | Finally.cs:65:35:65:51 | [exception: Exception] ... != ... | 5 | -| Finally.cs:65:26:65:26 | [exception: OutOfMemoryException] Exception e | Finally.cs:65:35:65:51 | [exception: OutOfMemoryException] ... != ... | 5 | | Finally.cs:66:9:67:9 | {...} | Finally.cs:70:13:70:40 | call to method WriteLine | 5 | | Finally.cs:69:9:71:9 | [finally: exception(Exception)] {...} | Finally.cs:70:13:70:40 | [finally: exception(Exception)] call to method WriteLine | 4 | -| Finally.cs:69:9:71:9 | [finally: exception(OutOfMemoryException)] {...} | Finally.cs:70:13:70:40 | [finally: exception(OutOfMemoryException)] call to method WriteLine | 4 | | Finally.cs:74:10:74:11 | enter M4 | Finally.cs:77:9:100:9 | while (...) ... | 6 | | Finally.cs:74:10:74:11 | exit M4 | Finally.cs:74:10:74:11 | exit M4 | 1 | | Finally.cs:74:10:74:11 | exit M4 (abnormal) | Finally.cs:74:10:74:11 | exit M4 (abnormal) | 1 | @@ -479,12 +471,12 @@ | Finally.cs:93:31:93:45 | [finally: continue] object creation of type Exception | Finally.cs:93:31:93:45 | [finally: continue] object creation of type Exception | 1 | | Finally.cs:93:31:93:45 | [finally: return] object creation of type Exception | Finally.cs:93:31:93:45 | [finally: return] object creation of type Exception | 1 | | Finally.cs:93:31:93:45 | object creation of type Exception | Finally.cs:93:31:93:45 | object creation of type Exception | 1 | -| Finally.cs:96:17:98:17 | [finally(2): exception(Exception)] {...} | Finally.cs:97:21:97:23 | [finally(2): exception(Exception)] ...-- | 4 | -| Finally.cs:96:17:98:17 | [finally: break, finally(2): exception(Exception)] {...} | Finally.cs:97:21:97:23 | [finally: break, finally(2): exception(Exception)] ...-- | 4 | +| Finally.cs:96:17:98:17 | [finally(1): exception(Exception)] {...} | Finally.cs:97:21:97:23 | [finally(1): exception(Exception)] ...-- | 4 | +| Finally.cs:96:17:98:17 | [finally: break, finally(1): exception(Exception)] {...} | Finally.cs:97:21:97:23 | [finally: break, finally(1): exception(Exception)] ...-- | 4 | | Finally.cs:96:17:98:17 | [finally: break] {...} | Finally.cs:97:21:97:23 | [finally: break] ...-- | 4 | -| Finally.cs:96:17:98:17 | [finally: continue, finally(2): exception(Exception)] {...} | Finally.cs:97:21:97:23 | [finally: continue, finally(2): exception(Exception)] ...-- | 4 | +| Finally.cs:96:17:98:17 | [finally: continue, finally(1): exception(Exception)] {...} | Finally.cs:97:21:97:23 | [finally: continue, finally(1): exception(Exception)] ...-- | 4 | | Finally.cs:96:17:98:17 | [finally: continue] {...} | Finally.cs:97:21:97:23 | [finally: continue] ...-- | 4 | -| Finally.cs:96:17:98:17 | [finally: return, finally(2): exception(Exception)] {...} | Finally.cs:97:21:97:23 | [finally: return, finally(2): exception(Exception)] ...-- | 4 | +| Finally.cs:96:17:98:17 | [finally: return, finally(1): exception(Exception)] {...} | Finally.cs:97:21:97:23 | [finally: return, finally(1): exception(Exception)] ...-- | 4 | | Finally.cs:96:17:98:17 | [finally: return] {...} | Finally.cs:97:21:97:23 | [finally: return] ...-- | 4 | | Finally.cs:96:17:98:17 | {...} | Finally.cs:97:21:97:23 | ...-- | 4 | | Finally.cs:103:10:103:11 | enter M5 | Finally.cs:107:17:107:21 | access to field Field | 7 | @@ -528,11 +520,9 @@ | Finally.cs:117:17:117:37 | [finally: exception(OutOfMemoryException)] ...; | Finally.cs:117:17:117:36 | [finally: exception(OutOfMemoryException)] call to method WriteLine | 3 | | Finally.cs:117:17:117:37 | [finally: return] ...; | Finally.cs:117:17:117:36 | [finally: return] call to method WriteLine | 3 | | Finally.cs:121:10:121:11 | enter M6 | Finally.cs:121:10:121:11 | exit M6 | 12 | -| Finally.cs:133:10:133:11 | enter M7 | Finally.cs:137:31:137:35 | "Try" | 6 | +| Finally.cs:133:10:133:11 | enter M7 | Finally.cs:137:13:137:36 | call to method WriteLine | 7 | | Finally.cs:133:10:133:11 | exit M7 (abnormal) | Finally.cs:133:10:133:11 | exit M7 | 2 | -| Finally.cs:137:13:137:36 | call to method WriteLine | Finally.cs:137:13:137:36 | call to method WriteLine | 1 | | Finally.cs:140:9:143:9 | [finally: exception(Exception)] {...} | Finally.cs:141:13:141:44 | [finally: exception(Exception)] throw ...; | 4 | -| Finally.cs:140:9:143:9 | [finally: exception(OutOfMemoryException)] {...} | Finally.cs:141:13:141:44 | [finally: exception(OutOfMemoryException)] throw ...; | 4 | | Finally.cs:140:9:143:9 | {...} | Finally.cs:141:13:141:44 | throw ...; | 4 | | Finally.cs:147:10:147:11 | enter M8 | Finally.cs:151:17:151:28 | ... == ... | 8 | | Finally.cs:147:10:147:11 | exit M8 | Finally.cs:147:10:147:11 | exit M8 | 1 | @@ -548,30 +538,21 @@ | Finally.cs:159:21:159:45 | [finally: exception(ArgumentNullException)] throw ...; | Finally.cs:159:21:159:45 | [finally: exception(ArgumentNullException)] throw ...; | 1 | | Finally.cs:159:21:159:45 | [finally: exception(Exception)] throw ...; | Finally.cs:159:21:159:45 | [finally: exception(Exception)] throw ...; | 1 | | Finally.cs:159:21:159:45 | throw ...; | Finally.cs:159:21:159:45 | throw ...; | 1 | -| Finally.cs:159:27:159:44 | [finally: exception(ArgumentNullException)] object creation of type Exception | Finally.cs:159:27:159:44 | [finally: exception(ArgumentNullException)] object creation of type Exception | 1 | -| Finally.cs:159:27:159:44 | [finally: exception(Exception)] object creation of type Exception | Finally.cs:159:27:159:44 | [finally: exception(Exception)] object creation of type Exception | 1 | -| Finally.cs:159:27:159:44 | object creation of type Exception | Finally.cs:159:27:159:44 | object creation of type Exception | 1 | -| Finally.cs:159:41:159:43 | "1" | Finally.cs:159:41:159:43 | "1" | 1 | -| Finally.cs:159:41:159:43 | [finally: exception(ArgumentNullException)] "1" | Finally.cs:159:41:159:43 | [finally: exception(ArgumentNullException)] "1" | 1 | -| Finally.cs:159:41:159:43 | [finally: exception(Exception)] "1" | Finally.cs:159:41:159:43 | [finally: exception(Exception)] "1" | 1 | +| Finally.cs:159:41:159:43 | "1" | Finally.cs:159:27:159:44 | object creation of type Exception | 2 | +| Finally.cs:159:41:159:43 | [finally: exception(ArgumentNullException)] "1" | Finally.cs:159:27:159:44 | [finally: exception(ArgumentNullException)] object creation of type Exception | 2 | +| Finally.cs:159:41:159:43 | [finally: exception(Exception)] "1" | Finally.cs:159:27:159:44 | [finally: exception(Exception)] object creation of type Exception | 2 | | Finally.cs:161:13:164:13 | [exception: Exception] catch (...) {...} | Finally.cs:161:13:164:13 | [exception: Exception] catch (...) {...} | 1 | | Finally.cs:161:13:164:13 | [exception: NullReferenceException] catch (...) {...} | Finally.cs:161:13:164:13 | [exception: NullReferenceException] catch (...) {...} | 1 | -| Finally.cs:161:13:164:13 | [exception: OutOfMemoryException] catch (...) {...} | Finally.cs:161:13:164:13 | [exception: OutOfMemoryException] catch (...) {...} | 1 | | Finally.cs:161:13:164:13 | [finally: exception(ArgumentNullException), exception: Exception] catch (...) {...} | Finally.cs:161:13:164:13 | [finally: exception(ArgumentNullException), exception: Exception] catch (...) {...} | 1 | | Finally.cs:161:13:164:13 | [finally: exception(ArgumentNullException), exception: NullReferenceException] catch (...) {...} | Finally.cs:161:13:164:13 | [finally: exception(ArgumentNullException), exception: NullReferenceException] catch (...) {...} | 1 | -| Finally.cs:161:13:164:13 | [finally: exception(ArgumentNullException), exception: OutOfMemoryException] catch (...) {...} | Finally.cs:161:13:164:13 | [finally: exception(ArgumentNullException), exception: OutOfMemoryException] catch (...) {...} | 1 | | Finally.cs:161:13:164:13 | [finally: exception(Exception), exception: Exception] catch (...) {...} | Finally.cs:161:13:164:13 | [finally: exception(Exception), exception: Exception] catch (...) {...} | 1 | | Finally.cs:161:13:164:13 | [finally: exception(Exception), exception: NullReferenceException] catch (...) {...} | Finally.cs:161:13:164:13 | [finally: exception(Exception), exception: NullReferenceException] catch (...) {...} | 1 | -| Finally.cs:161:13:164:13 | [finally: exception(Exception), exception: OutOfMemoryException] catch (...) {...} | Finally.cs:161:13:164:13 | [finally: exception(Exception), exception: OutOfMemoryException] catch (...) {...} | 1 | | Finally.cs:161:30:161:30 | [exception: Exception] Exception e | Finally.cs:161:39:161:54 | [exception: Exception] ... == ... | 5 | | Finally.cs:161:30:161:30 | [exception: NullReferenceException] Exception e | Finally.cs:161:39:161:54 | [exception: NullReferenceException] ... == ... | 5 | -| Finally.cs:161:30:161:30 | [exception: OutOfMemoryException] Exception e | Finally.cs:161:39:161:54 | [exception: OutOfMemoryException] ... == ... | 5 | | Finally.cs:161:30:161:30 | [finally: exception(ArgumentNullException), exception: Exception] Exception e | Finally.cs:161:39:161:54 | [finally: exception(ArgumentNullException), exception: Exception] ... == ... | 5 | | Finally.cs:161:30:161:30 | [finally: exception(ArgumentNullException), exception: NullReferenceException] Exception e | Finally.cs:161:39:161:54 | [finally: exception(ArgumentNullException), exception: NullReferenceException] ... == ... | 5 | -| Finally.cs:161:30:161:30 | [finally: exception(ArgumentNullException), exception: OutOfMemoryException] Exception e | Finally.cs:161:39:161:54 | [finally: exception(ArgumentNullException), exception: OutOfMemoryException] ... == ... | 5 | | Finally.cs:161:30:161:30 | [finally: exception(Exception), exception: Exception] Exception e | Finally.cs:161:39:161:54 | [finally: exception(Exception), exception: Exception] ... == ... | 5 | | Finally.cs:161:30:161:30 | [finally: exception(Exception), exception: NullReferenceException] Exception e | Finally.cs:161:39:161:54 | [finally: exception(Exception), exception: NullReferenceException] ... == ... | 5 | -| Finally.cs:161:30:161:30 | [finally: exception(Exception), exception: OutOfMemoryException] Exception e | Finally.cs:161:39:161:54 | [finally: exception(Exception), exception: OutOfMemoryException] ... == ... | 5 | | Finally.cs:162:13:164:13 | [finally: exception(ArgumentNullException)] {...} | Finally.cs:163:17:163:42 | [finally: exception(ArgumentNullException)] call to method WriteLine | 6 | | Finally.cs:162:13:164:13 | [finally: exception(Exception)] {...} | Finally.cs:163:17:163:42 | [finally: exception(Exception)] call to method WriteLine | 6 | | Finally.cs:162:13:164:13 | {...} | Finally.cs:163:17:163:42 | call to method WriteLine | 6 | @@ -613,34 +594,59 @@ | Finally.cs:199:27:199:42 | object creation of type ExceptionA | Finally.cs:199:27:199:42 | object creation of type ExceptionA | 1 | | Finally.cs:202:9:212:9 | [finally: exception(Exception)] {...} | Finally.cs:205:21:205:22 | [finally: exception(Exception)] access to parameter b2 | 5 | | Finally.cs:202:9:212:9 | {...} | Finally.cs:205:21:205:22 | access to parameter b2 | 5 | -| Finally.cs:205:25:205:47 | [finally: exception(Exception)] throw ...; | Finally.cs:209:21:209:22 | [finally: exception(Exception), finally(2): exception(ExceptionB)] access to parameter b3 | 4 | -| Finally.cs:205:25:205:47 | [finally: exception(ExceptionA)] throw ...; | Finally.cs:209:21:209:22 | [finally: exception(ExceptionA), finally(2): exception(ExceptionB)] access to parameter b3 | 4 | -| Finally.cs:205:25:205:47 | throw ...; | Finally.cs:209:21:209:22 | [finally(2): exception(ExceptionB)] access to parameter b3 | 4 | +| Finally.cs:205:25:205:47 | [finally: exception(Exception)] throw ...; | Finally.cs:209:21:209:22 | [finally: exception(Exception), finally(1): exception(ExceptionB)] access to parameter b3 | 4 | +| Finally.cs:205:25:205:47 | [finally: exception(ExceptionA)] throw ...; | Finally.cs:209:21:209:22 | [finally: exception(ExceptionA), finally(1): exception(ExceptionB)] access to parameter b3 | 4 | +| Finally.cs:205:25:205:47 | throw ...; | Finally.cs:209:21:209:22 | [finally(1): exception(ExceptionB)] access to parameter b3 | 4 | | Finally.cs:205:31:205:46 | [finally: exception(Exception)] object creation of type ExceptionB | Finally.cs:205:31:205:46 | [finally: exception(Exception)] object creation of type ExceptionB | 1 | | Finally.cs:205:31:205:46 | [finally: exception(ExceptionA)] object creation of type ExceptionB | Finally.cs:205:31:205:46 | [finally: exception(ExceptionA)] object creation of type ExceptionB | 1 | | Finally.cs:205:31:205:46 | object creation of type ExceptionB | Finally.cs:205:31:205:46 | object creation of type ExceptionB | 1 | -| Finally.cs:208:13:210:13 | [finally(2): exception(Exception)] {...} | Finally.cs:209:21:209:22 | [finally(2): exception(Exception)] access to parameter b3 | 3 | -| Finally.cs:208:13:210:13 | [finally: exception(Exception), finally(2): exception(Exception)] {...} | Finally.cs:209:21:209:22 | [finally: exception(Exception), finally(2): exception(Exception)] access to parameter b3 | 3 | +| Finally.cs:208:13:210:13 | [finally(1): exception(Exception)] {...} | Finally.cs:209:21:209:22 | [finally(1): exception(Exception)] access to parameter b3 | 3 | +| Finally.cs:208:13:210:13 | [finally: exception(Exception), finally(1): exception(Exception)] {...} | Finally.cs:209:21:209:22 | [finally: exception(Exception), finally(1): exception(Exception)] access to parameter b3 | 3 | | Finally.cs:208:13:210:13 | [finally: exception(Exception)] {...} | Finally.cs:209:21:209:22 | [finally: exception(Exception)] access to parameter b3 | 3 | -| Finally.cs:208:13:210:13 | [finally: exception(ExceptionA), finally(2): exception(Exception)] {...} | Finally.cs:209:21:209:22 | [finally: exception(ExceptionA), finally(2): exception(Exception)] access to parameter b3 | 3 | +| Finally.cs:208:13:210:13 | [finally: exception(ExceptionA), finally(1): exception(Exception)] {...} | Finally.cs:209:21:209:22 | [finally: exception(ExceptionA), finally(1): exception(Exception)] access to parameter b3 | 3 | | Finally.cs:208:13:210:13 | [finally: exception(ExceptionA)] {...} | Finally.cs:209:21:209:22 | [finally: exception(ExceptionA)] access to parameter b3 | 3 | | Finally.cs:208:13:210:13 | {...} | Finally.cs:209:21:209:22 | access to parameter b3 | 3 | -| Finally.cs:209:31:209:46 | [finally(2): exception(Exception)] object creation of type ExceptionC | Finally.cs:209:25:209:47 | [finally(2): exception(Exception)] throw ...; | 2 | -| Finally.cs:209:31:209:46 | [finally(2): exception(ExceptionB)] object creation of type ExceptionC | Finally.cs:209:25:209:47 | [finally(2): exception(ExceptionB)] throw ...; | 2 | -| Finally.cs:209:31:209:46 | [finally: exception(Exception), finally(2): exception(Exception)] object creation of type ExceptionC | Finally.cs:209:25:209:47 | [finally: exception(Exception), finally(2): exception(Exception)] throw ...; | 2 | -| Finally.cs:209:31:209:46 | [finally: exception(Exception), finally(2): exception(ExceptionB)] object creation of type ExceptionC | Finally.cs:209:25:209:47 | [finally: exception(Exception), finally(2): exception(ExceptionB)] throw ...; | 2 | +| Finally.cs:209:31:209:46 | [finally(1): exception(Exception)] object creation of type ExceptionC | Finally.cs:209:25:209:47 | [finally(1): exception(Exception)] throw ...; | 2 | +| Finally.cs:209:31:209:46 | [finally(1): exception(ExceptionB)] object creation of type ExceptionC | Finally.cs:209:25:209:47 | [finally(1): exception(ExceptionB)] throw ...; | 2 | +| Finally.cs:209:31:209:46 | [finally: exception(Exception), finally(1): exception(Exception)] object creation of type ExceptionC | Finally.cs:209:25:209:47 | [finally: exception(Exception), finally(1): exception(Exception)] throw ...; | 2 | +| Finally.cs:209:31:209:46 | [finally: exception(Exception), finally(1): exception(ExceptionB)] object creation of type ExceptionC | Finally.cs:209:25:209:47 | [finally: exception(Exception), finally(1): exception(ExceptionB)] throw ...; | 2 | | Finally.cs:209:31:209:46 | [finally: exception(Exception)] object creation of type ExceptionC | Finally.cs:209:25:209:47 | [finally: exception(Exception)] throw ...; | 2 | -| Finally.cs:209:31:209:46 | [finally: exception(ExceptionA), finally(2): exception(Exception)] object creation of type ExceptionC | Finally.cs:209:25:209:47 | [finally: exception(ExceptionA), finally(2): exception(Exception)] throw ...; | 2 | -| Finally.cs:209:31:209:46 | [finally: exception(ExceptionA), finally(2): exception(ExceptionB)] object creation of type ExceptionC | Finally.cs:209:25:209:47 | [finally: exception(ExceptionA), finally(2): exception(ExceptionB)] throw ...; | 2 | +| Finally.cs:209:31:209:46 | [finally: exception(ExceptionA), finally(1): exception(Exception)] object creation of type ExceptionC | Finally.cs:209:25:209:47 | [finally: exception(ExceptionA), finally(1): exception(Exception)] throw ...; | 2 | +| Finally.cs:209:31:209:46 | [finally: exception(ExceptionA), finally(1): exception(ExceptionB)] object creation of type ExceptionC | Finally.cs:209:25:209:47 | [finally: exception(ExceptionA), finally(1): exception(ExceptionB)] throw ...; | 2 | | Finally.cs:209:31:209:46 | [finally: exception(ExceptionA)] object creation of type ExceptionC | Finally.cs:209:25:209:47 | [finally: exception(ExceptionA)] throw ...; | 2 | | Finally.cs:209:31:209:46 | object creation of type ExceptionC | Finally.cs:209:25:209:47 | throw ...; | 2 | | Finally.cs:211:13:211:29 | ...; | Finally.cs:195:10:195:12 | exit M10 (normal) | 9 | | Finally.cs:211:13:211:29 | [finally: exception(Exception)] ...; | Finally.cs:211:13:211:28 | [finally: exception(Exception)] ... = ... | 4 | | Finally.cs:211:13:211:29 | [finally: exception(ExceptionA)] ...; | Finally.cs:211:13:211:28 | [finally: exception(ExceptionA)] ... = ... | 4 | -| Finally.cs:216:10:216:12 | enter M11 | Finally.cs:220:31:220:35 | "Try" | 6 | -| Finally.cs:220:13:220:36 | call to method WriteLine | Finally.cs:220:13:220:36 | call to method WriteLine | 1 | +| Finally.cs:216:10:216:12 | enter M11 | Finally.cs:220:13:220:36 | call to method WriteLine | 7 | | Finally.cs:222:9:225:9 | catch {...} | Finally.cs:224:13:224:38 | call to method WriteLine | 5 | | Finally.cs:227:9:229:9 | {...} | Finally.cs:216:10:216:12 | exit M11 | 9 | +| Finally.cs:233:10:233:12 | enter M12 | Finally.cs:239:21:239:22 | access to parameter b1 | 8 | +| Finally.cs:233:10:233:12 | exit M12 | Finally.cs:233:10:233:12 | exit M12 | 1 | +| Finally.cs:233:10:233:12 | exit M12 (abnormal) | Finally.cs:233:10:233:12 | exit M12 (abnormal) | 1 | +| Finally.cs:240:21:240:43 | throw ...; | Finally.cs:246:25:246:26 | [finally: exception(ExceptionA)] access to parameter b2 | 6 | +| Finally.cs:240:27:240:42 | object creation of type ExceptionA | Finally.cs:240:27:240:42 | object creation of type ExceptionA | 1 | +| Finally.cs:243:13:253:13 | [finally: exception(Exception)] {...} | Finally.cs:246:25:246:26 | [finally: exception(Exception)] access to parameter b2 | 5 | +| Finally.cs:243:13:253:13 | {...} | Finally.cs:246:25:246:26 | access to parameter b2 | 5 | +| Finally.cs:247:25:247:47 | [finally: exception(Exception)] throw ...; | Finally.cs:251:21:251:54 | [finally: exception(Exception), finally(1): exception(ExceptionA)] call to method WriteLine | 5 | +| Finally.cs:247:25:247:47 | [finally: exception(ExceptionA)] throw ...; | Finally.cs:251:21:251:54 | [finally: exception(ExceptionA), finally(1): exception(ExceptionA)] call to method WriteLine | 5 | +| Finally.cs:247:25:247:47 | throw ...; | Finally.cs:251:21:251:54 | [finally(1): exception(ExceptionA)] call to method WriteLine | 5 | +| Finally.cs:247:31:247:46 | [finally: exception(Exception)] object creation of type ExceptionA | Finally.cs:247:31:247:46 | [finally: exception(Exception)] object creation of type ExceptionA | 1 | +| Finally.cs:247:31:247:46 | [finally: exception(ExceptionA)] object creation of type ExceptionA | Finally.cs:247:31:247:46 | [finally: exception(ExceptionA)] object creation of type ExceptionA | 1 | +| Finally.cs:247:31:247:46 | object creation of type ExceptionA | Finally.cs:247:31:247:46 | object creation of type ExceptionA | 1 | +| Finally.cs:250:17:252:17 | [finally(1): exception(Exception)] {...} | Finally.cs:251:21:251:54 | [finally(1): exception(Exception)] call to method WriteLine | 4 | +| Finally.cs:250:17:252:17 | [finally: exception(Exception), finally(1): exception(Exception)] {...} | Finally.cs:251:21:251:54 | [finally: exception(Exception), finally(1): exception(Exception)] call to method WriteLine | 4 | +| Finally.cs:250:17:252:17 | [finally: exception(Exception)] {...} | Finally.cs:251:21:251:54 | [finally: exception(Exception)] call to method WriteLine | 4 | +| Finally.cs:250:17:252:17 | [finally: exception(ExceptionA), finally(1): exception(Exception)] {...} | Finally.cs:251:21:251:54 | [finally: exception(ExceptionA), finally(1): exception(Exception)] call to method WriteLine | 4 | +| Finally.cs:250:17:252:17 | [finally: exception(ExceptionA)] {...} | Finally.cs:251:21:251:54 | [finally: exception(ExceptionA)] call to method WriteLine | 4 | +| Finally.cs:250:17:252:17 | {...} | Finally.cs:254:13:254:44 | call to method WriteLine | 7 | +| Finally.cs:257:9:259:9 | [finally: exception(Exception)] {...} | Finally.cs:258:13:258:46 | [finally: exception(Exception)] call to method WriteLine | 4 | +| Finally.cs:257:9:259:9 | [finally: exception(ExceptionA)] {...} | Finally.cs:258:13:258:46 | [finally: exception(ExceptionA)] call to method WriteLine | 4 | +| Finally.cs:257:9:259:9 | {...} | Finally.cs:233:10:233:12 | exit M12 (normal) | 8 | +| Finally.cs:263:10:263:12 | enter M13 | Finally.cs:267:13:267:34 | call to method WriteLine | 7 | +| Finally.cs:263:10:263:12 | exit M13 | Finally.cs:263:10:263:12 | exit M13 | 1 | +| Finally.cs:270:9:273:9 | [finally: exception(Exception)] {...} | Finally.cs:263:10:263:12 | exit M13 (abnormal) | 10 | +| Finally.cs:270:9:273:9 | {...} | Finally.cs:263:10:263:12 | exit M13 (normal) | 10 | | Foreach.cs:6:10:6:11 | enter M1 | Foreach.cs:8:29:8:32 | access to parameter args | 3 | | Foreach.cs:6:10:6:11 | exit M1 (normal) | Foreach.cs:6:10:6:11 | exit M1 | 2 | | Foreach.cs:8:9:9:13 | foreach (... ... in ...) ... | Foreach.cs:8:9:9:13 | foreach (... ... in ...) ... | 1 | @@ -922,11 +928,17 @@ | NullCoalescing.cs:15:31:15:31 | 0 | NullCoalescing.cs:16:17:16:18 | "" | 5 | | NullCoalescing.cs:16:17:16:25 | ... ?? ... | NullCoalescing.cs:17:13:17:19 | (...) ... | 5 | | NullCoalescing.cs:17:13:17:24 | ... ?? ... | NullCoalescing.cs:13:10:13:11 | exit M6 | 4 | -| Patterns.cs:5:10:5:13 | enter Test | Patterns.cs:8:13:8:23 | ... is ... | 9 | +| Patterns.cs:5:10:5:11 | enter M1 | Patterns.cs:8:18:8:23 | Int32 i1 | 8 | +| Patterns.cs:8:13:8:23 | [false] ... is ... | Patterns.cs:8:13:8:23 | [false] ... is ... | 1 | +| Patterns.cs:8:13:8:23 | [true] ... is ... | Patterns.cs:8:13:8:23 | [true] ... is ... | 1 | | Patterns.cs:9:9:11:9 | {...} | Patterns.cs:10:13:10:42 | call to method WriteLine | 6 | -| Patterns.cs:12:14:18:9 | if (...) ... | Patterns.cs:12:18:12:31 | ... is ... | 4 | +| Patterns.cs:12:14:18:9 | if (...) ... | Patterns.cs:12:23:12:31 | String s1 | 3 | +| Patterns.cs:12:18:12:31 | [false] ... is ... | Patterns.cs:12:18:12:31 | [false] ... is ... | 1 | +| Patterns.cs:12:18:12:31 | [true] ... is ... | Patterns.cs:12:18:12:31 | [true] ... is ... | 1 | | Patterns.cs:13:9:15:9 | {...} | Patterns.cs:14:13:14:45 | call to method WriteLine | 6 | -| Patterns.cs:16:14:18:9 | if (...) ... | Patterns.cs:16:18:16:28 | ... is ... | 4 | +| Patterns.cs:16:14:18:9 | if (...) ... | Patterns.cs:16:23:16:28 | Object v1 | 3 | +| Patterns.cs:16:18:16:28 | [false] ... is ... | Patterns.cs:16:18:16:28 | [false] ... is ... | 1 | +| Patterns.cs:16:18:16:28 | [true] ... is ... | Patterns.cs:16:18:16:28 | [true] ... is ... | 1 | | Patterns.cs:17:9:18:9 | {...} | Patterns.cs:17:9:18:9 | {...} | 1 | | Patterns.cs:20:9:38:9 | switch (...) {...} | Patterns.cs:22:18:22:22 | "xyz" | 4 | | Patterns.cs:23:17:23:22 | break; | Patterns.cs:23:17:23:22 | break; | 1 | @@ -940,14 +952,86 @@ | Patterns.cs:33:13:33:24 | case ...: | Patterns.cs:33:18:33:23 | Object v2 | 2 | | Patterns.cs:34:17:34:22 | break; | Patterns.cs:34:17:34:22 | break; | 1 | | Patterns.cs:35:13:35:20 | default: | Patterns.cs:37:17:37:22 | break; | 5 | -| Patterns.cs:40:9:42:9 | switch (...) {...} | Patterns.cs:5:10:5:13 | exit Test | 4 | +| Patterns.cs:40:9:42:9 | switch (...) {...} | Patterns.cs:5:10:5:11 | exit M1 | 4 | +| Patterns.cs:47:24:47:25 | enter M2 | Patterns.cs:47:24:47:25 | exit M2 | 7 | +| Patterns.cs:50:24:50:25 | enter M3 | Patterns.cs:51:18:51:21 | null | 3 | +| Patterns.cs:51:9:51:21 | [false] ... is ... | Patterns.cs:51:9:51:21 | [false] ... is ... | 1 | +| Patterns.cs:51:9:51:21 | [true] ... is ... | Patterns.cs:51:9:51:21 | [true] ... is ... | 1 | +| Patterns.cs:51:9:51:39 | ... ? ... : ... | Patterns.cs:50:24:50:25 | exit M3 | 3 | +| Patterns.cs:51:14:51:21 | [match] not ... | Patterns.cs:51:14:51:21 | [match] not ... | 1 | +| Patterns.cs:51:14:51:21 | [no-match] not ... | Patterns.cs:51:14:51:21 | [no-match] not ... | 1 | +| Patterns.cs:51:25:51:25 | access to parameter c | Patterns.cs:51:25:51:30 | ... is ... | 3 | +| Patterns.cs:51:34:51:34 | access to parameter c | Patterns.cs:51:34:51:39 | ... is ... | 3 | +| Patterns.cs:53:24:53:25 | enter M4 | Patterns.cs:54:18:54:37 | Patterns u | 3 | +| Patterns.cs:54:18:54:37 | { ... } | Patterns.cs:53:24:53:25 | exit M4 | 5 | +| Patterns.cs:54:27:54:35 | [match] { ... } | Patterns.cs:54:27:54:35 | [match] { ... } | 1 | +| Patterns.cs:54:27:54:35 | [no-match] { ... } | Patterns.cs:54:27:54:35 | [no-match] { ... } | 1 | +| Patterns.cs:54:33:54:33 | 1 | Patterns.cs:54:33:54:33 | 1 | 1 | +| Patterns.cs:56:26:56:27 | enter M5 | Patterns.cs:60:17:60:17 | 1 | 4 | +| Patterns.cs:58:16:62:9 | ... switch { ... } | Patterns.cs:56:26:56:27 | exit M5 | 4 | +| Patterns.cs:60:13:60:17 | [match] not ... | Patterns.cs:60:13:60:17 | [match] not ... | 1 | +| Patterns.cs:60:13:60:17 | [no-match] not ... | Patterns.cs:60:13:60:17 | [no-match] not ... | 1 | +| Patterns.cs:60:22:60:28 | "not 1" | Patterns.cs:60:13:60:28 | ... => ... | 2 | +| Patterns.cs:61:13:61:13 | _ | Patterns.cs:61:13:61:13 | _ | 1 | +| Patterns.cs:61:18:61:24 | "other" | Patterns.cs:61:13:61:24 | ... => ... | 2 | +| Patterns.cs:65:26:65:27 | enter M6 | Patterns.cs:69:17:69:17 | 2 | 4 | +| Patterns.cs:69:13:69:17 | [no-match] not ... | Patterns.cs:69:13:69:17 | [no-match] not ... | 1 | +| Patterns.cs:70:13:70:13 | 2 | Patterns.cs:70:13:70:13 | 2 | 1 | +| Patterns.cs:70:18:70:27 | "possible" | Patterns.cs:65:26:65:27 | exit M6 | 6 | +| Patterns.cs:74:26:74:27 | enter M7 | Patterns.cs:78:13:78:15 | > ... | 5 | +| Patterns.cs:76:16:82:9 | ... switch { ... } | Patterns.cs:74:26:74:27 | exit M7 | 4 | +| Patterns.cs:78:20:78:24 | "> 1" | Patterns.cs:78:13:78:24 | ... => ... | 2 | +| Patterns.cs:79:15:79:15 | 0 | Patterns.cs:79:13:79:15 | < ... | 2 | +| Patterns.cs:79:20:79:24 | "< 0" | Patterns.cs:79:13:79:24 | ... => ... | 2 | +| Patterns.cs:80:13:80:13 | 1 | Patterns.cs:80:13:80:13 | 1 | 1 | +| Patterns.cs:80:18:80:20 | "1" | Patterns.cs:80:13:80:20 | ... => ... | 2 | +| Patterns.cs:81:13:81:13 | _ | Patterns.cs:81:13:81:13 | _ | 1 | +| Patterns.cs:81:18:81:20 | "0" | Patterns.cs:81:13:81:20 | ... => ... | 2 | +| Patterns.cs:85:26:85:27 | enter M8 | Patterns.cs:85:44:85:44 | 1 | 3 | +| Patterns.cs:85:39:85:53 | [false] ... is ... | Patterns.cs:85:39:85:53 | [false] ... is ... | 1 | +| Patterns.cs:85:39:85:53 | [true] ... is ... | Patterns.cs:85:39:85:53 | [true] ... is ... | 1 | +| Patterns.cs:85:39:85:69 | ... ? ... : ... | Patterns.cs:85:26:85:27 | exit M8 | 3 | +| Patterns.cs:85:44:85:53 | [match] ... or ... | Patterns.cs:85:44:85:53 | [match] ... or ... | 1 | +| Patterns.cs:85:44:85:53 | [no-match] ... or ... | Patterns.cs:85:44:85:53 | [no-match] ... or ... | 1 | +| Patterns.cs:85:49:85:53 | [match] not ... | Patterns.cs:85:49:85:53 | [match] not ... | 1 | +| Patterns.cs:85:49:85:53 | [no-match] not ... | Patterns.cs:85:49:85:53 | [no-match] not ... | 1 | +| Patterns.cs:85:53:85:53 | 2 | Patterns.cs:85:53:85:53 | 2 | 1 | +| Patterns.cs:85:57:85:63 | "not 2" | Patterns.cs:85:57:85:63 | "not 2" | 1 | +| Patterns.cs:85:67:85:69 | "2" | Patterns.cs:85:67:85:69 | "2" | 1 | +| Patterns.cs:87:26:87:27 | enter M9 | Patterns.cs:87:44:87:44 | 1 | 3 | +| Patterns.cs:87:39:87:54 | [false] ... is ... | Patterns.cs:87:39:87:54 | [false] ... is ... | 1 | +| Patterns.cs:87:39:87:54 | [true] ... is ... | Patterns.cs:87:39:87:54 | [true] ... is ... | 1 | +| Patterns.cs:87:39:87:70 | ... ? ... : ... | Patterns.cs:87:26:87:27 | exit M9 | 3 | +| Patterns.cs:87:44:87:54 | [match] ... and ... | Patterns.cs:87:44:87:54 | [match] ... and ... | 1 | +| Patterns.cs:87:44:87:54 | [no-match] ... and ... | Patterns.cs:87:44:87:54 | [no-match] ... and ... | 1 | +| Patterns.cs:87:50:87:54 | [match] not ... | Patterns.cs:87:50:87:54 | [match] not ... | 1 | +| Patterns.cs:87:50:87:54 | [no-match] not ... | Patterns.cs:87:50:87:54 | [no-match] not ... | 1 | +| Patterns.cs:87:54:87:54 | 2 | Patterns.cs:87:54:87:54 | 2 | 1 | +| Patterns.cs:87:58:87:60 | "1" | Patterns.cs:87:58:87:60 | "1" | 1 | +| Patterns.cs:87:64:87:70 | "not 1" | Patterns.cs:87:64:87:70 | "not 1" | 1 | +| Patterns.cs:93:17:93:19 | enter M10 | Patterns.cs:95:29:95:31 | access to constant A | 5 | +| Patterns.cs:93:17:93:19 | exit M10 (normal) | Patterns.cs:93:17:93:19 | exit M10 | 2 | +| Patterns.cs:95:13:95:40 | [false] ... is ... | Patterns.cs:95:13:95:40 | [false] ... is ... | 1 | +| Patterns.cs:95:13:95:40 | [true] ... is ... | Patterns.cs:95:13:95:40 | [true] ... is ... | 1 | +| Patterns.cs:95:21:95:40 | [match] { ... } | Patterns.cs:95:21:95:40 | [match] { ... } | 1 | +| Patterns.cs:95:21:95:40 | [match] { ... } | Patterns.cs:95:21:95:40 | [match] { ... } | 1 | +| Patterns.cs:95:21:95:40 | [no-match] { ... } | Patterns.cs:95:21:95:40 | [no-match] { ... } | 1 | +| Patterns.cs:95:21:95:40 | [no-match] { ... } | Patterns.cs:95:21:95:40 | [no-match] { ... } | 1 | +| Patterns.cs:95:29:95:38 | [match] ... or ... | Patterns.cs:95:29:95:38 | [match] ... or ... | 1 | +| Patterns.cs:95:29:95:38 | [no-match] ... or ... | Patterns.cs:95:29:95:38 | [no-match] ... or ... | 1 | +| Patterns.cs:95:36:95:38 | access to constant B | Patterns.cs:95:36:95:38 | access to constant B | 1 | +| Patterns.cs:96:9:98:9 | {...} | Patterns.cs:97:13:97:38 | call to method WriteLine | 4 | | PostDominance.cs:5:10:5:11 | enter M1 | PostDominance.cs:5:10:5:11 | exit M1 | 7 | -| PostDominance.cs:10:10:10:11 | enter M2 | PostDominance.cs:12:13:12:21 | ... is ... | 6 | +| PostDominance.cs:10:10:10:11 | enter M2 | PostDominance.cs:12:18:12:21 | null | 5 | | PostDominance.cs:10:10:10:11 | exit M2 (normal) | PostDominance.cs:10:10:10:11 | exit M2 | 2 | +| PostDominance.cs:12:13:12:21 | [false] ... is ... | PostDominance.cs:12:13:12:21 | [false] ... is ... | 1 | +| PostDominance.cs:12:13:12:21 | [true] ... is ... | PostDominance.cs:12:13:12:21 | [true] ... is ... | 1 | | PostDominance.cs:13:13:13:19 | return ...; | PostDominance.cs:13:13:13:19 | return ...; | 1 | | PostDominance.cs:14:9:14:29 | ...; | PostDominance.cs:14:9:14:28 | call to method WriteLine | 3 | -| PostDominance.cs:17:10:17:11 | enter M3 | PostDominance.cs:19:13:19:21 | ... is ... | 6 | +| PostDominance.cs:17:10:17:11 | enter M3 | PostDominance.cs:19:18:19:21 | null | 5 | | PostDominance.cs:17:10:17:11 | exit M3 | PostDominance.cs:17:10:17:11 | exit M3 | 1 | +| PostDominance.cs:19:13:19:21 | [false] ... is ... | PostDominance.cs:19:13:19:21 | [false] ... is ... | 1 | +| PostDominance.cs:19:13:19:21 | [true] ... is ... | PostDominance.cs:19:13:19:21 | [true] ... is ... | 1 | | PostDominance.cs:20:45:20:53 | nameof(...) | PostDominance.cs:17:10:17:11 | exit M3 (abnormal) | 4 | | PostDominance.cs:21:9:21:29 | ...; | PostDominance.cs:17:10:17:11 | exit M3 (normal) | 4 | | Qualifiers.cs:7:16:7:21 | enter Method | Qualifiers.cs:7:16:7:21 | exit Method | 4 | @@ -1063,7 +1147,9 @@ | Switch.cs:156:50:156:52 | "b" | Switch.cs:156:41:156:52 | ... => ... | 2 | | Switch.cs:158:13:158:49 | ...; | Switch.cs:158:13:158:48 | call to method WriteLine | 5 | | Switch.cs:160:13:160:49 | ...; | Switch.cs:160:13:160:48 | call to method WriteLine | 5 | -| TypeAccesses.cs:3:10:3:10 | enter M | TypeAccesses.cs:7:13:7:22 | ... is ... | 14 | +| TypeAccesses.cs:3:10:3:10 | enter M | TypeAccesses.cs:7:18:7:22 | Int32 j | 13 | +| TypeAccesses.cs:7:13:7:22 | [false] ... is ... | TypeAccesses.cs:7:13:7:22 | [false] ... is ... | 1 | +| TypeAccesses.cs:7:13:7:22 | [true] ... is ... | TypeAccesses.cs:7:13:7:22 | [true] ... is ... | 1 | | TypeAccesses.cs:7:25:7:25 | ; | TypeAccesses.cs:7:25:7:25 | ; | 1 | | TypeAccesses.cs:8:9:8:28 | ... ...; | TypeAccesses.cs:3:10:3:10 | exit M | 5 | | VarDecls.cs:5:18:5:19 | enter M1 | VarDecls.cs:5:18:5:19 | exit M1 | 19 | diff --git a/csharp/ql/test/library-tests/controlflow/graph/Condition.expected b/csharp/ql/test/library-tests/controlflow/graph/Condition.expected index 27b149e8271..ee9f9e77bb8 100644 --- a/csharp/ql/test/library-tests/controlflow/graph/Condition.expected +++ b/csharp/ql/test/library-tests/controlflow/graph/Condition.expected @@ -1305,48 +1305,48 @@ conditionBlock | Conditions.cs:143:10:143:12 | enter M11 | Conditions.cs:149:13:149:49 | ...; | false | | Conditions.cs:145:21:145:23 | [b (line 143): true] "a" | Conditions.cs:147:13:147:49 | ...; | true | | Conditions.cs:145:27:145:29 | [b (line 143): false] "b" | Conditions.cs:149:13:149:49 | ...; | false | -| ExitMethods.cs:43:9:46:9 | [exception: Exception] catch (...) {...} | ExitMethods.cs:47:9:50:9 | [exception: Exception] catch (...) {...} | false | -| ExitMethods.cs:43:9:46:9 | [exception: Exception] catch (...) {...} | ExitMethods.cs:48:9:50:9 | {...} | false | -| ExitMethods.cs:47:9:50:9 | [exception: Exception] catch (...) {...} | ExitMethods.cs:48:9:50:9 | {...} | true | -| ExitMethods.cs:65:17:65:26 | enter ErrorMaybe | ExitMethods.cs:65:17:65:26 | exit ErrorMaybe (normal) | false | -| ExitMethods.cs:65:17:65:26 | enter ErrorMaybe | ExitMethods.cs:68:19:68:33 | object creation of type Exception | true | -| ExitMethods.cs:71:17:71:27 | enter ErrorAlways | ExitMethods.cs:74:19:74:33 | object creation of type Exception | true | -| ExitMethods.cs:71:17:71:27 | enter ErrorAlways | ExitMethods.cs:76:41:76:43 | "b" | false | -| ExitMethods.cs:109:13:109:21 | enter ThrowExpr | ExitMethods.cs:111:29:111:29 | 1 | true | -| ExitMethods.cs:109:13:109:21 | enter ThrowExpr | ExitMethods.cs:111:69:111:75 | "input" | false | -| ExitMethods.cs:114:16:114:34 | enter ExtensionMethodCall | ExitMethods.cs:116:34:116:34 | 0 | true | -| ExitMethods.cs:114:16:114:34 | enter ExtensionMethodCall | ExitMethods.cs:116:38:116:38 | 1 | false | -| ExitMethods.cs:119:17:119:32 | enter FailingAssertion | ExitMethods.cs:121:9:121:28 | [assertion failure] call to method IsTrue | false | -| ExitMethods.cs:131:10:131:20 | enter AssertFalse | ExitMethods.cs:131:33:131:49 | [assertion failure] call to method IsFalse | true | -| ExitMethods.cs:131:10:131:20 | enter AssertFalse | ExitMethods.cs:131:33:131:49 | [assertion success] call to method IsFalse | false | -| ExitMethods.cs:133:17:133:33 | enter FailingAssertion3 | ExitMethods.cs:135:9:135:25 | [assertion failure] call to method AssertFalse | true | +| ExitMethods.cs:44:9:47:9 | [exception: Exception] catch (...) {...} | ExitMethods.cs:48:9:51:9 | [exception: Exception] catch (...) {...} | false | +| ExitMethods.cs:44:9:47:9 | [exception: Exception] catch (...) {...} | ExitMethods.cs:49:9:51:9 | {...} | false | +| ExitMethods.cs:48:9:51:9 | [exception: Exception] catch (...) {...} | ExitMethods.cs:49:9:51:9 | {...} | true | +| ExitMethods.cs:66:17:66:26 | enter ErrorMaybe | ExitMethods.cs:66:17:66:26 | exit ErrorMaybe (normal) | false | +| ExitMethods.cs:66:17:66:26 | enter ErrorMaybe | ExitMethods.cs:69:19:69:33 | object creation of type Exception | true | +| ExitMethods.cs:72:17:72:27 | enter ErrorAlways | ExitMethods.cs:75:19:75:33 | object creation of type Exception | true | +| ExitMethods.cs:72:17:72:27 | enter ErrorAlways | ExitMethods.cs:77:41:77:43 | "b" | false | +| ExitMethods.cs:110:13:110:21 | enter ThrowExpr | ExitMethods.cs:112:29:112:29 | 1 | true | +| ExitMethods.cs:110:13:110:21 | enter ThrowExpr | ExitMethods.cs:112:69:112:75 | "input" | false | +| ExitMethods.cs:115:16:115:34 | enter ExtensionMethodCall | ExitMethods.cs:117:34:117:34 | 0 | true | +| ExitMethods.cs:115:16:115:34 | enter ExtensionMethodCall | ExitMethods.cs:117:38:117:38 | 1 | false | +| ExitMethods.cs:120:17:120:32 | enter FailingAssertion | ExitMethods.cs:122:9:122:28 | [assertion failure] call to method IsTrue | false | +| ExitMethods.cs:132:10:132:20 | enter AssertFalse | ExitMethods.cs:132:33:132:49 | [assertion failure] call to method IsFalse | true | +| ExitMethods.cs:132:10:132:20 | enter AssertFalse | ExitMethods.cs:132:33:132:49 | [assertion success] call to method IsFalse | false | +| ExitMethods.cs:134:17:134:33 | enter FailingAssertion3 | ExitMethods.cs:136:9:136:25 | [assertion failure] call to method AssertFalse | true | +| ExitMethods.cs:140:17:140:42 | enter ExceptionDispatchInfoThrow | ExitMethods.cs:143:13:143:43 | ...; | true | +| ExitMethods.cs:140:17:140:42 | enter ExceptionDispatchInfoThrow | ExitMethods.cs:145:13:145:53 | ...; | false | | Finally.cs:26:9:29:9 | [exception: Exception] catch (...) {...} | Finally.cs:26:38:26:39 | [exception: Exception] IOException ex | true | | Finally.cs:26:9:29:9 | [exception: Exception] catch (...) {...} | Finally.cs:27:9:29:9 | {...} | true | | Finally.cs:26:9:29:9 | [exception: Exception] catch (...) {...} | Finally.cs:30:9:40:9 | [exception: Exception] catch (...) {...} | false | | Finally.cs:26:9:29:9 | [exception: Exception] catch (...) {...} | Finally.cs:30:41:30:42 | [exception: Exception] ArgumentException ex | false | | Finally.cs:26:9:29:9 | [exception: Exception] catch (...) {...} | Finally.cs:34:27:34:32 | throw ...; | false | | Finally.cs:26:9:29:9 | [exception: Exception] catch (...) {...} | Finally.cs:41:9:43:9 | [exception: Exception] catch (...) {...} | false | -| Finally.cs:26:9:29:9 | [exception: OutOfMemoryException] catch (...) {...} | Finally.cs:30:9:40:9 | [exception: OutOfMemoryException] catch (...) {...} | false | -| Finally.cs:26:9:29:9 | [exception: OutOfMemoryException] catch (...) {...} | Finally.cs:41:9:43:9 | [exception: OutOfMemoryException] catch (...) {...} | false | +| Finally.cs:26:9:29:9 | [exception: Exception] catch (...) {...} | Finally.cs:42:9:43:9 | {...} | false | | Finally.cs:26:38:26:39 | [exception: Exception] IOException ex | Finally.cs:27:9:29:9 | {...} | true | | Finally.cs:30:9:40:9 | [exception: Exception] catch (...) {...} | Finally.cs:30:41:30:42 | [exception: Exception] ArgumentException ex | true | | Finally.cs:30:9:40:9 | [exception: Exception] catch (...) {...} | Finally.cs:34:27:34:32 | throw ...; | true | | Finally.cs:30:9:40:9 | [exception: Exception] catch (...) {...} | Finally.cs:41:9:43:9 | [exception: Exception] catch (...) {...} | false | -| Finally.cs:30:9:40:9 | [exception: OutOfMemoryException] catch (...) {...} | Finally.cs:41:9:43:9 | [exception: OutOfMemoryException] catch (...) {...} | false | +| Finally.cs:30:9:40:9 | [exception: Exception] catch (...) {...} | Finally.cs:42:9:43:9 | {...} | false | | Finally.cs:30:41:30:42 | [exception: Exception] ArgumentException ex | Finally.cs:34:27:34:32 | throw ...; | true | +| Finally.cs:41:9:43:9 | [exception: Exception] catch (...) {...} | Finally.cs:42:9:43:9 | {...} | true | | Finally.cs:61:9:64:9 | [exception: Exception] catch (...) {...} | Finally.cs:61:38:61:39 | [exception: Exception] IOException ex | true | | Finally.cs:61:9:64:9 | [exception: Exception] catch (...) {...} | Finally.cs:62:9:64:9 | {...} | true | | Finally.cs:61:9:64:9 | [exception: Exception] catch (...) {...} | Finally.cs:65:9:67:9 | [exception: Exception] catch (...) {...} | false | | Finally.cs:61:9:64:9 | [exception: Exception] catch (...) {...} | Finally.cs:65:26:65:26 | [exception: Exception] Exception e | false | +| Finally.cs:61:9:64:9 | [exception: Exception] catch (...) {...} | Finally.cs:66:9:67:9 | {...} | false | | Finally.cs:61:9:64:9 | [exception: Exception] catch (...) {...} | Finally.cs:69:9:71:9 | [finally: exception(Exception)] {...} | false | -| Finally.cs:61:9:64:9 | [exception: OutOfMemoryException] catch (...) {...} | Finally.cs:65:9:67:9 | [exception: OutOfMemoryException] catch (...) {...} | false | -| Finally.cs:61:9:64:9 | [exception: OutOfMemoryException] catch (...) {...} | Finally.cs:65:26:65:26 | [exception: OutOfMemoryException] Exception e | false | -| Finally.cs:61:9:64:9 | [exception: OutOfMemoryException] catch (...) {...} | Finally.cs:69:9:71:9 | [finally: exception(OutOfMemoryException)] {...} | false | | Finally.cs:61:38:61:39 | [exception: Exception] IOException ex | Finally.cs:62:9:64:9 | {...} | true | | Finally.cs:65:9:67:9 | [exception: Exception] catch (...) {...} | Finally.cs:65:26:65:26 | [exception: Exception] Exception e | true | +| Finally.cs:65:9:67:9 | [exception: Exception] catch (...) {...} | Finally.cs:66:9:67:9 | {...} | true | | Finally.cs:65:9:67:9 | [exception: Exception] catch (...) {...} | Finally.cs:69:9:71:9 | [finally: exception(Exception)] {...} | true | -| Finally.cs:65:9:67:9 | [exception: OutOfMemoryException] catch (...) {...} | Finally.cs:65:26:65:26 | [exception: OutOfMemoryException] Exception e | true | -| Finally.cs:65:9:67:9 | [exception: OutOfMemoryException] catch (...) {...} | Finally.cs:69:9:71:9 | [finally: exception(OutOfMemoryException)] {...} | true | +| Finally.cs:65:26:65:26 | [exception: Exception] Exception e | Finally.cs:66:9:67:9 | {...} | true | | Finally.cs:77:16:77:16 | access to local variable i | Finally.cs:74:10:74:11 | exit M4 (abnormal) | true | | Finally.cs:77:16:77:16 | access to local variable i | Finally.cs:78:9:100:9 | {...} | true | | Finally.cs:77:16:77:16 | access to local variable i | Finally.cs:82:21:82:27 | return ...; | true | @@ -1363,12 +1363,12 @@ conditionBlock | Finally.cs:77:16:77:16 | access to local variable i | Finally.cs:93:31:93:45 | [finally: continue] object creation of type Exception | true | | Finally.cs:77:16:77:16 | access to local variable i | Finally.cs:93:31:93:45 | [finally: return] object creation of type Exception | true | | Finally.cs:77:16:77:16 | access to local variable i | Finally.cs:93:31:93:45 | object creation of type Exception | true | -| Finally.cs:77:16:77:16 | access to local variable i | Finally.cs:96:17:98:17 | [finally(2): exception(Exception)] {...} | true | -| Finally.cs:77:16:77:16 | access to local variable i | Finally.cs:96:17:98:17 | [finally: break, finally(2): exception(Exception)] {...} | true | +| Finally.cs:77:16:77:16 | access to local variable i | Finally.cs:96:17:98:17 | [finally(1): exception(Exception)] {...} | true | +| Finally.cs:77:16:77:16 | access to local variable i | Finally.cs:96:17:98:17 | [finally: break, finally(1): exception(Exception)] {...} | true | | Finally.cs:77:16:77:16 | access to local variable i | Finally.cs:96:17:98:17 | [finally: break] {...} | true | -| Finally.cs:77:16:77:16 | access to local variable i | Finally.cs:96:17:98:17 | [finally: continue, finally(2): exception(Exception)] {...} | true | +| Finally.cs:77:16:77:16 | access to local variable i | Finally.cs:96:17:98:17 | [finally: continue, finally(1): exception(Exception)] {...} | true | | Finally.cs:77:16:77:16 | access to local variable i | Finally.cs:96:17:98:17 | [finally: continue] {...} | true | -| Finally.cs:77:16:77:16 | access to local variable i | Finally.cs:96:17:98:17 | [finally: return, finally(2): exception(Exception)] {...} | true | +| Finally.cs:77:16:77:16 | access to local variable i | Finally.cs:96:17:98:17 | [finally: return, finally(1): exception(Exception)] {...} | true | | Finally.cs:77:16:77:16 | access to local variable i | Finally.cs:96:17:98:17 | [finally: return] {...} | true | | Finally.cs:77:16:77:16 | access to local variable i | Finally.cs:96:17:98:17 | {...} | true | | Finally.cs:78:9:100:9 | {...} | Finally.cs:82:21:82:27 | return ...; | true | @@ -1385,17 +1385,17 @@ conditionBlock | Finally.cs:78:9:100:9 | {...} | Finally.cs:93:31:93:45 | [finally: continue] object creation of type Exception | false | | Finally.cs:78:9:100:9 | {...} | Finally.cs:93:31:93:45 | [finally: return] object creation of type Exception | true | | Finally.cs:78:9:100:9 | {...} | Finally.cs:93:31:93:45 | object creation of type Exception | false | -| Finally.cs:78:9:100:9 | {...} | Finally.cs:96:17:98:17 | [finally(2): exception(Exception)] {...} | false | -| Finally.cs:78:9:100:9 | {...} | Finally.cs:96:17:98:17 | [finally: break, finally(2): exception(Exception)] {...} | false | +| Finally.cs:78:9:100:9 | {...} | Finally.cs:96:17:98:17 | [finally(1): exception(Exception)] {...} | false | +| Finally.cs:78:9:100:9 | {...} | Finally.cs:96:17:98:17 | [finally: break, finally(1): exception(Exception)] {...} | false | | Finally.cs:78:9:100:9 | {...} | Finally.cs:96:17:98:17 | [finally: break] {...} | false | -| Finally.cs:78:9:100:9 | {...} | Finally.cs:96:17:98:17 | [finally: continue, finally(2): exception(Exception)] {...} | false | +| Finally.cs:78:9:100:9 | {...} | Finally.cs:96:17:98:17 | [finally: continue, finally(1): exception(Exception)] {...} | false | | Finally.cs:78:9:100:9 | {...} | Finally.cs:96:17:98:17 | [finally: continue] {...} | false | -| Finally.cs:78:9:100:9 | {...} | Finally.cs:96:17:98:17 | [finally: return, finally(2): exception(Exception)] {...} | true | +| Finally.cs:78:9:100:9 | {...} | Finally.cs:96:17:98:17 | [finally: return, finally(1): exception(Exception)] {...} | true | | Finally.cs:78:9:100:9 | {...} | Finally.cs:96:17:98:17 | [finally: return] {...} | true | | Finally.cs:78:9:100:9 | {...} | Finally.cs:96:17:98:17 | {...} | false | | Finally.cs:82:21:82:27 | return ...; | Finally.cs:93:25:93:46 | [finally: return] throw ...; | true | | Finally.cs:82:21:82:27 | return ...; | Finally.cs:93:31:93:45 | [finally: return] object creation of type Exception | true | -| Finally.cs:82:21:82:27 | return ...; | Finally.cs:96:17:98:17 | [finally: return, finally(2): exception(Exception)] {...} | true | +| Finally.cs:82:21:82:27 | return ...; | Finally.cs:96:17:98:17 | [finally: return, finally(1): exception(Exception)] {...} | true | | Finally.cs:82:21:82:27 | return ...; | Finally.cs:96:17:98:17 | [finally: return] {...} | false | | Finally.cs:83:17:84:29 | if (...) ... | Finally.cs:84:21:84:29 | continue; | true | | Finally.cs:83:17:84:29 | if (...) ... | Finally.cs:85:17:86:26 | if (...) ... | false | @@ -1407,15 +1407,15 @@ conditionBlock | Finally.cs:83:17:84:29 | if (...) ... | Finally.cs:93:31:93:45 | [finally: break] object creation of type Exception | false | | Finally.cs:83:17:84:29 | if (...) ... | Finally.cs:93:31:93:45 | [finally: continue] object creation of type Exception | true | | Finally.cs:83:17:84:29 | if (...) ... | Finally.cs:93:31:93:45 | object creation of type Exception | false | -| Finally.cs:83:17:84:29 | if (...) ... | Finally.cs:96:17:98:17 | [finally(2): exception(Exception)] {...} | false | -| Finally.cs:83:17:84:29 | if (...) ... | Finally.cs:96:17:98:17 | [finally: break, finally(2): exception(Exception)] {...} | false | +| Finally.cs:83:17:84:29 | if (...) ... | Finally.cs:96:17:98:17 | [finally(1): exception(Exception)] {...} | false | +| Finally.cs:83:17:84:29 | if (...) ... | Finally.cs:96:17:98:17 | [finally: break, finally(1): exception(Exception)] {...} | false | | Finally.cs:83:17:84:29 | if (...) ... | Finally.cs:96:17:98:17 | [finally: break] {...} | false | -| Finally.cs:83:17:84:29 | if (...) ... | Finally.cs:96:17:98:17 | [finally: continue, finally(2): exception(Exception)] {...} | true | +| Finally.cs:83:17:84:29 | if (...) ... | Finally.cs:96:17:98:17 | [finally: continue, finally(1): exception(Exception)] {...} | true | | Finally.cs:83:17:84:29 | if (...) ... | Finally.cs:96:17:98:17 | [finally: continue] {...} | true | | Finally.cs:83:17:84:29 | if (...) ... | Finally.cs:96:17:98:17 | {...} | false | | Finally.cs:84:21:84:29 | continue; | Finally.cs:93:25:93:46 | [finally: continue] throw ...; | true | | Finally.cs:84:21:84:29 | continue; | Finally.cs:93:31:93:45 | [finally: continue] object creation of type Exception | true | -| Finally.cs:84:21:84:29 | continue; | Finally.cs:96:17:98:17 | [finally: continue, finally(2): exception(Exception)] {...} | true | +| Finally.cs:84:21:84:29 | continue; | Finally.cs:96:17:98:17 | [finally: continue, finally(1): exception(Exception)] {...} | true | | Finally.cs:84:21:84:29 | continue; | Finally.cs:96:17:98:17 | [finally: continue] {...} | false | | Finally.cs:85:17:86:26 | if (...) ... | Finally.cs:86:21:86:26 | break; | true | | Finally.cs:85:17:86:26 | if (...) ... | Finally.cs:89:13:99:13 | {...} | false | @@ -1423,17 +1423,17 @@ conditionBlock | Finally.cs:85:17:86:26 | if (...) ... | Finally.cs:93:25:93:46 | throw ...; | false | | Finally.cs:85:17:86:26 | if (...) ... | Finally.cs:93:31:93:45 | [finally: break] object creation of type Exception | true | | Finally.cs:85:17:86:26 | if (...) ... | Finally.cs:93:31:93:45 | object creation of type Exception | false | -| Finally.cs:85:17:86:26 | if (...) ... | Finally.cs:96:17:98:17 | [finally(2): exception(Exception)] {...} | false | -| Finally.cs:85:17:86:26 | if (...) ... | Finally.cs:96:17:98:17 | [finally: break, finally(2): exception(Exception)] {...} | true | +| Finally.cs:85:17:86:26 | if (...) ... | Finally.cs:96:17:98:17 | [finally(1): exception(Exception)] {...} | false | +| Finally.cs:85:17:86:26 | if (...) ... | Finally.cs:96:17:98:17 | [finally: break, finally(1): exception(Exception)] {...} | true | | Finally.cs:85:17:86:26 | if (...) ... | Finally.cs:96:17:98:17 | [finally: break] {...} | true | | Finally.cs:85:17:86:26 | if (...) ... | Finally.cs:96:17:98:17 | {...} | false | | Finally.cs:86:21:86:26 | break; | Finally.cs:93:25:93:46 | [finally: break] throw ...; | true | | Finally.cs:86:21:86:26 | break; | Finally.cs:93:31:93:45 | [finally: break] object creation of type Exception | true | -| Finally.cs:86:21:86:26 | break; | Finally.cs:96:17:98:17 | [finally: break, finally(2): exception(Exception)] {...} | true | +| Finally.cs:86:21:86:26 | break; | Finally.cs:96:17:98:17 | [finally: break, finally(1): exception(Exception)] {...} | true | | Finally.cs:86:21:86:26 | break; | Finally.cs:96:17:98:17 | [finally: break] {...} | false | | Finally.cs:89:13:99:13 | {...} | Finally.cs:93:25:93:46 | throw ...; | true | | Finally.cs:89:13:99:13 | {...} | Finally.cs:93:31:93:45 | object creation of type Exception | true | -| Finally.cs:89:13:99:13 | {...} | Finally.cs:96:17:98:17 | [finally(2): exception(Exception)] {...} | true | +| Finally.cs:89:13:99:13 | {...} | Finally.cs:96:17:98:17 | [finally(1): exception(Exception)] {...} | true | | Finally.cs:89:13:99:13 | {...} | Finally.cs:96:17:98:17 | {...} | false | | Finally.cs:107:33:107:33 | 0 | Finally.cs:108:17:108:23 | return ...; | true | | Finally.cs:107:33:107:33 | 0 | Finally.cs:109:13:110:49 | if (...) ... | false | @@ -1507,30 +1507,21 @@ conditionBlock | Finally.cs:147:10:147:11 | enter M8 | Finally.cs:159:21:159:45 | [finally: exception(ArgumentNullException)] throw ...; | true | | Finally.cs:147:10:147:11 | enter M8 | Finally.cs:159:21:159:45 | [finally: exception(Exception)] throw ...; | true | | Finally.cs:147:10:147:11 | enter M8 | Finally.cs:159:21:159:45 | throw ...; | false | -| Finally.cs:147:10:147:11 | enter M8 | Finally.cs:159:27:159:44 | [finally: exception(ArgumentNullException)] object creation of type Exception | true | -| Finally.cs:147:10:147:11 | enter M8 | Finally.cs:159:27:159:44 | [finally: exception(Exception)] object creation of type Exception | true | -| Finally.cs:147:10:147:11 | enter M8 | Finally.cs:159:27:159:44 | object creation of type Exception | false | | Finally.cs:147:10:147:11 | enter M8 | Finally.cs:159:41:159:43 | "1" | false | | Finally.cs:147:10:147:11 | enter M8 | Finally.cs:159:41:159:43 | [finally: exception(ArgumentNullException)] "1" | true | | Finally.cs:147:10:147:11 | enter M8 | Finally.cs:159:41:159:43 | [finally: exception(Exception)] "1" | true | | Finally.cs:147:10:147:11 | enter M8 | Finally.cs:161:13:164:13 | [exception: Exception] catch (...) {...} | false | | Finally.cs:147:10:147:11 | enter M8 | Finally.cs:161:13:164:13 | [exception: NullReferenceException] catch (...) {...} | false | -| Finally.cs:147:10:147:11 | enter M8 | Finally.cs:161:13:164:13 | [exception: OutOfMemoryException] catch (...) {...} | false | | Finally.cs:147:10:147:11 | enter M8 | Finally.cs:161:13:164:13 | [finally: exception(ArgumentNullException), exception: Exception] catch (...) {...} | true | | Finally.cs:147:10:147:11 | enter M8 | Finally.cs:161:13:164:13 | [finally: exception(ArgumentNullException), exception: NullReferenceException] catch (...) {...} | true | -| Finally.cs:147:10:147:11 | enter M8 | Finally.cs:161:13:164:13 | [finally: exception(ArgumentNullException), exception: OutOfMemoryException] catch (...) {...} | true | | Finally.cs:147:10:147:11 | enter M8 | Finally.cs:161:13:164:13 | [finally: exception(Exception), exception: Exception] catch (...) {...} | true | | Finally.cs:147:10:147:11 | enter M8 | Finally.cs:161:13:164:13 | [finally: exception(Exception), exception: NullReferenceException] catch (...) {...} | true | -| Finally.cs:147:10:147:11 | enter M8 | Finally.cs:161:13:164:13 | [finally: exception(Exception), exception: OutOfMemoryException] catch (...) {...} | true | | Finally.cs:147:10:147:11 | enter M8 | Finally.cs:161:30:161:30 | [exception: Exception] Exception e | false | | Finally.cs:147:10:147:11 | enter M8 | Finally.cs:161:30:161:30 | [exception: NullReferenceException] Exception e | false | -| Finally.cs:147:10:147:11 | enter M8 | Finally.cs:161:30:161:30 | [exception: OutOfMemoryException] Exception e | false | | Finally.cs:147:10:147:11 | enter M8 | Finally.cs:161:30:161:30 | [finally: exception(ArgumentNullException), exception: Exception] Exception e | true | | Finally.cs:147:10:147:11 | enter M8 | Finally.cs:161:30:161:30 | [finally: exception(ArgumentNullException), exception: NullReferenceException] Exception e | true | -| Finally.cs:147:10:147:11 | enter M8 | Finally.cs:161:30:161:30 | [finally: exception(ArgumentNullException), exception: OutOfMemoryException] Exception e | true | | Finally.cs:147:10:147:11 | enter M8 | Finally.cs:161:30:161:30 | [finally: exception(Exception), exception: Exception] Exception e | true | | Finally.cs:147:10:147:11 | enter M8 | Finally.cs:161:30:161:30 | [finally: exception(Exception), exception: NullReferenceException] Exception e | true | -| Finally.cs:147:10:147:11 | enter M8 | Finally.cs:161:30:161:30 | [finally: exception(Exception), exception: OutOfMemoryException] Exception e | true | | Finally.cs:147:10:147:11 | enter M8 | Finally.cs:162:13:164:13 | [finally: exception(ArgumentNullException)] {...} | true | | Finally.cs:147:10:147:11 | enter M8 | Finally.cs:162:13:164:13 | [finally: exception(Exception)] {...} | true | | Finally.cs:147:10:147:11 | enter M8 | Finally.cs:162:13:164:13 | {...} | false | @@ -1538,29 +1529,17 @@ conditionBlock | Finally.cs:147:10:147:11 | enter M8 | Finally.cs:165:13:168:13 | [finally: exception(Exception)] catch {...} | true | | Finally.cs:147:10:147:11 | enter M8 | Finally.cs:165:13:168:13 | catch {...} | false | | Finally.cs:158:36:158:36 | 1 | Finally.cs:159:21:159:45 | throw ...; | true | -| Finally.cs:158:36:158:36 | 1 | Finally.cs:159:27:159:44 | object creation of type Exception | true | | Finally.cs:158:36:158:36 | 1 | Finally.cs:159:41:159:43 | "1" | true | -| Finally.cs:158:36:158:36 | 1 | Finally.cs:161:13:164:13 | [exception: OutOfMemoryException] catch (...) {...} | true | -| Finally.cs:158:36:158:36 | 1 | Finally.cs:161:30:161:30 | [exception: OutOfMemoryException] Exception e | true | | Finally.cs:158:36:158:36 | [finally: exception(ArgumentNullException)] 1 | Finally.cs:159:21:159:45 | [finally: exception(ArgumentNullException)] throw ...; | true | -| Finally.cs:158:36:158:36 | [finally: exception(ArgumentNullException)] 1 | Finally.cs:159:27:159:44 | [finally: exception(ArgumentNullException)] object creation of type Exception | true | | Finally.cs:158:36:158:36 | [finally: exception(ArgumentNullException)] 1 | Finally.cs:159:41:159:43 | [finally: exception(ArgumentNullException)] "1" | true | -| Finally.cs:158:36:158:36 | [finally: exception(ArgumentNullException)] 1 | Finally.cs:161:13:164:13 | [finally: exception(ArgumentNullException), exception: OutOfMemoryException] catch (...) {...} | true | -| Finally.cs:158:36:158:36 | [finally: exception(ArgumentNullException)] 1 | Finally.cs:161:30:161:30 | [finally: exception(ArgumentNullException), exception: OutOfMemoryException] Exception e | true | | Finally.cs:158:36:158:36 | [finally: exception(Exception)] 1 | Finally.cs:159:21:159:45 | [finally: exception(Exception)] throw ...; | true | -| Finally.cs:158:36:158:36 | [finally: exception(Exception)] 1 | Finally.cs:159:27:159:44 | [finally: exception(Exception)] object creation of type Exception | true | | Finally.cs:158:36:158:36 | [finally: exception(Exception)] 1 | Finally.cs:159:41:159:43 | [finally: exception(Exception)] "1" | true | -| Finally.cs:158:36:158:36 | [finally: exception(Exception)] 1 | Finally.cs:161:13:164:13 | [finally: exception(Exception), exception: OutOfMemoryException] catch (...) {...} | true | -| Finally.cs:158:36:158:36 | [finally: exception(Exception)] 1 | Finally.cs:161:30:161:30 | [finally: exception(Exception), exception: OutOfMemoryException] Exception e | true | | Finally.cs:161:13:164:13 | [exception: Exception] catch (...) {...} | Finally.cs:161:30:161:30 | [exception: Exception] Exception e | true | | Finally.cs:161:13:164:13 | [exception: NullReferenceException] catch (...) {...} | Finally.cs:161:30:161:30 | [exception: NullReferenceException] Exception e | true | -| Finally.cs:161:13:164:13 | [exception: OutOfMemoryException] catch (...) {...} | Finally.cs:161:30:161:30 | [exception: OutOfMemoryException] Exception e | true | | Finally.cs:161:13:164:13 | [finally: exception(ArgumentNullException), exception: Exception] catch (...) {...} | Finally.cs:161:30:161:30 | [finally: exception(ArgumentNullException), exception: Exception] Exception e | true | | Finally.cs:161:13:164:13 | [finally: exception(ArgumentNullException), exception: NullReferenceException] catch (...) {...} | Finally.cs:161:30:161:30 | [finally: exception(ArgumentNullException), exception: NullReferenceException] Exception e | true | -| Finally.cs:161:13:164:13 | [finally: exception(ArgumentNullException), exception: OutOfMemoryException] catch (...) {...} | Finally.cs:161:30:161:30 | [finally: exception(ArgumentNullException), exception: OutOfMemoryException] Exception e | true | | Finally.cs:161:13:164:13 | [finally: exception(Exception), exception: Exception] catch (...) {...} | Finally.cs:161:30:161:30 | [finally: exception(Exception), exception: Exception] Exception e | true | | Finally.cs:161:13:164:13 | [finally: exception(Exception), exception: NullReferenceException] catch (...) {...} | Finally.cs:161:30:161:30 | [finally: exception(Exception), exception: NullReferenceException] Exception e | true | -| Finally.cs:161:13:164:13 | [finally: exception(Exception), exception: OutOfMemoryException] catch (...) {...} | Finally.cs:161:30:161:30 | [finally: exception(Exception), exception: OutOfMemoryException] Exception e | true | | Finally.cs:176:10:176:11 | enter M9 | Finally.cs:176:10:176:11 | exit M9 (normal) | false | | Finally.cs:176:10:176:11 | enter M9 | Finally.cs:180:21:180:43 | [b1 (line 176): true] throw ...; | true | | Finally.cs:176:10:176:11 | enter M9 | Finally.cs:180:27:180:42 | [b1 (line 176): true] object creation of type ExceptionA | true | @@ -1624,19 +1603,19 @@ conditionBlock | Finally.cs:195:10:195:12 | enter M10 | Finally.cs:205:31:205:46 | [finally: exception(Exception)] object creation of type ExceptionB | true | | Finally.cs:195:10:195:12 | enter M10 | Finally.cs:205:31:205:46 | [finally: exception(ExceptionA)] object creation of type ExceptionB | true | | Finally.cs:195:10:195:12 | enter M10 | Finally.cs:205:31:205:46 | object creation of type ExceptionB | false | -| Finally.cs:195:10:195:12 | enter M10 | Finally.cs:208:13:210:13 | [finally(2): exception(Exception)] {...} | false | -| Finally.cs:195:10:195:12 | enter M10 | Finally.cs:208:13:210:13 | [finally: exception(Exception), finally(2): exception(Exception)] {...} | true | +| Finally.cs:195:10:195:12 | enter M10 | Finally.cs:208:13:210:13 | [finally(1): exception(Exception)] {...} | false | +| Finally.cs:195:10:195:12 | enter M10 | Finally.cs:208:13:210:13 | [finally: exception(Exception), finally(1): exception(Exception)] {...} | true | | Finally.cs:195:10:195:12 | enter M10 | Finally.cs:208:13:210:13 | [finally: exception(Exception)] {...} | true | -| Finally.cs:195:10:195:12 | enter M10 | Finally.cs:208:13:210:13 | [finally: exception(ExceptionA), finally(2): exception(Exception)] {...} | true | +| Finally.cs:195:10:195:12 | enter M10 | Finally.cs:208:13:210:13 | [finally: exception(ExceptionA), finally(1): exception(Exception)] {...} | true | | Finally.cs:195:10:195:12 | enter M10 | Finally.cs:208:13:210:13 | [finally: exception(ExceptionA)] {...} | true | | Finally.cs:195:10:195:12 | enter M10 | Finally.cs:208:13:210:13 | {...} | false | -| Finally.cs:195:10:195:12 | enter M10 | Finally.cs:209:31:209:46 | [finally(2): exception(Exception)] object creation of type ExceptionC | false | -| Finally.cs:195:10:195:12 | enter M10 | Finally.cs:209:31:209:46 | [finally(2): exception(ExceptionB)] object creation of type ExceptionC | false | -| Finally.cs:195:10:195:12 | enter M10 | Finally.cs:209:31:209:46 | [finally: exception(Exception), finally(2): exception(Exception)] object creation of type ExceptionC | true | -| Finally.cs:195:10:195:12 | enter M10 | Finally.cs:209:31:209:46 | [finally: exception(Exception), finally(2): exception(ExceptionB)] object creation of type ExceptionC | true | +| Finally.cs:195:10:195:12 | enter M10 | Finally.cs:209:31:209:46 | [finally(1): exception(Exception)] object creation of type ExceptionC | false | +| Finally.cs:195:10:195:12 | enter M10 | Finally.cs:209:31:209:46 | [finally(1): exception(ExceptionB)] object creation of type ExceptionC | false | +| Finally.cs:195:10:195:12 | enter M10 | Finally.cs:209:31:209:46 | [finally: exception(Exception), finally(1): exception(Exception)] object creation of type ExceptionC | true | +| Finally.cs:195:10:195:12 | enter M10 | Finally.cs:209:31:209:46 | [finally: exception(Exception), finally(1): exception(ExceptionB)] object creation of type ExceptionC | true | | Finally.cs:195:10:195:12 | enter M10 | Finally.cs:209:31:209:46 | [finally: exception(Exception)] object creation of type ExceptionC | true | -| Finally.cs:195:10:195:12 | enter M10 | Finally.cs:209:31:209:46 | [finally: exception(ExceptionA), finally(2): exception(Exception)] object creation of type ExceptionC | true | -| Finally.cs:195:10:195:12 | enter M10 | Finally.cs:209:31:209:46 | [finally: exception(ExceptionA), finally(2): exception(ExceptionB)] object creation of type ExceptionC | true | +| Finally.cs:195:10:195:12 | enter M10 | Finally.cs:209:31:209:46 | [finally: exception(ExceptionA), finally(1): exception(Exception)] object creation of type ExceptionC | true | +| Finally.cs:195:10:195:12 | enter M10 | Finally.cs:209:31:209:46 | [finally: exception(ExceptionA), finally(1): exception(ExceptionB)] object creation of type ExceptionC | true | | Finally.cs:195:10:195:12 | enter M10 | Finally.cs:209:31:209:46 | [finally: exception(ExceptionA)] object creation of type ExceptionC | true | | Finally.cs:195:10:195:12 | enter M10 | Finally.cs:209:31:209:46 | object creation of type ExceptionC | false | | Finally.cs:195:10:195:12 | enter M10 | Finally.cs:211:13:211:29 | ...; | false | @@ -1644,40 +1623,70 @@ conditionBlock | Finally.cs:195:10:195:12 | enter M10 | Finally.cs:211:13:211:29 | [finally: exception(ExceptionA)] ...; | true | | Finally.cs:199:21:199:43 | throw ...; | Finally.cs:205:25:205:47 | [finally: exception(ExceptionA)] throw ...; | true | | Finally.cs:199:21:199:43 | throw ...; | Finally.cs:205:31:205:46 | [finally: exception(ExceptionA)] object creation of type ExceptionB | true | -| Finally.cs:199:21:199:43 | throw ...; | Finally.cs:208:13:210:13 | [finally: exception(ExceptionA), finally(2): exception(Exception)] {...} | true | +| Finally.cs:199:21:199:43 | throw ...; | Finally.cs:208:13:210:13 | [finally: exception(ExceptionA), finally(1): exception(Exception)] {...} | true | | Finally.cs:199:21:199:43 | throw ...; | Finally.cs:208:13:210:13 | [finally: exception(ExceptionA)] {...} | false | -| Finally.cs:199:21:199:43 | throw ...; | Finally.cs:209:31:209:46 | [finally: exception(ExceptionA), finally(2): exception(Exception)] object creation of type ExceptionC | true | -| Finally.cs:199:21:199:43 | throw ...; | Finally.cs:209:31:209:46 | [finally: exception(ExceptionA), finally(2): exception(ExceptionB)] object creation of type ExceptionC | true | +| Finally.cs:199:21:199:43 | throw ...; | Finally.cs:209:31:209:46 | [finally: exception(ExceptionA), finally(1): exception(Exception)] object creation of type ExceptionC | true | +| Finally.cs:199:21:199:43 | throw ...; | Finally.cs:209:31:209:46 | [finally: exception(ExceptionA), finally(1): exception(ExceptionB)] object creation of type ExceptionC | true | | Finally.cs:199:21:199:43 | throw ...; | Finally.cs:209:31:209:46 | [finally: exception(ExceptionA)] object creation of type ExceptionC | false | | Finally.cs:199:21:199:43 | throw ...; | Finally.cs:211:13:211:29 | [finally: exception(ExceptionA)] ...; | false | | Finally.cs:202:9:212:9 | [finally: exception(Exception)] {...} | Finally.cs:205:25:205:47 | [finally: exception(Exception)] throw ...; | true | | Finally.cs:202:9:212:9 | [finally: exception(Exception)] {...} | Finally.cs:205:31:205:46 | [finally: exception(Exception)] object creation of type ExceptionB | true | -| Finally.cs:202:9:212:9 | [finally: exception(Exception)] {...} | Finally.cs:208:13:210:13 | [finally: exception(Exception), finally(2): exception(Exception)] {...} | true | +| Finally.cs:202:9:212:9 | [finally: exception(Exception)] {...} | Finally.cs:208:13:210:13 | [finally: exception(Exception), finally(1): exception(Exception)] {...} | true | | Finally.cs:202:9:212:9 | [finally: exception(Exception)] {...} | Finally.cs:208:13:210:13 | [finally: exception(Exception)] {...} | false | -| Finally.cs:202:9:212:9 | [finally: exception(Exception)] {...} | Finally.cs:209:31:209:46 | [finally: exception(Exception), finally(2): exception(Exception)] object creation of type ExceptionC | true | -| Finally.cs:202:9:212:9 | [finally: exception(Exception)] {...} | Finally.cs:209:31:209:46 | [finally: exception(Exception), finally(2): exception(ExceptionB)] object creation of type ExceptionC | true | +| Finally.cs:202:9:212:9 | [finally: exception(Exception)] {...} | Finally.cs:209:31:209:46 | [finally: exception(Exception), finally(1): exception(Exception)] object creation of type ExceptionC | true | +| Finally.cs:202:9:212:9 | [finally: exception(Exception)] {...} | Finally.cs:209:31:209:46 | [finally: exception(Exception), finally(1): exception(ExceptionB)] object creation of type ExceptionC | true | | Finally.cs:202:9:212:9 | [finally: exception(Exception)] {...} | Finally.cs:209:31:209:46 | [finally: exception(Exception)] object creation of type ExceptionC | false | | Finally.cs:202:9:212:9 | [finally: exception(Exception)] {...} | Finally.cs:211:13:211:29 | [finally: exception(Exception)] ...; | false | | Finally.cs:202:9:212:9 | {...} | Finally.cs:205:25:205:47 | throw ...; | true | | Finally.cs:202:9:212:9 | {...} | Finally.cs:205:31:205:46 | object creation of type ExceptionB | true | -| Finally.cs:202:9:212:9 | {...} | Finally.cs:208:13:210:13 | [finally(2): exception(Exception)] {...} | true | +| Finally.cs:202:9:212:9 | {...} | Finally.cs:208:13:210:13 | [finally(1): exception(Exception)] {...} | true | | Finally.cs:202:9:212:9 | {...} | Finally.cs:208:13:210:13 | {...} | false | -| Finally.cs:202:9:212:9 | {...} | Finally.cs:209:31:209:46 | [finally(2): exception(Exception)] object creation of type ExceptionC | true | -| Finally.cs:202:9:212:9 | {...} | Finally.cs:209:31:209:46 | [finally(2): exception(ExceptionB)] object creation of type ExceptionC | true | +| Finally.cs:202:9:212:9 | {...} | Finally.cs:209:31:209:46 | [finally(1): exception(Exception)] object creation of type ExceptionC | true | +| Finally.cs:202:9:212:9 | {...} | Finally.cs:209:31:209:46 | [finally(1): exception(ExceptionB)] object creation of type ExceptionC | true | | Finally.cs:202:9:212:9 | {...} | Finally.cs:209:31:209:46 | object creation of type ExceptionC | false | | Finally.cs:202:9:212:9 | {...} | Finally.cs:211:13:211:29 | ...; | false | -| Finally.cs:205:25:205:47 | [finally: exception(Exception)] throw ...; | Finally.cs:209:31:209:46 | [finally: exception(Exception), finally(2): exception(ExceptionB)] object creation of type ExceptionC | true | -| Finally.cs:205:25:205:47 | [finally: exception(ExceptionA)] throw ...; | Finally.cs:209:31:209:46 | [finally: exception(ExceptionA), finally(2): exception(ExceptionB)] object creation of type ExceptionC | true | -| Finally.cs:205:25:205:47 | throw ...; | Finally.cs:209:31:209:46 | [finally(2): exception(ExceptionB)] object creation of type ExceptionC | true | -| Finally.cs:208:13:210:13 | [finally(2): exception(Exception)] {...} | Finally.cs:209:31:209:46 | [finally(2): exception(Exception)] object creation of type ExceptionC | true | -| Finally.cs:208:13:210:13 | [finally: exception(Exception), finally(2): exception(Exception)] {...} | Finally.cs:209:31:209:46 | [finally: exception(Exception), finally(2): exception(Exception)] object creation of type ExceptionC | true | +| Finally.cs:205:25:205:47 | [finally: exception(Exception)] throw ...; | Finally.cs:209:31:209:46 | [finally: exception(Exception), finally(1): exception(ExceptionB)] object creation of type ExceptionC | true | +| Finally.cs:205:25:205:47 | [finally: exception(ExceptionA)] throw ...; | Finally.cs:209:31:209:46 | [finally: exception(ExceptionA), finally(1): exception(ExceptionB)] object creation of type ExceptionC | true | +| Finally.cs:205:25:205:47 | throw ...; | Finally.cs:209:31:209:46 | [finally(1): exception(ExceptionB)] object creation of type ExceptionC | true | +| Finally.cs:208:13:210:13 | [finally(1): exception(Exception)] {...} | Finally.cs:209:31:209:46 | [finally(1): exception(Exception)] object creation of type ExceptionC | true | +| Finally.cs:208:13:210:13 | [finally: exception(Exception), finally(1): exception(Exception)] {...} | Finally.cs:209:31:209:46 | [finally: exception(Exception), finally(1): exception(Exception)] object creation of type ExceptionC | true | | Finally.cs:208:13:210:13 | [finally: exception(Exception)] {...} | Finally.cs:209:31:209:46 | [finally: exception(Exception)] object creation of type ExceptionC | true | | Finally.cs:208:13:210:13 | [finally: exception(Exception)] {...} | Finally.cs:211:13:211:29 | [finally: exception(Exception)] ...; | false | -| Finally.cs:208:13:210:13 | [finally: exception(ExceptionA), finally(2): exception(Exception)] {...} | Finally.cs:209:31:209:46 | [finally: exception(ExceptionA), finally(2): exception(Exception)] object creation of type ExceptionC | true | +| Finally.cs:208:13:210:13 | [finally: exception(ExceptionA), finally(1): exception(Exception)] {...} | Finally.cs:209:31:209:46 | [finally: exception(ExceptionA), finally(1): exception(Exception)] object creation of type ExceptionC | true | | Finally.cs:208:13:210:13 | [finally: exception(ExceptionA)] {...} | Finally.cs:209:31:209:46 | [finally: exception(ExceptionA)] object creation of type ExceptionC | true | | Finally.cs:208:13:210:13 | [finally: exception(ExceptionA)] {...} | Finally.cs:211:13:211:29 | [finally: exception(ExceptionA)] ...; | false | | Finally.cs:208:13:210:13 | {...} | Finally.cs:209:31:209:46 | object creation of type ExceptionC | true | | Finally.cs:208:13:210:13 | {...} | Finally.cs:211:13:211:29 | ...; | false | +| Finally.cs:233:10:233:12 | enter M12 | Finally.cs:240:21:240:43 | throw ...; | true | +| Finally.cs:233:10:233:12 | enter M12 | Finally.cs:240:27:240:42 | object creation of type ExceptionA | true | +| Finally.cs:233:10:233:12 | enter M12 | Finally.cs:243:13:253:13 | [finally: exception(Exception)] {...} | true | +| Finally.cs:233:10:233:12 | enter M12 | Finally.cs:243:13:253:13 | {...} | false | +| Finally.cs:233:10:233:12 | enter M12 | Finally.cs:247:25:247:47 | [finally: exception(Exception)] throw ...; | true | +| Finally.cs:233:10:233:12 | enter M12 | Finally.cs:247:25:247:47 | [finally: exception(ExceptionA)] throw ...; | true | +| Finally.cs:233:10:233:12 | enter M12 | Finally.cs:247:25:247:47 | throw ...; | false | +| Finally.cs:233:10:233:12 | enter M12 | Finally.cs:247:31:247:46 | [finally: exception(Exception)] object creation of type ExceptionA | true | +| Finally.cs:233:10:233:12 | enter M12 | Finally.cs:247:31:247:46 | [finally: exception(ExceptionA)] object creation of type ExceptionA | true | +| Finally.cs:233:10:233:12 | enter M12 | Finally.cs:247:31:247:46 | object creation of type ExceptionA | false | +| Finally.cs:233:10:233:12 | enter M12 | Finally.cs:250:17:252:17 | [finally(1): exception(Exception)] {...} | false | +| Finally.cs:233:10:233:12 | enter M12 | Finally.cs:250:17:252:17 | [finally: exception(Exception), finally(1): exception(Exception)] {...} | true | +| Finally.cs:233:10:233:12 | enter M12 | Finally.cs:250:17:252:17 | [finally: exception(Exception)] {...} | true | +| Finally.cs:233:10:233:12 | enter M12 | Finally.cs:250:17:252:17 | [finally: exception(ExceptionA), finally(1): exception(Exception)] {...} | true | +| Finally.cs:233:10:233:12 | enter M12 | Finally.cs:250:17:252:17 | [finally: exception(ExceptionA)] {...} | true | +| Finally.cs:233:10:233:12 | enter M12 | Finally.cs:250:17:252:17 | {...} | false | +| Finally.cs:233:10:233:12 | enter M12 | Finally.cs:257:9:259:9 | {...} | false | +| Finally.cs:240:21:240:43 | throw ...; | Finally.cs:247:25:247:47 | [finally: exception(ExceptionA)] throw ...; | true | +| Finally.cs:240:21:240:43 | throw ...; | Finally.cs:247:31:247:46 | [finally: exception(ExceptionA)] object creation of type ExceptionA | true | +| Finally.cs:240:21:240:43 | throw ...; | Finally.cs:250:17:252:17 | [finally: exception(ExceptionA), finally(1): exception(Exception)] {...} | true | +| Finally.cs:240:21:240:43 | throw ...; | Finally.cs:250:17:252:17 | [finally: exception(ExceptionA)] {...} | false | +| Finally.cs:243:13:253:13 | [finally: exception(Exception)] {...} | Finally.cs:247:25:247:47 | [finally: exception(Exception)] throw ...; | true | +| Finally.cs:243:13:253:13 | [finally: exception(Exception)] {...} | Finally.cs:247:31:247:46 | [finally: exception(Exception)] object creation of type ExceptionA | true | +| Finally.cs:243:13:253:13 | [finally: exception(Exception)] {...} | Finally.cs:250:17:252:17 | [finally: exception(Exception), finally(1): exception(Exception)] {...} | true | +| Finally.cs:243:13:253:13 | [finally: exception(Exception)] {...} | Finally.cs:250:17:252:17 | [finally: exception(Exception)] {...} | false | +| Finally.cs:243:13:253:13 | {...} | Finally.cs:247:25:247:47 | throw ...; | true | +| Finally.cs:243:13:253:13 | {...} | Finally.cs:247:31:247:46 | object creation of type ExceptionA | true | +| Finally.cs:243:13:253:13 | {...} | Finally.cs:250:17:252:17 | [finally(1): exception(Exception)] {...} | true | +| Finally.cs:243:13:253:13 | {...} | Finally.cs:250:17:252:17 | {...} | false | +| Finally.cs:243:13:253:13 | {...} | Finally.cs:257:9:259:9 | {...} | false | | Foreach.cs:8:9:9:13 | foreach (... ... in ...) ... | Foreach.cs:6:10:6:11 | exit M1 (normal) | true | | Foreach.cs:8:9:9:13 | foreach (... ... in ...) ... | Foreach.cs:8:22:8:24 | String arg | false | | Foreach.cs:14:9:15:13 | foreach (... ... in ...) ... | Foreach.cs:12:10:12:11 | exit M2 (normal) | true | @@ -1776,15 +1785,42 @@ conditionBlock | NullCoalescing.cs:15:31:15:31 | 0 | NullCoalescing.cs:16:17:16:25 | ... ?? ... | false | | NullCoalescing.cs:15:31:15:31 | 0 | NullCoalescing.cs:17:13:17:24 | ... ?? ... | false | | NullCoalescing.cs:16:17:16:25 | ... ?? ... | NullCoalescing.cs:17:13:17:24 | ... ?? ... | false | -| Patterns.cs:5:10:5:13 | enter Test | Patterns.cs:9:9:11:9 | {...} | true | -| Patterns.cs:5:10:5:13 | enter Test | Patterns.cs:12:14:18:9 | if (...) ... | false | -| Patterns.cs:5:10:5:13 | enter Test | Patterns.cs:13:9:15:9 | {...} | false | -| Patterns.cs:5:10:5:13 | enter Test | Patterns.cs:16:14:18:9 | if (...) ... | false | -| Patterns.cs:5:10:5:13 | enter Test | Patterns.cs:17:9:18:9 | {...} | false | +| Patterns.cs:5:10:5:11 | enter M1 | Patterns.cs:8:13:8:23 | [false] ... is ... | false | +| Patterns.cs:5:10:5:11 | enter M1 | Patterns.cs:8:13:8:23 | [true] ... is ... | true | +| Patterns.cs:5:10:5:11 | enter M1 | Patterns.cs:9:9:11:9 | {...} | true | +| Patterns.cs:5:10:5:11 | enter M1 | Patterns.cs:12:14:18:9 | if (...) ... | false | +| Patterns.cs:5:10:5:11 | enter M1 | Patterns.cs:12:18:12:31 | [false] ... is ... | false | +| Patterns.cs:5:10:5:11 | enter M1 | Patterns.cs:12:18:12:31 | [true] ... is ... | false | +| Patterns.cs:5:10:5:11 | enter M1 | Patterns.cs:13:9:15:9 | {...} | false | +| Patterns.cs:5:10:5:11 | enter M1 | Patterns.cs:16:14:18:9 | if (...) ... | false | +| Patterns.cs:5:10:5:11 | enter M1 | Patterns.cs:16:18:16:28 | [false] ... is ... | false | +| Patterns.cs:5:10:5:11 | enter M1 | Patterns.cs:16:18:16:28 | [true] ... is ... | false | +| Patterns.cs:5:10:5:11 | enter M1 | Patterns.cs:17:9:18:9 | {...} | false | +| Patterns.cs:8:13:8:23 | [false] ... is ... | Patterns.cs:12:14:18:9 | if (...) ... | false | +| Patterns.cs:8:13:8:23 | [false] ... is ... | Patterns.cs:12:18:12:31 | [false] ... is ... | false | +| Patterns.cs:8:13:8:23 | [false] ... is ... | Patterns.cs:12:18:12:31 | [true] ... is ... | false | +| Patterns.cs:8:13:8:23 | [false] ... is ... | Patterns.cs:13:9:15:9 | {...} | false | +| Patterns.cs:8:13:8:23 | [false] ... is ... | Patterns.cs:16:14:18:9 | if (...) ... | false | +| Patterns.cs:8:13:8:23 | [false] ... is ... | Patterns.cs:16:18:16:28 | [false] ... is ... | false | +| Patterns.cs:8:13:8:23 | [false] ... is ... | Patterns.cs:16:18:16:28 | [true] ... is ... | false | +| Patterns.cs:8:13:8:23 | [false] ... is ... | Patterns.cs:17:9:18:9 | {...} | false | +| Patterns.cs:8:13:8:23 | [true] ... is ... | Patterns.cs:9:9:11:9 | {...} | true | +| Patterns.cs:12:14:18:9 | if (...) ... | Patterns.cs:12:18:12:31 | [false] ... is ... | false | +| Patterns.cs:12:14:18:9 | if (...) ... | Patterns.cs:12:18:12:31 | [true] ... is ... | true | | Patterns.cs:12:14:18:9 | if (...) ... | Patterns.cs:13:9:15:9 | {...} | true | | Patterns.cs:12:14:18:9 | if (...) ... | Patterns.cs:16:14:18:9 | if (...) ... | false | +| Patterns.cs:12:14:18:9 | if (...) ... | Patterns.cs:16:18:16:28 | [false] ... is ... | false | +| Patterns.cs:12:14:18:9 | if (...) ... | Patterns.cs:16:18:16:28 | [true] ... is ... | false | | Patterns.cs:12:14:18:9 | if (...) ... | Patterns.cs:17:9:18:9 | {...} | false | +| Patterns.cs:12:18:12:31 | [false] ... is ... | Patterns.cs:16:14:18:9 | if (...) ... | false | +| Patterns.cs:12:18:12:31 | [false] ... is ... | Patterns.cs:16:18:16:28 | [false] ... is ... | false | +| Patterns.cs:12:18:12:31 | [false] ... is ... | Patterns.cs:16:18:16:28 | [true] ... is ... | false | +| Patterns.cs:12:18:12:31 | [false] ... is ... | Patterns.cs:17:9:18:9 | {...} | false | +| Patterns.cs:12:18:12:31 | [true] ... is ... | Patterns.cs:13:9:15:9 | {...} | true | +| Patterns.cs:16:14:18:9 | if (...) ... | Patterns.cs:16:18:16:28 | [false] ... is ... | false | +| Patterns.cs:16:14:18:9 | if (...) ... | Patterns.cs:16:18:16:28 | [true] ... is ... | true | | Patterns.cs:16:14:18:9 | if (...) ... | Patterns.cs:17:9:18:9 | {...} | true | +| Patterns.cs:16:18:16:28 | [true] ... is ... | Patterns.cs:17:9:18:9 | {...} | true | | Patterns.cs:20:9:38:9 | switch (...) {...} | Patterns.cs:23:17:23:22 | break; | true | | Patterns.cs:20:9:38:9 | switch (...) {...} | Patterns.cs:24:13:24:36 | case ...: | false | | Patterns.cs:20:9:38:9 | switch (...) {...} | Patterns.cs:24:30:24:31 | access to local variable i2 | false | @@ -1811,10 +1847,131 @@ conditionBlock | Patterns.cs:30:13:30:27 | case ...: | Patterns.cs:35:13:35:20 | default: | false | | Patterns.cs:33:13:33:24 | case ...: | Patterns.cs:34:17:34:22 | break; | true | | Patterns.cs:33:13:33:24 | case ...: | Patterns.cs:35:13:35:20 | default: | false | +| Patterns.cs:50:24:50:25 | enter M3 | Patterns.cs:51:9:51:21 | [false] ... is ... | true | +| Patterns.cs:50:24:50:25 | enter M3 | Patterns.cs:51:9:51:21 | [true] ... is ... | false | +| Patterns.cs:50:24:50:25 | enter M3 | Patterns.cs:51:14:51:21 | [match] not ... | false | +| Patterns.cs:50:24:50:25 | enter M3 | Patterns.cs:51:14:51:21 | [no-match] not ... | true | +| Patterns.cs:50:24:50:25 | enter M3 | Patterns.cs:51:25:51:25 | access to parameter c | false | +| Patterns.cs:50:24:50:25 | enter M3 | Patterns.cs:51:34:51:34 | access to parameter c | true | +| Patterns.cs:51:9:51:21 | [false] ... is ... | Patterns.cs:51:34:51:34 | access to parameter c | false | +| Patterns.cs:51:9:51:21 | [true] ... is ... | Patterns.cs:51:25:51:25 | access to parameter c | true | +| Patterns.cs:51:14:51:21 | [match] not ... | Patterns.cs:51:9:51:21 | [true] ... is ... | true | +| Patterns.cs:51:14:51:21 | [match] not ... | Patterns.cs:51:25:51:25 | access to parameter c | true | +| Patterns.cs:51:14:51:21 | [no-match] not ... | Patterns.cs:51:9:51:21 | [false] ... is ... | false | +| Patterns.cs:51:14:51:21 | [no-match] not ... | Patterns.cs:51:34:51:34 | access to parameter c | false | +| Patterns.cs:53:24:53:25 | enter M4 | Patterns.cs:54:27:54:35 | [match] { ... } | true | +| Patterns.cs:53:24:53:25 | enter M4 | Patterns.cs:54:27:54:35 | [no-match] { ... } | true | +| Patterns.cs:53:24:53:25 | enter M4 | Patterns.cs:54:33:54:33 | 1 | true | +| Patterns.cs:54:33:54:33 | 1 | Patterns.cs:54:27:54:35 | [match] { ... } | true | +| Patterns.cs:54:33:54:33 | 1 | Patterns.cs:54:27:54:35 | [no-match] { ... } | false | +| Patterns.cs:56:26:56:27 | enter M5 | Patterns.cs:60:13:60:17 | [match] not ... | false | +| Patterns.cs:56:26:56:27 | enter M5 | Patterns.cs:60:13:60:17 | [no-match] not ... | true | +| Patterns.cs:56:26:56:27 | enter M5 | Patterns.cs:60:22:60:28 | "not 1" | false | +| Patterns.cs:56:26:56:27 | enter M5 | Patterns.cs:61:13:61:13 | _ | true | +| Patterns.cs:56:26:56:27 | enter M5 | Patterns.cs:61:18:61:24 | "other" | true | +| Patterns.cs:60:13:60:17 | [match] not ... | Patterns.cs:60:22:60:28 | "not 1" | true | +| Patterns.cs:60:13:60:17 | [no-match] not ... | Patterns.cs:61:13:61:13 | _ | false | +| Patterns.cs:60:13:60:17 | [no-match] not ... | Patterns.cs:61:18:61:24 | "other" | false | +| Patterns.cs:61:13:61:13 | _ | Patterns.cs:61:18:61:24 | "other" | true | +| Patterns.cs:65:26:65:27 | enter M6 | Patterns.cs:69:13:69:17 | [no-match] not ... | true | +| Patterns.cs:65:26:65:27 | enter M6 | Patterns.cs:70:13:70:13 | 2 | true | +| Patterns.cs:65:26:65:27 | enter M6 | Patterns.cs:70:18:70:27 | "possible" | true | +| Patterns.cs:69:13:69:17 | [no-match] not ... | Patterns.cs:70:13:70:13 | 2 | false | +| Patterns.cs:69:13:69:17 | [no-match] not ... | Patterns.cs:70:18:70:27 | "possible" | false | +| Patterns.cs:70:13:70:13 | 2 | Patterns.cs:70:18:70:27 | "possible" | true | +| Patterns.cs:74:26:74:27 | enter M7 | Patterns.cs:78:20:78:24 | "> 1" | true | +| Patterns.cs:74:26:74:27 | enter M7 | Patterns.cs:79:15:79:15 | 0 | false | +| Patterns.cs:74:26:74:27 | enter M7 | Patterns.cs:79:20:79:24 | "< 0" | false | +| Patterns.cs:74:26:74:27 | enter M7 | Patterns.cs:80:13:80:13 | 1 | false | +| Patterns.cs:74:26:74:27 | enter M7 | Patterns.cs:80:18:80:20 | "1" | false | +| Patterns.cs:74:26:74:27 | enter M7 | Patterns.cs:81:13:81:13 | _ | false | +| Patterns.cs:74:26:74:27 | enter M7 | Patterns.cs:81:18:81:20 | "0" | false | +| Patterns.cs:79:15:79:15 | 0 | Patterns.cs:79:20:79:24 | "< 0" | true | +| Patterns.cs:79:15:79:15 | 0 | Patterns.cs:80:13:80:13 | 1 | false | +| Patterns.cs:79:15:79:15 | 0 | Patterns.cs:80:18:80:20 | "1" | false | +| Patterns.cs:79:15:79:15 | 0 | Patterns.cs:81:13:81:13 | _ | false | +| Patterns.cs:79:15:79:15 | 0 | Patterns.cs:81:18:81:20 | "0" | false | +| Patterns.cs:80:13:80:13 | 1 | Patterns.cs:80:18:80:20 | "1" | true | +| Patterns.cs:80:13:80:13 | 1 | Patterns.cs:81:13:81:13 | _ | false | +| Patterns.cs:80:13:80:13 | 1 | Patterns.cs:81:18:81:20 | "0" | false | +| Patterns.cs:81:13:81:13 | _ | Patterns.cs:81:18:81:20 | "0" | true | +| Patterns.cs:85:26:85:27 | enter M8 | Patterns.cs:85:39:85:53 | [false] ... is ... | false | +| Patterns.cs:85:26:85:27 | enter M8 | Patterns.cs:85:44:85:53 | [no-match] ... or ... | false | +| Patterns.cs:85:26:85:27 | enter M8 | Patterns.cs:85:49:85:53 | [match] not ... | false | +| Patterns.cs:85:26:85:27 | enter M8 | Patterns.cs:85:49:85:53 | [no-match] not ... | false | +| Patterns.cs:85:26:85:27 | enter M8 | Patterns.cs:85:53:85:53 | 2 | false | +| Patterns.cs:85:26:85:27 | enter M8 | Patterns.cs:85:67:85:69 | "2" | false | +| Patterns.cs:85:39:85:53 | [false] ... is ... | Patterns.cs:85:67:85:69 | "2" | false | +| Patterns.cs:85:39:85:53 | [true] ... is ... | Patterns.cs:85:57:85:63 | "not 2" | true | +| Patterns.cs:85:44:85:53 | [match] ... or ... | Patterns.cs:85:39:85:53 | [true] ... is ... | true | +| Patterns.cs:85:44:85:53 | [match] ... or ... | Patterns.cs:85:57:85:63 | "not 2" | true | +| Patterns.cs:85:44:85:53 | [no-match] ... or ... | Patterns.cs:85:39:85:53 | [false] ... is ... | false | +| Patterns.cs:85:44:85:53 | [no-match] ... or ... | Patterns.cs:85:67:85:69 | "2" | false | +| Patterns.cs:85:49:85:53 | [no-match] not ... | Patterns.cs:85:39:85:53 | [false] ... is ... | false | +| Patterns.cs:85:49:85:53 | [no-match] not ... | Patterns.cs:85:44:85:53 | [no-match] ... or ... | false | +| Patterns.cs:85:49:85:53 | [no-match] not ... | Patterns.cs:85:67:85:69 | "2" | false | +| Patterns.cs:85:53:85:53 | 2 | Patterns.cs:85:39:85:53 | [false] ... is ... | true | +| Patterns.cs:85:53:85:53 | 2 | Patterns.cs:85:44:85:53 | [no-match] ... or ... | true | +| Patterns.cs:85:53:85:53 | 2 | Patterns.cs:85:49:85:53 | [match] not ... | false | +| Patterns.cs:85:53:85:53 | 2 | Patterns.cs:85:49:85:53 | [no-match] not ... | true | +| Patterns.cs:85:53:85:53 | 2 | Patterns.cs:85:67:85:69 | "2" | true | +| Patterns.cs:87:26:87:27 | enter M9 | Patterns.cs:87:39:87:54 | [true] ... is ... | true | +| Patterns.cs:87:26:87:27 | enter M9 | Patterns.cs:87:44:87:54 | [match] ... and ... | true | +| Patterns.cs:87:26:87:27 | enter M9 | Patterns.cs:87:50:87:54 | [match] not ... | true | +| Patterns.cs:87:26:87:27 | enter M9 | Patterns.cs:87:50:87:54 | [no-match] not ... | true | +| Patterns.cs:87:26:87:27 | enter M9 | Patterns.cs:87:54:87:54 | 2 | true | +| Patterns.cs:87:26:87:27 | enter M9 | Patterns.cs:87:58:87:60 | "1" | true | +| Patterns.cs:87:39:87:54 | [false] ... is ... | Patterns.cs:87:64:87:70 | "not 1" | false | +| Patterns.cs:87:39:87:54 | [true] ... is ... | Patterns.cs:87:58:87:60 | "1" | true | +| Patterns.cs:87:44:87:54 | [match] ... and ... | Patterns.cs:87:39:87:54 | [true] ... is ... | true | +| Patterns.cs:87:44:87:54 | [match] ... and ... | Patterns.cs:87:58:87:60 | "1" | true | +| Patterns.cs:87:44:87:54 | [no-match] ... and ... | Patterns.cs:87:39:87:54 | [false] ... is ... | false | +| Patterns.cs:87:44:87:54 | [no-match] ... and ... | Patterns.cs:87:64:87:70 | "not 1" | false | +| Patterns.cs:87:50:87:54 | [match] not ... | Patterns.cs:87:39:87:54 | [true] ... is ... | true | +| Patterns.cs:87:50:87:54 | [match] not ... | Patterns.cs:87:44:87:54 | [match] ... and ... | true | +| Patterns.cs:87:50:87:54 | [match] not ... | Patterns.cs:87:58:87:60 | "1" | true | +| Patterns.cs:87:54:87:54 | 2 | Patterns.cs:87:39:87:54 | [true] ... is ... | false | +| Patterns.cs:87:54:87:54 | 2 | Patterns.cs:87:44:87:54 | [match] ... and ... | false | +| Patterns.cs:87:54:87:54 | 2 | Patterns.cs:87:50:87:54 | [match] not ... | false | +| Patterns.cs:87:54:87:54 | 2 | Patterns.cs:87:50:87:54 | [no-match] not ... | true | +| Patterns.cs:87:54:87:54 | 2 | Patterns.cs:87:58:87:60 | "1" | false | +| Patterns.cs:93:17:93:19 | enter M10 | Patterns.cs:95:13:95:40 | [false] ... is ... | false | +| Patterns.cs:93:17:93:19 | enter M10 | Patterns.cs:95:21:95:40 | [no-match] { ... } | false | +| Patterns.cs:93:17:93:19 | enter M10 | Patterns.cs:95:21:95:40 | [no-match] { ... } | false | +| Patterns.cs:93:17:93:19 | enter M10 | Patterns.cs:95:29:95:38 | [no-match] ... or ... | false | +| Patterns.cs:93:17:93:19 | enter M10 | Patterns.cs:95:36:95:38 | access to constant B | false | +| Patterns.cs:95:13:95:40 | [true] ... is ... | Patterns.cs:96:9:98:9 | {...} | true | +| Patterns.cs:95:21:95:40 | [match] { ... } | Patterns.cs:95:13:95:40 | [true] ... is ... | true | +| Patterns.cs:95:21:95:40 | [match] { ... } | Patterns.cs:95:13:95:40 | [true] ... is ... | true | +| Patterns.cs:95:21:95:40 | [match] { ... } | Patterns.cs:95:21:95:40 | [match] { ... } | true | +| Patterns.cs:95:21:95:40 | [match] { ... } | Patterns.cs:96:9:98:9 | {...} | true | +| Patterns.cs:95:21:95:40 | [match] { ... } | Patterns.cs:96:9:98:9 | {...} | true | +| Patterns.cs:95:21:95:40 | [no-match] { ... } | Patterns.cs:95:13:95:40 | [false] ... is ... | false | +| Patterns.cs:95:21:95:40 | [no-match] { ... } | Patterns.cs:95:13:95:40 | [false] ... is ... | false | +| Patterns.cs:95:21:95:40 | [no-match] { ... } | Patterns.cs:95:21:95:40 | [no-match] { ... } | false | +| Patterns.cs:95:29:95:38 | [match] ... or ... | Patterns.cs:95:13:95:40 | [true] ... is ... | true | +| Patterns.cs:95:29:95:38 | [match] ... or ... | Patterns.cs:95:21:95:40 | [match] { ... } | true | +| Patterns.cs:95:29:95:38 | [match] ... or ... | Patterns.cs:95:21:95:40 | [match] { ... } | true | +| Patterns.cs:95:29:95:38 | [match] ... or ... | Patterns.cs:96:9:98:9 | {...} | true | +| Patterns.cs:95:29:95:38 | [no-match] ... or ... | Patterns.cs:95:13:95:40 | [false] ... is ... | false | +| Patterns.cs:95:29:95:38 | [no-match] ... or ... | Patterns.cs:95:21:95:40 | [no-match] { ... } | false | +| Patterns.cs:95:29:95:38 | [no-match] ... or ... | Patterns.cs:95:21:95:40 | [no-match] { ... } | false | +| Patterns.cs:95:36:95:38 | access to constant B | Patterns.cs:95:13:95:40 | [false] ... is ... | false | +| Patterns.cs:95:36:95:38 | access to constant B | Patterns.cs:95:21:95:40 | [no-match] { ... } | false | +| Patterns.cs:95:36:95:38 | access to constant B | Patterns.cs:95:21:95:40 | [no-match] { ... } | false | +| Patterns.cs:95:36:95:38 | access to constant B | Patterns.cs:95:29:95:38 | [no-match] ... or ... | false | +| PostDominance.cs:10:10:10:11 | enter M2 | PostDominance.cs:12:13:12:21 | [false] ... is ... | false | +| PostDominance.cs:10:10:10:11 | enter M2 | PostDominance.cs:12:13:12:21 | [true] ... is ... | true | | PostDominance.cs:10:10:10:11 | enter M2 | PostDominance.cs:13:13:13:19 | return ...; | true | | PostDominance.cs:10:10:10:11 | enter M2 | PostDominance.cs:14:9:14:29 | ...; | false | +| PostDominance.cs:12:13:12:21 | [false] ... is ... | PostDominance.cs:14:9:14:29 | ...; | false | +| PostDominance.cs:12:13:12:21 | [true] ... is ... | PostDominance.cs:13:13:13:19 | return ...; | true | +| PostDominance.cs:17:10:17:11 | enter M3 | PostDominance.cs:19:13:19:21 | [false] ... is ... | false | +| PostDominance.cs:17:10:17:11 | enter M3 | PostDominance.cs:19:13:19:21 | [true] ... is ... | true | | PostDominance.cs:17:10:17:11 | enter M3 | PostDominance.cs:20:45:20:53 | nameof(...) | true | | PostDominance.cs:17:10:17:11 | enter M3 | PostDominance.cs:21:9:21:29 | ...; | false | +| PostDominance.cs:19:13:19:21 | [false] ... is ... | PostDominance.cs:21:9:21:29 | ...; | false | +| PostDominance.cs:19:13:19:21 | [true] ... is ... | PostDominance.cs:20:45:20:53 | nameof(...) | true | | Switch.cs:10:10:10:11 | enter M2 | Switch.cs:10:10:10:11 | exit M2 (abnormal) | false | | Switch.cs:10:10:10:11 | enter M2 | Switch.cs:15:17:15:23 | return ...; | true | | Switch.cs:10:10:10:11 | enter M2 | Switch.cs:16:13:16:19 | case ...: | false | @@ -1983,7 +2140,10 @@ conditionBlock | Switch.cs:156:17:156:54 | ... switch { ... } | Switch.cs:158:13:158:49 | ...; | true | | Switch.cs:156:17:156:54 | ... switch { ... } | Switch.cs:160:13:160:49 | ...; | false | | Switch.cs:156:41:156:45 | false | Switch.cs:156:50:156:52 | "b" | true | +| TypeAccesses.cs:3:10:3:10 | enter M | TypeAccesses.cs:7:13:7:22 | [false] ... is ... | false | +| TypeAccesses.cs:3:10:3:10 | enter M | TypeAccesses.cs:7:13:7:22 | [true] ... is ... | true | | TypeAccesses.cs:3:10:3:10 | enter M | TypeAccesses.cs:7:25:7:25 | ; | true | +| TypeAccesses.cs:7:13:7:22 | [true] ... is ... | TypeAccesses.cs:7:25:7:25 | ; | true | | VarDecls.cs:19:7:19:8 | enter M3 | VarDecls.cs:25:24:25:24 | access to local variable x | true | | VarDecls.cs:19:7:19:8 | enter M3 | VarDecls.cs:25:28:25:28 | access to local variable y | false | | cflow.cs:5:17:5:20 | enter Main | cflow.cs:12:13:12:49 | ...; | true | @@ -2544,23 +2704,24 @@ conditionFlow | Conditions.cs:145:17:145:17 | access to parameter b | Conditions.cs:145:27:145:29 | [b (line 143): false] "b" | false | | Conditions.cs:146:13:146:13 | [b (line 143): false] access to parameter b | Conditions.cs:149:13:149:49 | ...; | false | | Conditions.cs:146:13:146:13 | [b (line 143): true] access to parameter b | Conditions.cs:147:13:147:49 | ...; | true | -| ExitMethods.cs:67:13:67:13 | access to parameter b | ExitMethods.cs:65:17:65:26 | exit ErrorMaybe (normal) | false | -| ExitMethods.cs:67:13:67:13 | access to parameter b | ExitMethods.cs:68:19:68:33 | object creation of type Exception | true | -| ExitMethods.cs:73:13:73:13 | access to parameter b | ExitMethods.cs:74:19:74:33 | object creation of type Exception | true | -| ExitMethods.cs:73:13:73:13 | access to parameter b | ExitMethods.cs:76:41:76:43 | "b" | false | -| ExitMethods.cs:111:16:111:25 | ... != ... | ExitMethods.cs:111:29:111:29 | 1 | true | -| ExitMethods.cs:111:16:111:25 | ... != ... | ExitMethods.cs:111:69:111:75 | "input" | false | -| ExitMethods.cs:116:16:116:30 | call to method Contains | ExitMethods.cs:116:34:116:34 | 0 | true | -| ExitMethods.cs:116:16:116:30 | call to method Contains | ExitMethods.cs:116:38:116:38 | 1 | false | -| ExitMethods.cs:121:23:121:27 | false | ExitMethods.cs:121:9:121:28 | [assertion failure] call to method IsTrue | false | -| ExitMethods.cs:131:48:131:48 | access to parameter b | ExitMethods.cs:131:33:131:49 | [assertion failure] call to method IsFalse | true | -| ExitMethods.cs:131:48:131:48 | access to parameter b | ExitMethods.cs:131:33:131:49 | [assertion success] call to method IsFalse | false | -| ExitMethods.cs:135:21:135:24 | true | ExitMethods.cs:135:9:135:25 | [assertion failure] call to method AssertFalse | true | +| ExitMethods.cs:68:13:68:13 | access to parameter b | ExitMethods.cs:66:17:66:26 | exit ErrorMaybe (normal) | false | +| ExitMethods.cs:68:13:68:13 | access to parameter b | ExitMethods.cs:69:19:69:33 | object creation of type Exception | true | +| ExitMethods.cs:74:13:74:13 | access to parameter b | ExitMethods.cs:75:19:75:33 | object creation of type Exception | true | +| ExitMethods.cs:74:13:74:13 | access to parameter b | ExitMethods.cs:77:41:77:43 | "b" | false | +| ExitMethods.cs:112:16:112:25 | ... != ... | ExitMethods.cs:112:29:112:29 | 1 | true | +| ExitMethods.cs:112:16:112:25 | ... != ... | ExitMethods.cs:112:69:112:75 | "input" | false | +| ExitMethods.cs:117:16:117:30 | call to method Contains | ExitMethods.cs:117:34:117:34 | 0 | true | +| ExitMethods.cs:117:16:117:30 | call to method Contains | ExitMethods.cs:117:38:117:38 | 1 | false | +| ExitMethods.cs:122:23:122:27 | false | ExitMethods.cs:122:9:122:28 | [assertion failure] call to method IsTrue | false | +| ExitMethods.cs:132:48:132:48 | access to parameter b | ExitMethods.cs:132:33:132:49 | [assertion failure] call to method IsFalse | true | +| ExitMethods.cs:132:48:132:48 | access to parameter b | ExitMethods.cs:132:33:132:49 | [assertion success] call to method IsFalse | false | +| ExitMethods.cs:136:21:136:24 | true | ExitMethods.cs:136:9:136:25 | [assertion failure] call to method AssertFalse | true | +| ExitMethods.cs:142:13:142:13 | access to parameter b | ExitMethods.cs:143:13:143:43 | ...; | true | +| ExitMethods.cs:142:13:142:13 | access to parameter b | ExitMethods.cs:145:13:145:53 | ...; | false | | Finally.cs:26:48:26:51 | [exception: Exception] true | Finally.cs:27:9:29:9 | {...} | true | | Finally.cs:34:21:34:24 | true | Finally.cs:34:27:34:32 | throw ...; | true | | Finally.cs:61:48:61:51 | [exception: Exception] true | Finally.cs:62:9:64:9 | {...} | true | | Finally.cs:65:35:65:51 | [exception: Exception] ... != ... | Finally.cs:66:9:67:9 | {...} | true | -| Finally.cs:65:35:65:51 | [exception: OutOfMemoryException] ... != ... | Finally.cs:66:9:67:9 | {...} | true | | Finally.cs:77:16:77:20 | ... > ... | Finally.cs:74:10:74:11 | exit M4 (normal) | false | | Finally.cs:77:16:77:20 | ... > ... | Finally.cs:78:9:100:9 | {...} | true | | Finally.cs:81:21:81:26 | ... == ... | Finally.cs:82:21:82:27 | return ...; | true | @@ -2617,20 +2778,14 @@ conditionFlow | Finally.cs:161:39:161:54 | [exception: Exception] ... == ... | Finally.cs:165:13:168:13 | catch {...} | false | | Finally.cs:161:39:161:54 | [exception: NullReferenceException] ... == ... | Finally.cs:162:13:164:13 | {...} | true | | Finally.cs:161:39:161:54 | [exception: NullReferenceException] ... == ... | Finally.cs:165:13:168:13 | catch {...} | false | -| Finally.cs:161:39:161:54 | [exception: OutOfMemoryException] ... == ... | Finally.cs:162:13:164:13 | {...} | true | -| Finally.cs:161:39:161:54 | [exception: OutOfMemoryException] ... == ... | Finally.cs:165:13:168:13 | catch {...} | false | | Finally.cs:161:39:161:54 | [finally: exception(ArgumentNullException), exception: Exception] ... == ... | Finally.cs:162:13:164:13 | [finally: exception(ArgumentNullException)] {...} | true | | Finally.cs:161:39:161:54 | [finally: exception(ArgumentNullException), exception: Exception] ... == ... | Finally.cs:165:13:168:13 | [finally: exception(ArgumentNullException)] catch {...} | false | | Finally.cs:161:39:161:54 | [finally: exception(ArgumentNullException), exception: NullReferenceException] ... == ... | Finally.cs:162:13:164:13 | [finally: exception(ArgumentNullException)] {...} | true | | Finally.cs:161:39:161:54 | [finally: exception(ArgumentNullException), exception: NullReferenceException] ... == ... | Finally.cs:165:13:168:13 | [finally: exception(ArgumentNullException)] catch {...} | false | -| Finally.cs:161:39:161:54 | [finally: exception(ArgumentNullException), exception: OutOfMemoryException] ... == ... | Finally.cs:162:13:164:13 | [finally: exception(ArgumentNullException)] {...} | true | -| Finally.cs:161:39:161:54 | [finally: exception(ArgumentNullException), exception: OutOfMemoryException] ... == ... | Finally.cs:165:13:168:13 | [finally: exception(ArgumentNullException)] catch {...} | false | | Finally.cs:161:39:161:54 | [finally: exception(Exception), exception: Exception] ... == ... | Finally.cs:162:13:164:13 | [finally: exception(Exception)] {...} | true | | Finally.cs:161:39:161:54 | [finally: exception(Exception), exception: Exception] ... == ... | Finally.cs:165:13:168:13 | [finally: exception(Exception)] catch {...} | false | | Finally.cs:161:39:161:54 | [finally: exception(Exception), exception: NullReferenceException] ... == ... | Finally.cs:162:13:164:13 | [finally: exception(Exception)] {...} | true | | Finally.cs:161:39:161:54 | [finally: exception(Exception), exception: NullReferenceException] ... == ... | Finally.cs:165:13:168:13 | [finally: exception(Exception)] catch {...} | false | -| Finally.cs:161:39:161:54 | [finally: exception(Exception), exception: OutOfMemoryException] ... == ... | Finally.cs:162:13:164:13 | [finally: exception(Exception)] {...} | true | -| Finally.cs:161:39:161:54 | [finally: exception(Exception), exception: OutOfMemoryException] ... == ... | Finally.cs:165:13:168:13 | [finally: exception(Exception)] catch {...} | false | | Finally.cs:180:17:180:18 | access to parameter b1 | Finally.cs:180:27:180:42 | [b1 (line 176): true] object creation of type ExceptionA | true | | Finally.cs:180:17:180:18 | access to parameter b1 | Finally.cs:183:9:192:9 | [b1 (line 176): false] {...} | false | | Finally.cs:186:21:186:22 | [b1 (line 176): false] access to parameter b2 | Finally.cs:176:10:176:11 | exit M9 (normal) | false | @@ -2654,18 +2809,26 @@ conditionFlow | Finally.cs:205:21:205:22 | [finally: exception(ExceptionA)] access to parameter b2 | Finally.cs:208:13:210:13 | [finally: exception(ExceptionA)] {...} | false | | Finally.cs:205:21:205:22 | access to parameter b2 | Finally.cs:205:31:205:46 | object creation of type ExceptionB | true | | Finally.cs:205:21:205:22 | access to parameter b2 | Finally.cs:208:13:210:13 | {...} | false | -| Finally.cs:209:21:209:22 | [finally(2): exception(Exception)] access to parameter b3 | Finally.cs:209:31:209:46 | [finally(2): exception(Exception)] object creation of type ExceptionC | true | -| Finally.cs:209:21:209:22 | [finally(2): exception(ExceptionB)] access to parameter b3 | Finally.cs:209:31:209:46 | [finally(2): exception(ExceptionB)] object creation of type ExceptionC | true | -| Finally.cs:209:21:209:22 | [finally: exception(Exception), finally(2): exception(Exception)] access to parameter b3 | Finally.cs:209:31:209:46 | [finally: exception(Exception), finally(2): exception(Exception)] object creation of type ExceptionC | true | -| Finally.cs:209:21:209:22 | [finally: exception(Exception), finally(2): exception(ExceptionB)] access to parameter b3 | Finally.cs:209:31:209:46 | [finally: exception(Exception), finally(2): exception(ExceptionB)] object creation of type ExceptionC | true | +| Finally.cs:209:21:209:22 | [finally(1): exception(Exception)] access to parameter b3 | Finally.cs:209:31:209:46 | [finally(1): exception(Exception)] object creation of type ExceptionC | true | +| Finally.cs:209:21:209:22 | [finally(1): exception(ExceptionB)] access to parameter b3 | Finally.cs:209:31:209:46 | [finally(1): exception(ExceptionB)] object creation of type ExceptionC | true | +| Finally.cs:209:21:209:22 | [finally: exception(Exception), finally(1): exception(Exception)] access to parameter b3 | Finally.cs:209:31:209:46 | [finally: exception(Exception), finally(1): exception(Exception)] object creation of type ExceptionC | true | +| Finally.cs:209:21:209:22 | [finally: exception(Exception), finally(1): exception(ExceptionB)] access to parameter b3 | Finally.cs:209:31:209:46 | [finally: exception(Exception), finally(1): exception(ExceptionB)] object creation of type ExceptionC | true | | Finally.cs:209:21:209:22 | [finally: exception(Exception)] access to parameter b3 | Finally.cs:209:31:209:46 | [finally: exception(Exception)] object creation of type ExceptionC | true | | Finally.cs:209:21:209:22 | [finally: exception(Exception)] access to parameter b3 | Finally.cs:211:13:211:29 | [finally: exception(Exception)] ...; | false | -| Finally.cs:209:21:209:22 | [finally: exception(ExceptionA), finally(2): exception(Exception)] access to parameter b3 | Finally.cs:209:31:209:46 | [finally: exception(ExceptionA), finally(2): exception(Exception)] object creation of type ExceptionC | true | -| Finally.cs:209:21:209:22 | [finally: exception(ExceptionA), finally(2): exception(ExceptionB)] access to parameter b3 | Finally.cs:209:31:209:46 | [finally: exception(ExceptionA), finally(2): exception(ExceptionB)] object creation of type ExceptionC | true | +| Finally.cs:209:21:209:22 | [finally: exception(ExceptionA), finally(1): exception(Exception)] access to parameter b3 | Finally.cs:209:31:209:46 | [finally: exception(ExceptionA), finally(1): exception(Exception)] object creation of type ExceptionC | true | +| Finally.cs:209:21:209:22 | [finally: exception(ExceptionA), finally(1): exception(ExceptionB)] access to parameter b3 | Finally.cs:209:31:209:46 | [finally: exception(ExceptionA), finally(1): exception(ExceptionB)] object creation of type ExceptionC | true | | Finally.cs:209:21:209:22 | [finally: exception(ExceptionA)] access to parameter b3 | Finally.cs:209:31:209:46 | [finally: exception(ExceptionA)] object creation of type ExceptionC | true | | Finally.cs:209:21:209:22 | [finally: exception(ExceptionA)] access to parameter b3 | Finally.cs:211:13:211:29 | [finally: exception(ExceptionA)] ...; | false | | Finally.cs:209:21:209:22 | access to parameter b3 | Finally.cs:209:31:209:46 | object creation of type ExceptionC | true | | Finally.cs:209:21:209:22 | access to parameter b3 | Finally.cs:211:13:211:29 | ...; | false | +| Finally.cs:239:21:239:22 | access to parameter b1 | Finally.cs:240:27:240:42 | object creation of type ExceptionA | true | +| Finally.cs:239:21:239:22 | access to parameter b1 | Finally.cs:243:13:253:13 | {...} | false | +| Finally.cs:246:25:246:26 | [finally: exception(Exception)] access to parameter b2 | Finally.cs:247:31:247:46 | [finally: exception(Exception)] object creation of type ExceptionA | true | +| Finally.cs:246:25:246:26 | [finally: exception(Exception)] access to parameter b2 | Finally.cs:250:17:252:17 | [finally: exception(Exception)] {...} | false | +| Finally.cs:246:25:246:26 | [finally: exception(ExceptionA)] access to parameter b2 | Finally.cs:247:31:247:46 | [finally: exception(ExceptionA)] object creation of type ExceptionA | true | +| Finally.cs:246:25:246:26 | [finally: exception(ExceptionA)] access to parameter b2 | Finally.cs:250:17:252:17 | [finally: exception(ExceptionA)] {...} | false | +| Finally.cs:246:25:246:26 | access to parameter b2 | Finally.cs:247:31:247:46 | object creation of type ExceptionA | true | +| Finally.cs:246:25:246:26 | access to parameter b2 | Finally.cs:250:17:252:17 | {...} | false | | LoopUnrolling.cs:9:13:9:28 | ... == ... | LoopUnrolling.cs:10:13:10:19 | return ...; | true | | LoopUnrolling.cs:9:13:9:28 | ... == ... | LoopUnrolling.cs:11:29:11:32 | access to parameter args | false | | LoopUnrolling.cs:60:17:60:17 | [b (line 55): false] access to parameter b | LoopUnrolling.cs:62:13:63:37 | [b (line 55): false] if (...) ... | false | @@ -2695,18 +2858,26 @@ conditionFlow | NullCoalescing.cs:11:51:11:58 | [true] ... && ... | NullCoalescing.cs:11:44:11:59 | [true] ... ?? ... | true | | NullCoalescing.cs:11:57:11:58 | access to parameter b3 | NullCoalescing.cs:11:51:11:58 | [false] ... && ... | false | | NullCoalescing.cs:11:57:11:58 | access to parameter b3 | NullCoalescing.cs:11:51:11:58 | [true] ... && ... | true | -| Patterns.cs:8:13:8:23 | ... is ... | Patterns.cs:9:9:11:9 | {...} | true | -| Patterns.cs:8:13:8:23 | ... is ... | Patterns.cs:12:14:18:9 | if (...) ... | false | -| Patterns.cs:12:18:12:31 | ... is ... | Patterns.cs:13:9:15:9 | {...} | true | -| Patterns.cs:12:18:12:31 | ... is ... | Patterns.cs:16:14:18:9 | if (...) ... | false | -| Patterns.cs:16:18:16:28 | ... is ... | Patterns.cs:17:9:18:9 | {...} | true | -| Patterns.cs:16:18:16:28 | ... is ... | Patterns.cs:20:9:38:9 | switch (...) {...} | false | +| Patterns.cs:8:13:8:23 | [false] ... is ... | Patterns.cs:12:14:18:9 | if (...) ... | false | +| Patterns.cs:8:13:8:23 | [true] ... is ... | Patterns.cs:9:9:11:9 | {...} | true | +| Patterns.cs:12:18:12:31 | [false] ... is ... | Patterns.cs:16:14:18:9 | if (...) ... | false | +| Patterns.cs:12:18:12:31 | [true] ... is ... | Patterns.cs:13:9:15:9 | {...} | true | +| Patterns.cs:16:18:16:28 | [false] ... is ... | Patterns.cs:20:9:38:9 | switch (...) {...} | false | +| Patterns.cs:16:18:16:28 | [true] ... is ... | Patterns.cs:17:9:18:9 | {...} | true | | Patterns.cs:24:30:24:35 | ... > ... | Patterns.cs:25:17:25:52 | ...; | true | | Patterns.cs:24:30:24:35 | ... > ... | Patterns.cs:27:13:27:24 | case ...: | false | -| PostDominance.cs:12:13:12:21 | ... is ... | PostDominance.cs:13:13:13:19 | return ...; | true | -| PostDominance.cs:12:13:12:21 | ... is ... | PostDominance.cs:14:9:14:29 | ...; | false | -| PostDominance.cs:19:13:19:21 | ... is ... | PostDominance.cs:20:45:20:53 | nameof(...) | true | -| PostDominance.cs:19:13:19:21 | ... is ... | PostDominance.cs:21:9:21:29 | ...; | false | +| Patterns.cs:51:9:51:21 | [false] ... is ... | Patterns.cs:51:34:51:34 | access to parameter c | false | +| Patterns.cs:51:9:51:21 | [true] ... is ... | Patterns.cs:51:25:51:25 | access to parameter c | true | +| Patterns.cs:85:39:85:53 | [false] ... is ... | Patterns.cs:85:67:85:69 | "2" | false | +| Patterns.cs:85:39:85:53 | [true] ... is ... | Patterns.cs:85:57:85:63 | "not 2" | true | +| Patterns.cs:87:39:87:54 | [false] ... is ... | Patterns.cs:87:64:87:70 | "not 1" | false | +| Patterns.cs:87:39:87:54 | [true] ... is ... | Patterns.cs:87:58:87:60 | "1" | true | +| Patterns.cs:95:13:95:40 | [false] ... is ... | Patterns.cs:93:17:93:19 | exit M10 (normal) | false | +| Patterns.cs:95:13:95:40 | [true] ... is ... | Patterns.cs:96:9:98:9 | {...} | true | +| PostDominance.cs:12:13:12:21 | [false] ... is ... | PostDominance.cs:14:9:14:29 | ...; | false | +| PostDominance.cs:12:13:12:21 | [true] ... is ... | PostDominance.cs:13:13:13:19 | return ...; | true | +| PostDominance.cs:19:13:19:21 | [false] ... is ... | PostDominance.cs:21:9:21:29 | ...; | false | +| PostDominance.cs:19:13:19:21 | [true] ... is ... | PostDominance.cs:20:45:20:53 | nameof(...) | true | | Switch.cs:21:21:21:29 | ... == ... | Switch.cs:22:21:22:27 | return ...; | true | | Switch.cs:21:21:21:29 | ... == ... | Switch.cs:23:27:23:27 | 0 | false | | Switch.cs:24:32:24:43 | ... > ... | Switch.cs:24:32:24:55 | [false] ... && ... | false | @@ -2733,8 +2904,8 @@ conditionFlow | Switch.cs:125:42:125:46 | false | Switch.cs:125:37:125:46 | [false] ... => ... | false | | Switch.cs:157:13:157:13 | access to parameter b | Switch.cs:158:13:158:49 | ...; | true | | Switch.cs:157:13:157:13 | access to parameter b | Switch.cs:160:13:160:49 | ...; | false | -| TypeAccesses.cs:7:13:7:22 | ... is ... | TypeAccesses.cs:7:25:7:25 | ; | true | -| TypeAccesses.cs:7:13:7:22 | ... is ... | TypeAccesses.cs:8:9:8:28 | ... ...; | false | +| TypeAccesses.cs:7:13:7:22 | [false] ... is ... | TypeAccesses.cs:8:9:8:28 | ... ...; | false | +| TypeAccesses.cs:7:13:7:22 | [true] ... is ... | TypeAccesses.cs:7:25:7:25 | ; | true | | VarDecls.cs:25:20:25:20 | access to parameter b | VarDecls.cs:25:24:25:24 | access to local variable x | true | | VarDecls.cs:25:20:25:20 | access to parameter b | VarDecls.cs:25:28:25:28 | access to local variable y | false | | cflow.cs:11:13:11:17 | ... > ... | cflow.cs:12:13:12:49 | ...; | true | diff --git a/csharp/ql/test/library-tests/controlflow/graph/Dominance.expected b/csharp/ql/test/library-tests/controlflow/graph/Dominance.expected index bbc1b35641b..2583984542d 100644 --- a/csharp/ql/test/library-tests/controlflow/graph/Dominance.expected +++ b/csharp/ql/test/library-tests/controlflow/graph/Dominance.expected @@ -1496,154 +1496,165 @@ dominance | Conditions.cs:149:38:149:47 | $"..." | Conditions.cs:149:13:149:48 | call to method WriteLine | | Conditions.cs:149:40:149:43 | "b = " | Conditions.cs:149:45:149:45 | access to local variable s | | Conditions.cs:149:45:149:45 | access to local variable s | Conditions.cs:149:38:149:47 | $"..." | -| ExitMethods.cs:7:10:7:11 | enter M1 | ExitMethods.cs:8:5:11:5 | {...} | -| ExitMethods.cs:7:10:7:11 | exit M1 (normal) | ExitMethods.cs:7:10:7:11 | exit M1 | -| ExitMethods.cs:8:5:11:5 | {...} | ExitMethods.cs:9:9:9:25 | ...; | -| ExitMethods.cs:9:9:9:24 | call to method ErrorMaybe | ExitMethods.cs:10:9:10:15 | return ...; | -| ExitMethods.cs:9:9:9:25 | ...; | ExitMethods.cs:9:20:9:23 | true | -| ExitMethods.cs:9:20:9:23 | true | ExitMethods.cs:9:9:9:24 | call to method ErrorMaybe | -| ExitMethods.cs:10:9:10:15 | return ...; | ExitMethods.cs:7:10:7:11 | exit M1 (normal) | -| ExitMethods.cs:13:10:13:11 | enter M2 | ExitMethods.cs:14:5:17:5 | {...} | -| ExitMethods.cs:13:10:13:11 | exit M2 (normal) | ExitMethods.cs:13:10:13:11 | exit M2 | -| ExitMethods.cs:14:5:17:5 | {...} | ExitMethods.cs:15:9:15:26 | ...; | -| ExitMethods.cs:15:9:15:25 | call to method ErrorMaybe | ExitMethods.cs:16:9:16:15 | return ...; | -| ExitMethods.cs:15:9:15:26 | ...; | ExitMethods.cs:15:20:15:24 | false | -| ExitMethods.cs:15:20:15:24 | false | ExitMethods.cs:15:9:15:25 | call to method ErrorMaybe | -| ExitMethods.cs:16:9:16:15 | return ...; | ExitMethods.cs:13:10:13:11 | exit M2 (normal) | -| ExitMethods.cs:19:10:19:11 | enter M3 | ExitMethods.cs:20:5:23:5 | {...} | -| ExitMethods.cs:19:10:19:11 | exit M3 (abnormal) | ExitMethods.cs:19:10:19:11 | exit M3 | -| ExitMethods.cs:20:5:23:5 | {...} | ExitMethods.cs:21:9:21:26 | ...; | -| ExitMethods.cs:21:9:21:25 | call to method ErrorAlways | ExitMethods.cs:19:10:19:11 | exit M3 (abnormal) | -| ExitMethods.cs:21:9:21:26 | ...; | ExitMethods.cs:21:21:21:24 | true | -| ExitMethods.cs:21:21:21:24 | true | ExitMethods.cs:21:9:21:25 | call to method ErrorAlways | -| ExitMethods.cs:25:10:25:11 | enter M4 | ExitMethods.cs:26:5:29:5 | {...} | -| ExitMethods.cs:25:10:25:11 | exit M4 (abnormal) | ExitMethods.cs:25:10:25:11 | exit M4 | -| ExitMethods.cs:26:5:29:5 | {...} | ExitMethods.cs:27:9:27:15 | ...; | -| ExitMethods.cs:27:9:27:14 | call to method Exit | ExitMethods.cs:25:10:25:11 | exit M4 (abnormal) | -| ExitMethods.cs:27:9:27:14 | this access | ExitMethods.cs:27:9:27:14 | call to method Exit | -| ExitMethods.cs:27:9:27:15 | ...; | ExitMethods.cs:27:9:27:14 | this access | -| ExitMethods.cs:31:10:31:11 | enter M5 | ExitMethods.cs:32:5:35:5 | {...} | -| ExitMethods.cs:31:10:31:11 | exit M5 (abnormal) | ExitMethods.cs:31:10:31:11 | exit M5 | -| ExitMethods.cs:32:5:35:5 | {...} | ExitMethods.cs:33:9:33:26 | ...; | -| ExitMethods.cs:33:9:33:25 | call to method ApplicationExit | ExitMethods.cs:31:10:31:11 | exit M5 (abnormal) | -| ExitMethods.cs:33:9:33:25 | this access | ExitMethods.cs:33:9:33:25 | call to method ApplicationExit | -| ExitMethods.cs:33:9:33:26 | ...; | ExitMethods.cs:33:9:33:25 | this access | -| ExitMethods.cs:37:10:37:11 | enter M6 | ExitMethods.cs:38:5:51:5 | {...} | -| ExitMethods.cs:37:10:37:11 | exit M6 (normal) | ExitMethods.cs:37:10:37:11 | exit M6 | -| ExitMethods.cs:38:5:51:5 | {...} | ExitMethods.cs:39:9:50:9 | try {...} ... | -| ExitMethods.cs:39:9:50:9 | try {...} ... | ExitMethods.cs:40:9:42:9 | {...} | -| ExitMethods.cs:40:9:42:9 | {...} | ExitMethods.cs:41:13:41:31 | ...; | -| ExitMethods.cs:41:13:41:30 | call to method ErrorAlways | ExitMethods.cs:43:9:46:9 | [exception: ArgumentException] catch (...) {...} | -| ExitMethods.cs:41:13:41:30 | call to method ErrorAlways | ExitMethods.cs:43:9:46:9 | [exception: Exception] catch (...) {...} | -| ExitMethods.cs:41:13:41:31 | ...; | ExitMethods.cs:41:25:41:29 | false | -| ExitMethods.cs:41:25:41:29 | false | ExitMethods.cs:41:13:41:30 | call to method ErrorAlways | -| ExitMethods.cs:43:9:46:9 | [exception: Exception] catch (...) {...} | ExitMethods.cs:47:9:50:9 | [exception: Exception] catch (...) {...} | -| ExitMethods.cs:44:9:46:9 | {...} | ExitMethods.cs:45:13:45:19 | return ...; | -| ExitMethods.cs:47:9:50:9 | [exception: Exception] catch (...) {...} | ExitMethods.cs:48:9:50:9 | {...} | -| ExitMethods.cs:48:9:50:9 | {...} | ExitMethods.cs:49:13:49:19 | return ...; | -| ExitMethods.cs:53:10:53:11 | enter M7 | ExitMethods.cs:54:5:57:5 | {...} | -| ExitMethods.cs:53:10:53:11 | exit M7 (abnormal) | ExitMethods.cs:53:10:53:11 | exit M7 | -| ExitMethods.cs:54:5:57:5 | {...} | ExitMethods.cs:55:9:55:23 | ...; | -| ExitMethods.cs:55:9:55:22 | call to method ErrorAlways2 | ExitMethods.cs:53:10:53:11 | exit M7 (abnormal) | -| ExitMethods.cs:55:9:55:23 | ...; | ExitMethods.cs:55:9:55:22 | call to method ErrorAlways2 | -| ExitMethods.cs:59:10:59:11 | enter M8 | ExitMethods.cs:60:5:63:5 | {...} | -| ExitMethods.cs:59:10:59:11 | exit M8 (abnormal) | ExitMethods.cs:59:10:59:11 | exit M8 | -| ExitMethods.cs:60:5:63:5 | {...} | ExitMethods.cs:61:9:61:23 | ...; | -| ExitMethods.cs:61:9:61:22 | call to method ErrorAlways3 | ExitMethods.cs:59:10:59:11 | exit M8 (abnormal) | -| ExitMethods.cs:61:9:61:23 | ...; | ExitMethods.cs:61:9:61:22 | call to method ErrorAlways3 | -| ExitMethods.cs:65:17:65:26 | enter ErrorMaybe | ExitMethods.cs:66:5:69:5 | {...} | -| ExitMethods.cs:66:5:69:5 | {...} | ExitMethods.cs:67:9:68:34 | if (...) ... | -| ExitMethods.cs:67:9:68:34 | if (...) ... | ExitMethods.cs:67:13:67:13 | access to parameter b | -| ExitMethods.cs:67:13:67:13 | access to parameter b | ExitMethods.cs:65:17:65:26 | exit ErrorMaybe (normal) | -| ExitMethods.cs:67:13:67:13 | access to parameter b | ExitMethods.cs:68:19:68:33 | object creation of type Exception | -| ExitMethods.cs:68:13:68:34 | throw ...; | ExitMethods.cs:65:17:65:26 | exit ErrorMaybe (abnormal) | -| ExitMethods.cs:68:19:68:33 | object creation of type Exception | ExitMethods.cs:68:13:68:34 | throw ...; | -| ExitMethods.cs:71:17:71:27 | enter ErrorAlways | ExitMethods.cs:72:5:77:5 | {...} | -| ExitMethods.cs:71:17:71:27 | exit ErrorAlways (abnormal) | ExitMethods.cs:71:17:71:27 | exit ErrorAlways | -| ExitMethods.cs:72:5:77:5 | {...} | ExitMethods.cs:73:9:76:45 | if (...) ... | -| ExitMethods.cs:73:9:76:45 | if (...) ... | ExitMethods.cs:73:13:73:13 | access to parameter b | -| ExitMethods.cs:73:13:73:13 | access to parameter b | ExitMethods.cs:74:19:74:33 | object creation of type Exception | -| ExitMethods.cs:73:13:73:13 | access to parameter b | ExitMethods.cs:76:41:76:43 | "b" | -| ExitMethods.cs:74:19:74:33 | object creation of type Exception | ExitMethods.cs:74:13:74:34 | throw ...; | -| ExitMethods.cs:76:19:76:44 | object creation of type ArgumentException | ExitMethods.cs:76:13:76:45 | throw ...; | -| ExitMethods.cs:76:41:76:43 | "b" | ExitMethods.cs:76:19:76:44 | object creation of type ArgumentException | -| ExitMethods.cs:79:17:79:28 | enter ErrorAlways2 | ExitMethods.cs:80:5:82:5 | {...} | -| ExitMethods.cs:79:17:79:28 | exit ErrorAlways2 (abnormal) | ExitMethods.cs:79:17:79:28 | exit ErrorAlways2 | -| ExitMethods.cs:80:5:82:5 | {...} | ExitMethods.cs:81:15:81:29 | object creation of type Exception | -| ExitMethods.cs:81:9:81:30 | throw ...; | ExitMethods.cs:79:17:79:28 | exit ErrorAlways2 (abnormal) | -| ExitMethods.cs:81:15:81:29 | object creation of type Exception | ExitMethods.cs:81:9:81:30 | throw ...; | -| ExitMethods.cs:84:17:84:28 | enter ErrorAlways3 | ExitMethods.cs:84:41:84:55 | object creation of type Exception | -| ExitMethods.cs:84:17:84:28 | exit ErrorAlways3 (abnormal) | ExitMethods.cs:84:17:84:28 | exit ErrorAlways3 | -| ExitMethods.cs:84:35:84:55 | throw ... | ExitMethods.cs:84:17:84:28 | exit ErrorAlways3 (abnormal) | -| ExitMethods.cs:84:41:84:55 | object creation of type Exception | ExitMethods.cs:84:35:84:55 | throw ... | -| ExitMethods.cs:86:10:86:13 | enter Exit | ExitMethods.cs:87:5:89:5 | {...} | -| ExitMethods.cs:86:10:86:13 | exit Exit (abnormal) | ExitMethods.cs:86:10:86:13 | exit Exit | -| ExitMethods.cs:87:5:89:5 | {...} | ExitMethods.cs:88:9:88:28 | ...; | -| ExitMethods.cs:88:9:88:27 | call to method Exit | ExitMethods.cs:86:10:86:13 | exit Exit (abnormal) | -| ExitMethods.cs:88:9:88:28 | ...; | ExitMethods.cs:88:26:88:26 | 0 | -| ExitMethods.cs:88:26:88:26 | 0 | ExitMethods.cs:88:9:88:27 | call to method Exit | -| ExitMethods.cs:91:10:91:18 | enter ExitInTry | ExitMethods.cs:92:5:102:5 | {...} | -| ExitMethods.cs:91:10:91:18 | exit ExitInTry (abnormal) | ExitMethods.cs:91:10:91:18 | exit ExitInTry | -| ExitMethods.cs:92:5:102:5 | {...} | ExitMethods.cs:93:9:101:9 | try {...} ... | -| ExitMethods.cs:93:9:101:9 | try {...} ... | ExitMethods.cs:94:9:96:9 | {...} | -| ExitMethods.cs:94:9:96:9 | {...} | ExitMethods.cs:95:13:95:19 | ...; | -| ExitMethods.cs:95:13:95:18 | call to method Exit | ExitMethods.cs:91:10:91:18 | exit ExitInTry (abnormal) | -| ExitMethods.cs:95:13:95:18 | this access | ExitMethods.cs:95:13:95:18 | call to method Exit | -| ExitMethods.cs:95:13:95:19 | ...; | ExitMethods.cs:95:13:95:18 | this access | -| ExitMethods.cs:104:10:104:24 | enter ApplicationExit | ExitMethods.cs:105:5:107:5 | {...} | -| ExitMethods.cs:104:10:104:24 | exit ApplicationExit (abnormal) | ExitMethods.cs:104:10:104:24 | exit ApplicationExit | -| ExitMethods.cs:105:5:107:5 | {...} | ExitMethods.cs:106:9:106:48 | ...; | -| ExitMethods.cs:106:9:106:47 | call to method Exit | ExitMethods.cs:104:10:104:24 | exit ApplicationExit (abnormal) | -| ExitMethods.cs:106:9:106:48 | ...; | ExitMethods.cs:106:9:106:47 | call to method Exit | -| ExitMethods.cs:109:13:109:21 | enter ThrowExpr | ExitMethods.cs:110:5:112:5 | {...} | -| ExitMethods.cs:110:5:112:5 | {...} | ExitMethods.cs:111:16:111:20 | access to parameter input | -| ExitMethods.cs:111:9:111:77 | return ...; | ExitMethods.cs:109:13:109:21 | exit ThrowExpr (normal) | -| ExitMethods.cs:111:16:111:20 | access to parameter input | ExitMethods.cs:111:25:111:25 | 0 | -| ExitMethods.cs:111:16:111:25 | ... != ... | ExitMethods.cs:111:29:111:29 | 1 | -| ExitMethods.cs:111:16:111:25 | ... != ... | ExitMethods.cs:111:69:111:75 | "input" | -| ExitMethods.cs:111:16:111:76 | ... ? ... : ... | ExitMethods.cs:111:9:111:77 | return ...; | -| ExitMethods.cs:111:25:111:25 | 0 | ExitMethods.cs:111:25:111:25 | (...) ... | -| ExitMethods.cs:111:25:111:25 | (...) ... | ExitMethods.cs:111:16:111:25 | ... != ... | -| ExitMethods.cs:111:29:111:29 | 1 | ExitMethods.cs:111:29:111:29 | (...) ... | -| ExitMethods.cs:111:29:111:29 | (...) ... | ExitMethods.cs:111:33:111:37 | access to parameter input | -| ExitMethods.cs:111:29:111:37 | ... / ... | ExitMethods.cs:111:16:111:76 | ... ? ... : ... | -| ExitMethods.cs:111:33:111:37 | access to parameter input | ExitMethods.cs:111:29:111:37 | ... / ... | -| ExitMethods.cs:111:41:111:76 | throw ... | ExitMethods.cs:109:13:109:21 | exit ThrowExpr (abnormal) | -| ExitMethods.cs:111:47:111:76 | object creation of type ArgumentException | ExitMethods.cs:111:41:111:76 | throw ... | -| ExitMethods.cs:111:69:111:75 | "input" | ExitMethods.cs:111:47:111:76 | object creation of type ArgumentException | -| ExitMethods.cs:114:16:114:34 | enter ExtensionMethodCall | ExitMethods.cs:115:5:117:5 | {...} | -| ExitMethods.cs:114:16:114:34 | exit ExtensionMethodCall (normal) | ExitMethods.cs:114:16:114:34 | exit ExtensionMethodCall | -| ExitMethods.cs:115:5:117:5 | {...} | ExitMethods.cs:116:16:116:16 | access to parameter s | -| ExitMethods.cs:116:9:116:39 | return ...; | ExitMethods.cs:114:16:114:34 | exit ExtensionMethodCall (normal) | -| ExitMethods.cs:116:16:116:16 | access to parameter s | ExitMethods.cs:116:27:116:29 | - | -| ExitMethods.cs:116:16:116:30 | call to method Contains | ExitMethods.cs:116:34:116:34 | 0 | -| ExitMethods.cs:116:16:116:30 | call to method Contains | ExitMethods.cs:116:38:116:38 | 1 | -| ExitMethods.cs:116:16:116:38 | ... ? ... : ... | ExitMethods.cs:116:9:116:39 | return ...; | -| ExitMethods.cs:116:27:116:29 | - | ExitMethods.cs:116:16:116:30 | call to method Contains | -| ExitMethods.cs:119:17:119:32 | enter FailingAssertion | ExitMethods.cs:120:5:123:5 | {...} | -| ExitMethods.cs:119:17:119:32 | exit FailingAssertion (abnormal) | ExitMethods.cs:119:17:119:32 | exit FailingAssertion | -| ExitMethods.cs:120:5:123:5 | {...} | ExitMethods.cs:121:9:121:29 | ...; | -| ExitMethods.cs:121:9:121:28 | [assertion failure] call to method IsTrue | ExitMethods.cs:119:17:119:32 | exit FailingAssertion (abnormal) | -| ExitMethods.cs:121:9:121:29 | ...; | ExitMethods.cs:121:23:121:27 | false | -| ExitMethods.cs:121:23:121:27 | false | ExitMethods.cs:121:9:121:28 | [assertion failure] call to method IsTrue | -| ExitMethods.cs:125:17:125:33 | enter FailingAssertion2 | ExitMethods.cs:126:5:129:5 | {...} | -| ExitMethods.cs:125:17:125:33 | exit FailingAssertion2 (abnormal) | ExitMethods.cs:125:17:125:33 | exit FailingAssertion2 | -| ExitMethods.cs:126:5:129:5 | {...} | ExitMethods.cs:127:9:127:27 | ...; | -| ExitMethods.cs:127:9:127:26 | call to method FailingAssertion | ExitMethods.cs:125:17:125:33 | exit FailingAssertion2 (abnormal) | -| ExitMethods.cs:127:9:127:26 | this access | ExitMethods.cs:127:9:127:26 | call to method FailingAssertion | -| ExitMethods.cs:127:9:127:27 | ...; | ExitMethods.cs:127:9:127:26 | this access | -| ExitMethods.cs:131:10:131:20 | enter AssertFalse | ExitMethods.cs:131:48:131:48 | access to parameter b | -| ExitMethods.cs:131:33:131:49 | [assertion failure] call to method IsFalse | ExitMethods.cs:131:10:131:20 | exit AssertFalse (abnormal) | -| ExitMethods.cs:131:33:131:49 | [assertion success] call to method IsFalse | ExitMethods.cs:131:10:131:20 | exit AssertFalse (normal) | -| ExitMethods.cs:131:48:131:48 | access to parameter b | ExitMethods.cs:131:33:131:49 | [assertion failure] call to method IsFalse | -| ExitMethods.cs:131:48:131:48 | access to parameter b | ExitMethods.cs:131:33:131:49 | [assertion success] call to method IsFalse | -| ExitMethods.cs:133:17:133:33 | enter FailingAssertion3 | ExitMethods.cs:134:5:137:5 | {...} | -| ExitMethods.cs:133:17:133:33 | exit FailingAssertion3 (abnormal) | ExitMethods.cs:133:17:133:33 | exit FailingAssertion3 | -| ExitMethods.cs:134:5:137:5 | {...} | ExitMethods.cs:135:9:135:26 | ...; | -| ExitMethods.cs:135:9:135:25 | [assertion failure] call to method AssertFalse | ExitMethods.cs:133:17:133:33 | exit FailingAssertion3 (abnormal) | -| ExitMethods.cs:135:9:135:25 | this access | ExitMethods.cs:135:21:135:24 | true | -| ExitMethods.cs:135:9:135:26 | ...; | ExitMethods.cs:135:9:135:25 | this access | -| ExitMethods.cs:135:21:135:24 | true | ExitMethods.cs:135:9:135:25 | [assertion failure] call to method AssertFalse | +| ExitMethods.cs:8:10:8:11 | enter M1 | ExitMethods.cs:9:5:12:5 | {...} | +| ExitMethods.cs:8:10:8:11 | exit M1 (normal) | ExitMethods.cs:8:10:8:11 | exit M1 | +| ExitMethods.cs:9:5:12:5 | {...} | ExitMethods.cs:10:9:10:25 | ...; | +| ExitMethods.cs:10:9:10:24 | call to method ErrorMaybe | ExitMethods.cs:11:9:11:15 | return ...; | +| ExitMethods.cs:10:9:10:25 | ...; | ExitMethods.cs:10:20:10:23 | true | +| ExitMethods.cs:10:20:10:23 | true | ExitMethods.cs:10:9:10:24 | call to method ErrorMaybe | +| ExitMethods.cs:11:9:11:15 | return ...; | ExitMethods.cs:8:10:8:11 | exit M1 (normal) | +| ExitMethods.cs:14:10:14:11 | enter M2 | ExitMethods.cs:15:5:18:5 | {...} | +| ExitMethods.cs:14:10:14:11 | exit M2 (normal) | ExitMethods.cs:14:10:14:11 | exit M2 | +| ExitMethods.cs:15:5:18:5 | {...} | ExitMethods.cs:16:9:16:26 | ...; | +| ExitMethods.cs:16:9:16:25 | call to method ErrorMaybe | ExitMethods.cs:17:9:17:15 | return ...; | +| ExitMethods.cs:16:9:16:26 | ...; | ExitMethods.cs:16:20:16:24 | false | +| ExitMethods.cs:16:20:16:24 | false | ExitMethods.cs:16:9:16:25 | call to method ErrorMaybe | +| ExitMethods.cs:17:9:17:15 | return ...; | ExitMethods.cs:14:10:14:11 | exit M2 (normal) | +| ExitMethods.cs:20:10:20:11 | enter M3 | ExitMethods.cs:21:5:24:5 | {...} | +| ExitMethods.cs:20:10:20:11 | exit M3 (abnormal) | ExitMethods.cs:20:10:20:11 | exit M3 | +| ExitMethods.cs:21:5:24:5 | {...} | ExitMethods.cs:22:9:22:26 | ...; | +| ExitMethods.cs:22:9:22:25 | call to method ErrorAlways | ExitMethods.cs:20:10:20:11 | exit M3 (abnormal) | +| ExitMethods.cs:22:9:22:26 | ...; | ExitMethods.cs:22:21:22:24 | true | +| ExitMethods.cs:22:21:22:24 | true | ExitMethods.cs:22:9:22:25 | call to method ErrorAlways | +| ExitMethods.cs:26:10:26:11 | enter M4 | ExitMethods.cs:27:5:30:5 | {...} | +| ExitMethods.cs:26:10:26:11 | exit M4 (abnormal) | ExitMethods.cs:26:10:26:11 | exit M4 | +| ExitMethods.cs:27:5:30:5 | {...} | ExitMethods.cs:28:9:28:15 | ...; | +| ExitMethods.cs:28:9:28:14 | call to method Exit | ExitMethods.cs:26:10:26:11 | exit M4 (abnormal) | +| ExitMethods.cs:28:9:28:14 | this access | ExitMethods.cs:28:9:28:14 | call to method Exit | +| ExitMethods.cs:28:9:28:15 | ...; | ExitMethods.cs:28:9:28:14 | this access | +| ExitMethods.cs:32:10:32:11 | enter M5 | ExitMethods.cs:33:5:36:5 | {...} | +| ExitMethods.cs:32:10:32:11 | exit M5 (abnormal) | ExitMethods.cs:32:10:32:11 | exit M5 | +| ExitMethods.cs:33:5:36:5 | {...} | ExitMethods.cs:34:9:34:26 | ...; | +| ExitMethods.cs:34:9:34:25 | call to method ApplicationExit | ExitMethods.cs:32:10:32:11 | exit M5 (abnormal) | +| ExitMethods.cs:34:9:34:25 | this access | ExitMethods.cs:34:9:34:25 | call to method ApplicationExit | +| ExitMethods.cs:34:9:34:26 | ...; | ExitMethods.cs:34:9:34:25 | this access | +| ExitMethods.cs:38:10:38:11 | enter M6 | ExitMethods.cs:39:5:52:5 | {...} | +| ExitMethods.cs:38:10:38:11 | exit M6 (normal) | ExitMethods.cs:38:10:38:11 | exit M6 | +| ExitMethods.cs:39:5:52:5 | {...} | ExitMethods.cs:40:9:51:9 | try {...} ... | +| ExitMethods.cs:40:9:51:9 | try {...} ... | ExitMethods.cs:41:9:43:9 | {...} | +| ExitMethods.cs:41:9:43:9 | {...} | ExitMethods.cs:42:13:42:31 | ...; | +| ExitMethods.cs:42:13:42:30 | call to method ErrorAlways | ExitMethods.cs:44:9:47:9 | [exception: ArgumentException] catch (...) {...} | +| ExitMethods.cs:42:13:42:30 | call to method ErrorAlways | ExitMethods.cs:44:9:47:9 | [exception: Exception] catch (...) {...} | +| ExitMethods.cs:42:13:42:31 | ...; | ExitMethods.cs:42:25:42:29 | false | +| ExitMethods.cs:42:25:42:29 | false | ExitMethods.cs:42:13:42:30 | call to method ErrorAlways | +| ExitMethods.cs:44:9:47:9 | [exception: Exception] catch (...) {...} | ExitMethods.cs:48:9:51:9 | [exception: Exception] catch (...) {...} | +| ExitMethods.cs:45:9:47:9 | {...} | ExitMethods.cs:46:13:46:19 | return ...; | +| ExitMethods.cs:48:9:51:9 | [exception: Exception] catch (...) {...} | ExitMethods.cs:49:9:51:9 | {...} | +| ExitMethods.cs:49:9:51:9 | {...} | ExitMethods.cs:50:13:50:19 | return ...; | +| ExitMethods.cs:54:10:54:11 | enter M7 | ExitMethods.cs:55:5:58:5 | {...} | +| ExitMethods.cs:54:10:54:11 | exit M7 (abnormal) | ExitMethods.cs:54:10:54:11 | exit M7 | +| ExitMethods.cs:55:5:58:5 | {...} | ExitMethods.cs:56:9:56:23 | ...; | +| ExitMethods.cs:56:9:56:22 | call to method ErrorAlways2 | ExitMethods.cs:54:10:54:11 | exit M7 (abnormal) | +| ExitMethods.cs:56:9:56:23 | ...; | ExitMethods.cs:56:9:56:22 | call to method ErrorAlways2 | +| ExitMethods.cs:60:10:60:11 | enter M8 | ExitMethods.cs:61:5:64:5 | {...} | +| ExitMethods.cs:60:10:60:11 | exit M8 (abnormal) | ExitMethods.cs:60:10:60:11 | exit M8 | +| ExitMethods.cs:61:5:64:5 | {...} | ExitMethods.cs:62:9:62:23 | ...; | +| ExitMethods.cs:62:9:62:22 | call to method ErrorAlways3 | ExitMethods.cs:60:10:60:11 | exit M8 (abnormal) | +| ExitMethods.cs:62:9:62:23 | ...; | ExitMethods.cs:62:9:62:22 | call to method ErrorAlways3 | +| ExitMethods.cs:66:17:66:26 | enter ErrorMaybe | ExitMethods.cs:67:5:70:5 | {...} | +| ExitMethods.cs:67:5:70:5 | {...} | ExitMethods.cs:68:9:69:34 | if (...) ... | +| ExitMethods.cs:68:9:69:34 | if (...) ... | ExitMethods.cs:68:13:68:13 | access to parameter b | +| ExitMethods.cs:68:13:68:13 | access to parameter b | ExitMethods.cs:66:17:66:26 | exit ErrorMaybe (normal) | +| ExitMethods.cs:68:13:68:13 | access to parameter b | ExitMethods.cs:69:19:69:33 | object creation of type Exception | +| ExitMethods.cs:69:13:69:34 | throw ...; | ExitMethods.cs:66:17:66:26 | exit ErrorMaybe (abnormal) | +| ExitMethods.cs:69:19:69:33 | object creation of type Exception | ExitMethods.cs:69:13:69:34 | throw ...; | +| ExitMethods.cs:72:17:72:27 | enter ErrorAlways | ExitMethods.cs:73:5:78:5 | {...} | +| ExitMethods.cs:72:17:72:27 | exit ErrorAlways (abnormal) | ExitMethods.cs:72:17:72:27 | exit ErrorAlways | +| ExitMethods.cs:73:5:78:5 | {...} | ExitMethods.cs:74:9:77:45 | if (...) ... | +| ExitMethods.cs:74:9:77:45 | if (...) ... | ExitMethods.cs:74:13:74:13 | access to parameter b | +| ExitMethods.cs:74:13:74:13 | access to parameter b | ExitMethods.cs:75:19:75:33 | object creation of type Exception | +| ExitMethods.cs:74:13:74:13 | access to parameter b | ExitMethods.cs:77:41:77:43 | "b" | +| ExitMethods.cs:75:19:75:33 | object creation of type Exception | ExitMethods.cs:75:13:75:34 | throw ...; | +| ExitMethods.cs:77:19:77:44 | object creation of type ArgumentException | ExitMethods.cs:77:13:77:45 | throw ...; | +| ExitMethods.cs:77:41:77:43 | "b" | ExitMethods.cs:77:19:77:44 | object creation of type ArgumentException | +| ExitMethods.cs:80:17:80:28 | enter ErrorAlways2 | ExitMethods.cs:81:5:83:5 | {...} | +| ExitMethods.cs:80:17:80:28 | exit ErrorAlways2 (abnormal) | ExitMethods.cs:80:17:80:28 | exit ErrorAlways2 | +| ExitMethods.cs:81:5:83:5 | {...} | ExitMethods.cs:82:15:82:29 | object creation of type Exception | +| ExitMethods.cs:82:9:82:30 | throw ...; | ExitMethods.cs:80:17:80:28 | exit ErrorAlways2 (abnormal) | +| ExitMethods.cs:82:15:82:29 | object creation of type Exception | ExitMethods.cs:82:9:82:30 | throw ...; | +| ExitMethods.cs:85:17:85:28 | enter ErrorAlways3 | ExitMethods.cs:85:41:85:55 | object creation of type Exception | +| ExitMethods.cs:85:17:85:28 | exit ErrorAlways3 (abnormal) | ExitMethods.cs:85:17:85:28 | exit ErrorAlways3 | +| ExitMethods.cs:85:35:85:55 | throw ... | ExitMethods.cs:85:17:85:28 | exit ErrorAlways3 (abnormal) | +| ExitMethods.cs:85:41:85:55 | object creation of type Exception | ExitMethods.cs:85:35:85:55 | throw ... | +| ExitMethods.cs:87:10:87:13 | enter Exit | ExitMethods.cs:88:5:90:5 | {...} | +| ExitMethods.cs:87:10:87:13 | exit Exit (abnormal) | ExitMethods.cs:87:10:87:13 | exit Exit | +| ExitMethods.cs:88:5:90:5 | {...} | ExitMethods.cs:89:9:89:28 | ...; | +| ExitMethods.cs:89:9:89:27 | call to method Exit | ExitMethods.cs:87:10:87:13 | exit Exit (abnormal) | +| ExitMethods.cs:89:9:89:28 | ...; | ExitMethods.cs:89:26:89:26 | 0 | +| ExitMethods.cs:89:26:89:26 | 0 | ExitMethods.cs:89:9:89:27 | call to method Exit | +| ExitMethods.cs:92:10:92:18 | enter ExitInTry | ExitMethods.cs:93:5:103:5 | {...} | +| ExitMethods.cs:92:10:92:18 | exit ExitInTry (abnormal) | ExitMethods.cs:92:10:92:18 | exit ExitInTry | +| ExitMethods.cs:93:5:103:5 | {...} | ExitMethods.cs:94:9:102:9 | try {...} ... | +| ExitMethods.cs:94:9:102:9 | try {...} ... | ExitMethods.cs:95:9:97:9 | {...} | +| ExitMethods.cs:95:9:97:9 | {...} | ExitMethods.cs:96:13:96:19 | ...; | +| ExitMethods.cs:96:13:96:18 | call to method Exit | ExitMethods.cs:92:10:92:18 | exit ExitInTry (abnormal) | +| ExitMethods.cs:96:13:96:18 | this access | ExitMethods.cs:96:13:96:18 | call to method Exit | +| ExitMethods.cs:96:13:96:19 | ...; | ExitMethods.cs:96:13:96:18 | this access | +| ExitMethods.cs:105:10:105:24 | enter ApplicationExit | ExitMethods.cs:106:5:108:5 | {...} | +| ExitMethods.cs:105:10:105:24 | exit ApplicationExit (abnormal) | ExitMethods.cs:105:10:105:24 | exit ApplicationExit | +| ExitMethods.cs:106:5:108:5 | {...} | ExitMethods.cs:107:9:107:48 | ...; | +| ExitMethods.cs:107:9:107:47 | call to method Exit | ExitMethods.cs:105:10:105:24 | exit ApplicationExit (abnormal) | +| ExitMethods.cs:107:9:107:48 | ...; | ExitMethods.cs:107:9:107:47 | call to method Exit | +| ExitMethods.cs:110:13:110:21 | enter ThrowExpr | ExitMethods.cs:111:5:113:5 | {...} | +| ExitMethods.cs:111:5:113:5 | {...} | ExitMethods.cs:112:16:112:20 | access to parameter input | +| ExitMethods.cs:112:9:112:77 | return ...; | ExitMethods.cs:110:13:110:21 | exit ThrowExpr (normal) | +| ExitMethods.cs:112:16:112:20 | access to parameter input | ExitMethods.cs:112:25:112:25 | 0 | +| ExitMethods.cs:112:16:112:25 | ... != ... | ExitMethods.cs:112:29:112:29 | 1 | +| ExitMethods.cs:112:16:112:25 | ... != ... | ExitMethods.cs:112:69:112:75 | "input" | +| ExitMethods.cs:112:16:112:76 | ... ? ... : ... | ExitMethods.cs:112:9:112:77 | return ...; | +| ExitMethods.cs:112:25:112:25 | 0 | ExitMethods.cs:112:25:112:25 | (...) ... | +| ExitMethods.cs:112:25:112:25 | (...) ... | ExitMethods.cs:112:16:112:25 | ... != ... | +| ExitMethods.cs:112:29:112:29 | 1 | ExitMethods.cs:112:29:112:29 | (...) ... | +| ExitMethods.cs:112:29:112:29 | (...) ... | ExitMethods.cs:112:33:112:37 | access to parameter input | +| ExitMethods.cs:112:29:112:37 | ... / ... | ExitMethods.cs:112:16:112:76 | ... ? ... : ... | +| ExitMethods.cs:112:33:112:37 | access to parameter input | ExitMethods.cs:112:29:112:37 | ... / ... | +| ExitMethods.cs:112:41:112:76 | throw ... | ExitMethods.cs:110:13:110:21 | exit ThrowExpr (abnormal) | +| ExitMethods.cs:112:47:112:76 | object creation of type ArgumentException | ExitMethods.cs:112:41:112:76 | throw ... | +| ExitMethods.cs:112:69:112:75 | "input" | ExitMethods.cs:112:47:112:76 | object creation of type ArgumentException | +| ExitMethods.cs:115:16:115:34 | enter ExtensionMethodCall | ExitMethods.cs:116:5:118:5 | {...} | +| ExitMethods.cs:115:16:115:34 | exit ExtensionMethodCall (normal) | ExitMethods.cs:115:16:115:34 | exit ExtensionMethodCall | +| ExitMethods.cs:116:5:118:5 | {...} | ExitMethods.cs:117:16:117:16 | access to parameter s | +| ExitMethods.cs:117:9:117:39 | return ...; | ExitMethods.cs:115:16:115:34 | exit ExtensionMethodCall (normal) | +| ExitMethods.cs:117:16:117:16 | access to parameter s | ExitMethods.cs:117:27:117:29 | - | +| ExitMethods.cs:117:16:117:30 | call to method Contains | ExitMethods.cs:117:34:117:34 | 0 | +| ExitMethods.cs:117:16:117:30 | call to method Contains | ExitMethods.cs:117:38:117:38 | 1 | +| ExitMethods.cs:117:16:117:38 | ... ? ... : ... | ExitMethods.cs:117:9:117:39 | return ...; | +| ExitMethods.cs:117:27:117:29 | - | ExitMethods.cs:117:16:117:30 | call to method Contains | +| ExitMethods.cs:120:17:120:32 | enter FailingAssertion | ExitMethods.cs:121:5:124:5 | {...} | +| ExitMethods.cs:120:17:120:32 | exit FailingAssertion (abnormal) | ExitMethods.cs:120:17:120:32 | exit FailingAssertion | +| ExitMethods.cs:121:5:124:5 | {...} | ExitMethods.cs:122:9:122:29 | ...; | +| ExitMethods.cs:122:9:122:28 | [assertion failure] call to method IsTrue | ExitMethods.cs:120:17:120:32 | exit FailingAssertion (abnormal) | +| ExitMethods.cs:122:9:122:29 | ...; | ExitMethods.cs:122:23:122:27 | false | +| ExitMethods.cs:122:23:122:27 | false | ExitMethods.cs:122:9:122:28 | [assertion failure] call to method IsTrue | +| ExitMethods.cs:126:17:126:33 | enter FailingAssertion2 | ExitMethods.cs:127:5:130:5 | {...} | +| ExitMethods.cs:126:17:126:33 | exit FailingAssertion2 (abnormal) | ExitMethods.cs:126:17:126:33 | exit FailingAssertion2 | +| ExitMethods.cs:127:5:130:5 | {...} | ExitMethods.cs:128:9:128:27 | ...; | +| ExitMethods.cs:128:9:128:26 | call to method FailingAssertion | ExitMethods.cs:126:17:126:33 | exit FailingAssertion2 (abnormal) | +| ExitMethods.cs:128:9:128:26 | this access | ExitMethods.cs:128:9:128:26 | call to method FailingAssertion | +| ExitMethods.cs:128:9:128:27 | ...; | ExitMethods.cs:128:9:128:26 | this access | +| ExitMethods.cs:132:10:132:20 | enter AssertFalse | ExitMethods.cs:132:48:132:48 | access to parameter b | +| ExitMethods.cs:132:33:132:49 | [assertion failure] call to method IsFalse | ExitMethods.cs:132:10:132:20 | exit AssertFalse (abnormal) | +| ExitMethods.cs:132:33:132:49 | [assertion success] call to method IsFalse | ExitMethods.cs:132:10:132:20 | exit AssertFalse (normal) | +| ExitMethods.cs:132:48:132:48 | access to parameter b | ExitMethods.cs:132:33:132:49 | [assertion failure] call to method IsFalse | +| ExitMethods.cs:132:48:132:48 | access to parameter b | ExitMethods.cs:132:33:132:49 | [assertion success] call to method IsFalse | +| ExitMethods.cs:134:17:134:33 | enter FailingAssertion3 | ExitMethods.cs:135:5:138:5 | {...} | +| ExitMethods.cs:134:17:134:33 | exit FailingAssertion3 (abnormal) | ExitMethods.cs:134:17:134:33 | exit FailingAssertion3 | +| ExitMethods.cs:135:5:138:5 | {...} | ExitMethods.cs:136:9:136:26 | ...; | +| ExitMethods.cs:136:9:136:25 | [assertion failure] call to method AssertFalse | ExitMethods.cs:134:17:134:33 | exit FailingAssertion3 (abnormal) | +| ExitMethods.cs:136:9:136:25 | this access | ExitMethods.cs:136:21:136:24 | true | +| ExitMethods.cs:136:9:136:26 | ...; | ExitMethods.cs:136:9:136:25 | this access | +| ExitMethods.cs:136:21:136:24 | true | ExitMethods.cs:136:9:136:25 | [assertion failure] call to method AssertFalse | +| ExitMethods.cs:140:17:140:42 | enter ExceptionDispatchInfoThrow | ExitMethods.cs:141:5:147:5 | {...} | +| ExitMethods.cs:140:17:140:42 | exit ExceptionDispatchInfoThrow (abnormal) | ExitMethods.cs:140:17:140:42 | exit ExceptionDispatchInfoThrow | +| ExitMethods.cs:141:5:147:5 | {...} | ExitMethods.cs:142:9:145:53 | if (...) ... | +| ExitMethods.cs:142:9:145:53 | if (...) ... | ExitMethods.cs:142:13:142:13 | access to parameter b | +| ExitMethods.cs:142:13:142:13 | access to parameter b | ExitMethods.cs:143:13:143:43 | ...; | +| ExitMethods.cs:142:13:142:13 | access to parameter b | ExitMethods.cs:145:13:145:53 | ...; | +| ExitMethods.cs:143:13:143:43 | ...; | ExitMethods.cs:143:41:143:41 | access to parameter e | +| ExitMethods.cs:143:41:143:41 | access to parameter e | ExitMethods.cs:143:13:143:42 | call to method Throw | +| ExitMethods.cs:145:13:145:44 | call to method Capture | ExitMethods.cs:145:13:145:52 | call to method Throw | +| ExitMethods.cs:145:13:145:53 | ...; | ExitMethods.cs:145:43:145:43 | access to parameter e | +| ExitMethods.cs:145:43:145:43 | access to parameter e | ExitMethods.cs:145:13:145:44 | call to method Capture | | Extensions.cs:5:23:5:29 | enter ToInt32 | Extensions.cs:6:5:8:5 | {...} | | Extensions.cs:5:23:5:29 | exit ToInt32 (normal) | Extensions.cs:5:23:5:29 | exit ToInt32 | | Extensions.cs:6:5:8:5 | {...} | Extensions.cs:7:28:7:28 | access to parameter s | @@ -1688,17 +1699,14 @@ dominance | Finally.cs:11:13:11:37 | call to method WriteLine | Finally.cs:14:9:16:9 | {...} | | Finally.cs:11:13:11:38 | ...; | Finally.cs:11:31:11:36 | "Try1" | | Finally.cs:11:31:11:36 | "Try1" | Finally.cs:11:13:11:37 | call to method WriteLine | -| Finally.cs:11:31:11:36 | "Try1" | Finally.cs:14:9:16:9 | [finally: exception(OutOfMemoryException)] {...} | | Finally.cs:14:9:16:9 | [finally: exception(Exception)] {...} | Finally.cs:15:13:15:41 | [finally: exception(Exception)] ...; | -| Finally.cs:14:9:16:9 | [finally: exception(OutOfMemoryException)] {...} | Finally.cs:15:13:15:41 | [finally: exception(OutOfMemoryException)] ...; | | Finally.cs:14:9:16:9 | {...} | Finally.cs:15:13:15:41 | ...; | +| Finally.cs:15:13:15:40 | [finally: exception(Exception)] call to method WriteLine | Finally.cs:7:10:7:11 | exit M1 (abnormal) | | Finally.cs:15:13:15:40 | call to method WriteLine | Finally.cs:7:10:7:11 | exit M1 (normal) | | Finally.cs:15:13:15:41 | ...; | Finally.cs:15:31:15:39 | "Finally" | | Finally.cs:15:13:15:41 | [finally: exception(Exception)] ...; | Finally.cs:15:31:15:39 | [finally: exception(Exception)] "Finally" | -| Finally.cs:15:13:15:41 | [finally: exception(OutOfMemoryException)] ...; | Finally.cs:15:31:15:39 | [finally: exception(OutOfMemoryException)] "Finally" | | Finally.cs:15:31:15:39 | "Finally" | Finally.cs:15:13:15:40 | call to method WriteLine | | Finally.cs:15:31:15:39 | [finally: exception(Exception)] "Finally" | Finally.cs:15:13:15:40 | [finally: exception(Exception)] call to method WriteLine | -| Finally.cs:15:31:15:39 | [finally: exception(OutOfMemoryException)] "Finally" | Finally.cs:15:13:15:40 | [finally: exception(OutOfMemoryException)] call to method WriteLine | | Finally.cs:19:10:19:11 | enter M2 | Finally.cs:20:5:52:5 | {...} | | Finally.cs:20:5:52:5 | {...} | Finally.cs:21:9:51:9 | try {...} ... | | Finally.cs:21:9:51:9 | try {...} ... | Finally.cs:22:9:25:9 | {...} | @@ -1707,18 +1715,15 @@ dominance | Finally.cs:23:13:23:37 | call to method WriteLine | Finally.cs:26:9:29:9 | [exception: Exception] catch (...) {...} | | Finally.cs:23:13:23:38 | ...; | Finally.cs:23:31:23:36 | "Try2" | | Finally.cs:23:31:23:36 | "Try2" | Finally.cs:23:13:23:37 | call to method WriteLine | -| Finally.cs:23:31:23:36 | "Try2" | Finally.cs:26:9:29:9 | [exception: OutOfMemoryException] catch (...) {...} | | Finally.cs:24:13:24:19 | return ...; | Finally.cs:49:9:51:9 | [finally: return] {...} | | Finally.cs:26:9:29:9 | [exception: Exception] catch (...) {...} | Finally.cs:26:38:26:39 | [exception: Exception] IOException ex | | Finally.cs:26:9:29:9 | [exception: Exception] catch (...) {...} | Finally.cs:30:9:40:9 | [exception: Exception] catch (...) {...} | -| Finally.cs:26:9:29:9 | [exception: OutOfMemoryException] catch (...) {...} | Finally.cs:30:9:40:9 | [exception: OutOfMemoryException] catch (...) {...} | | Finally.cs:26:38:26:39 | [exception: Exception] IOException ex | Finally.cs:26:48:26:51 | [exception: Exception] true | | Finally.cs:26:48:26:51 | [exception: Exception] true | Finally.cs:27:9:29:9 | {...} | | Finally.cs:27:9:29:9 | {...} | Finally.cs:28:13:28:18 | throw ...; | | Finally.cs:28:13:28:18 | throw ...; | Finally.cs:49:9:51:9 | [finally: exception(IOException)] {...} | | Finally.cs:30:9:40:9 | [exception: Exception] catch (...) {...} | Finally.cs:30:41:30:42 | [exception: Exception] ArgumentException ex | | Finally.cs:30:9:40:9 | [exception: Exception] catch (...) {...} | Finally.cs:41:9:43:9 | [exception: Exception] catch (...) {...} | -| Finally.cs:30:9:40:9 | [exception: OutOfMemoryException] catch (...) {...} | Finally.cs:41:9:43:9 | [exception: OutOfMemoryException] catch (...) {...} | | Finally.cs:30:41:30:42 | [exception: Exception] ArgumentException ex | Finally.cs:31:9:40:9 | {...} | | Finally.cs:31:9:40:9 | {...} | Finally.cs:32:13:39:13 | try {...} ... | | Finally.cs:32:13:39:13 | try {...} ... | Finally.cs:33:13:35:13 | {...} | @@ -1730,6 +1735,7 @@ dominance | Finally.cs:38:17:38:44 | [finally: exception(ArgumentException)] throw ...; | Finally.cs:49:9:51:9 | [finally: exception(Exception)] {...} | | Finally.cs:38:23:38:43 | [finally: exception(ArgumentException)] object creation of type Exception | Finally.cs:38:17:38:44 | [finally: exception(ArgumentException)] throw ...; | | Finally.cs:38:37:38:42 | [finally: exception(ArgumentException)] "Boo!" | Finally.cs:38:23:38:43 | [finally: exception(ArgumentException)] object creation of type Exception | +| Finally.cs:41:9:43:9 | [exception: Exception] catch (...) {...} | Finally.cs:42:9:43:9 | {...} | | Finally.cs:42:9:43:9 | {...} | Finally.cs:49:9:51:9 | {...} | | Finally.cs:49:9:51:9 | [finally: exception(Exception)] {...} | Finally.cs:50:13:50:41 | [finally: exception(Exception)] ...; | | Finally.cs:49:9:51:9 | [finally: exception(IOException)] {...} | Finally.cs:50:13:50:41 | [finally: exception(IOException)] ...; | @@ -1751,42 +1757,32 @@ dominance | Finally.cs:58:13:58:37 | call to method WriteLine | Finally.cs:61:9:64:9 | [exception: Exception] catch (...) {...} | | Finally.cs:58:13:58:38 | ...; | Finally.cs:58:31:58:36 | "Try3" | | Finally.cs:58:31:58:36 | "Try3" | Finally.cs:58:13:58:37 | call to method WriteLine | -| Finally.cs:58:31:58:36 | "Try3" | Finally.cs:61:9:64:9 | [exception: OutOfMemoryException] catch (...) {...} | | Finally.cs:59:13:59:19 | return ...; | Finally.cs:69:9:71:9 | [finally: return] {...} | | Finally.cs:61:9:64:9 | [exception: Exception] catch (...) {...} | Finally.cs:61:38:61:39 | [exception: Exception] IOException ex | | Finally.cs:61:9:64:9 | [exception: Exception] catch (...) {...} | Finally.cs:65:9:67:9 | [exception: Exception] catch (...) {...} | -| Finally.cs:61:9:64:9 | [exception: OutOfMemoryException] catch (...) {...} | Finally.cs:65:9:67:9 | [exception: OutOfMemoryException] catch (...) {...} | | Finally.cs:61:38:61:39 | [exception: Exception] IOException ex | Finally.cs:61:48:61:51 | [exception: Exception] true | | Finally.cs:61:48:61:51 | [exception: Exception] true | Finally.cs:62:9:64:9 | {...} | | Finally.cs:62:9:64:9 | {...} | Finally.cs:63:13:63:18 | throw ...; | | Finally.cs:63:13:63:18 | throw ...; | Finally.cs:69:9:71:9 | [finally: exception(IOException)] {...} | | Finally.cs:65:9:67:9 | [exception: Exception] catch (...) {...} | Finally.cs:65:26:65:26 | [exception: Exception] Exception e | -| Finally.cs:65:9:67:9 | [exception: OutOfMemoryException] catch (...) {...} | Finally.cs:65:26:65:26 | [exception: OutOfMemoryException] Exception e | | Finally.cs:65:26:65:26 | [exception: Exception] Exception e | Finally.cs:65:35:65:35 | [exception: Exception] access to local variable e | -| Finally.cs:65:26:65:26 | [exception: OutOfMemoryException] Exception e | Finally.cs:65:35:65:35 | [exception: OutOfMemoryException] access to local variable e | | Finally.cs:65:35:65:35 | [exception: Exception] access to local variable e | Finally.cs:65:35:65:43 | [exception: Exception] access to property Message | -| Finally.cs:65:35:65:35 | [exception: OutOfMemoryException] access to local variable e | Finally.cs:65:35:65:43 | [exception: OutOfMemoryException] access to property Message | | Finally.cs:65:35:65:43 | [exception: Exception] access to property Message | Finally.cs:65:48:65:51 | [exception: Exception] null | -| Finally.cs:65:35:65:43 | [exception: OutOfMemoryException] access to property Message | Finally.cs:65:48:65:51 | [exception: OutOfMemoryException] null | +| Finally.cs:65:35:65:51 | [exception: Exception] ... != ... | Finally.cs:66:9:67:9 | {...} | | Finally.cs:65:35:65:51 | [exception: Exception] ... != ... | Finally.cs:69:9:71:9 | [finally: exception(Exception)] {...} | -| Finally.cs:65:35:65:51 | [exception: OutOfMemoryException] ... != ... | Finally.cs:69:9:71:9 | [finally: exception(OutOfMemoryException)] {...} | | Finally.cs:65:48:65:51 | [exception: Exception] null | Finally.cs:65:35:65:51 | [exception: Exception] ... != ... | -| Finally.cs:65:48:65:51 | [exception: OutOfMemoryException] null | Finally.cs:65:35:65:51 | [exception: OutOfMemoryException] ... != ... | | Finally.cs:66:9:67:9 | {...} | Finally.cs:69:9:71:9 | {...} | | Finally.cs:69:9:71:9 | [finally: exception(Exception)] {...} | Finally.cs:70:13:70:41 | [finally: exception(Exception)] ...; | | Finally.cs:69:9:71:9 | [finally: exception(IOException)] {...} | Finally.cs:70:13:70:41 | [finally: exception(IOException)] ...; | -| Finally.cs:69:9:71:9 | [finally: exception(OutOfMemoryException)] {...} | Finally.cs:70:13:70:41 | [finally: exception(OutOfMemoryException)] ...; | | Finally.cs:69:9:71:9 | [finally: return] {...} | Finally.cs:70:13:70:41 | [finally: return] ...; | | Finally.cs:69:9:71:9 | {...} | Finally.cs:70:13:70:41 | ...; | | Finally.cs:70:13:70:41 | ...; | Finally.cs:70:31:70:39 | "Finally" | | Finally.cs:70:13:70:41 | [finally: exception(Exception)] ...; | Finally.cs:70:31:70:39 | [finally: exception(Exception)] "Finally" | | Finally.cs:70:13:70:41 | [finally: exception(IOException)] ...; | Finally.cs:70:31:70:39 | [finally: exception(IOException)] "Finally" | -| Finally.cs:70:13:70:41 | [finally: exception(OutOfMemoryException)] ...; | Finally.cs:70:31:70:39 | [finally: exception(OutOfMemoryException)] "Finally" | | Finally.cs:70:13:70:41 | [finally: return] ...; | Finally.cs:70:31:70:39 | [finally: return] "Finally" | | Finally.cs:70:31:70:39 | "Finally" | Finally.cs:70:13:70:40 | call to method WriteLine | | Finally.cs:70:31:70:39 | [finally: exception(Exception)] "Finally" | Finally.cs:70:13:70:40 | [finally: exception(Exception)] call to method WriteLine | | Finally.cs:70:31:70:39 | [finally: exception(IOException)] "Finally" | Finally.cs:70:13:70:40 | [finally: exception(IOException)] call to method WriteLine | -| Finally.cs:70:31:70:39 | [finally: exception(OutOfMemoryException)] "Finally" | Finally.cs:70:13:70:40 | [finally: exception(OutOfMemoryException)] call to method WriteLine | | Finally.cs:70:31:70:39 | [finally: return] "Finally" | Finally.cs:70:13:70:40 | [finally: return] call to method WriteLine | | Finally.cs:74:10:74:11 | enter M4 | Finally.cs:75:5:101:5 | {...} | | Finally.cs:75:5:101:5 | {...} | Finally.cs:76:9:76:19 | ... ...; | @@ -1852,36 +1848,36 @@ dominance | Finally.cs:92:30:92:30 | [finally: continue] 3 | Finally.cs:92:25:92:30 | [finally: continue] ... == ... | | Finally.cs:92:30:92:30 | [finally: return] 3 | Finally.cs:92:25:92:30 | [finally: return] ... == ... | | Finally.cs:93:31:93:45 | [finally: break] object creation of type Exception | Finally.cs:93:25:93:46 | [finally: break] throw ...; | -| Finally.cs:93:31:93:45 | [finally: break] object creation of type Exception | Finally.cs:96:17:98:17 | [finally: break, finally(2): exception(Exception)] {...} | +| Finally.cs:93:31:93:45 | [finally: break] object creation of type Exception | Finally.cs:96:17:98:17 | [finally: break, finally(1): exception(Exception)] {...} | | Finally.cs:93:31:93:45 | [finally: continue] object creation of type Exception | Finally.cs:93:25:93:46 | [finally: continue] throw ...; | -| Finally.cs:93:31:93:45 | [finally: continue] object creation of type Exception | Finally.cs:96:17:98:17 | [finally: continue, finally(2): exception(Exception)] {...} | +| Finally.cs:93:31:93:45 | [finally: continue] object creation of type Exception | Finally.cs:96:17:98:17 | [finally: continue, finally(1): exception(Exception)] {...} | | Finally.cs:93:31:93:45 | [finally: return] object creation of type Exception | Finally.cs:93:25:93:46 | [finally: return] throw ...; | -| Finally.cs:93:31:93:45 | [finally: return] object creation of type Exception | Finally.cs:96:17:98:17 | [finally: return, finally(2): exception(Exception)] {...} | +| Finally.cs:93:31:93:45 | [finally: return] object creation of type Exception | Finally.cs:96:17:98:17 | [finally: return, finally(1): exception(Exception)] {...} | | Finally.cs:93:31:93:45 | object creation of type Exception | Finally.cs:93:25:93:46 | throw ...; | -| Finally.cs:93:31:93:45 | object creation of type Exception | Finally.cs:96:17:98:17 | [finally(2): exception(Exception)] {...} | -| Finally.cs:96:17:98:17 | [finally(2): exception(Exception)] {...} | Finally.cs:97:21:97:24 | [finally(2): exception(Exception)] ...; | -| Finally.cs:96:17:98:17 | [finally: break, finally(2): exception(Exception)] {...} | Finally.cs:97:21:97:24 | [finally: break, finally(2): exception(Exception)] ...; | +| Finally.cs:93:31:93:45 | object creation of type Exception | Finally.cs:96:17:98:17 | [finally(1): exception(Exception)] {...} | +| Finally.cs:96:17:98:17 | [finally(1): exception(Exception)] {...} | Finally.cs:97:21:97:24 | [finally(1): exception(Exception)] ...; | +| Finally.cs:96:17:98:17 | [finally: break, finally(1): exception(Exception)] {...} | Finally.cs:97:21:97:24 | [finally: break, finally(1): exception(Exception)] ...; | | Finally.cs:96:17:98:17 | [finally: break] {...} | Finally.cs:97:21:97:24 | [finally: break] ...; | -| Finally.cs:96:17:98:17 | [finally: continue, finally(2): exception(Exception)] {...} | Finally.cs:97:21:97:24 | [finally: continue, finally(2): exception(Exception)] ...; | +| Finally.cs:96:17:98:17 | [finally: continue, finally(1): exception(Exception)] {...} | Finally.cs:97:21:97:24 | [finally: continue, finally(1): exception(Exception)] ...; | | Finally.cs:96:17:98:17 | [finally: continue] {...} | Finally.cs:97:21:97:24 | [finally: continue] ...; | -| Finally.cs:96:17:98:17 | [finally: return, finally(2): exception(Exception)] {...} | Finally.cs:97:21:97:24 | [finally: return, finally(2): exception(Exception)] ...; | +| Finally.cs:96:17:98:17 | [finally: return, finally(1): exception(Exception)] {...} | Finally.cs:97:21:97:24 | [finally: return, finally(1): exception(Exception)] ...; | | Finally.cs:96:17:98:17 | [finally: return] {...} | Finally.cs:97:21:97:24 | [finally: return] ...; | | Finally.cs:96:17:98:17 | {...} | Finally.cs:97:21:97:24 | ...; | -| Finally.cs:97:21:97:21 | [finally(2): exception(Exception)] access to local variable i | Finally.cs:97:21:97:23 | [finally(2): exception(Exception)] ...-- | -| Finally.cs:97:21:97:21 | [finally: break, finally(2): exception(Exception)] access to local variable i | Finally.cs:97:21:97:23 | [finally: break, finally(2): exception(Exception)] ...-- | +| Finally.cs:97:21:97:21 | [finally(1): exception(Exception)] access to local variable i | Finally.cs:97:21:97:23 | [finally(1): exception(Exception)] ...-- | +| Finally.cs:97:21:97:21 | [finally: break, finally(1): exception(Exception)] access to local variable i | Finally.cs:97:21:97:23 | [finally: break, finally(1): exception(Exception)] ...-- | | Finally.cs:97:21:97:21 | [finally: break] access to local variable i | Finally.cs:97:21:97:23 | [finally: break] ...-- | -| Finally.cs:97:21:97:21 | [finally: continue, finally(2): exception(Exception)] access to local variable i | Finally.cs:97:21:97:23 | [finally: continue, finally(2): exception(Exception)] ...-- | +| Finally.cs:97:21:97:21 | [finally: continue, finally(1): exception(Exception)] access to local variable i | Finally.cs:97:21:97:23 | [finally: continue, finally(1): exception(Exception)] ...-- | | Finally.cs:97:21:97:21 | [finally: continue] access to local variable i | Finally.cs:97:21:97:23 | [finally: continue] ...-- | -| Finally.cs:97:21:97:21 | [finally: return, finally(2): exception(Exception)] access to local variable i | Finally.cs:97:21:97:23 | [finally: return, finally(2): exception(Exception)] ...-- | +| Finally.cs:97:21:97:21 | [finally: return, finally(1): exception(Exception)] access to local variable i | Finally.cs:97:21:97:23 | [finally: return, finally(1): exception(Exception)] ...-- | | Finally.cs:97:21:97:21 | [finally: return] access to local variable i | Finally.cs:97:21:97:23 | [finally: return] ...-- | | Finally.cs:97:21:97:21 | access to local variable i | Finally.cs:97:21:97:23 | ...-- | | Finally.cs:97:21:97:24 | ...; | Finally.cs:97:21:97:21 | access to local variable i | -| Finally.cs:97:21:97:24 | [finally(2): exception(Exception)] ...; | Finally.cs:97:21:97:21 | [finally(2): exception(Exception)] access to local variable i | -| Finally.cs:97:21:97:24 | [finally: break, finally(2): exception(Exception)] ...; | Finally.cs:97:21:97:21 | [finally: break, finally(2): exception(Exception)] access to local variable i | +| Finally.cs:97:21:97:24 | [finally(1): exception(Exception)] ...; | Finally.cs:97:21:97:21 | [finally(1): exception(Exception)] access to local variable i | +| Finally.cs:97:21:97:24 | [finally: break, finally(1): exception(Exception)] ...; | Finally.cs:97:21:97:21 | [finally: break, finally(1): exception(Exception)] access to local variable i | | Finally.cs:97:21:97:24 | [finally: break] ...; | Finally.cs:97:21:97:21 | [finally: break] access to local variable i | -| Finally.cs:97:21:97:24 | [finally: continue, finally(2): exception(Exception)] ...; | Finally.cs:97:21:97:21 | [finally: continue, finally(2): exception(Exception)] access to local variable i | +| Finally.cs:97:21:97:24 | [finally: continue, finally(1): exception(Exception)] ...; | Finally.cs:97:21:97:21 | [finally: continue, finally(1): exception(Exception)] access to local variable i | | Finally.cs:97:21:97:24 | [finally: continue] ...; | Finally.cs:97:21:97:21 | [finally: continue] access to local variable i | -| Finally.cs:97:21:97:24 | [finally: return, finally(2): exception(Exception)] ...; | Finally.cs:97:21:97:21 | [finally: return, finally(2): exception(Exception)] access to local variable i | +| Finally.cs:97:21:97:24 | [finally: return, finally(1): exception(Exception)] ...; | Finally.cs:97:21:97:21 | [finally: return, finally(1): exception(Exception)] access to local variable i | | Finally.cs:97:21:97:24 | [finally: return] ...; | Finally.cs:97:21:97:21 | [finally: return] access to local variable i | | Finally.cs:103:10:103:11 | enter M5 | Finally.cs:104:5:119:5 | {...} | | Finally.cs:104:5:119:5 | {...} | Finally.cs:105:9:118:9 | try {...} ... | @@ -2026,16 +2022,12 @@ dominance | Finally.cs:137:13:137:36 | call to method WriteLine | Finally.cs:140:9:143:9 | {...} | | Finally.cs:137:13:137:37 | ...; | Finally.cs:137:31:137:35 | "Try" | | Finally.cs:137:31:137:35 | "Try" | Finally.cs:137:13:137:36 | call to method WriteLine | -| Finally.cs:137:31:137:35 | "Try" | Finally.cs:140:9:143:9 | [finally: exception(OutOfMemoryException)] {...} | | Finally.cs:140:9:143:9 | [finally: exception(Exception)] {...} | Finally.cs:141:41:141:42 | [finally: exception(Exception)] "" | -| Finally.cs:140:9:143:9 | [finally: exception(OutOfMemoryException)] {...} | Finally.cs:141:41:141:42 | [finally: exception(OutOfMemoryException)] "" | | Finally.cs:140:9:143:9 | {...} | Finally.cs:141:41:141:42 | "" | | Finally.cs:141:19:141:43 | [finally: exception(Exception)] object creation of type ArgumentException | Finally.cs:141:13:141:44 | [finally: exception(Exception)] throw ...; | -| Finally.cs:141:19:141:43 | [finally: exception(OutOfMemoryException)] object creation of type ArgumentException | Finally.cs:141:13:141:44 | [finally: exception(OutOfMemoryException)] throw ...; | | Finally.cs:141:19:141:43 | object creation of type ArgumentException | Finally.cs:141:13:141:44 | throw ...; | | Finally.cs:141:41:141:42 | "" | Finally.cs:141:19:141:43 | object creation of type ArgumentException | | Finally.cs:141:41:141:42 | [finally: exception(Exception)] "" | Finally.cs:141:19:141:43 | [finally: exception(Exception)] object creation of type ArgumentException | -| Finally.cs:141:41:141:42 | [finally: exception(OutOfMemoryException)] "" | Finally.cs:141:19:141:43 | [finally: exception(OutOfMemoryException)] object creation of type ArgumentException | | Finally.cs:147:10:147:11 | enter M8 | Finally.cs:148:5:170:5 | {...} | | Finally.cs:148:5:170:5 | {...} | Finally.cs:149:9:169:9 | try {...} ... | | Finally.cs:149:9:169:9 | try {...} ... | Finally.cs:150:9:153:9 | {...} | @@ -2082,56 +2074,38 @@ dominance | Finally.cs:159:27:159:44 | [finally: exception(Exception)] object creation of type Exception | Finally.cs:159:21:159:45 | [finally: exception(Exception)] throw ...; | | Finally.cs:159:27:159:44 | object creation of type Exception | Finally.cs:159:21:159:45 | throw ...; | | Finally.cs:159:41:159:43 | "1" | Finally.cs:159:27:159:44 | object creation of type Exception | -| Finally.cs:159:41:159:43 | "1" | Finally.cs:161:13:164:13 | [exception: OutOfMemoryException] catch (...) {...} | | Finally.cs:159:41:159:43 | [finally: exception(ArgumentNullException)] "1" | Finally.cs:159:27:159:44 | [finally: exception(ArgumentNullException)] object creation of type Exception | -| Finally.cs:159:41:159:43 | [finally: exception(ArgumentNullException)] "1" | Finally.cs:161:13:164:13 | [finally: exception(ArgumentNullException), exception: OutOfMemoryException] catch (...) {...} | | Finally.cs:159:41:159:43 | [finally: exception(Exception)] "1" | Finally.cs:159:27:159:44 | [finally: exception(Exception)] object creation of type Exception | -| Finally.cs:159:41:159:43 | [finally: exception(Exception)] "1" | Finally.cs:161:13:164:13 | [finally: exception(Exception), exception: OutOfMemoryException] catch (...) {...} | | Finally.cs:161:13:164:13 | [exception: Exception] catch (...) {...} | Finally.cs:161:30:161:30 | [exception: Exception] Exception e | | Finally.cs:161:13:164:13 | [exception: NullReferenceException] catch (...) {...} | Finally.cs:161:30:161:30 | [exception: NullReferenceException] Exception e | -| Finally.cs:161:13:164:13 | [exception: OutOfMemoryException] catch (...) {...} | Finally.cs:161:30:161:30 | [exception: OutOfMemoryException] Exception e | | Finally.cs:161:13:164:13 | [finally: exception(ArgumentNullException), exception: Exception] catch (...) {...} | Finally.cs:161:30:161:30 | [finally: exception(ArgumentNullException), exception: Exception] Exception e | | Finally.cs:161:13:164:13 | [finally: exception(ArgumentNullException), exception: NullReferenceException] catch (...) {...} | Finally.cs:161:30:161:30 | [finally: exception(ArgumentNullException), exception: NullReferenceException] Exception e | -| Finally.cs:161:13:164:13 | [finally: exception(ArgumentNullException), exception: OutOfMemoryException] catch (...) {...} | Finally.cs:161:30:161:30 | [finally: exception(ArgumentNullException), exception: OutOfMemoryException] Exception e | | Finally.cs:161:13:164:13 | [finally: exception(Exception), exception: Exception] catch (...) {...} | Finally.cs:161:30:161:30 | [finally: exception(Exception), exception: Exception] Exception e | | Finally.cs:161:13:164:13 | [finally: exception(Exception), exception: NullReferenceException] catch (...) {...} | Finally.cs:161:30:161:30 | [finally: exception(Exception), exception: NullReferenceException] Exception e | -| Finally.cs:161:13:164:13 | [finally: exception(Exception), exception: OutOfMemoryException] catch (...) {...} | Finally.cs:161:30:161:30 | [finally: exception(Exception), exception: OutOfMemoryException] Exception e | | Finally.cs:161:30:161:30 | [exception: Exception] Exception e | Finally.cs:161:39:161:39 | [exception: Exception] access to local variable e | | Finally.cs:161:30:161:30 | [exception: NullReferenceException] Exception e | Finally.cs:161:39:161:39 | [exception: NullReferenceException] access to local variable e | -| Finally.cs:161:30:161:30 | [exception: OutOfMemoryException] Exception e | Finally.cs:161:39:161:39 | [exception: OutOfMemoryException] access to local variable e | | Finally.cs:161:30:161:30 | [finally: exception(ArgumentNullException), exception: Exception] Exception e | Finally.cs:161:39:161:39 | [finally: exception(ArgumentNullException), exception: Exception] access to local variable e | | Finally.cs:161:30:161:30 | [finally: exception(ArgumentNullException), exception: NullReferenceException] Exception e | Finally.cs:161:39:161:39 | [finally: exception(ArgumentNullException), exception: NullReferenceException] access to local variable e | -| Finally.cs:161:30:161:30 | [finally: exception(ArgumentNullException), exception: OutOfMemoryException] Exception e | Finally.cs:161:39:161:39 | [finally: exception(ArgumentNullException), exception: OutOfMemoryException] access to local variable e | | Finally.cs:161:30:161:30 | [finally: exception(Exception), exception: Exception] Exception e | Finally.cs:161:39:161:39 | [finally: exception(Exception), exception: Exception] access to local variable e | | Finally.cs:161:30:161:30 | [finally: exception(Exception), exception: NullReferenceException] Exception e | Finally.cs:161:39:161:39 | [finally: exception(Exception), exception: NullReferenceException] access to local variable e | -| Finally.cs:161:30:161:30 | [finally: exception(Exception), exception: OutOfMemoryException] Exception e | Finally.cs:161:39:161:39 | [finally: exception(Exception), exception: OutOfMemoryException] access to local variable e | | Finally.cs:161:39:161:39 | [exception: Exception] access to local variable e | Finally.cs:161:39:161:47 | [exception: Exception] access to property Message | | Finally.cs:161:39:161:39 | [exception: NullReferenceException] access to local variable e | Finally.cs:161:39:161:47 | [exception: NullReferenceException] access to property Message | -| Finally.cs:161:39:161:39 | [exception: OutOfMemoryException] access to local variable e | Finally.cs:161:39:161:47 | [exception: OutOfMemoryException] access to property Message | | Finally.cs:161:39:161:39 | [finally: exception(ArgumentNullException), exception: Exception] access to local variable e | Finally.cs:161:39:161:47 | [finally: exception(ArgumentNullException), exception: Exception] access to property Message | | Finally.cs:161:39:161:39 | [finally: exception(ArgumentNullException), exception: NullReferenceException] access to local variable e | Finally.cs:161:39:161:47 | [finally: exception(ArgumentNullException), exception: NullReferenceException] access to property Message | -| Finally.cs:161:39:161:39 | [finally: exception(ArgumentNullException), exception: OutOfMemoryException] access to local variable e | Finally.cs:161:39:161:47 | [finally: exception(ArgumentNullException), exception: OutOfMemoryException] access to property Message | | Finally.cs:161:39:161:39 | [finally: exception(Exception), exception: Exception] access to local variable e | Finally.cs:161:39:161:47 | [finally: exception(Exception), exception: Exception] access to property Message | | Finally.cs:161:39:161:39 | [finally: exception(Exception), exception: NullReferenceException] access to local variable e | Finally.cs:161:39:161:47 | [finally: exception(Exception), exception: NullReferenceException] access to property Message | -| Finally.cs:161:39:161:39 | [finally: exception(Exception), exception: OutOfMemoryException] access to local variable e | Finally.cs:161:39:161:47 | [finally: exception(Exception), exception: OutOfMemoryException] access to property Message | | Finally.cs:161:39:161:47 | [exception: Exception] access to property Message | Finally.cs:161:52:161:54 | [exception: Exception] "1" | | Finally.cs:161:39:161:47 | [exception: NullReferenceException] access to property Message | Finally.cs:161:52:161:54 | [exception: NullReferenceException] "1" | -| Finally.cs:161:39:161:47 | [exception: OutOfMemoryException] access to property Message | Finally.cs:161:52:161:54 | [exception: OutOfMemoryException] "1" | | Finally.cs:161:39:161:47 | [finally: exception(ArgumentNullException), exception: Exception] access to property Message | Finally.cs:161:52:161:54 | [finally: exception(ArgumentNullException), exception: Exception] "1" | | Finally.cs:161:39:161:47 | [finally: exception(ArgumentNullException), exception: NullReferenceException] access to property Message | Finally.cs:161:52:161:54 | [finally: exception(ArgumentNullException), exception: NullReferenceException] "1" | -| Finally.cs:161:39:161:47 | [finally: exception(ArgumentNullException), exception: OutOfMemoryException] access to property Message | Finally.cs:161:52:161:54 | [finally: exception(ArgumentNullException), exception: OutOfMemoryException] "1" | | Finally.cs:161:39:161:47 | [finally: exception(Exception), exception: Exception] access to property Message | Finally.cs:161:52:161:54 | [finally: exception(Exception), exception: Exception] "1" | | Finally.cs:161:39:161:47 | [finally: exception(Exception), exception: NullReferenceException] access to property Message | Finally.cs:161:52:161:54 | [finally: exception(Exception), exception: NullReferenceException] "1" | -| Finally.cs:161:39:161:47 | [finally: exception(Exception), exception: OutOfMemoryException] access to property Message | Finally.cs:161:52:161:54 | [finally: exception(Exception), exception: OutOfMemoryException] "1" | | Finally.cs:161:52:161:54 | [exception: Exception] "1" | Finally.cs:161:39:161:54 | [exception: Exception] ... == ... | | Finally.cs:161:52:161:54 | [exception: NullReferenceException] "1" | Finally.cs:161:39:161:54 | [exception: NullReferenceException] ... == ... | -| Finally.cs:161:52:161:54 | [exception: OutOfMemoryException] "1" | Finally.cs:161:39:161:54 | [exception: OutOfMemoryException] ... == ... | | Finally.cs:161:52:161:54 | [finally: exception(ArgumentNullException), exception: Exception] "1" | Finally.cs:161:39:161:54 | [finally: exception(ArgumentNullException), exception: Exception] ... == ... | | Finally.cs:161:52:161:54 | [finally: exception(ArgumentNullException), exception: NullReferenceException] "1" | Finally.cs:161:39:161:54 | [finally: exception(ArgumentNullException), exception: NullReferenceException] ... == ... | -| Finally.cs:161:52:161:54 | [finally: exception(ArgumentNullException), exception: OutOfMemoryException] "1" | Finally.cs:161:39:161:54 | [finally: exception(ArgumentNullException), exception: OutOfMemoryException] ... == ... | | Finally.cs:161:52:161:54 | [finally: exception(Exception), exception: Exception] "1" | Finally.cs:161:39:161:54 | [finally: exception(Exception), exception: Exception] ... == ... | | Finally.cs:161:52:161:54 | [finally: exception(Exception), exception: NullReferenceException] "1" | Finally.cs:161:39:161:54 | [finally: exception(Exception), exception: NullReferenceException] ... == ... | -| Finally.cs:161:52:161:54 | [finally: exception(Exception), exception: OutOfMemoryException] "1" | Finally.cs:161:39:161:54 | [finally: exception(Exception), exception: OutOfMemoryException] ... == ... | | Finally.cs:162:13:164:13 | [finally: exception(ArgumentNullException)] {...} | Finally.cs:163:17:163:43 | [finally: exception(ArgumentNullException)] ...; | | Finally.cs:162:13:164:13 | [finally: exception(Exception)] {...} | Finally.cs:163:17:163:43 | [finally: exception(Exception)] ...; | | Finally.cs:162:13:164:13 | {...} | Finally.cs:163:17:163:43 | ...; | @@ -2238,52 +2212,52 @@ dominance | Finally.cs:205:21:205:22 | [finally: exception(ExceptionA)] access to parameter b2 | Finally.cs:208:13:210:13 | [finally: exception(ExceptionA)] {...} | | Finally.cs:205:21:205:22 | access to parameter b2 | Finally.cs:205:31:205:46 | object creation of type ExceptionB | | Finally.cs:205:21:205:22 | access to parameter b2 | Finally.cs:208:13:210:13 | {...} | -| Finally.cs:205:25:205:47 | [finally: exception(Exception)] throw ...; | Finally.cs:208:13:210:13 | [finally: exception(Exception), finally(2): exception(ExceptionB)] {...} | -| Finally.cs:205:25:205:47 | [finally: exception(ExceptionA)] throw ...; | Finally.cs:208:13:210:13 | [finally: exception(ExceptionA), finally(2): exception(ExceptionB)] {...} | -| Finally.cs:205:25:205:47 | throw ...; | Finally.cs:208:13:210:13 | [finally(2): exception(ExceptionB)] {...} | +| Finally.cs:205:25:205:47 | [finally: exception(Exception)] throw ...; | Finally.cs:208:13:210:13 | [finally: exception(Exception), finally(1): exception(ExceptionB)] {...} | +| Finally.cs:205:25:205:47 | [finally: exception(ExceptionA)] throw ...; | Finally.cs:208:13:210:13 | [finally: exception(ExceptionA), finally(1): exception(ExceptionB)] {...} | +| Finally.cs:205:25:205:47 | throw ...; | Finally.cs:208:13:210:13 | [finally(1): exception(ExceptionB)] {...} | | Finally.cs:205:31:205:46 | [finally: exception(Exception)] object creation of type ExceptionB | Finally.cs:205:25:205:47 | [finally: exception(Exception)] throw ...; | -| Finally.cs:205:31:205:46 | [finally: exception(Exception)] object creation of type ExceptionB | Finally.cs:208:13:210:13 | [finally: exception(Exception), finally(2): exception(Exception)] {...} | +| Finally.cs:205:31:205:46 | [finally: exception(Exception)] object creation of type ExceptionB | Finally.cs:208:13:210:13 | [finally: exception(Exception), finally(1): exception(Exception)] {...} | | Finally.cs:205:31:205:46 | [finally: exception(ExceptionA)] object creation of type ExceptionB | Finally.cs:205:25:205:47 | [finally: exception(ExceptionA)] throw ...; | -| Finally.cs:205:31:205:46 | [finally: exception(ExceptionA)] object creation of type ExceptionB | Finally.cs:208:13:210:13 | [finally: exception(ExceptionA), finally(2): exception(Exception)] {...} | +| Finally.cs:205:31:205:46 | [finally: exception(ExceptionA)] object creation of type ExceptionB | Finally.cs:208:13:210:13 | [finally: exception(ExceptionA), finally(1): exception(Exception)] {...} | | Finally.cs:205:31:205:46 | object creation of type ExceptionB | Finally.cs:205:25:205:47 | throw ...; | -| Finally.cs:205:31:205:46 | object creation of type ExceptionB | Finally.cs:208:13:210:13 | [finally(2): exception(Exception)] {...} | -| Finally.cs:208:13:210:13 | [finally(2): exception(Exception)] {...} | Finally.cs:209:17:209:47 | [finally(2): exception(Exception)] if (...) ... | -| Finally.cs:208:13:210:13 | [finally(2): exception(ExceptionB)] {...} | Finally.cs:209:17:209:47 | [finally(2): exception(ExceptionB)] if (...) ... | -| Finally.cs:208:13:210:13 | [finally: exception(Exception), finally(2): exception(Exception)] {...} | Finally.cs:209:17:209:47 | [finally: exception(Exception), finally(2): exception(Exception)] if (...) ... | -| Finally.cs:208:13:210:13 | [finally: exception(Exception), finally(2): exception(ExceptionB)] {...} | Finally.cs:209:17:209:47 | [finally: exception(Exception), finally(2): exception(ExceptionB)] if (...) ... | +| Finally.cs:205:31:205:46 | object creation of type ExceptionB | Finally.cs:208:13:210:13 | [finally(1): exception(Exception)] {...} | +| Finally.cs:208:13:210:13 | [finally(1): exception(Exception)] {...} | Finally.cs:209:17:209:47 | [finally(1): exception(Exception)] if (...) ... | +| Finally.cs:208:13:210:13 | [finally(1): exception(ExceptionB)] {...} | Finally.cs:209:17:209:47 | [finally(1): exception(ExceptionB)] if (...) ... | +| Finally.cs:208:13:210:13 | [finally: exception(Exception), finally(1): exception(Exception)] {...} | Finally.cs:209:17:209:47 | [finally: exception(Exception), finally(1): exception(Exception)] if (...) ... | +| Finally.cs:208:13:210:13 | [finally: exception(Exception), finally(1): exception(ExceptionB)] {...} | Finally.cs:209:17:209:47 | [finally: exception(Exception), finally(1): exception(ExceptionB)] if (...) ... | | Finally.cs:208:13:210:13 | [finally: exception(Exception)] {...} | Finally.cs:209:17:209:47 | [finally: exception(Exception)] if (...) ... | -| Finally.cs:208:13:210:13 | [finally: exception(ExceptionA), finally(2): exception(Exception)] {...} | Finally.cs:209:17:209:47 | [finally: exception(ExceptionA), finally(2): exception(Exception)] if (...) ... | -| Finally.cs:208:13:210:13 | [finally: exception(ExceptionA), finally(2): exception(ExceptionB)] {...} | Finally.cs:209:17:209:47 | [finally: exception(ExceptionA), finally(2): exception(ExceptionB)] if (...) ... | +| Finally.cs:208:13:210:13 | [finally: exception(ExceptionA), finally(1): exception(Exception)] {...} | Finally.cs:209:17:209:47 | [finally: exception(ExceptionA), finally(1): exception(Exception)] if (...) ... | +| Finally.cs:208:13:210:13 | [finally: exception(ExceptionA), finally(1): exception(ExceptionB)] {...} | Finally.cs:209:17:209:47 | [finally: exception(ExceptionA), finally(1): exception(ExceptionB)] if (...) ... | | Finally.cs:208:13:210:13 | [finally: exception(ExceptionA)] {...} | Finally.cs:209:17:209:47 | [finally: exception(ExceptionA)] if (...) ... | | Finally.cs:208:13:210:13 | {...} | Finally.cs:209:17:209:47 | if (...) ... | -| Finally.cs:209:17:209:47 | [finally(2): exception(Exception)] if (...) ... | Finally.cs:209:21:209:22 | [finally(2): exception(Exception)] access to parameter b3 | -| Finally.cs:209:17:209:47 | [finally(2): exception(ExceptionB)] if (...) ... | Finally.cs:209:21:209:22 | [finally(2): exception(ExceptionB)] access to parameter b3 | -| Finally.cs:209:17:209:47 | [finally: exception(Exception), finally(2): exception(Exception)] if (...) ... | Finally.cs:209:21:209:22 | [finally: exception(Exception), finally(2): exception(Exception)] access to parameter b3 | -| Finally.cs:209:17:209:47 | [finally: exception(Exception), finally(2): exception(ExceptionB)] if (...) ... | Finally.cs:209:21:209:22 | [finally: exception(Exception), finally(2): exception(ExceptionB)] access to parameter b3 | +| Finally.cs:209:17:209:47 | [finally(1): exception(Exception)] if (...) ... | Finally.cs:209:21:209:22 | [finally(1): exception(Exception)] access to parameter b3 | +| Finally.cs:209:17:209:47 | [finally(1): exception(ExceptionB)] if (...) ... | Finally.cs:209:21:209:22 | [finally(1): exception(ExceptionB)] access to parameter b3 | +| Finally.cs:209:17:209:47 | [finally: exception(Exception), finally(1): exception(Exception)] if (...) ... | Finally.cs:209:21:209:22 | [finally: exception(Exception), finally(1): exception(Exception)] access to parameter b3 | +| Finally.cs:209:17:209:47 | [finally: exception(Exception), finally(1): exception(ExceptionB)] if (...) ... | Finally.cs:209:21:209:22 | [finally: exception(Exception), finally(1): exception(ExceptionB)] access to parameter b3 | | Finally.cs:209:17:209:47 | [finally: exception(Exception)] if (...) ... | Finally.cs:209:21:209:22 | [finally: exception(Exception)] access to parameter b3 | -| Finally.cs:209:17:209:47 | [finally: exception(ExceptionA), finally(2): exception(Exception)] if (...) ... | Finally.cs:209:21:209:22 | [finally: exception(ExceptionA), finally(2): exception(Exception)] access to parameter b3 | -| Finally.cs:209:17:209:47 | [finally: exception(ExceptionA), finally(2): exception(ExceptionB)] if (...) ... | Finally.cs:209:21:209:22 | [finally: exception(ExceptionA), finally(2): exception(ExceptionB)] access to parameter b3 | +| Finally.cs:209:17:209:47 | [finally: exception(ExceptionA), finally(1): exception(Exception)] if (...) ... | Finally.cs:209:21:209:22 | [finally: exception(ExceptionA), finally(1): exception(Exception)] access to parameter b3 | +| Finally.cs:209:17:209:47 | [finally: exception(ExceptionA), finally(1): exception(ExceptionB)] if (...) ... | Finally.cs:209:21:209:22 | [finally: exception(ExceptionA), finally(1): exception(ExceptionB)] access to parameter b3 | | Finally.cs:209:17:209:47 | [finally: exception(ExceptionA)] if (...) ... | Finally.cs:209:21:209:22 | [finally: exception(ExceptionA)] access to parameter b3 | | Finally.cs:209:17:209:47 | if (...) ... | Finally.cs:209:21:209:22 | access to parameter b3 | -| Finally.cs:209:21:209:22 | [finally(2): exception(Exception)] access to parameter b3 | Finally.cs:209:31:209:46 | [finally(2): exception(Exception)] object creation of type ExceptionC | -| Finally.cs:209:21:209:22 | [finally(2): exception(ExceptionB)] access to parameter b3 | Finally.cs:209:31:209:46 | [finally(2): exception(ExceptionB)] object creation of type ExceptionC | -| Finally.cs:209:21:209:22 | [finally: exception(Exception), finally(2): exception(Exception)] access to parameter b3 | Finally.cs:209:31:209:46 | [finally: exception(Exception), finally(2): exception(Exception)] object creation of type ExceptionC | -| Finally.cs:209:21:209:22 | [finally: exception(Exception), finally(2): exception(ExceptionB)] access to parameter b3 | Finally.cs:209:31:209:46 | [finally: exception(Exception), finally(2): exception(ExceptionB)] object creation of type ExceptionC | +| Finally.cs:209:21:209:22 | [finally(1): exception(Exception)] access to parameter b3 | Finally.cs:209:31:209:46 | [finally(1): exception(Exception)] object creation of type ExceptionC | +| Finally.cs:209:21:209:22 | [finally(1): exception(ExceptionB)] access to parameter b3 | Finally.cs:209:31:209:46 | [finally(1): exception(ExceptionB)] object creation of type ExceptionC | +| Finally.cs:209:21:209:22 | [finally: exception(Exception), finally(1): exception(Exception)] access to parameter b3 | Finally.cs:209:31:209:46 | [finally: exception(Exception), finally(1): exception(Exception)] object creation of type ExceptionC | +| Finally.cs:209:21:209:22 | [finally: exception(Exception), finally(1): exception(ExceptionB)] access to parameter b3 | Finally.cs:209:31:209:46 | [finally: exception(Exception), finally(1): exception(ExceptionB)] object creation of type ExceptionC | | Finally.cs:209:21:209:22 | [finally: exception(Exception)] access to parameter b3 | Finally.cs:209:31:209:46 | [finally: exception(Exception)] object creation of type ExceptionC | | Finally.cs:209:21:209:22 | [finally: exception(Exception)] access to parameter b3 | Finally.cs:211:13:211:29 | [finally: exception(Exception)] ...; | -| Finally.cs:209:21:209:22 | [finally: exception(ExceptionA), finally(2): exception(Exception)] access to parameter b3 | Finally.cs:209:31:209:46 | [finally: exception(ExceptionA), finally(2): exception(Exception)] object creation of type ExceptionC | -| Finally.cs:209:21:209:22 | [finally: exception(ExceptionA), finally(2): exception(ExceptionB)] access to parameter b3 | Finally.cs:209:31:209:46 | [finally: exception(ExceptionA), finally(2): exception(ExceptionB)] object creation of type ExceptionC | +| Finally.cs:209:21:209:22 | [finally: exception(ExceptionA), finally(1): exception(Exception)] access to parameter b3 | Finally.cs:209:31:209:46 | [finally: exception(ExceptionA), finally(1): exception(Exception)] object creation of type ExceptionC | +| Finally.cs:209:21:209:22 | [finally: exception(ExceptionA), finally(1): exception(ExceptionB)] access to parameter b3 | Finally.cs:209:31:209:46 | [finally: exception(ExceptionA), finally(1): exception(ExceptionB)] object creation of type ExceptionC | | Finally.cs:209:21:209:22 | [finally: exception(ExceptionA)] access to parameter b3 | Finally.cs:209:31:209:46 | [finally: exception(ExceptionA)] object creation of type ExceptionC | | Finally.cs:209:21:209:22 | [finally: exception(ExceptionA)] access to parameter b3 | Finally.cs:211:13:211:29 | [finally: exception(ExceptionA)] ...; | | Finally.cs:209:21:209:22 | access to parameter b3 | Finally.cs:209:31:209:46 | object creation of type ExceptionC | | Finally.cs:209:21:209:22 | access to parameter b3 | Finally.cs:211:13:211:29 | ...; | -| Finally.cs:209:31:209:46 | [finally(2): exception(Exception)] object creation of type ExceptionC | Finally.cs:209:25:209:47 | [finally(2): exception(Exception)] throw ...; | -| Finally.cs:209:31:209:46 | [finally(2): exception(ExceptionB)] object creation of type ExceptionC | Finally.cs:209:25:209:47 | [finally(2): exception(ExceptionB)] throw ...; | -| Finally.cs:209:31:209:46 | [finally: exception(Exception), finally(2): exception(Exception)] object creation of type ExceptionC | Finally.cs:209:25:209:47 | [finally: exception(Exception), finally(2): exception(Exception)] throw ...; | -| Finally.cs:209:31:209:46 | [finally: exception(Exception), finally(2): exception(ExceptionB)] object creation of type ExceptionC | Finally.cs:209:25:209:47 | [finally: exception(Exception), finally(2): exception(ExceptionB)] throw ...; | +| Finally.cs:209:31:209:46 | [finally(1): exception(Exception)] object creation of type ExceptionC | Finally.cs:209:25:209:47 | [finally(1): exception(Exception)] throw ...; | +| Finally.cs:209:31:209:46 | [finally(1): exception(ExceptionB)] object creation of type ExceptionC | Finally.cs:209:25:209:47 | [finally(1): exception(ExceptionB)] throw ...; | +| Finally.cs:209:31:209:46 | [finally: exception(Exception), finally(1): exception(Exception)] object creation of type ExceptionC | Finally.cs:209:25:209:47 | [finally: exception(Exception), finally(1): exception(Exception)] throw ...; | +| Finally.cs:209:31:209:46 | [finally: exception(Exception), finally(1): exception(ExceptionB)] object creation of type ExceptionC | Finally.cs:209:25:209:47 | [finally: exception(Exception), finally(1): exception(ExceptionB)] throw ...; | | Finally.cs:209:31:209:46 | [finally: exception(Exception)] object creation of type ExceptionC | Finally.cs:209:25:209:47 | [finally: exception(Exception)] throw ...; | -| Finally.cs:209:31:209:46 | [finally: exception(ExceptionA), finally(2): exception(Exception)] object creation of type ExceptionC | Finally.cs:209:25:209:47 | [finally: exception(ExceptionA), finally(2): exception(Exception)] throw ...; | -| Finally.cs:209:31:209:46 | [finally: exception(ExceptionA), finally(2): exception(ExceptionB)] object creation of type ExceptionC | Finally.cs:209:25:209:47 | [finally: exception(ExceptionA), finally(2): exception(ExceptionB)] throw ...; | +| Finally.cs:209:31:209:46 | [finally: exception(ExceptionA), finally(1): exception(Exception)] object creation of type ExceptionC | Finally.cs:209:25:209:47 | [finally: exception(ExceptionA), finally(1): exception(Exception)] throw ...; | +| Finally.cs:209:31:209:46 | [finally: exception(ExceptionA), finally(1): exception(ExceptionB)] object creation of type ExceptionC | Finally.cs:209:25:209:47 | [finally: exception(ExceptionA), finally(1): exception(ExceptionB)] throw ...; | | Finally.cs:209:31:209:46 | [finally: exception(ExceptionA)] object creation of type ExceptionC | Finally.cs:209:25:209:47 | [finally: exception(ExceptionA)] throw ...; | | Finally.cs:209:31:209:46 | object creation of type ExceptionC | Finally.cs:209:25:209:47 | throw ...; | | Finally.cs:211:13:211:16 | [finally: exception(Exception)] this access | Finally.cs:211:26:211:28 | [finally: exception(Exception)] "0" | @@ -2305,9 +2279,10 @@ dominance | Finally.cs:217:5:231:5 | {...} | Finally.cs:218:9:229:9 | try {...} ... | | Finally.cs:218:9:229:9 | try {...} ... | Finally.cs:219:9:221:9 | {...} | | Finally.cs:219:9:221:9 | {...} | Finally.cs:220:13:220:37 | ...; | +| Finally.cs:220:13:220:36 | call to method WriteLine | Finally.cs:222:9:225:9 | catch {...} | +| Finally.cs:220:13:220:36 | call to method WriteLine | Finally.cs:227:9:229:9 | {...} | | Finally.cs:220:13:220:37 | ...; | Finally.cs:220:31:220:35 | "Try" | | Finally.cs:220:31:220:35 | "Try" | Finally.cs:220:13:220:36 | call to method WriteLine | -| Finally.cs:220:31:220:35 | "Try" | Finally.cs:222:9:225:9 | catch {...} | | Finally.cs:222:9:225:9 | catch {...} | Finally.cs:223:9:225:9 | {...} | | Finally.cs:223:9:225:9 | {...} | Finally.cs:224:13:224:39 | ...; | | Finally.cs:224:13:224:39 | ...; | Finally.cs:224:31:224:37 | "Catch" | @@ -2319,6 +2294,115 @@ dominance | Finally.cs:230:9:230:33 | call to method WriteLine | Finally.cs:216:10:216:12 | exit M11 (normal) | | Finally.cs:230:9:230:34 | ...; | Finally.cs:230:27:230:32 | "Done" | | Finally.cs:230:27:230:32 | "Done" | Finally.cs:230:9:230:33 | call to method WriteLine | +| Finally.cs:233:10:233:12 | enter M12 | Finally.cs:234:5:261:5 | {...} | +| Finally.cs:234:5:261:5 | {...} | Finally.cs:235:9:259:9 | try {...} ... | +| Finally.cs:235:9:259:9 | try {...} ... | Finally.cs:236:9:255:9 | {...} | +| Finally.cs:236:9:255:9 | {...} | Finally.cs:237:13:253:13 | try {...} ... | +| Finally.cs:237:13:253:13 | try {...} ... | Finally.cs:238:13:241:13 | {...} | +| Finally.cs:238:13:241:13 | {...} | Finally.cs:239:17:240:43 | if (...) ... | +| Finally.cs:239:17:240:43 | if (...) ... | Finally.cs:239:21:239:22 | access to parameter b1 | +| Finally.cs:239:21:239:22 | access to parameter b1 | Finally.cs:240:27:240:42 | object creation of type ExceptionA | +| Finally.cs:239:21:239:22 | access to parameter b1 | Finally.cs:243:13:253:13 | {...} | +| Finally.cs:240:21:240:43 | throw ...; | Finally.cs:243:13:253:13 | [finally: exception(ExceptionA)] {...} | +| Finally.cs:240:27:240:42 | object creation of type ExceptionA | Finally.cs:240:21:240:43 | throw ...; | +| Finally.cs:240:27:240:42 | object creation of type ExceptionA | Finally.cs:243:13:253:13 | [finally: exception(Exception)] {...} | +| Finally.cs:243:13:253:13 | [finally: exception(Exception)] {...} | Finally.cs:244:17:252:17 | [finally: exception(Exception)] try {...} ... | +| Finally.cs:243:13:253:13 | [finally: exception(ExceptionA)] {...} | Finally.cs:244:17:252:17 | [finally: exception(ExceptionA)] try {...} ... | +| Finally.cs:243:13:253:13 | {...} | Finally.cs:244:17:252:17 | try {...} ... | +| Finally.cs:244:17:252:17 | [finally: exception(Exception)] try {...} ... | Finally.cs:245:17:248:17 | [finally: exception(Exception)] {...} | +| Finally.cs:244:17:252:17 | [finally: exception(ExceptionA)] try {...} ... | Finally.cs:245:17:248:17 | [finally: exception(ExceptionA)] {...} | +| Finally.cs:244:17:252:17 | try {...} ... | Finally.cs:245:17:248:17 | {...} | +| Finally.cs:245:17:248:17 | [finally: exception(Exception)] {...} | Finally.cs:246:21:247:47 | [finally: exception(Exception)] if (...) ... | +| Finally.cs:245:17:248:17 | [finally: exception(ExceptionA)] {...} | Finally.cs:246:21:247:47 | [finally: exception(ExceptionA)] if (...) ... | +| Finally.cs:245:17:248:17 | {...} | Finally.cs:246:21:247:47 | if (...) ... | +| Finally.cs:246:21:247:47 | [finally: exception(Exception)] if (...) ... | Finally.cs:246:25:246:26 | [finally: exception(Exception)] access to parameter b2 | +| Finally.cs:246:21:247:47 | [finally: exception(ExceptionA)] if (...) ... | Finally.cs:246:25:246:26 | [finally: exception(ExceptionA)] access to parameter b2 | +| Finally.cs:246:21:247:47 | if (...) ... | Finally.cs:246:25:246:26 | access to parameter b2 | +| Finally.cs:246:25:246:26 | [finally: exception(Exception)] access to parameter b2 | Finally.cs:247:31:247:46 | [finally: exception(Exception)] object creation of type ExceptionA | +| Finally.cs:246:25:246:26 | [finally: exception(Exception)] access to parameter b2 | Finally.cs:250:17:252:17 | [finally: exception(Exception)] {...} | +| Finally.cs:246:25:246:26 | [finally: exception(ExceptionA)] access to parameter b2 | Finally.cs:247:31:247:46 | [finally: exception(ExceptionA)] object creation of type ExceptionA | +| Finally.cs:246:25:246:26 | [finally: exception(ExceptionA)] access to parameter b2 | Finally.cs:250:17:252:17 | [finally: exception(ExceptionA)] {...} | +| Finally.cs:246:25:246:26 | access to parameter b2 | Finally.cs:247:31:247:46 | object creation of type ExceptionA | +| Finally.cs:246:25:246:26 | access to parameter b2 | Finally.cs:250:17:252:17 | {...} | +| Finally.cs:247:25:247:47 | [finally: exception(Exception)] throw ...; | Finally.cs:250:17:252:17 | [finally: exception(Exception), finally(1): exception(ExceptionA)] {...} | +| Finally.cs:247:25:247:47 | [finally: exception(ExceptionA)] throw ...; | Finally.cs:250:17:252:17 | [finally: exception(ExceptionA), finally(1): exception(ExceptionA)] {...} | +| Finally.cs:247:25:247:47 | throw ...; | Finally.cs:250:17:252:17 | [finally(1): exception(ExceptionA)] {...} | +| Finally.cs:247:31:247:46 | [finally: exception(Exception)] object creation of type ExceptionA | Finally.cs:247:25:247:47 | [finally: exception(Exception)] throw ...; | +| Finally.cs:247:31:247:46 | [finally: exception(Exception)] object creation of type ExceptionA | Finally.cs:250:17:252:17 | [finally: exception(Exception), finally(1): exception(Exception)] {...} | +| Finally.cs:247:31:247:46 | [finally: exception(ExceptionA)] object creation of type ExceptionA | Finally.cs:247:25:247:47 | [finally: exception(ExceptionA)] throw ...; | +| Finally.cs:247:31:247:46 | [finally: exception(ExceptionA)] object creation of type ExceptionA | Finally.cs:250:17:252:17 | [finally: exception(ExceptionA), finally(1): exception(Exception)] {...} | +| Finally.cs:247:31:247:46 | object creation of type ExceptionA | Finally.cs:247:25:247:47 | throw ...; | +| Finally.cs:247:31:247:46 | object creation of type ExceptionA | Finally.cs:250:17:252:17 | [finally(1): exception(Exception)] {...} | +| Finally.cs:250:17:252:17 | [finally(1): exception(Exception)] {...} | Finally.cs:251:21:251:55 | [finally(1): exception(Exception)] ...; | +| Finally.cs:250:17:252:17 | [finally(1): exception(ExceptionA)] {...} | Finally.cs:251:21:251:55 | [finally(1): exception(ExceptionA)] ...; | +| Finally.cs:250:17:252:17 | [finally: exception(Exception), finally(1): exception(Exception)] {...} | Finally.cs:251:21:251:55 | [finally: exception(Exception), finally(1): exception(Exception)] ...; | +| Finally.cs:250:17:252:17 | [finally: exception(Exception), finally(1): exception(ExceptionA)] {...} | Finally.cs:251:21:251:55 | [finally: exception(Exception), finally(1): exception(ExceptionA)] ...; | +| Finally.cs:250:17:252:17 | [finally: exception(Exception)] {...} | Finally.cs:251:21:251:55 | [finally: exception(Exception)] ...; | +| Finally.cs:250:17:252:17 | [finally: exception(ExceptionA), finally(1): exception(Exception)] {...} | Finally.cs:251:21:251:55 | [finally: exception(ExceptionA), finally(1): exception(Exception)] ...; | +| Finally.cs:250:17:252:17 | [finally: exception(ExceptionA), finally(1): exception(ExceptionA)] {...} | Finally.cs:251:21:251:55 | [finally: exception(ExceptionA), finally(1): exception(ExceptionA)] ...; | +| Finally.cs:250:17:252:17 | [finally: exception(ExceptionA)] {...} | Finally.cs:251:21:251:55 | [finally: exception(ExceptionA)] ...; | +| Finally.cs:250:17:252:17 | {...} | Finally.cs:251:21:251:55 | ...; | +| Finally.cs:251:21:251:54 | call to method WriteLine | Finally.cs:254:13:254:45 | ...; | +| Finally.cs:251:21:251:55 | ...; | Finally.cs:251:39:251:53 | "Inner finally" | +| Finally.cs:251:21:251:55 | [finally(1): exception(Exception)] ...; | Finally.cs:251:39:251:53 | [finally(1): exception(Exception)] "Inner finally" | +| Finally.cs:251:21:251:55 | [finally(1): exception(ExceptionA)] ...; | Finally.cs:251:39:251:53 | [finally(1): exception(ExceptionA)] "Inner finally" | +| Finally.cs:251:21:251:55 | [finally: exception(Exception), finally(1): exception(Exception)] ...; | Finally.cs:251:39:251:53 | [finally: exception(Exception), finally(1): exception(Exception)] "Inner finally" | +| Finally.cs:251:21:251:55 | [finally: exception(Exception), finally(1): exception(ExceptionA)] ...; | Finally.cs:251:39:251:53 | [finally: exception(Exception), finally(1): exception(ExceptionA)] "Inner finally" | +| Finally.cs:251:21:251:55 | [finally: exception(Exception)] ...; | Finally.cs:251:39:251:53 | [finally: exception(Exception)] "Inner finally" | +| Finally.cs:251:21:251:55 | [finally: exception(ExceptionA), finally(1): exception(Exception)] ...; | Finally.cs:251:39:251:53 | [finally: exception(ExceptionA), finally(1): exception(Exception)] "Inner finally" | +| Finally.cs:251:21:251:55 | [finally: exception(ExceptionA), finally(1): exception(ExceptionA)] ...; | Finally.cs:251:39:251:53 | [finally: exception(ExceptionA), finally(1): exception(ExceptionA)] "Inner finally" | +| Finally.cs:251:21:251:55 | [finally: exception(ExceptionA)] ...; | Finally.cs:251:39:251:53 | [finally: exception(ExceptionA)] "Inner finally" | +| Finally.cs:251:39:251:53 | "Inner finally" | Finally.cs:251:21:251:54 | call to method WriteLine | +| Finally.cs:251:39:251:53 | [finally(1): exception(Exception)] "Inner finally" | Finally.cs:251:21:251:54 | [finally(1): exception(Exception)] call to method WriteLine | +| Finally.cs:251:39:251:53 | [finally(1): exception(ExceptionA)] "Inner finally" | Finally.cs:251:21:251:54 | [finally(1): exception(ExceptionA)] call to method WriteLine | +| Finally.cs:251:39:251:53 | [finally: exception(Exception), finally(1): exception(Exception)] "Inner finally" | Finally.cs:251:21:251:54 | [finally: exception(Exception), finally(1): exception(Exception)] call to method WriteLine | +| Finally.cs:251:39:251:53 | [finally: exception(Exception), finally(1): exception(ExceptionA)] "Inner finally" | Finally.cs:251:21:251:54 | [finally: exception(Exception), finally(1): exception(ExceptionA)] call to method WriteLine | +| Finally.cs:251:39:251:53 | [finally: exception(Exception)] "Inner finally" | Finally.cs:251:21:251:54 | [finally: exception(Exception)] call to method WriteLine | +| Finally.cs:251:39:251:53 | [finally: exception(ExceptionA), finally(1): exception(Exception)] "Inner finally" | Finally.cs:251:21:251:54 | [finally: exception(ExceptionA), finally(1): exception(Exception)] call to method WriteLine | +| Finally.cs:251:39:251:53 | [finally: exception(ExceptionA), finally(1): exception(ExceptionA)] "Inner finally" | Finally.cs:251:21:251:54 | [finally: exception(ExceptionA), finally(1): exception(ExceptionA)] call to method WriteLine | +| Finally.cs:251:39:251:53 | [finally: exception(ExceptionA)] "Inner finally" | Finally.cs:251:21:251:54 | [finally: exception(ExceptionA)] call to method WriteLine | +| Finally.cs:254:13:254:44 | call to method WriteLine | Finally.cs:257:9:259:9 | {...} | +| Finally.cs:254:13:254:45 | ...; | Finally.cs:254:31:254:43 | "Mid finally" | +| Finally.cs:254:31:254:43 | "Mid finally" | Finally.cs:254:13:254:44 | call to method WriteLine | +| Finally.cs:257:9:259:9 | [finally: exception(Exception)] {...} | Finally.cs:258:13:258:47 | [finally: exception(Exception)] ...; | +| Finally.cs:257:9:259:9 | [finally: exception(ExceptionA)] {...} | Finally.cs:258:13:258:47 | [finally: exception(ExceptionA)] ...; | +| Finally.cs:257:9:259:9 | {...} | Finally.cs:258:13:258:47 | ...; | +| Finally.cs:258:13:258:46 | call to method WriteLine | Finally.cs:260:9:260:34 | ...; | +| Finally.cs:258:13:258:47 | ...; | Finally.cs:258:31:258:45 | "Outer finally" | +| Finally.cs:258:13:258:47 | [finally: exception(Exception)] ...; | Finally.cs:258:31:258:45 | [finally: exception(Exception)] "Outer finally" | +| Finally.cs:258:13:258:47 | [finally: exception(ExceptionA)] ...; | Finally.cs:258:31:258:45 | [finally: exception(ExceptionA)] "Outer finally" | +| Finally.cs:258:31:258:45 | "Outer finally" | Finally.cs:258:13:258:46 | call to method WriteLine | +| Finally.cs:258:31:258:45 | [finally: exception(Exception)] "Outer finally" | Finally.cs:258:13:258:46 | [finally: exception(Exception)] call to method WriteLine | +| Finally.cs:258:31:258:45 | [finally: exception(ExceptionA)] "Outer finally" | Finally.cs:258:13:258:46 | [finally: exception(ExceptionA)] call to method WriteLine | +| Finally.cs:260:9:260:33 | call to method WriteLine | Finally.cs:233:10:233:12 | exit M12 (normal) | +| Finally.cs:260:9:260:34 | ...; | Finally.cs:260:27:260:32 | "Done" | +| Finally.cs:260:27:260:32 | "Done" | Finally.cs:260:9:260:33 | call to method WriteLine | +| Finally.cs:263:10:263:12 | enter M13 | Finally.cs:264:5:274:5 | {...} | +| Finally.cs:264:5:274:5 | {...} | Finally.cs:265:9:273:9 | try {...} ... | +| Finally.cs:265:9:273:9 | try {...} ... | Finally.cs:266:9:268:9 | {...} | +| Finally.cs:266:9:268:9 | {...} | Finally.cs:267:13:267:35 | ...; | +| Finally.cs:267:13:267:34 | call to method WriteLine | Finally.cs:270:9:273:9 | [finally: exception(Exception)] {...} | +| Finally.cs:267:13:267:34 | call to method WriteLine | Finally.cs:270:9:273:9 | {...} | +| Finally.cs:267:13:267:35 | ...; | Finally.cs:267:31:267:33 | "1" | +| Finally.cs:267:31:267:33 | "1" | Finally.cs:267:13:267:34 | call to method WriteLine | +| Finally.cs:270:9:273:9 | [finally: exception(Exception)] {...} | Finally.cs:271:13:271:35 | [finally: exception(Exception)] ...; | +| Finally.cs:270:9:273:9 | {...} | Finally.cs:271:13:271:35 | ...; | +| Finally.cs:271:13:271:34 | [finally: exception(Exception)] call to method WriteLine | Finally.cs:272:13:272:19 | [finally: exception(Exception)] ...; | +| Finally.cs:271:13:271:34 | call to method WriteLine | Finally.cs:272:13:272:19 | ...; | +| Finally.cs:271:13:271:35 | ...; | Finally.cs:271:31:271:33 | "3" | +| Finally.cs:271:13:271:35 | [finally: exception(Exception)] ...; | Finally.cs:271:31:271:33 | [finally: exception(Exception)] "3" | +| Finally.cs:271:31:271:33 | "3" | Finally.cs:271:13:271:34 | call to method WriteLine | +| Finally.cs:271:31:271:33 | [finally: exception(Exception)] "3" | Finally.cs:271:13:271:34 | [finally: exception(Exception)] call to method WriteLine | +| Finally.cs:272:13:272:13 | [finally: exception(Exception)] access to parameter i | Finally.cs:272:18:272:18 | [finally: exception(Exception)] 3 | +| Finally.cs:272:13:272:13 | access to parameter i | Finally.cs:272:18:272:18 | 3 | +| Finally.cs:272:13:272:18 | ... + ... | Finally.cs:272:13:272:18 | ... = ... | +| Finally.cs:272:13:272:18 | ... = ... | Finally.cs:263:10:263:12 | exit M13 (normal) | +| Finally.cs:272:13:272:18 | [finally: exception(Exception)] ... + ... | Finally.cs:272:13:272:18 | [finally: exception(Exception)] ... = ... | +| Finally.cs:272:13:272:18 | [finally: exception(Exception)] ... = ... | Finally.cs:263:10:263:12 | exit M13 (abnormal) | +| Finally.cs:272:13:272:19 | ...; | Finally.cs:272:13:272:13 | access to parameter i | +| Finally.cs:272:13:272:19 | [finally: exception(Exception)] ...; | Finally.cs:272:13:272:13 | [finally: exception(Exception)] access to parameter i | +| Finally.cs:272:18:272:18 | 3 | Finally.cs:272:13:272:18 | ... + ... | +| Finally.cs:272:18:272:18 | [finally: exception(Exception)] 3 | Finally.cs:272:13:272:18 | [finally: exception(Exception)] ... + ... | | Foreach.cs:6:10:6:11 | enter M1 | Foreach.cs:7:5:10:5 | {...} | | Foreach.cs:6:10:6:11 | exit M1 (normal) | Foreach.cs:6:10:6:11 | exit M1 | | Foreach.cs:7:5:10:5 | {...} | Foreach.cs:8:29:8:32 | access to parameter args | @@ -2977,17 +3061,18 @@ dominance | NullCoalescing.cs:17:13:17:19 | (...) ... | NullCoalescing.cs:17:13:17:24 | ... ?? ... | | NullCoalescing.cs:17:13:17:24 | ... ?? ... | NullCoalescing.cs:17:9:17:24 | ... = ... | | NullCoalescing.cs:17:19:17:19 | access to parameter i | NullCoalescing.cs:17:13:17:19 | (...) ... | -| Patterns.cs:5:10:5:13 | enter Test | Patterns.cs:6:5:43:5 | {...} | -| Patterns.cs:5:10:5:13 | exit Test (normal) | Patterns.cs:5:10:5:13 | exit Test | +| Patterns.cs:5:10:5:11 | enter M1 | Patterns.cs:6:5:43:5 | {...} | +| Patterns.cs:5:10:5:11 | exit M1 (normal) | Patterns.cs:5:10:5:11 | exit M1 | | Patterns.cs:6:5:43:5 | {...} | Patterns.cs:7:9:7:24 | ... ...; | | Patterns.cs:7:9:7:24 | ... ...; | Patterns.cs:7:20:7:23 | null | | Patterns.cs:7:16:7:23 | Object o = ... | Patterns.cs:8:9:18:9 | if (...) ... | | Patterns.cs:7:20:7:23 | null | Patterns.cs:7:16:7:23 | Object o = ... | | Patterns.cs:8:9:18:9 | if (...) ... | Patterns.cs:8:13:8:13 | access to local variable o | | Patterns.cs:8:13:8:13 | access to local variable o | Patterns.cs:8:18:8:23 | Int32 i1 | -| Patterns.cs:8:13:8:23 | ... is ... | Patterns.cs:9:9:11:9 | {...} | -| Patterns.cs:8:13:8:23 | ... is ... | Patterns.cs:12:14:18:9 | if (...) ... | -| Patterns.cs:8:18:8:23 | Int32 i1 | Patterns.cs:8:13:8:23 | ... is ... | +| Patterns.cs:8:13:8:23 | [false] ... is ... | Patterns.cs:12:14:18:9 | if (...) ... | +| Patterns.cs:8:13:8:23 | [true] ... is ... | Patterns.cs:9:9:11:9 | {...} | +| Patterns.cs:8:18:8:23 | Int32 i1 | Patterns.cs:8:13:8:23 | [false] ... is ... | +| Patterns.cs:8:18:8:23 | Int32 i1 | Patterns.cs:8:13:8:23 | [true] ... is ... | | Patterns.cs:9:9:11:9 | {...} | Patterns.cs:10:13:10:43 | ...; | | Patterns.cs:10:13:10:43 | ...; | Patterns.cs:10:33:10:36 | "int " | | Patterns.cs:10:31:10:41 | $"..." | Patterns.cs:10:13:10:42 | call to method WriteLine | @@ -2995,9 +3080,10 @@ dominance | Patterns.cs:10:38:10:39 | access to local variable i1 | Patterns.cs:10:31:10:41 | $"..." | | Patterns.cs:12:14:18:9 | if (...) ... | Patterns.cs:12:18:12:18 | access to local variable o | | Patterns.cs:12:18:12:18 | access to local variable o | Patterns.cs:12:23:12:31 | String s1 | -| Patterns.cs:12:18:12:31 | ... is ... | Patterns.cs:13:9:15:9 | {...} | -| Patterns.cs:12:18:12:31 | ... is ... | Patterns.cs:16:14:18:9 | if (...) ... | -| Patterns.cs:12:23:12:31 | String s1 | Patterns.cs:12:18:12:31 | ... is ... | +| Patterns.cs:12:18:12:31 | [false] ... is ... | Patterns.cs:16:14:18:9 | if (...) ... | +| Patterns.cs:12:18:12:31 | [true] ... is ... | Patterns.cs:13:9:15:9 | {...} | +| Patterns.cs:12:23:12:31 | String s1 | Patterns.cs:12:18:12:31 | [false] ... is ... | +| Patterns.cs:12:23:12:31 | String s1 | Patterns.cs:12:18:12:31 | [true] ... is ... | | Patterns.cs:13:9:15:9 | {...} | Patterns.cs:14:13:14:46 | ...; | | Patterns.cs:14:13:14:46 | ...; | Patterns.cs:14:33:14:39 | "string " | | Patterns.cs:14:31:14:44 | $"..." | Patterns.cs:14:13:14:45 | call to method WriteLine | @@ -3005,8 +3091,9 @@ dominance | Patterns.cs:14:41:14:42 | access to local variable s1 | Patterns.cs:14:31:14:44 | $"..." | | Patterns.cs:16:14:18:9 | if (...) ... | Patterns.cs:16:18:16:18 | access to local variable o | | Patterns.cs:16:18:16:18 | access to local variable o | Patterns.cs:16:23:16:28 | Object v1 | -| Patterns.cs:16:18:16:28 | ... is ... | Patterns.cs:17:9:18:9 | {...} | -| Patterns.cs:16:23:16:28 | Object v1 | Patterns.cs:16:18:16:28 | ... is ... | +| Patterns.cs:16:18:16:28 | [true] ... is ... | Patterns.cs:17:9:18:9 | {...} | +| Patterns.cs:16:23:16:28 | Object v1 | Patterns.cs:16:18:16:28 | [false] ... is ... | +| Patterns.cs:16:23:16:28 | Object v1 | Patterns.cs:16:18:16:28 | [true] ... is ... | | Patterns.cs:20:9:38:9 | switch (...) {...} | Patterns.cs:20:17:20:17 | access to local variable o | | Patterns.cs:20:17:20:17 | access to local variable o | Patterns.cs:22:13:22:23 | case ...: | | Patterns.cs:22:13:22:23 | case ...: | Patterns.cs:22:18:22:22 | "xyz" | @@ -3047,7 +3134,124 @@ dominance | Patterns.cs:36:17:36:52 | ...; | Patterns.cs:36:35:36:50 | "Something else" | | Patterns.cs:36:35:36:50 | "Something else" | Patterns.cs:36:17:36:51 | call to method WriteLine | | Patterns.cs:40:9:42:9 | switch (...) {...} | Patterns.cs:40:17:40:17 | access to local variable o | -| Patterns.cs:40:17:40:17 | access to local variable o | Patterns.cs:5:10:5:13 | exit Test (normal) | +| Patterns.cs:40:17:40:17 | access to local variable o | Patterns.cs:5:10:5:11 | exit M1 (normal) | +| Patterns.cs:47:24:47:25 | enter M2 | Patterns.cs:48:9:48:9 | access to parameter c | +| Patterns.cs:47:24:47:25 | exit M2 (normal) | Patterns.cs:47:24:47:25 | exit M2 | +| Patterns.cs:48:9:48:9 | access to parameter c | Patterns.cs:48:18:48:20 | a | +| Patterns.cs:48:9:48:20 | ... is ... | Patterns.cs:47:24:47:25 | exit M2 (normal) | +| Patterns.cs:48:14:48:20 | not ... | Patterns.cs:48:9:48:20 | ... is ... | +| Patterns.cs:48:18:48:20 | a | Patterns.cs:48:14:48:20 | not ... | +| Patterns.cs:50:24:50:25 | enter M3 | Patterns.cs:51:9:51:9 | access to parameter c | +| Patterns.cs:50:24:50:25 | exit M3 (normal) | Patterns.cs:50:24:50:25 | exit M3 | +| Patterns.cs:51:9:51:9 | access to parameter c | Patterns.cs:51:18:51:21 | null | +| Patterns.cs:51:9:51:21 | [false] ... is ... | Patterns.cs:51:34:51:34 | access to parameter c | +| Patterns.cs:51:9:51:21 | [true] ... is ... | Patterns.cs:51:25:51:25 | access to parameter c | +| Patterns.cs:51:9:51:39 | ... ? ... : ... | Patterns.cs:50:24:50:25 | exit M3 (normal) | +| Patterns.cs:51:14:51:21 | [match] not ... | Patterns.cs:51:9:51:21 | [true] ... is ... | +| Patterns.cs:51:14:51:21 | [no-match] not ... | Patterns.cs:51:9:51:21 | [false] ... is ... | +| Patterns.cs:51:18:51:21 | null | Patterns.cs:51:14:51:21 | [match] not ... | +| Patterns.cs:51:18:51:21 | null | Patterns.cs:51:14:51:21 | [no-match] not ... | +| Patterns.cs:51:25:51:25 | access to parameter c | Patterns.cs:51:30:51:30 | 1 | +| Patterns.cs:51:30:51:30 | 1 | Patterns.cs:51:25:51:30 | ... is ... | +| Patterns.cs:51:34:51:34 | access to parameter c | Patterns.cs:51:39:51:39 | 2 | +| Patterns.cs:51:39:51:39 | 2 | Patterns.cs:51:34:51:39 | ... is ... | +| Patterns.cs:53:24:53:25 | enter M4 | Patterns.cs:54:9:54:9 | access to parameter c | +| Patterns.cs:53:24:53:25 | exit M4 (normal) | Patterns.cs:53:24:53:25 | exit M4 | +| Patterns.cs:54:9:54:9 | access to parameter c | Patterns.cs:54:18:54:37 | Patterns u | +| Patterns.cs:54:9:54:37 | ... is ... | Patterns.cs:53:24:53:25 | exit M4 (normal) | +| Patterns.cs:54:14:54:37 | not ... | Patterns.cs:54:9:54:37 | ... is ... | +| Patterns.cs:54:18:54:37 | Patterns u | Patterns.cs:54:18:54:37 | { ... } | +| Patterns.cs:54:18:54:37 | Patterns u | Patterns.cs:54:33:54:33 | 1 | +| Patterns.cs:54:18:54:37 | { ... } | Patterns.cs:54:14:54:37 | not ... | +| Patterns.cs:54:33:54:33 | 1 | Patterns.cs:54:27:54:35 | [match] { ... } | +| Patterns.cs:54:33:54:33 | 1 | Patterns.cs:54:27:54:35 | [no-match] { ... } | +| Patterns.cs:56:26:56:27 | enter M5 | Patterns.cs:57:5:63:5 | {...} | +| Patterns.cs:56:26:56:27 | exit M5 (normal) | Patterns.cs:56:26:56:27 | exit M5 | +| Patterns.cs:57:5:63:5 | {...} | Patterns.cs:58:16:58:16 | access to parameter i | +| Patterns.cs:58:9:62:10 | return ...; | Patterns.cs:56:26:56:27 | exit M5 (normal) | +| Patterns.cs:58:16:58:16 | access to parameter i | Patterns.cs:60:17:60:17 | 1 | +| Patterns.cs:58:16:62:9 | ... switch { ... } | Patterns.cs:58:9:62:10 | return ...; | +| Patterns.cs:60:13:60:17 | [match] not ... | Patterns.cs:60:22:60:28 | "not 1" | +| Patterns.cs:60:13:60:17 | [no-match] not ... | Patterns.cs:61:13:61:13 | _ | +| Patterns.cs:60:17:60:17 | 1 | Patterns.cs:60:13:60:17 | [match] not ... | +| Patterns.cs:60:17:60:17 | 1 | Patterns.cs:60:13:60:17 | [no-match] not ... | +| Patterns.cs:60:22:60:28 | "not 1" | Patterns.cs:60:13:60:28 | ... => ... | +| Patterns.cs:61:13:61:13 | _ | Patterns.cs:61:18:61:24 | "other" | +| Patterns.cs:61:18:61:24 | "other" | Patterns.cs:61:13:61:24 | ... => ... | +| Patterns.cs:65:26:65:27 | enter M6 | Patterns.cs:66:5:72:5 | {...} | +| Patterns.cs:65:26:65:27 | exit M6 (normal) | Patterns.cs:65:26:65:27 | exit M6 | +| Patterns.cs:66:5:72:5 | {...} | Patterns.cs:67:16:67:16 | 2 | +| Patterns.cs:67:9:71:10 | return ...; | Patterns.cs:65:26:65:27 | exit M6 (normal) | +| Patterns.cs:67:16:67:16 | 2 | Patterns.cs:69:17:69:17 | 2 | +| Patterns.cs:67:16:71:9 | ... switch { ... } | Patterns.cs:67:9:71:10 | return ...; | +| Patterns.cs:69:13:69:17 | [no-match] not ... | Patterns.cs:70:13:70:13 | 2 | +| Patterns.cs:69:17:69:17 | 2 | Patterns.cs:69:13:69:17 | [no-match] not ... | +| Patterns.cs:70:13:70:13 | 2 | Patterns.cs:70:18:70:27 | "possible" | +| Patterns.cs:70:13:70:27 | ... => ... | Patterns.cs:67:16:71:9 | ... switch { ... } | +| Patterns.cs:70:18:70:27 | "possible" | Patterns.cs:70:13:70:27 | ... => ... | +| Patterns.cs:74:26:74:27 | enter M7 | Patterns.cs:75:5:83:5 | {...} | +| Patterns.cs:74:26:74:27 | exit M7 (normal) | Patterns.cs:74:26:74:27 | exit M7 | +| Patterns.cs:75:5:83:5 | {...} | Patterns.cs:76:16:76:16 | access to parameter i | +| Patterns.cs:76:9:82:10 | return ...; | Patterns.cs:74:26:74:27 | exit M7 (normal) | +| Patterns.cs:76:16:76:16 | access to parameter i | Patterns.cs:78:15:78:15 | 1 | +| Patterns.cs:76:16:82:9 | ... switch { ... } | Patterns.cs:76:9:82:10 | return ...; | +| Patterns.cs:78:13:78:15 | > ... | Patterns.cs:78:20:78:24 | "> 1" | +| Patterns.cs:78:13:78:15 | > ... | Patterns.cs:79:15:79:15 | 0 | +| Patterns.cs:78:15:78:15 | 1 | Patterns.cs:78:13:78:15 | > ... | +| Patterns.cs:78:20:78:24 | "> 1" | Patterns.cs:78:13:78:24 | ... => ... | +| Patterns.cs:79:13:79:15 | < ... | Patterns.cs:79:20:79:24 | "< 0" | +| Patterns.cs:79:13:79:15 | < ... | Patterns.cs:80:13:80:13 | 1 | +| Patterns.cs:79:15:79:15 | 0 | Patterns.cs:79:13:79:15 | < ... | +| Patterns.cs:79:20:79:24 | "< 0" | Patterns.cs:79:13:79:24 | ... => ... | +| Patterns.cs:80:13:80:13 | 1 | Patterns.cs:80:18:80:20 | "1" | +| Patterns.cs:80:13:80:13 | 1 | Patterns.cs:81:13:81:13 | _ | +| Patterns.cs:80:18:80:20 | "1" | Patterns.cs:80:13:80:20 | ... => ... | +| Patterns.cs:81:13:81:13 | _ | Patterns.cs:81:18:81:20 | "0" | +| Patterns.cs:81:18:81:20 | "0" | Patterns.cs:81:13:81:20 | ... => ... | +| Patterns.cs:85:26:85:27 | enter M8 | Patterns.cs:85:39:85:39 | access to parameter i | +| Patterns.cs:85:26:85:27 | exit M8 (normal) | Patterns.cs:85:26:85:27 | exit M8 | +| Patterns.cs:85:39:85:39 | access to parameter i | Patterns.cs:85:44:85:44 | 1 | +| Patterns.cs:85:39:85:53 | [false] ... is ... | Patterns.cs:85:67:85:69 | "2" | +| Patterns.cs:85:39:85:53 | [true] ... is ... | Patterns.cs:85:57:85:63 | "not 2" | +| Patterns.cs:85:39:85:69 | ... ? ... : ... | Patterns.cs:85:26:85:27 | exit M8 (normal) | +| Patterns.cs:85:44:85:44 | 1 | Patterns.cs:85:44:85:53 | [match] ... or ... | +| Patterns.cs:85:44:85:44 | 1 | Patterns.cs:85:53:85:53 | 2 | +| Patterns.cs:85:44:85:53 | [match] ... or ... | Patterns.cs:85:39:85:53 | [true] ... is ... | +| Patterns.cs:85:44:85:53 | [no-match] ... or ... | Patterns.cs:85:39:85:53 | [false] ... is ... | +| Patterns.cs:85:49:85:53 | [no-match] not ... | Patterns.cs:85:44:85:53 | [no-match] ... or ... | +| Patterns.cs:85:53:85:53 | 2 | Patterns.cs:85:49:85:53 | [match] not ... | +| Patterns.cs:85:53:85:53 | 2 | Patterns.cs:85:49:85:53 | [no-match] not ... | +| Patterns.cs:87:26:87:27 | enter M9 | Patterns.cs:87:39:87:39 | access to parameter i | +| Patterns.cs:87:26:87:27 | exit M9 (normal) | Patterns.cs:87:26:87:27 | exit M9 | +| Patterns.cs:87:39:87:39 | access to parameter i | Patterns.cs:87:44:87:44 | 1 | +| Patterns.cs:87:39:87:54 | [false] ... is ... | Patterns.cs:87:64:87:70 | "not 1" | +| Patterns.cs:87:39:87:54 | [true] ... is ... | Patterns.cs:87:58:87:60 | "1" | +| Patterns.cs:87:39:87:70 | ... ? ... : ... | Patterns.cs:87:26:87:27 | exit M9 (normal) | +| Patterns.cs:87:44:87:44 | 1 | Patterns.cs:87:44:87:54 | [no-match] ... and ... | +| Patterns.cs:87:44:87:44 | 1 | Patterns.cs:87:54:87:54 | 2 | +| Patterns.cs:87:44:87:54 | [match] ... and ... | Patterns.cs:87:39:87:54 | [true] ... is ... | +| Patterns.cs:87:44:87:54 | [no-match] ... and ... | Patterns.cs:87:39:87:54 | [false] ... is ... | +| Patterns.cs:87:50:87:54 | [match] not ... | Patterns.cs:87:44:87:54 | [match] ... and ... | +| Patterns.cs:87:54:87:54 | 2 | Patterns.cs:87:50:87:54 | [match] not ... | +| Patterns.cs:87:54:87:54 | 2 | Patterns.cs:87:50:87:54 | [no-match] not ... | +| Patterns.cs:93:17:93:19 | enter M10 | Patterns.cs:94:5:99:5 | {...} | +| Patterns.cs:93:17:93:19 | exit M10 (normal) | Patterns.cs:93:17:93:19 | exit M10 | +| Patterns.cs:94:5:99:5 | {...} | Patterns.cs:95:9:98:9 | if (...) ... | +| Patterns.cs:95:9:98:9 | if (...) ... | Patterns.cs:95:13:95:16 | this access | +| Patterns.cs:95:13:95:16 | this access | Patterns.cs:95:29:95:31 | access to constant A | +| Patterns.cs:95:13:95:40 | [true] ... is ... | Patterns.cs:96:9:98:9 | {...} | +| Patterns.cs:95:21:95:40 | [match] { ... } | Patterns.cs:95:13:95:40 | [true] ... is ... | +| Patterns.cs:95:21:95:40 | [match] { ... } | Patterns.cs:95:21:95:40 | [match] { ... } | +| Patterns.cs:95:21:95:40 | [no-match] { ... } | Patterns.cs:95:13:95:40 | [false] ... is ... | +| Patterns.cs:95:21:95:40 | [no-match] { ... } | Patterns.cs:95:21:95:40 | [no-match] { ... } | +| Patterns.cs:95:29:95:31 | access to constant A | Patterns.cs:95:29:95:38 | [match] ... or ... | +| Patterns.cs:95:29:95:31 | access to constant A | Patterns.cs:95:36:95:38 | access to constant B | +| Patterns.cs:95:29:95:38 | [match] ... or ... | Patterns.cs:95:21:95:40 | [match] { ... } | +| Patterns.cs:95:29:95:38 | [no-match] ... or ... | Patterns.cs:95:21:95:40 | [no-match] { ... } | +| Patterns.cs:95:36:95:38 | access to constant B | Patterns.cs:95:29:95:38 | [no-match] ... or ... | +| Patterns.cs:96:9:98:9 | {...} | Patterns.cs:97:13:97:39 | ...; | +| Patterns.cs:97:13:97:39 | ...; | Patterns.cs:97:31:97:37 | "not C" | +| Patterns.cs:97:31:97:37 | "not C" | Patterns.cs:97:13:97:38 | call to method WriteLine | | PostDominance.cs:5:10:5:11 | enter M1 | PostDominance.cs:6:5:8:5 | {...} | | PostDominance.cs:5:10:5:11 | exit M1 (normal) | PostDominance.cs:5:10:5:11 | exit M1 | | PostDominance.cs:6:5:8:5 | {...} | PostDominance.cs:7:9:7:29 | ...; | @@ -3059,18 +3263,20 @@ dominance | PostDominance.cs:11:5:15:5 | {...} | PostDominance.cs:12:9:13:19 | if (...) ... | | PostDominance.cs:12:9:13:19 | if (...) ... | PostDominance.cs:12:13:12:13 | access to parameter s | | PostDominance.cs:12:13:12:13 | access to parameter s | PostDominance.cs:12:18:12:21 | null | -| PostDominance.cs:12:13:12:21 | ... is ... | PostDominance.cs:13:13:13:19 | return ...; | -| PostDominance.cs:12:13:12:21 | ... is ... | PostDominance.cs:14:9:14:29 | ...; | -| PostDominance.cs:12:18:12:21 | null | PostDominance.cs:12:13:12:21 | ... is ... | +| PostDominance.cs:12:13:12:21 | [false] ... is ... | PostDominance.cs:14:9:14:29 | ...; | +| PostDominance.cs:12:13:12:21 | [true] ... is ... | PostDominance.cs:13:13:13:19 | return ...; | +| PostDominance.cs:12:18:12:21 | null | PostDominance.cs:12:13:12:21 | [false] ... is ... | +| PostDominance.cs:12:18:12:21 | null | PostDominance.cs:12:13:12:21 | [true] ... is ... | | PostDominance.cs:14:9:14:29 | ...; | PostDominance.cs:14:27:14:27 | access to parameter s | | PostDominance.cs:14:27:14:27 | access to parameter s | PostDominance.cs:14:9:14:28 | call to method WriteLine | | PostDominance.cs:17:10:17:11 | enter M3 | PostDominance.cs:18:5:22:5 | {...} | | PostDominance.cs:18:5:22:5 | {...} | PostDominance.cs:19:9:20:55 | if (...) ... | | PostDominance.cs:19:9:20:55 | if (...) ... | PostDominance.cs:19:13:19:13 | access to parameter s | | PostDominance.cs:19:13:19:13 | access to parameter s | PostDominance.cs:19:18:19:21 | null | -| PostDominance.cs:19:13:19:21 | ... is ... | PostDominance.cs:20:45:20:53 | nameof(...) | -| PostDominance.cs:19:13:19:21 | ... is ... | PostDominance.cs:21:9:21:29 | ...; | -| PostDominance.cs:19:18:19:21 | null | PostDominance.cs:19:13:19:21 | ... is ... | +| PostDominance.cs:19:13:19:21 | [false] ... is ... | PostDominance.cs:21:9:21:29 | ...; | +| PostDominance.cs:19:13:19:21 | [true] ... is ... | PostDominance.cs:20:45:20:53 | nameof(...) | +| PostDominance.cs:19:18:19:21 | null | PostDominance.cs:19:13:19:21 | [false] ... is ... | +| PostDominance.cs:19:18:19:21 | null | PostDominance.cs:19:13:19:21 | [true] ... is ... | | PostDominance.cs:20:13:20:55 | throw ...; | PostDominance.cs:17:10:17:11 | exit M3 (abnormal) | | PostDominance.cs:20:19:20:54 | object creation of type ArgumentNullException | PostDominance.cs:20:13:20:55 | throw ...; | | PostDominance.cs:20:45:20:53 | nameof(...) | PostDominance.cs:20:19:20:54 | object creation of type ArgumentNullException | @@ -3394,9 +3600,9 @@ dominance | TypeAccesses.cs:6:13:6:23 | ... as ... | TypeAccesses.cs:6:9:6:23 | ... = ... | | TypeAccesses.cs:7:9:7:25 | if (...) ... | TypeAccesses.cs:7:13:7:13 | access to parameter o | | TypeAccesses.cs:7:13:7:13 | access to parameter o | TypeAccesses.cs:7:18:7:22 | Int32 j | -| TypeAccesses.cs:7:13:7:22 | ... is ... | TypeAccesses.cs:7:25:7:25 | ; | -| TypeAccesses.cs:7:13:7:22 | ... is ... | TypeAccesses.cs:8:9:8:28 | ... ...; | -| TypeAccesses.cs:7:18:7:22 | Int32 j | TypeAccesses.cs:7:13:7:22 | ... is ... | +| TypeAccesses.cs:7:13:7:22 | [true] ... is ... | TypeAccesses.cs:7:25:7:25 | ; | +| TypeAccesses.cs:7:18:7:22 | Int32 j | TypeAccesses.cs:7:13:7:22 | [false] ... is ... | +| TypeAccesses.cs:7:18:7:22 | Int32 j | TypeAccesses.cs:7:13:7:22 | [true] ... is ... | | TypeAccesses.cs:8:9:8:28 | ... ...; | TypeAccesses.cs:8:17:8:27 | typeof(...) | | TypeAccesses.cs:8:13:8:27 | Type t = ... | TypeAccesses.cs:3:10:3:10 | exit M (normal) | | TypeAccesses.cs:8:17:8:27 | typeof(...) | TypeAccesses.cs:8:13:8:27 | Type t = ... | @@ -5509,147 +5715,156 @@ postDominance | Conditions.cs:149:38:149:47 | $"..." | Conditions.cs:149:45:149:45 | access to local variable s | | Conditions.cs:149:40:149:43 | "b = " | Conditions.cs:149:13:149:49 | ...; | | Conditions.cs:149:45:149:45 | access to local variable s | Conditions.cs:149:40:149:43 | "b = " | -| ExitMethods.cs:7:10:7:11 | exit M1 | ExitMethods.cs:7:10:7:11 | exit M1 (normal) | -| ExitMethods.cs:7:10:7:11 | exit M1 (normal) | ExitMethods.cs:10:9:10:15 | return ...; | -| ExitMethods.cs:8:5:11:5 | {...} | ExitMethods.cs:7:10:7:11 | enter M1 | -| ExitMethods.cs:9:9:9:24 | call to method ErrorMaybe | ExitMethods.cs:9:20:9:23 | true | -| ExitMethods.cs:9:9:9:25 | ...; | ExitMethods.cs:8:5:11:5 | {...} | -| ExitMethods.cs:9:20:9:23 | true | ExitMethods.cs:9:9:9:25 | ...; | -| ExitMethods.cs:10:9:10:15 | return ...; | ExitMethods.cs:9:9:9:24 | call to method ErrorMaybe | -| ExitMethods.cs:13:10:13:11 | exit M2 | ExitMethods.cs:13:10:13:11 | exit M2 (normal) | -| ExitMethods.cs:13:10:13:11 | exit M2 (normal) | ExitMethods.cs:16:9:16:15 | return ...; | -| ExitMethods.cs:14:5:17:5 | {...} | ExitMethods.cs:13:10:13:11 | enter M2 | -| ExitMethods.cs:15:9:15:25 | call to method ErrorMaybe | ExitMethods.cs:15:20:15:24 | false | -| ExitMethods.cs:15:9:15:26 | ...; | ExitMethods.cs:14:5:17:5 | {...} | -| ExitMethods.cs:15:20:15:24 | false | ExitMethods.cs:15:9:15:26 | ...; | -| ExitMethods.cs:16:9:16:15 | return ...; | ExitMethods.cs:15:9:15:25 | call to method ErrorMaybe | -| ExitMethods.cs:19:10:19:11 | exit M3 | ExitMethods.cs:19:10:19:11 | exit M3 (abnormal) | -| ExitMethods.cs:19:10:19:11 | exit M3 (abnormal) | ExitMethods.cs:21:9:21:25 | call to method ErrorAlways | -| ExitMethods.cs:20:5:23:5 | {...} | ExitMethods.cs:19:10:19:11 | enter M3 | -| ExitMethods.cs:21:9:21:25 | call to method ErrorAlways | ExitMethods.cs:21:21:21:24 | true | -| ExitMethods.cs:21:9:21:26 | ...; | ExitMethods.cs:20:5:23:5 | {...} | -| ExitMethods.cs:21:21:21:24 | true | ExitMethods.cs:21:9:21:26 | ...; | -| ExitMethods.cs:25:10:25:11 | exit M4 | ExitMethods.cs:25:10:25:11 | exit M4 (abnormal) | -| ExitMethods.cs:25:10:25:11 | exit M4 (abnormal) | ExitMethods.cs:27:9:27:14 | call to method Exit | -| ExitMethods.cs:26:5:29:5 | {...} | ExitMethods.cs:25:10:25:11 | enter M4 | -| ExitMethods.cs:27:9:27:14 | call to method Exit | ExitMethods.cs:27:9:27:14 | this access | -| ExitMethods.cs:27:9:27:14 | this access | ExitMethods.cs:27:9:27:15 | ...; | -| ExitMethods.cs:27:9:27:15 | ...; | ExitMethods.cs:26:5:29:5 | {...} | -| ExitMethods.cs:31:10:31:11 | exit M5 | ExitMethods.cs:31:10:31:11 | exit M5 (abnormal) | -| ExitMethods.cs:31:10:31:11 | exit M5 (abnormal) | ExitMethods.cs:33:9:33:25 | call to method ApplicationExit | -| ExitMethods.cs:32:5:35:5 | {...} | ExitMethods.cs:31:10:31:11 | enter M5 | -| ExitMethods.cs:33:9:33:25 | call to method ApplicationExit | ExitMethods.cs:33:9:33:25 | this access | -| ExitMethods.cs:33:9:33:25 | this access | ExitMethods.cs:33:9:33:26 | ...; | -| ExitMethods.cs:33:9:33:26 | ...; | ExitMethods.cs:32:5:35:5 | {...} | -| ExitMethods.cs:37:10:37:11 | exit M6 | ExitMethods.cs:37:10:37:11 | exit M6 (normal) | -| ExitMethods.cs:37:10:37:11 | exit M6 (normal) | ExitMethods.cs:45:13:45:19 | return ...; | -| ExitMethods.cs:37:10:37:11 | exit M6 (normal) | ExitMethods.cs:49:13:49:19 | return ...; | -| ExitMethods.cs:38:5:51:5 | {...} | ExitMethods.cs:37:10:37:11 | enter M6 | -| ExitMethods.cs:39:9:50:9 | try {...} ... | ExitMethods.cs:38:5:51:5 | {...} | -| ExitMethods.cs:40:9:42:9 | {...} | ExitMethods.cs:39:9:50:9 | try {...} ... | -| ExitMethods.cs:41:13:41:30 | call to method ErrorAlways | ExitMethods.cs:41:25:41:29 | false | -| ExitMethods.cs:41:13:41:31 | ...; | ExitMethods.cs:40:9:42:9 | {...} | -| ExitMethods.cs:41:25:41:29 | false | ExitMethods.cs:41:13:41:31 | ...; | -| ExitMethods.cs:44:9:46:9 | {...} | ExitMethods.cs:43:9:46:9 | [exception: ArgumentException] catch (...) {...} | -| ExitMethods.cs:45:13:45:19 | return ...; | ExitMethods.cs:44:9:46:9 | {...} | -| ExitMethods.cs:48:9:50:9 | {...} | ExitMethods.cs:47:9:50:9 | [exception: Exception] catch (...) {...} | -| ExitMethods.cs:49:13:49:19 | return ...; | ExitMethods.cs:48:9:50:9 | {...} | -| ExitMethods.cs:53:10:53:11 | exit M7 | ExitMethods.cs:53:10:53:11 | exit M7 (abnormal) | -| ExitMethods.cs:53:10:53:11 | exit M7 (abnormal) | ExitMethods.cs:55:9:55:22 | call to method ErrorAlways2 | -| ExitMethods.cs:54:5:57:5 | {...} | ExitMethods.cs:53:10:53:11 | enter M7 | -| ExitMethods.cs:55:9:55:22 | call to method ErrorAlways2 | ExitMethods.cs:55:9:55:23 | ...; | -| ExitMethods.cs:55:9:55:23 | ...; | ExitMethods.cs:54:5:57:5 | {...} | -| ExitMethods.cs:59:10:59:11 | exit M8 | ExitMethods.cs:59:10:59:11 | exit M8 (abnormal) | -| ExitMethods.cs:59:10:59:11 | exit M8 (abnormal) | ExitMethods.cs:61:9:61:22 | call to method ErrorAlways3 | -| ExitMethods.cs:60:5:63:5 | {...} | ExitMethods.cs:59:10:59:11 | enter M8 | -| ExitMethods.cs:61:9:61:22 | call to method ErrorAlways3 | ExitMethods.cs:61:9:61:23 | ...; | -| ExitMethods.cs:61:9:61:23 | ...; | ExitMethods.cs:60:5:63:5 | {...} | -| ExitMethods.cs:65:17:65:26 | exit ErrorMaybe (abnormal) | ExitMethods.cs:68:13:68:34 | throw ...; | -| ExitMethods.cs:65:17:65:26 | exit ErrorMaybe (normal) | ExitMethods.cs:67:13:67:13 | access to parameter b | -| ExitMethods.cs:66:5:69:5 | {...} | ExitMethods.cs:65:17:65:26 | enter ErrorMaybe | -| ExitMethods.cs:67:9:68:34 | if (...) ... | ExitMethods.cs:66:5:69:5 | {...} | -| ExitMethods.cs:67:13:67:13 | access to parameter b | ExitMethods.cs:67:9:68:34 | if (...) ... | -| ExitMethods.cs:68:13:68:34 | throw ...; | ExitMethods.cs:68:19:68:33 | object creation of type Exception | -| ExitMethods.cs:71:17:71:27 | exit ErrorAlways | ExitMethods.cs:71:17:71:27 | exit ErrorAlways (abnormal) | -| ExitMethods.cs:72:5:77:5 | {...} | ExitMethods.cs:71:17:71:27 | enter ErrorAlways | -| ExitMethods.cs:73:9:76:45 | if (...) ... | ExitMethods.cs:72:5:77:5 | {...} | -| ExitMethods.cs:73:13:73:13 | access to parameter b | ExitMethods.cs:73:9:76:45 | if (...) ... | -| ExitMethods.cs:74:13:74:34 | throw ...; | ExitMethods.cs:74:19:74:33 | object creation of type Exception | -| ExitMethods.cs:76:13:76:45 | throw ...; | ExitMethods.cs:76:19:76:44 | object creation of type ArgumentException | -| ExitMethods.cs:76:19:76:44 | object creation of type ArgumentException | ExitMethods.cs:76:41:76:43 | "b" | -| ExitMethods.cs:79:17:79:28 | exit ErrorAlways2 | ExitMethods.cs:79:17:79:28 | exit ErrorAlways2 (abnormal) | -| ExitMethods.cs:79:17:79:28 | exit ErrorAlways2 (abnormal) | ExitMethods.cs:81:9:81:30 | throw ...; | -| ExitMethods.cs:80:5:82:5 | {...} | ExitMethods.cs:79:17:79:28 | enter ErrorAlways2 | -| ExitMethods.cs:81:9:81:30 | throw ...; | ExitMethods.cs:81:15:81:29 | object creation of type Exception | -| ExitMethods.cs:81:15:81:29 | object creation of type Exception | ExitMethods.cs:80:5:82:5 | {...} | -| ExitMethods.cs:84:17:84:28 | exit ErrorAlways3 | ExitMethods.cs:84:17:84:28 | exit ErrorAlways3 (abnormal) | -| ExitMethods.cs:84:17:84:28 | exit ErrorAlways3 (abnormal) | ExitMethods.cs:84:35:84:55 | throw ... | -| ExitMethods.cs:84:35:84:55 | throw ... | ExitMethods.cs:84:41:84:55 | object creation of type Exception | -| ExitMethods.cs:84:41:84:55 | object creation of type Exception | ExitMethods.cs:84:17:84:28 | enter ErrorAlways3 | -| ExitMethods.cs:86:10:86:13 | exit Exit | ExitMethods.cs:86:10:86:13 | exit Exit (abnormal) | -| ExitMethods.cs:86:10:86:13 | exit Exit (abnormal) | ExitMethods.cs:88:9:88:27 | call to method Exit | -| ExitMethods.cs:87:5:89:5 | {...} | ExitMethods.cs:86:10:86:13 | enter Exit | -| ExitMethods.cs:88:9:88:27 | call to method Exit | ExitMethods.cs:88:26:88:26 | 0 | -| ExitMethods.cs:88:9:88:28 | ...; | ExitMethods.cs:87:5:89:5 | {...} | -| ExitMethods.cs:88:26:88:26 | 0 | ExitMethods.cs:88:9:88:28 | ...; | -| ExitMethods.cs:91:10:91:18 | exit ExitInTry | ExitMethods.cs:91:10:91:18 | exit ExitInTry (abnormal) | -| ExitMethods.cs:91:10:91:18 | exit ExitInTry (abnormal) | ExitMethods.cs:95:13:95:18 | call to method Exit | -| ExitMethods.cs:92:5:102:5 | {...} | ExitMethods.cs:91:10:91:18 | enter ExitInTry | -| ExitMethods.cs:93:9:101:9 | try {...} ... | ExitMethods.cs:92:5:102:5 | {...} | -| ExitMethods.cs:94:9:96:9 | {...} | ExitMethods.cs:93:9:101:9 | try {...} ... | -| ExitMethods.cs:95:13:95:18 | call to method Exit | ExitMethods.cs:95:13:95:18 | this access | -| ExitMethods.cs:95:13:95:18 | this access | ExitMethods.cs:95:13:95:19 | ...; | -| ExitMethods.cs:95:13:95:19 | ...; | ExitMethods.cs:94:9:96:9 | {...} | -| ExitMethods.cs:104:10:104:24 | exit ApplicationExit | ExitMethods.cs:104:10:104:24 | exit ApplicationExit (abnormal) | -| ExitMethods.cs:104:10:104:24 | exit ApplicationExit (abnormal) | ExitMethods.cs:106:9:106:47 | call to method Exit | -| ExitMethods.cs:105:5:107:5 | {...} | ExitMethods.cs:104:10:104:24 | enter ApplicationExit | -| ExitMethods.cs:106:9:106:47 | call to method Exit | ExitMethods.cs:106:9:106:48 | ...; | -| ExitMethods.cs:106:9:106:48 | ...; | ExitMethods.cs:105:5:107:5 | {...} | -| ExitMethods.cs:109:13:109:21 | exit ThrowExpr (abnormal) | ExitMethods.cs:111:41:111:76 | throw ... | -| ExitMethods.cs:109:13:109:21 | exit ThrowExpr (normal) | ExitMethods.cs:111:9:111:77 | return ...; | -| ExitMethods.cs:110:5:112:5 | {...} | ExitMethods.cs:109:13:109:21 | enter ThrowExpr | -| ExitMethods.cs:111:9:111:77 | return ...; | ExitMethods.cs:111:16:111:76 | ... ? ... : ... | -| ExitMethods.cs:111:16:111:20 | access to parameter input | ExitMethods.cs:110:5:112:5 | {...} | -| ExitMethods.cs:111:16:111:25 | ... != ... | ExitMethods.cs:111:25:111:25 | (...) ... | -| ExitMethods.cs:111:16:111:76 | ... ? ... : ... | ExitMethods.cs:111:29:111:37 | ... / ... | -| ExitMethods.cs:111:25:111:25 | 0 | ExitMethods.cs:111:16:111:20 | access to parameter input | -| ExitMethods.cs:111:25:111:25 | (...) ... | ExitMethods.cs:111:25:111:25 | 0 | -| ExitMethods.cs:111:29:111:29 | 1 | ExitMethods.cs:111:16:111:25 | ... != ... | -| ExitMethods.cs:111:29:111:29 | (...) ... | ExitMethods.cs:111:29:111:29 | 1 | -| ExitMethods.cs:111:29:111:37 | ... / ... | ExitMethods.cs:111:33:111:37 | access to parameter input | -| ExitMethods.cs:111:33:111:37 | access to parameter input | ExitMethods.cs:111:29:111:29 | (...) ... | -| ExitMethods.cs:111:41:111:76 | throw ... | ExitMethods.cs:111:47:111:76 | object creation of type ArgumentException | -| ExitMethods.cs:111:47:111:76 | object creation of type ArgumentException | ExitMethods.cs:111:69:111:75 | "input" | -| ExitMethods.cs:114:16:114:34 | exit ExtensionMethodCall | ExitMethods.cs:114:16:114:34 | exit ExtensionMethodCall (normal) | -| ExitMethods.cs:114:16:114:34 | exit ExtensionMethodCall (normal) | ExitMethods.cs:116:9:116:39 | return ...; | -| ExitMethods.cs:115:5:117:5 | {...} | ExitMethods.cs:114:16:114:34 | enter ExtensionMethodCall | -| ExitMethods.cs:116:9:116:39 | return ...; | ExitMethods.cs:116:16:116:38 | ... ? ... : ... | -| ExitMethods.cs:116:16:116:16 | access to parameter s | ExitMethods.cs:115:5:117:5 | {...} | -| ExitMethods.cs:116:16:116:30 | call to method Contains | ExitMethods.cs:116:27:116:29 | - | -| ExitMethods.cs:116:16:116:38 | ... ? ... : ... | ExitMethods.cs:116:34:116:34 | 0 | -| ExitMethods.cs:116:16:116:38 | ... ? ... : ... | ExitMethods.cs:116:38:116:38 | 1 | -| ExitMethods.cs:116:27:116:29 | - | ExitMethods.cs:116:16:116:16 | access to parameter s | -| ExitMethods.cs:119:17:119:32 | exit FailingAssertion | ExitMethods.cs:119:17:119:32 | exit FailingAssertion (abnormal) | -| ExitMethods.cs:119:17:119:32 | exit FailingAssertion (abnormal) | ExitMethods.cs:121:9:121:28 | [assertion failure] call to method IsTrue | -| ExitMethods.cs:120:5:123:5 | {...} | ExitMethods.cs:119:17:119:32 | enter FailingAssertion | -| ExitMethods.cs:121:9:121:29 | ...; | ExitMethods.cs:120:5:123:5 | {...} | -| ExitMethods.cs:121:23:121:27 | false | ExitMethods.cs:121:9:121:29 | ...; | -| ExitMethods.cs:125:17:125:33 | exit FailingAssertion2 | ExitMethods.cs:125:17:125:33 | exit FailingAssertion2 (abnormal) | -| ExitMethods.cs:125:17:125:33 | exit FailingAssertion2 (abnormal) | ExitMethods.cs:127:9:127:26 | call to method FailingAssertion | -| ExitMethods.cs:126:5:129:5 | {...} | ExitMethods.cs:125:17:125:33 | enter FailingAssertion2 | -| ExitMethods.cs:127:9:127:26 | call to method FailingAssertion | ExitMethods.cs:127:9:127:26 | this access | -| ExitMethods.cs:127:9:127:26 | this access | ExitMethods.cs:127:9:127:27 | ...; | -| ExitMethods.cs:127:9:127:27 | ...; | ExitMethods.cs:126:5:129:5 | {...} | -| ExitMethods.cs:131:10:131:20 | exit AssertFalse (abnormal) | ExitMethods.cs:131:33:131:49 | [assertion failure] call to method IsFalse | -| ExitMethods.cs:131:10:131:20 | exit AssertFalse (normal) | ExitMethods.cs:131:33:131:49 | [assertion success] call to method IsFalse | -| ExitMethods.cs:131:33:131:49 | [assertion success] call to method IsFalse | ExitMethods.cs:131:48:131:48 | access to parameter b | -| ExitMethods.cs:131:48:131:48 | access to parameter b | ExitMethods.cs:131:10:131:20 | enter AssertFalse | -| ExitMethods.cs:133:17:133:33 | exit FailingAssertion3 | ExitMethods.cs:133:17:133:33 | exit FailingAssertion3 (abnormal) | -| ExitMethods.cs:133:17:133:33 | exit FailingAssertion3 (abnormal) | ExitMethods.cs:135:9:135:25 | [assertion failure] call to method AssertFalse | -| ExitMethods.cs:134:5:137:5 | {...} | ExitMethods.cs:133:17:133:33 | enter FailingAssertion3 | -| ExitMethods.cs:135:9:135:25 | this access | ExitMethods.cs:135:9:135:26 | ...; | -| ExitMethods.cs:135:9:135:26 | ...; | ExitMethods.cs:134:5:137:5 | {...} | -| ExitMethods.cs:135:21:135:24 | true | ExitMethods.cs:135:9:135:25 | this access | +| ExitMethods.cs:8:10:8:11 | exit M1 | ExitMethods.cs:8:10:8:11 | exit M1 (normal) | +| ExitMethods.cs:8:10:8:11 | exit M1 (normal) | ExitMethods.cs:11:9:11:15 | return ...; | +| ExitMethods.cs:9:5:12:5 | {...} | ExitMethods.cs:8:10:8:11 | enter M1 | +| ExitMethods.cs:10:9:10:24 | call to method ErrorMaybe | ExitMethods.cs:10:20:10:23 | true | +| ExitMethods.cs:10:9:10:25 | ...; | ExitMethods.cs:9:5:12:5 | {...} | +| ExitMethods.cs:10:20:10:23 | true | ExitMethods.cs:10:9:10:25 | ...; | +| ExitMethods.cs:11:9:11:15 | return ...; | ExitMethods.cs:10:9:10:24 | call to method ErrorMaybe | +| ExitMethods.cs:14:10:14:11 | exit M2 | ExitMethods.cs:14:10:14:11 | exit M2 (normal) | +| ExitMethods.cs:14:10:14:11 | exit M2 (normal) | ExitMethods.cs:17:9:17:15 | return ...; | +| ExitMethods.cs:15:5:18:5 | {...} | ExitMethods.cs:14:10:14:11 | enter M2 | +| ExitMethods.cs:16:9:16:25 | call to method ErrorMaybe | ExitMethods.cs:16:20:16:24 | false | +| ExitMethods.cs:16:9:16:26 | ...; | ExitMethods.cs:15:5:18:5 | {...} | +| ExitMethods.cs:16:20:16:24 | false | ExitMethods.cs:16:9:16:26 | ...; | +| ExitMethods.cs:17:9:17:15 | return ...; | ExitMethods.cs:16:9:16:25 | call to method ErrorMaybe | +| ExitMethods.cs:20:10:20:11 | exit M3 | ExitMethods.cs:20:10:20:11 | exit M3 (abnormal) | +| ExitMethods.cs:20:10:20:11 | exit M3 (abnormal) | ExitMethods.cs:22:9:22:25 | call to method ErrorAlways | +| ExitMethods.cs:21:5:24:5 | {...} | ExitMethods.cs:20:10:20:11 | enter M3 | +| ExitMethods.cs:22:9:22:25 | call to method ErrorAlways | ExitMethods.cs:22:21:22:24 | true | +| ExitMethods.cs:22:9:22:26 | ...; | ExitMethods.cs:21:5:24:5 | {...} | +| ExitMethods.cs:22:21:22:24 | true | ExitMethods.cs:22:9:22:26 | ...; | +| ExitMethods.cs:26:10:26:11 | exit M4 | ExitMethods.cs:26:10:26:11 | exit M4 (abnormal) | +| ExitMethods.cs:26:10:26:11 | exit M4 (abnormal) | ExitMethods.cs:28:9:28:14 | call to method Exit | +| ExitMethods.cs:27:5:30:5 | {...} | ExitMethods.cs:26:10:26:11 | enter M4 | +| ExitMethods.cs:28:9:28:14 | call to method Exit | ExitMethods.cs:28:9:28:14 | this access | +| ExitMethods.cs:28:9:28:14 | this access | ExitMethods.cs:28:9:28:15 | ...; | +| ExitMethods.cs:28:9:28:15 | ...; | ExitMethods.cs:27:5:30:5 | {...} | +| ExitMethods.cs:32:10:32:11 | exit M5 | ExitMethods.cs:32:10:32:11 | exit M5 (abnormal) | +| ExitMethods.cs:32:10:32:11 | exit M5 (abnormal) | ExitMethods.cs:34:9:34:25 | call to method ApplicationExit | +| ExitMethods.cs:33:5:36:5 | {...} | ExitMethods.cs:32:10:32:11 | enter M5 | +| ExitMethods.cs:34:9:34:25 | call to method ApplicationExit | ExitMethods.cs:34:9:34:25 | this access | +| ExitMethods.cs:34:9:34:25 | this access | ExitMethods.cs:34:9:34:26 | ...; | +| ExitMethods.cs:34:9:34:26 | ...; | ExitMethods.cs:33:5:36:5 | {...} | +| ExitMethods.cs:38:10:38:11 | exit M6 | ExitMethods.cs:38:10:38:11 | exit M6 (normal) | +| ExitMethods.cs:38:10:38:11 | exit M6 (normal) | ExitMethods.cs:46:13:46:19 | return ...; | +| ExitMethods.cs:38:10:38:11 | exit M6 (normal) | ExitMethods.cs:50:13:50:19 | return ...; | +| ExitMethods.cs:39:5:52:5 | {...} | ExitMethods.cs:38:10:38:11 | enter M6 | +| ExitMethods.cs:40:9:51:9 | try {...} ... | ExitMethods.cs:39:5:52:5 | {...} | +| ExitMethods.cs:41:9:43:9 | {...} | ExitMethods.cs:40:9:51:9 | try {...} ... | +| ExitMethods.cs:42:13:42:30 | call to method ErrorAlways | ExitMethods.cs:42:25:42:29 | false | +| ExitMethods.cs:42:13:42:31 | ...; | ExitMethods.cs:41:9:43:9 | {...} | +| ExitMethods.cs:42:25:42:29 | false | ExitMethods.cs:42:13:42:31 | ...; | +| ExitMethods.cs:45:9:47:9 | {...} | ExitMethods.cs:44:9:47:9 | [exception: ArgumentException] catch (...) {...} | +| ExitMethods.cs:46:13:46:19 | return ...; | ExitMethods.cs:45:9:47:9 | {...} | +| ExitMethods.cs:49:9:51:9 | {...} | ExitMethods.cs:48:9:51:9 | [exception: Exception] catch (...) {...} | +| ExitMethods.cs:50:13:50:19 | return ...; | ExitMethods.cs:49:9:51:9 | {...} | +| ExitMethods.cs:54:10:54:11 | exit M7 | ExitMethods.cs:54:10:54:11 | exit M7 (abnormal) | +| ExitMethods.cs:54:10:54:11 | exit M7 (abnormal) | ExitMethods.cs:56:9:56:22 | call to method ErrorAlways2 | +| ExitMethods.cs:55:5:58:5 | {...} | ExitMethods.cs:54:10:54:11 | enter M7 | +| ExitMethods.cs:56:9:56:22 | call to method ErrorAlways2 | ExitMethods.cs:56:9:56:23 | ...; | +| ExitMethods.cs:56:9:56:23 | ...; | ExitMethods.cs:55:5:58:5 | {...} | +| ExitMethods.cs:60:10:60:11 | exit M8 | ExitMethods.cs:60:10:60:11 | exit M8 (abnormal) | +| ExitMethods.cs:60:10:60:11 | exit M8 (abnormal) | ExitMethods.cs:62:9:62:22 | call to method ErrorAlways3 | +| ExitMethods.cs:61:5:64:5 | {...} | ExitMethods.cs:60:10:60:11 | enter M8 | +| ExitMethods.cs:62:9:62:22 | call to method ErrorAlways3 | ExitMethods.cs:62:9:62:23 | ...; | +| ExitMethods.cs:62:9:62:23 | ...; | ExitMethods.cs:61:5:64:5 | {...} | +| ExitMethods.cs:66:17:66:26 | exit ErrorMaybe (abnormal) | ExitMethods.cs:69:13:69:34 | throw ...; | +| ExitMethods.cs:66:17:66:26 | exit ErrorMaybe (normal) | ExitMethods.cs:68:13:68:13 | access to parameter b | +| ExitMethods.cs:67:5:70:5 | {...} | ExitMethods.cs:66:17:66:26 | enter ErrorMaybe | +| ExitMethods.cs:68:9:69:34 | if (...) ... | ExitMethods.cs:67:5:70:5 | {...} | +| ExitMethods.cs:68:13:68:13 | access to parameter b | ExitMethods.cs:68:9:69:34 | if (...) ... | +| ExitMethods.cs:69:13:69:34 | throw ...; | ExitMethods.cs:69:19:69:33 | object creation of type Exception | +| ExitMethods.cs:72:17:72:27 | exit ErrorAlways | ExitMethods.cs:72:17:72:27 | exit ErrorAlways (abnormal) | +| ExitMethods.cs:73:5:78:5 | {...} | ExitMethods.cs:72:17:72:27 | enter ErrorAlways | +| ExitMethods.cs:74:9:77:45 | if (...) ... | ExitMethods.cs:73:5:78:5 | {...} | +| ExitMethods.cs:74:13:74:13 | access to parameter b | ExitMethods.cs:74:9:77:45 | if (...) ... | +| ExitMethods.cs:75:13:75:34 | throw ...; | ExitMethods.cs:75:19:75:33 | object creation of type Exception | +| ExitMethods.cs:77:13:77:45 | throw ...; | ExitMethods.cs:77:19:77:44 | object creation of type ArgumentException | +| ExitMethods.cs:77:19:77:44 | object creation of type ArgumentException | ExitMethods.cs:77:41:77:43 | "b" | +| ExitMethods.cs:80:17:80:28 | exit ErrorAlways2 | ExitMethods.cs:80:17:80:28 | exit ErrorAlways2 (abnormal) | +| ExitMethods.cs:80:17:80:28 | exit ErrorAlways2 (abnormal) | ExitMethods.cs:82:9:82:30 | throw ...; | +| ExitMethods.cs:81:5:83:5 | {...} | ExitMethods.cs:80:17:80:28 | enter ErrorAlways2 | +| ExitMethods.cs:82:9:82:30 | throw ...; | ExitMethods.cs:82:15:82:29 | object creation of type Exception | +| ExitMethods.cs:82:15:82:29 | object creation of type Exception | ExitMethods.cs:81:5:83:5 | {...} | +| ExitMethods.cs:85:17:85:28 | exit ErrorAlways3 | ExitMethods.cs:85:17:85:28 | exit ErrorAlways3 (abnormal) | +| ExitMethods.cs:85:17:85:28 | exit ErrorAlways3 (abnormal) | ExitMethods.cs:85:35:85:55 | throw ... | +| ExitMethods.cs:85:35:85:55 | throw ... | ExitMethods.cs:85:41:85:55 | object creation of type Exception | +| ExitMethods.cs:85:41:85:55 | object creation of type Exception | ExitMethods.cs:85:17:85:28 | enter ErrorAlways3 | +| ExitMethods.cs:87:10:87:13 | exit Exit | ExitMethods.cs:87:10:87:13 | exit Exit (abnormal) | +| ExitMethods.cs:87:10:87:13 | exit Exit (abnormal) | ExitMethods.cs:89:9:89:27 | call to method Exit | +| ExitMethods.cs:88:5:90:5 | {...} | ExitMethods.cs:87:10:87:13 | enter Exit | +| ExitMethods.cs:89:9:89:27 | call to method Exit | ExitMethods.cs:89:26:89:26 | 0 | +| ExitMethods.cs:89:9:89:28 | ...; | ExitMethods.cs:88:5:90:5 | {...} | +| ExitMethods.cs:89:26:89:26 | 0 | ExitMethods.cs:89:9:89:28 | ...; | +| ExitMethods.cs:92:10:92:18 | exit ExitInTry | ExitMethods.cs:92:10:92:18 | exit ExitInTry (abnormal) | +| ExitMethods.cs:92:10:92:18 | exit ExitInTry (abnormal) | ExitMethods.cs:96:13:96:18 | call to method Exit | +| ExitMethods.cs:93:5:103:5 | {...} | ExitMethods.cs:92:10:92:18 | enter ExitInTry | +| ExitMethods.cs:94:9:102:9 | try {...} ... | ExitMethods.cs:93:5:103:5 | {...} | +| ExitMethods.cs:95:9:97:9 | {...} | ExitMethods.cs:94:9:102:9 | try {...} ... | +| ExitMethods.cs:96:13:96:18 | call to method Exit | ExitMethods.cs:96:13:96:18 | this access | +| ExitMethods.cs:96:13:96:18 | this access | ExitMethods.cs:96:13:96:19 | ...; | +| ExitMethods.cs:96:13:96:19 | ...; | ExitMethods.cs:95:9:97:9 | {...} | +| ExitMethods.cs:105:10:105:24 | exit ApplicationExit | ExitMethods.cs:105:10:105:24 | exit ApplicationExit (abnormal) | +| ExitMethods.cs:105:10:105:24 | exit ApplicationExit (abnormal) | ExitMethods.cs:107:9:107:47 | call to method Exit | +| ExitMethods.cs:106:5:108:5 | {...} | ExitMethods.cs:105:10:105:24 | enter ApplicationExit | +| ExitMethods.cs:107:9:107:47 | call to method Exit | ExitMethods.cs:107:9:107:48 | ...; | +| ExitMethods.cs:107:9:107:48 | ...; | ExitMethods.cs:106:5:108:5 | {...} | +| ExitMethods.cs:110:13:110:21 | exit ThrowExpr (abnormal) | ExitMethods.cs:112:41:112:76 | throw ... | +| ExitMethods.cs:110:13:110:21 | exit ThrowExpr (normal) | ExitMethods.cs:112:9:112:77 | return ...; | +| ExitMethods.cs:111:5:113:5 | {...} | ExitMethods.cs:110:13:110:21 | enter ThrowExpr | +| ExitMethods.cs:112:9:112:77 | return ...; | ExitMethods.cs:112:16:112:76 | ... ? ... : ... | +| ExitMethods.cs:112:16:112:20 | access to parameter input | ExitMethods.cs:111:5:113:5 | {...} | +| ExitMethods.cs:112:16:112:25 | ... != ... | ExitMethods.cs:112:25:112:25 | (...) ... | +| ExitMethods.cs:112:16:112:76 | ... ? ... : ... | ExitMethods.cs:112:29:112:37 | ... / ... | +| ExitMethods.cs:112:25:112:25 | 0 | ExitMethods.cs:112:16:112:20 | access to parameter input | +| ExitMethods.cs:112:25:112:25 | (...) ... | ExitMethods.cs:112:25:112:25 | 0 | +| ExitMethods.cs:112:29:112:29 | 1 | ExitMethods.cs:112:16:112:25 | ... != ... | +| ExitMethods.cs:112:29:112:29 | (...) ... | ExitMethods.cs:112:29:112:29 | 1 | +| ExitMethods.cs:112:29:112:37 | ... / ... | ExitMethods.cs:112:33:112:37 | access to parameter input | +| ExitMethods.cs:112:33:112:37 | access to parameter input | ExitMethods.cs:112:29:112:29 | (...) ... | +| ExitMethods.cs:112:41:112:76 | throw ... | ExitMethods.cs:112:47:112:76 | object creation of type ArgumentException | +| ExitMethods.cs:112:47:112:76 | object creation of type ArgumentException | ExitMethods.cs:112:69:112:75 | "input" | +| ExitMethods.cs:115:16:115:34 | exit ExtensionMethodCall | ExitMethods.cs:115:16:115:34 | exit ExtensionMethodCall (normal) | +| ExitMethods.cs:115:16:115:34 | exit ExtensionMethodCall (normal) | ExitMethods.cs:117:9:117:39 | return ...; | +| ExitMethods.cs:116:5:118:5 | {...} | ExitMethods.cs:115:16:115:34 | enter ExtensionMethodCall | +| ExitMethods.cs:117:9:117:39 | return ...; | ExitMethods.cs:117:16:117:38 | ... ? ... : ... | +| ExitMethods.cs:117:16:117:16 | access to parameter s | ExitMethods.cs:116:5:118:5 | {...} | +| ExitMethods.cs:117:16:117:30 | call to method Contains | ExitMethods.cs:117:27:117:29 | - | +| ExitMethods.cs:117:16:117:38 | ... ? ... : ... | ExitMethods.cs:117:34:117:34 | 0 | +| ExitMethods.cs:117:16:117:38 | ... ? ... : ... | ExitMethods.cs:117:38:117:38 | 1 | +| ExitMethods.cs:117:27:117:29 | - | ExitMethods.cs:117:16:117:16 | access to parameter s | +| ExitMethods.cs:120:17:120:32 | exit FailingAssertion | ExitMethods.cs:120:17:120:32 | exit FailingAssertion (abnormal) | +| ExitMethods.cs:120:17:120:32 | exit FailingAssertion (abnormal) | ExitMethods.cs:122:9:122:28 | [assertion failure] call to method IsTrue | +| ExitMethods.cs:121:5:124:5 | {...} | ExitMethods.cs:120:17:120:32 | enter FailingAssertion | +| ExitMethods.cs:122:9:122:29 | ...; | ExitMethods.cs:121:5:124:5 | {...} | +| ExitMethods.cs:122:23:122:27 | false | ExitMethods.cs:122:9:122:29 | ...; | +| ExitMethods.cs:126:17:126:33 | exit FailingAssertion2 | ExitMethods.cs:126:17:126:33 | exit FailingAssertion2 (abnormal) | +| ExitMethods.cs:126:17:126:33 | exit FailingAssertion2 (abnormal) | ExitMethods.cs:128:9:128:26 | call to method FailingAssertion | +| ExitMethods.cs:127:5:130:5 | {...} | ExitMethods.cs:126:17:126:33 | enter FailingAssertion2 | +| ExitMethods.cs:128:9:128:26 | call to method FailingAssertion | ExitMethods.cs:128:9:128:26 | this access | +| ExitMethods.cs:128:9:128:26 | this access | ExitMethods.cs:128:9:128:27 | ...; | +| ExitMethods.cs:128:9:128:27 | ...; | ExitMethods.cs:127:5:130:5 | {...} | +| ExitMethods.cs:132:10:132:20 | exit AssertFalse (abnormal) | ExitMethods.cs:132:33:132:49 | [assertion failure] call to method IsFalse | +| ExitMethods.cs:132:10:132:20 | exit AssertFalse (normal) | ExitMethods.cs:132:33:132:49 | [assertion success] call to method IsFalse | +| ExitMethods.cs:132:33:132:49 | [assertion success] call to method IsFalse | ExitMethods.cs:132:48:132:48 | access to parameter b | +| ExitMethods.cs:132:48:132:48 | access to parameter b | ExitMethods.cs:132:10:132:20 | enter AssertFalse | +| ExitMethods.cs:134:17:134:33 | exit FailingAssertion3 | ExitMethods.cs:134:17:134:33 | exit FailingAssertion3 (abnormal) | +| ExitMethods.cs:134:17:134:33 | exit FailingAssertion3 (abnormal) | ExitMethods.cs:136:9:136:25 | [assertion failure] call to method AssertFalse | +| ExitMethods.cs:135:5:138:5 | {...} | ExitMethods.cs:134:17:134:33 | enter FailingAssertion3 | +| ExitMethods.cs:136:9:136:25 | this access | ExitMethods.cs:136:9:136:26 | ...; | +| ExitMethods.cs:136:9:136:26 | ...; | ExitMethods.cs:135:5:138:5 | {...} | +| ExitMethods.cs:136:21:136:24 | true | ExitMethods.cs:136:9:136:25 | this access | +| ExitMethods.cs:140:17:140:42 | exit ExceptionDispatchInfoThrow | ExitMethods.cs:140:17:140:42 | exit ExceptionDispatchInfoThrow (abnormal) | +| ExitMethods.cs:141:5:147:5 | {...} | ExitMethods.cs:140:17:140:42 | enter ExceptionDispatchInfoThrow | +| ExitMethods.cs:142:9:145:53 | if (...) ... | ExitMethods.cs:141:5:147:5 | {...} | +| ExitMethods.cs:142:13:142:13 | access to parameter b | ExitMethods.cs:142:9:145:53 | if (...) ... | +| ExitMethods.cs:143:13:143:42 | call to method Throw | ExitMethods.cs:143:41:143:41 | access to parameter e | +| ExitMethods.cs:143:41:143:41 | access to parameter e | ExitMethods.cs:143:13:143:43 | ...; | +| ExitMethods.cs:145:13:145:44 | call to method Capture | ExitMethods.cs:145:43:145:43 | access to parameter e | +| ExitMethods.cs:145:13:145:52 | call to method Throw | ExitMethods.cs:145:13:145:44 | call to method Capture | +| ExitMethods.cs:145:43:145:43 | access to parameter e | ExitMethods.cs:145:13:145:53 | ...; | | Extensions.cs:5:23:5:29 | exit ToInt32 | Extensions.cs:5:23:5:29 | exit ToInt32 (normal) | | Extensions.cs:5:23:5:29 | exit ToInt32 (normal) | Extensions.cs:7:9:7:30 | return ...; | | Extensions.cs:6:5:8:5 | {...} | Extensions.cs:5:23:5:29 | enter ToInt32 | @@ -5686,6 +5901,7 @@ postDominance | Extensions.cs:25:9:25:34 | ...; | Extensions.cs:24:9:24:45 | call to method ToBool | | Extensions.cs:25:23:25:32 | access to method Parse | Extensions.cs:25:9:25:14 | "true" | | Extensions.cs:25:23:25:32 | delegate creation of type Func<String,Boolean> | Extensions.cs:25:23:25:32 | access to method Parse | +| Finally.cs:7:10:7:11 | exit M1 (abnormal) | Finally.cs:15:13:15:40 | [finally: exception(Exception)] call to method WriteLine | | Finally.cs:7:10:7:11 | exit M1 (normal) | Finally.cs:15:13:15:40 | call to method WriteLine | | Finally.cs:8:5:17:5 | {...} | Finally.cs:7:10:7:11 | enter M1 | | Finally.cs:9:9:16:9 | try {...} ... | Finally.cs:8:5:17:5 | {...} | @@ -5695,25 +5911,22 @@ postDominance | Finally.cs:11:31:11:36 | "Try1" | Finally.cs:11:13:11:38 | ...; | | Finally.cs:14:9:16:9 | {...} | Finally.cs:11:13:11:37 | call to method WriteLine | | Finally.cs:15:13:15:40 | [finally: exception(Exception)] call to method WriteLine | Finally.cs:15:31:15:39 | [finally: exception(Exception)] "Finally" | -| Finally.cs:15:13:15:40 | [finally: exception(OutOfMemoryException)] call to method WriteLine | Finally.cs:15:31:15:39 | [finally: exception(OutOfMemoryException)] "Finally" | | Finally.cs:15:13:15:40 | call to method WriteLine | Finally.cs:15:31:15:39 | "Finally" | | Finally.cs:15:13:15:41 | ...; | Finally.cs:14:9:16:9 | {...} | | Finally.cs:15:13:15:41 | [finally: exception(Exception)] ...; | Finally.cs:14:9:16:9 | [finally: exception(Exception)] {...} | -| Finally.cs:15:13:15:41 | [finally: exception(OutOfMemoryException)] ...; | Finally.cs:14:9:16:9 | [finally: exception(OutOfMemoryException)] {...} | | Finally.cs:15:31:15:39 | "Finally" | Finally.cs:15:13:15:41 | ...; | | Finally.cs:15:31:15:39 | [finally: exception(Exception)] "Finally" | Finally.cs:15:13:15:41 | [finally: exception(Exception)] ...; | -| Finally.cs:15:31:15:39 | [finally: exception(OutOfMemoryException)] "Finally" | Finally.cs:15:13:15:41 | [finally: exception(OutOfMemoryException)] ...; | | Finally.cs:19:10:19:11 | exit M2 (normal) | Finally.cs:50:13:50:40 | [finally: return] call to method WriteLine | | Finally.cs:19:10:19:11 | exit M2 (normal) | Finally.cs:50:13:50:40 | call to method WriteLine | | Finally.cs:20:5:52:5 | {...} | Finally.cs:19:10:19:11 | enter M2 | | Finally.cs:21:9:51:9 | try {...} ... | Finally.cs:20:5:52:5 | {...} | | Finally.cs:22:9:25:9 | {...} | Finally.cs:21:9:51:9 | try {...} ... | +| Finally.cs:23:13:23:37 | call to method WriteLine | Finally.cs:23:31:23:36 | "Try2" | | Finally.cs:23:13:23:38 | ...; | Finally.cs:22:9:25:9 | {...} | | Finally.cs:23:31:23:36 | "Try2" | Finally.cs:23:13:23:38 | ...; | | Finally.cs:26:48:26:51 | [exception: Exception] true | Finally.cs:26:38:26:39 | [exception: Exception] IOException ex | | Finally.cs:28:13:28:18 | throw ...; | Finally.cs:27:9:29:9 | {...} | | Finally.cs:30:9:40:9 | [exception: Exception] catch (...) {...} | Finally.cs:26:9:29:9 | [exception: Exception] catch (...) {...} | -| Finally.cs:30:9:40:9 | [exception: OutOfMemoryException] catch (...) {...} | Finally.cs:26:9:29:9 | [exception: OutOfMemoryException] catch (...) {...} | | Finally.cs:31:9:40:9 | {...} | Finally.cs:30:41:30:42 | [exception: Exception] ArgumentException ex | | Finally.cs:32:13:39:13 | try {...} ... | Finally.cs:31:9:40:9 | {...} | | Finally.cs:33:13:35:13 | {...} | Finally.cs:32:13:39:13 | try {...} ... | @@ -5724,9 +5937,7 @@ postDominance | Finally.cs:38:23:38:43 | [finally: exception(ArgumentException)] object creation of type Exception | Finally.cs:38:37:38:42 | [finally: exception(ArgumentException)] "Boo!" | | Finally.cs:38:37:38:42 | [finally: exception(ArgumentException)] "Boo!" | Finally.cs:37:13:39:13 | [finally: exception(ArgumentException)] {...} | | Finally.cs:41:9:43:9 | [exception: Exception] catch (...) {...} | Finally.cs:30:9:40:9 | [exception: Exception] catch (...) {...} | -| Finally.cs:41:9:43:9 | [exception: OutOfMemoryException] catch (...) {...} | Finally.cs:30:9:40:9 | [exception: OutOfMemoryException] catch (...) {...} | | Finally.cs:42:9:43:9 | {...} | Finally.cs:41:9:43:9 | [exception: Exception] catch (...) {...} | -| Finally.cs:42:9:43:9 | {...} | Finally.cs:41:9:43:9 | [exception: OutOfMemoryException] catch (...) {...} | | Finally.cs:49:9:51:9 | [finally: exception(Exception)] {...} | Finally.cs:38:17:38:44 | [finally: exception(ArgumentException)] throw ...; | | Finally.cs:49:9:51:9 | [finally: exception(IOException)] {...} | Finally.cs:28:13:28:18 | throw ...; | | Finally.cs:49:9:51:9 | [finally: return] {...} | Finally.cs:24:13:24:19 | return ...; | @@ -5748,41 +5959,32 @@ postDominance | Finally.cs:55:5:72:5 | {...} | Finally.cs:54:10:54:11 | enter M3 | | Finally.cs:56:9:71:9 | try {...} ... | Finally.cs:55:5:72:5 | {...} | | Finally.cs:57:9:60:9 | {...} | Finally.cs:56:9:71:9 | try {...} ... | +| Finally.cs:58:13:58:37 | call to method WriteLine | Finally.cs:58:31:58:36 | "Try3" | | Finally.cs:58:13:58:38 | ...; | Finally.cs:57:9:60:9 | {...} | | Finally.cs:58:31:58:36 | "Try3" | Finally.cs:58:13:58:38 | ...; | | Finally.cs:61:48:61:51 | [exception: Exception] true | Finally.cs:61:38:61:39 | [exception: Exception] IOException ex | | Finally.cs:63:13:63:18 | throw ...; | Finally.cs:62:9:64:9 | {...} | | Finally.cs:65:9:67:9 | [exception: Exception] catch (...) {...} | Finally.cs:61:9:64:9 | [exception: Exception] catch (...) {...} | -| Finally.cs:65:9:67:9 | [exception: OutOfMemoryException] catch (...) {...} | Finally.cs:61:9:64:9 | [exception: OutOfMemoryException] catch (...) {...} | | Finally.cs:65:26:65:26 | [exception: Exception] Exception e | Finally.cs:65:9:67:9 | [exception: Exception] catch (...) {...} | -| Finally.cs:65:26:65:26 | [exception: OutOfMemoryException] Exception e | Finally.cs:65:9:67:9 | [exception: OutOfMemoryException] catch (...) {...} | | Finally.cs:65:35:65:35 | [exception: Exception] access to local variable e | Finally.cs:65:26:65:26 | [exception: Exception] Exception e | -| Finally.cs:65:35:65:35 | [exception: OutOfMemoryException] access to local variable e | Finally.cs:65:26:65:26 | [exception: OutOfMemoryException] Exception e | | Finally.cs:65:35:65:43 | [exception: Exception] access to property Message | Finally.cs:65:35:65:35 | [exception: Exception] access to local variable e | -| Finally.cs:65:35:65:43 | [exception: OutOfMemoryException] access to property Message | Finally.cs:65:35:65:35 | [exception: OutOfMemoryException] access to local variable e | | Finally.cs:65:35:65:51 | [exception: Exception] ... != ... | Finally.cs:65:48:65:51 | [exception: Exception] null | -| Finally.cs:65:35:65:51 | [exception: OutOfMemoryException] ... != ... | Finally.cs:65:48:65:51 | [exception: OutOfMemoryException] null | | Finally.cs:65:48:65:51 | [exception: Exception] null | Finally.cs:65:35:65:43 | [exception: Exception] access to property Message | -| Finally.cs:65:48:65:51 | [exception: OutOfMemoryException] null | Finally.cs:65:35:65:43 | [exception: OutOfMemoryException] access to property Message | | Finally.cs:66:9:67:9 | {...} | Finally.cs:65:35:65:51 | [exception: Exception] ... != ... | -| Finally.cs:66:9:67:9 | {...} | Finally.cs:65:35:65:51 | [exception: OutOfMemoryException] ... != ... | | Finally.cs:69:9:71:9 | [finally: exception(IOException)] {...} | Finally.cs:63:13:63:18 | throw ...; | | Finally.cs:69:9:71:9 | [finally: return] {...} | Finally.cs:59:13:59:19 | return ...; | | Finally.cs:69:9:71:9 | {...} | Finally.cs:66:9:67:9 | {...} | | Finally.cs:70:13:70:40 | [finally: exception(Exception)] call to method WriteLine | Finally.cs:70:31:70:39 | [finally: exception(Exception)] "Finally" | | Finally.cs:70:13:70:40 | [finally: exception(IOException)] call to method WriteLine | Finally.cs:70:31:70:39 | [finally: exception(IOException)] "Finally" | -| Finally.cs:70:13:70:40 | [finally: exception(OutOfMemoryException)] call to method WriteLine | Finally.cs:70:31:70:39 | [finally: exception(OutOfMemoryException)] "Finally" | | Finally.cs:70:13:70:40 | [finally: return] call to method WriteLine | Finally.cs:70:31:70:39 | [finally: return] "Finally" | | Finally.cs:70:13:70:40 | call to method WriteLine | Finally.cs:70:31:70:39 | "Finally" | | Finally.cs:70:13:70:41 | ...; | Finally.cs:69:9:71:9 | {...} | | Finally.cs:70:13:70:41 | [finally: exception(Exception)] ...; | Finally.cs:69:9:71:9 | [finally: exception(Exception)] {...} | | Finally.cs:70:13:70:41 | [finally: exception(IOException)] ...; | Finally.cs:69:9:71:9 | [finally: exception(IOException)] {...} | -| Finally.cs:70:13:70:41 | [finally: exception(OutOfMemoryException)] ...; | Finally.cs:69:9:71:9 | [finally: exception(OutOfMemoryException)] {...} | | Finally.cs:70:13:70:41 | [finally: return] ...; | Finally.cs:69:9:71:9 | [finally: return] {...} | | Finally.cs:70:31:70:39 | "Finally" | Finally.cs:70:13:70:41 | ...; | | Finally.cs:70:31:70:39 | [finally: exception(Exception)] "Finally" | Finally.cs:70:13:70:41 | [finally: exception(Exception)] ...; | | Finally.cs:70:31:70:39 | [finally: exception(IOException)] "Finally" | Finally.cs:70:13:70:41 | [finally: exception(IOException)] ...; | -| Finally.cs:70:31:70:39 | [finally: exception(OutOfMemoryException)] "Finally" | Finally.cs:70:13:70:41 | [finally: exception(OutOfMemoryException)] ...; | | Finally.cs:70:31:70:39 | [finally: return] "Finally" | Finally.cs:70:13:70:41 | [finally: return] ...; | | Finally.cs:74:10:74:11 | exit M4 (normal) | Finally.cs:77:16:77:20 | ... > ... | | Finally.cs:74:10:74:11 | exit M4 (normal) | Finally.cs:97:21:97:23 | [finally: break] ...-- | @@ -5840,29 +6042,29 @@ postDominance | Finally.cs:96:17:98:17 | [finally: continue] {...} | Finally.cs:92:25:92:30 | [finally: continue] ... == ... | | Finally.cs:96:17:98:17 | [finally: return] {...} | Finally.cs:92:25:92:30 | [finally: return] ... == ... | | Finally.cs:96:17:98:17 | {...} | Finally.cs:92:25:92:30 | ... == ... | -| Finally.cs:97:21:97:21 | [finally(2): exception(Exception)] access to local variable i | Finally.cs:97:21:97:24 | [finally(2): exception(Exception)] ...; | -| Finally.cs:97:21:97:21 | [finally: break, finally(2): exception(Exception)] access to local variable i | Finally.cs:97:21:97:24 | [finally: break, finally(2): exception(Exception)] ...; | +| Finally.cs:97:21:97:21 | [finally(1): exception(Exception)] access to local variable i | Finally.cs:97:21:97:24 | [finally(1): exception(Exception)] ...; | +| Finally.cs:97:21:97:21 | [finally: break, finally(1): exception(Exception)] access to local variable i | Finally.cs:97:21:97:24 | [finally: break, finally(1): exception(Exception)] ...; | | Finally.cs:97:21:97:21 | [finally: break] access to local variable i | Finally.cs:97:21:97:24 | [finally: break] ...; | -| Finally.cs:97:21:97:21 | [finally: continue, finally(2): exception(Exception)] access to local variable i | Finally.cs:97:21:97:24 | [finally: continue, finally(2): exception(Exception)] ...; | +| Finally.cs:97:21:97:21 | [finally: continue, finally(1): exception(Exception)] access to local variable i | Finally.cs:97:21:97:24 | [finally: continue, finally(1): exception(Exception)] ...; | | Finally.cs:97:21:97:21 | [finally: continue] access to local variable i | Finally.cs:97:21:97:24 | [finally: continue] ...; | -| Finally.cs:97:21:97:21 | [finally: return, finally(2): exception(Exception)] access to local variable i | Finally.cs:97:21:97:24 | [finally: return, finally(2): exception(Exception)] ...; | +| Finally.cs:97:21:97:21 | [finally: return, finally(1): exception(Exception)] access to local variable i | Finally.cs:97:21:97:24 | [finally: return, finally(1): exception(Exception)] ...; | | Finally.cs:97:21:97:21 | [finally: return] access to local variable i | Finally.cs:97:21:97:24 | [finally: return] ...; | | Finally.cs:97:21:97:21 | access to local variable i | Finally.cs:97:21:97:24 | ...; | | Finally.cs:97:21:97:23 | ...-- | Finally.cs:97:21:97:21 | access to local variable i | -| Finally.cs:97:21:97:23 | [finally(2): exception(Exception)] ...-- | Finally.cs:97:21:97:21 | [finally(2): exception(Exception)] access to local variable i | -| Finally.cs:97:21:97:23 | [finally: break, finally(2): exception(Exception)] ...-- | Finally.cs:97:21:97:21 | [finally: break, finally(2): exception(Exception)] access to local variable i | +| Finally.cs:97:21:97:23 | [finally(1): exception(Exception)] ...-- | Finally.cs:97:21:97:21 | [finally(1): exception(Exception)] access to local variable i | +| Finally.cs:97:21:97:23 | [finally: break, finally(1): exception(Exception)] ...-- | Finally.cs:97:21:97:21 | [finally: break, finally(1): exception(Exception)] access to local variable i | | Finally.cs:97:21:97:23 | [finally: break] ...-- | Finally.cs:97:21:97:21 | [finally: break] access to local variable i | -| Finally.cs:97:21:97:23 | [finally: continue, finally(2): exception(Exception)] ...-- | Finally.cs:97:21:97:21 | [finally: continue, finally(2): exception(Exception)] access to local variable i | +| Finally.cs:97:21:97:23 | [finally: continue, finally(1): exception(Exception)] ...-- | Finally.cs:97:21:97:21 | [finally: continue, finally(1): exception(Exception)] access to local variable i | | Finally.cs:97:21:97:23 | [finally: continue] ...-- | Finally.cs:97:21:97:21 | [finally: continue] access to local variable i | -| Finally.cs:97:21:97:23 | [finally: return, finally(2): exception(Exception)] ...-- | Finally.cs:97:21:97:21 | [finally: return, finally(2): exception(Exception)] access to local variable i | +| Finally.cs:97:21:97:23 | [finally: return, finally(1): exception(Exception)] ...-- | Finally.cs:97:21:97:21 | [finally: return, finally(1): exception(Exception)] access to local variable i | | Finally.cs:97:21:97:23 | [finally: return] ...-- | Finally.cs:97:21:97:21 | [finally: return] access to local variable i | | Finally.cs:97:21:97:24 | ...; | Finally.cs:96:17:98:17 | {...} | -| Finally.cs:97:21:97:24 | [finally(2): exception(Exception)] ...; | Finally.cs:96:17:98:17 | [finally(2): exception(Exception)] {...} | -| Finally.cs:97:21:97:24 | [finally: break, finally(2): exception(Exception)] ...; | Finally.cs:96:17:98:17 | [finally: break, finally(2): exception(Exception)] {...} | +| Finally.cs:97:21:97:24 | [finally(1): exception(Exception)] ...; | Finally.cs:96:17:98:17 | [finally(1): exception(Exception)] {...} | +| Finally.cs:97:21:97:24 | [finally: break, finally(1): exception(Exception)] ...; | Finally.cs:96:17:98:17 | [finally: break, finally(1): exception(Exception)] {...} | | Finally.cs:97:21:97:24 | [finally: break] ...; | Finally.cs:96:17:98:17 | [finally: break] {...} | -| Finally.cs:97:21:97:24 | [finally: continue, finally(2): exception(Exception)] ...; | Finally.cs:96:17:98:17 | [finally: continue, finally(2): exception(Exception)] {...} | +| Finally.cs:97:21:97:24 | [finally: continue, finally(1): exception(Exception)] ...; | Finally.cs:96:17:98:17 | [finally: continue, finally(1): exception(Exception)] {...} | | Finally.cs:97:21:97:24 | [finally: continue] ...; | Finally.cs:96:17:98:17 | [finally: continue] {...} | -| Finally.cs:97:21:97:24 | [finally: return, finally(2): exception(Exception)] ...; | Finally.cs:96:17:98:17 | [finally: return, finally(2): exception(Exception)] {...} | +| Finally.cs:97:21:97:24 | [finally: return, finally(1): exception(Exception)] ...; | Finally.cs:96:17:98:17 | [finally: return, finally(1): exception(Exception)] {...} | | Finally.cs:97:21:97:24 | [finally: return] ...; | Finally.cs:96:17:98:17 | [finally: return] {...} | | Finally.cs:103:10:103:11 | exit M5 (normal) | Finally.cs:116:17:116:32 | ... > ... | | Finally.cs:103:10:103:11 | exit M5 (normal) | Finally.cs:116:17:116:32 | [finally: return] ... > ... | @@ -5986,17 +6188,15 @@ postDominance | Finally.cs:134:5:145:5 | {...} | Finally.cs:133:10:133:11 | enter M7 | | Finally.cs:135:9:143:9 | try {...} ... | Finally.cs:134:5:145:5 | {...} | | Finally.cs:136:9:138:9 | {...} | Finally.cs:135:9:143:9 | try {...} ... | +| Finally.cs:137:13:137:36 | call to method WriteLine | Finally.cs:137:31:137:35 | "Try" | | Finally.cs:137:13:137:37 | ...; | Finally.cs:136:9:138:9 | {...} | | Finally.cs:137:31:137:35 | "Try" | Finally.cs:137:13:137:37 | ...; | | Finally.cs:141:13:141:44 | [finally: exception(Exception)] throw ...; | Finally.cs:141:19:141:43 | [finally: exception(Exception)] object creation of type ArgumentException | -| Finally.cs:141:13:141:44 | [finally: exception(OutOfMemoryException)] throw ...; | Finally.cs:141:19:141:43 | [finally: exception(OutOfMemoryException)] object creation of type ArgumentException | | Finally.cs:141:13:141:44 | throw ...; | Finally.cs:141:19:141:43 | object creation of type ArgumentException | | Finally.cs:141:19:141:43 | [finally: exception(Exception)] object creation of type ArgumentException | Finally.cs:141:41:141:42 | [finally: exception(Exception)] "" | -| Finally.cs:141:19:141:43 | [finally: exception(OutOfMemoryException)] object creation of type ArgumentException | Finally.cs:141:41:141:42 | [finally: exception(OutOfMemoryException)] "" | | Finally.cs:141:19:141:43 | object creation of type ArgumentException | Finally.cs:141:41:141:42 | "" | | Finally.cs:141:41:141:42 | "" | Finally.cs:140:9:143:9 | {...} | | Finally.cs:141:41:141:42 | [finally: exception(Exception)] "" | Finally.cs:140:9:143:9 | [finally: exception(Exception)] {...} | -| Finally.cs:141:41:141:42 | [finally: exception(OutOfMemoryException)] "" | Finally.cs:140:9:143:9 | [finally: exception(OutOfMemoryException)] {...} | | Finally.cs:147:10:147:11 | exit M8 (normal) | Finally.cs:158:21:158:36 | ... == ... | | Finally.cs:147:10:147:11 | exit M8 (normal) | Finally.cs:163:17:163:42 | call to method WriteLine | | Finally.cs:147:10:147:11 | exit M8 (normal) | Finally.cs:167:17:167:37 | call to method WriteLine | @@ -6027,47 +6227,37 @@ postDominance | Finally.cs:158:21:158:36 | ... == ... | Finally.cs:158:36:158:36 | 1 | | Finally.cs:158:21:158:36 | [finally: exception(ArgumentNullException)] ... == ... | Finally.cs:158:36:158:36 | [finally: exception(ArgumentNullException)] 1 | | Finally.cs:158:21:158:36 | [finally: exception(Exception)] ... == ... | Finally.cs:158:36:158:36 | [finally: exception(Exception)] 1 | +| Finally.cs:159:27:159:44 | [finally: exception(ArgumentNullException)] object creation of type Exception | Finally.cs:159:41:159:43 | [finally: exception(ArgumentNullException)] "1" | +| Finally.cs:159:27:159:44 | [finally: exception(Exception)] object creation of type Exception | Finally.cs:159:41:159:43 | [finally: exception(Exception)] "1" | +| Finally.cs:159:27:159:44 | object creation of type Exception | Finally.cs:159:41:159:43 | "1" | | Finally.cs:161:13:164:13 | [exception: Exception] catch (...) {...} | Finally.cs:159:21:159:45 | throw ...; | | Finally.cs:161:13:164:13 | [exception: Exception] catch (...) {...} | Finally.cs:159:27:159:44 | object creation of type Exception | | Finally.cs:161:30:161:30 | [exception: Exception] Exception e | Finally.cs:161:13:164:13 | [exception: Exception] catch (...) {...} | | Finally.cs:161:30:161:30 | [exception: NullReferenceException] Exception e | Finally.cs:161:13:164:13 | [exception: NullReferenceException] catch (...) {...} | -| Finally.cs:161:30:161:30 | [exception: OutOfMemoryException] Exception e | Finally.cs:161:13:164:13 | [exception: OutOfMemoryException] catch (...) {...} | | Finally.cs:161:39:161:39 | [exception: Exception] access to local variable e | Finally.cs:161:30:161:30 | [exception: Exception] Exception e | | Finally.cs:161:39:161:39 | [exception: NullReferenceException] access to local variable e | Finally.cs:161:30:161:30 | [exception: NullReferenceException] Exception e | -| Finally.cs:161:39:161:39 | [exception: OutOfMemoryException] access to local variable e | Finally.cs:161:30:161:30 | [exception: OutOfMemoryException] Exception e | | Finally.cs:161:39:161:39 | [finally: exception(ArgumentNullException), exception: Exception] access to local variable e | Finally.cs:161:30:161:30 | [finally: exception(ArgumentNullException), exception: Exception] Exception e | | Finally.cs:161:39:161:39 | [finally: exception(ArgumentNullException), exception: NullReferenceException] access to local variable e | Finally.cs:161:30:161:30 | [finally: exception(ArgumentNullException), exception: NullReferenceException] Exception e | -| Finally.cs:161:39:161:39 | [finally: exception(ArgumentNullException), exception: OutOfMemoryException] access to local variable e | Finally.cs:161:30:161:30 | [finally: exception(ArgumentNullException), exception: OutOfMemoryException] Exception e | | Finally.cs:161:39:161:39 | [finally: exception(Exception), exception: Exception] access to local variable e | Finally.cs:161:30:161:30 | [finally: exception(Exception), exception: Exception] Exception e | | Finally.cs:161:39:161:39 | [finally: exception(Exception), exception: NullReferenceException] access to local variable e | Finally.cs:161:30:161:30 | [finally: exception(Exception), exception: NullReferenceException] Exception e | -| Finally.cs:161:39:161:39 | [finally: exception(Exception), exception: OutOfMemoryException] access to local variable e | Finally.cs:161:30:161:30 | [finally: exception(Exception), exception: OutOfMemoryException] Exception e | | Finally.cs:161:39:161:47 | [exception: Exception] access to property Message | Finally.cs:161:39:161:39 | [exception: Exception] access to local variable e | | Finally.cs:161:39:161:47 | [exception: NullReferenceException] access to property Message | Finally.cs:161:39:161:39 | [exception: NullReferenceException] access to local variable e | -| Finally.cs:161:39:161:47 | [exception: OutOfMemoryException] access to property Message | Finally.cs:161:39:161:39 | [exception: OutOfMemoryException] access to local variable e | | Finally.cs:161:39:161:47 | [finally: exception(ArgumentNullException), exception: Exception] access to property Message | Finally.cs:161:39:161:39 | [finally: exception(ArgumentNullException), exception: Exception] access to local variable e | | Finally.cs:161:39:161:47 | [finally: exception(ArgumentNullException), exception: NullReferenceException] access to property Message | Finally.cs:161:39:161:39 | [finally: exception(ArgumentNullException), exception: NullReferenceException] access to local variable e | -| Finally.cs:161:39:161:47 | [finally: exception(ArgumentNullException), exception: OutOfMemoryException] access to property Message | Finally.cs:161:39:161:39 | [finally: exception(ArgumentNullException), exception: OutOfMemoryException] access to local variable e | | Finally.cs:161:39:161:47 | [finally: exception(Exception), exception: Exception] access to property Message | Finally.cs:161:39:161:39 | [finally: exception(Exception), exception: Exception] access to local variable e | | Finally.cs:161:39:161:47 | [finally: exception(Exception), exception: NullReferenceException] access to property Message | Finally.cs:161:39:161:39 | [finally: exception(Exception), exception: NullReferenceException] access to local variable e | -| Finally.cs:161:39:161:47 | [finally: exception(Exception), exception: OutOfMemoryException] access to property Message | Finally.cs:161:39:161:39 | [finally: exception(Exception), exception: OutOfMemoryException] access to local variable e | | Finally.cs:161:39:161:54 | [exception: Exception] ... == ... | Finally.cs:161:52:161:54 | [exception: Exception] "1" | | Finally.cs:161:39:161:54 | [exception: NullReferenceException] ... == ... | Finally.cs:161:52:161:54 | [exception: NullReferenceException] "1" | -| Finally.cs:161:39:161:54 | [exception: OutOfMemoryException] ... == ... | Finally.cs:161:52:161:54 | [exception: OutOfMemoryException] "1" | | Finally.cs:161:39:161:54 | [finally: exception(ArgumentNullException), exception: Exception] ... == ... | Finally.cs:161:52:161:54 | [finally: exception(ArgumentNullException), exception: Exception] "1" | | Finally.cs:161:39:161:54 | [finally: exception(ArgumentNullException), exception: NullReferenceException] ... == ... | Finally.cs:161:52:161:54 | [finally: exception(ArgumentNullException), exception: NullReferenceException] "1" | -| Finally.cs:161:39:161:54 | [finally: exception(ArgumentNullException), exception: OutOfMemoryException] ... == ... | Finally.cs:161:52:161:54 | [finally: exception(ArgumentNullException), exception: OutOfMemoryException] "1" | | Finally.cs:161:39:161:54 | [finally: exception(Exception), exception: Exception] ... == ... | Finally.cs:161:52:161:54 | [finally: exception(Exception), exception: Exception] "1" | | Finally.cs:161:39:161:54 | [finally: exception(Exception), exception: NullReferenceException] ... == ... | Finally.cs:161:52:161:54 | [finally: exception(Exception), exception: NullReferenceException] "1" | -| Finally.cs:161:39:161:54 | [finally: exception(Exception), exception: OutOfMemoryException] ... == ... | Finally.cs:161:52:161:54 | [finally: exception(Exception), exception: OutOfMemoryException] "1" | | Finally.cs:161:52:161:54 | [exception: Exception] "1" | Finally.cs:161:39:161:47 | [exception: Exception] access to property Message | | Finally.cs:161:52:161:54 | [exception: NullReferenceException] "1" | Finally.cs:161:39:161:47 | [exception: NullReferenceException] access to property Message | -| Finally.cs:161:52:161:54 | [exception: OutOfMemoryException] "1" | Finally.cs:161:39:161:47 | [exception: OutOfMemoryException] access to property Message | | Finally.cs:161:52:161:54 | [finally: exception(ArgumentNullException), exception: Exception] "1" | Finally.cs:161:39:161:47 | [finally: exception(ArgumentNullException), exception: Exception] access to property Message | | Finally.cs:161:52:161:54 | [finally: exception(ArgumentNullException), exception: NullReferenceException] "1" | Finally.cs:161:39:161:47 | [finally: exception(ArgumentNullException), exception: NullReferenceException] access to property Message | -| Finally.cs:161:52:161:54 | [finally: exception(ArgumentNullException), exception: OutOfMemoryException] "1" | Finally.cs:161:39:161:47 | [finally: exception(ArgumentNullException), exception: OutOfMemoryException] access to property Message | | Finally.cs:161:52:161:54 | [finally: exception(Exception), exception: Exception] "1" | Finally.cs:161:39:161:47 | [finally: exception(Exception), exception: Exception] access to property Message | | Finally.cs:161:52:161:54 | [finally: exception(Exception), exception: NullReferenceException] "1" | Finally.cs:161:39:161:47 | [finally: exception(Exception), exception: NullReferenceException] access to property Message | -| Finally.cs:161:52:161:54 | [finally: exception(Exception), exception: OutOfMemoryException] "1" | Finally.cs:161:39:161:47 | [finally: exception(Exception), exception: OutOfMemoryException] access to property Message | | Finally.cs:163:17:163:42 | [finally: exception(ArgumentNullException)] call to method WriteLine | Finally.cs:163:35:163:41 | [finally: exception(ArgumentNullException)] access to array element | | Finally.cs:163:17:163:42 | [finally: exception(Exception)] call to method WriteLine | Finally.cs:163:35:163:41 | [finally: exception(Exception)] access to array element | | Finally.cs:163:17:163:42 | call to method WriteLine | Finally.cs:163:35:163:41 | access to array element | @@ -6151,35 +6341,35 @@ postDominance | Finally.cs:205:21:205:22 | [finally: exception(Exception)] access to parameter b2 | Finally.cs:205:17:205:47 | [finally: exception(Exception)] if (...) ... | | Finally.cs:205:21:205:22 | [finally: exception(ExceptionA)] access to parameter b2 | Finally.cs:205:17:205:47 | [finally: exception(ExceptionA)] if (...) ... | | Finally.cs:205:21:205:22 | access to parameter b2 | Finally.cs:205:17:205:47 | if (...) ... | -| Finally.cs:208:13:210:13 | [finally(2): exception(ExceptionB)] {...} | Finally.cs:205:25:205:47 | throw ...; | -| Finally.cs:208:13:210:13 | [finally: exception(Exception), finally(2): exception(ExceptionB)] {...} | Finally.cs:205:25:205:47 | [finally: exception(Exception)] throw ...; | -| Finally.cs:208:13:210:13 | [finally: exception(ExceptionA), finally(2): exception(ExceptionB)] {...} | Finally.cs:205:25:205:47 | [finally: exception(ExceptionA)] throw ...; | +| Finally.cs:208:13:210:13 | [finally(1): exception(ExceptionB)] {...} | Finally.cs:205:25:205:47 | throw ...; | +| Finally.cs:208:13:210:13 | [finally: exception(Exception), finally(1): exception(ExceptionB)] {...} | Finally.cs:205:25:205:47 | [finally: exception(Exception)] throw ...; | +| Finally.cs:208:13:210:13 | [finally: exception(ExceptionA), finally(1): exception(ExceptionB)] {...} | Finally.cs:205:25:205:47 | [finally: exception(ExceptionA)] throw ...; | | Finally.cs:208:13:210:13 | {...} | Finally.cs:205:21:205:22 | access to parameter b2 | -| Finally.cs:209:17:209:47 | [finally(2): exception(Exception)] if (...) ... | Finally.cs:208:13:210:13 | [finally(2): exception(Exception)] {...} | -| Finally.cs:209:17:209:47 | [finally(2): exception(ExceptionB)] if (...) ... | Finally.cs:208:13:210:13 | [finally(2): exception(ExceptionB)] {...} | -| Finally.cs:209:17:209:47 | [finally: exception(Exception), finally(2): exception(Exception)] if (...) ... | Finally.cs:208:13:210:13 | [finally: exception(Exception), finally(2): exception(Exception)] {...} | -| Finally.cs:209:17:209:47 | [finally: exception(Exception), finally(2): exception(ExceptionB)] if (...) ... | Finally.cs:208:13:210:13 | [finally: exception(Exception), finally(2): exception(ExceptionB)] {...} | +| Finally.cs:209:17:209:47 | [finally(1): exception(Exception)] if (...) ... | Finally.cs:208:13:210:13 | [finally(1): exception(Exception)] {...} | +| Finally.cs:209:17:209:47 | [finally(1): exception(ExceptionB)] if (...) ... | Finally.cs:208:13:210:13 | [finally(1): exception(ExceptionB)] {...} | +| Finally.cs:209:17:209:47 | [finally: exception(Exception), finally(1): exception(Exception)] if (...) ... | Finally.cs:208:13:210:13 | [finally: exception(Exception), finally(1): exception(Exception)] {...} | +| Finally.cs:209:17:209:47 | [finally: exception(Exception), finally(1): exception(ExceptionB)] if (...) ... | Finally.cs:208:13:210:13 | [finally: exception(Exception), finally(1): exception(ExceptionB)] {...} | | Finally.cs:209:17:209:47 | [finally: exception(Exception)] if (...) ... | Finally.cs:208:13:210:13 | [finally: exception(Exception)] {...} | -| Finally.cs:209:17:209:47 | [finally: exception(ExceptionA), finally(2): exception(Exception)] if (...) ... | Finally.cs:208:13:210:13 | [finally: exception(ExceptionA), finally(2): exception(Exception)] {...} | -| Finally.cs:209:17:209:47 | [finally: exception(ExceptionA), finally(2): exception(ExceptionB)] if (...) ... | Finally.cs:208:13:210:13 | [finally: exception(ExceptionA), finally(2): exception(ExceptionB)] {...} | +| Finally.cs:209:17:209:47 | [finally: exception(ExceptionA), finally(1): exception(Exception)] if (...) ... | Finally.cs:208:13:210:13 | [finally: exception(ExceptionA), finally(1): exception(Exception)] {...} | +| Finally.cs:209:17:209:47 | [finally: exception(ExceptionA), finally(1): exception(ExceptionB)] if (...) ... | Finally.cs:208:13:210:13 | [finally: exception(ExceptionA), finally(1): exception(ExceptionB)] {...} | | Finally.cs:209:17:209:47 | [finally: exception(ExceptionA)] if (...) ... | Finally.cs:208:13:210:13 | [finally: exception(ExceptionA)] {...} | | Finally.cs:209:17:209:47 | if (...) ... | Finally.cs:208:13:210:13 | {...} | -| Finally.cs:209:21:209:22 | [finally(2): exception(Exception)] access to parameter b3 | Finally.cs:209:17:209:47 | [finally(2): exception(Exception)] if (...) ... | -| Finally.cs:209:21:209:22 | [finally(2): exception(ExceptionB)] access to parameter b3 | Finally.cs:209:17:209:47 | [finally(2): exception(ExceptionB)] if (...) ... | -| Finally.cs:209:21:209:22 | [finally: exception(Exception), finally(2): exception(Exception)] access to parameter b3 | Finally.cs:209:17:209:47 | [finally: exception(Exception), finally(2): exception(Exception)] if (...) ... | -| Finally.cs:209:21:209:22 | [finally: exception(Exception), finally(2): exception(ExceptionB)] access to parameter b3 | Finally.cs:209:17:209:47 | [finally: exception(Exception), finally(2): exception(ExceptionB)] if (...) ... | +| Finally.cs:209:21:209:22 | [finally(1): exception(Exception)] access to parameter b3 | Finally.cs:209:17:209:47 | [finally(1): exception(Exception)] if (...) ... | +| Finally.cs:209:21:209:22 | [finally(1): exception(ExceptionB)] access to parameter b3 | Finally.cs:209:17:209:47 | [finally(1): exception(ExceptionB)] if (...) ... | +| Finally.cs:209:21:209:22 | [finally: exception(Exception), finally(1): exception(Exception)] access to parameter b3 | Finally.cs:209:17:209:47 | [finally: exception(Exception), finally(1): exception(Exception)] if (...) ... | +| Finally.cs:209:21:209:22 | [finally: exception(Exception), finally(1): exception(ExceptionB)] access to parameter b3 | Finally.cs:209:17:209:47 | [finally: exception(Exception), finally(1): exception(ExceptionB)] if (...) ... | | Finally.cs:209:21:209:22 | [finally: exception(Exception)] access to parameter b3 | Finally.cs:209:17:209:47 | [finally: exception(Exception)] if (...) ... | -| Finally.cs:209:21:209:22 | [finally: exception(ExceptionA), finally(2): exception(Exception)] access to parameter b3 | Finally.cs:209:17:209:47 | [finally: exception(ExceptionA), finally(2): exception(Exception)] if (...) ... | -| Finally.cs:209:21:209:22 | [finally: exception(ExceptionA), finally(2): exception(ExceptionB)] access to parameter b3 | Finally.cs:209:17:209:47 | [finally: exception(ExceptionA), finally(2): exception(ExceptionB)] if (...) ... | +| Finally.cs:209:21:209:22 | [finally: exception(ExceptionA), finally(1): exception(Exception)] access to parameter b3 | Finally.cs:209:17:209:47 | [finally: exception(ExceptionA), finally(1): exception(Exception)] if (...) ... | +| Finally.cs:209:21:209:22 | [finally: exception(ExceptionA), finally(1): exception(ExceptionB)] access to parameter b3 | Finally.cs:209:17:209:47 | [finally: exception(ExceptionA), finally(1): exception(ExceptionB)] if (...) ... | | Finally.cs:209:21:209:22 | [finally: exception(ExceptionA)] access to parameter b3 | Finally.cs:209:17:209:47 | [finally: exception(ExceptionA)] if (...) ... | | Finally.cs:209:21:209:22 | access to parameter b3 | Finally.cs:209:17:209:47 | if (...) ... | -| Finally.cs:209:25:209:47 | [finally(2): exception(Exception)] throw ...; | Finally.cs:209:31:209:46 | [finally(2): exception(Exception)] object creation of type ExceptionC | -| Finally.cs:209:25:209:47 | [finally(2): exception(ExceptionB)] throw ...; | Finally.cs:209:31:209:46 | [finally(2): exception(ExceptionB)] object creation of type ExceptionC | -| Finally.cs:209:25:209:47 | [finally: exception(Exception), finally(2): exception(Exception)] throw ...; | Finally.cs:209:31:209:46 | [finally: exception(Exception), finally(2): exception(Exception)] object creation of type ExceptionC | -| Finally.cs:209:25:209:47 | [finally: exception(Exception), finally(2): exception(ExceptionB)] throw ...; | Finally.cs:209:31:209:46 | [finally: exception(Exception), finally(2): exception(ExceptionB)] object creation of type ExceptionC | +| Finally.cs:209:25:209:47 | [finally(1): exception(Exception)] throw ...; | Finally.cs:209:31:209:46 | [finally(1): exception(Exception)] object creation of type ExceptionC | +| Finally.cs:209:25:209:47 | [finally(1): exception(ExceptionB)] throw ...; | Finally.cs:209:31:209:46 | [finally(1): exception(ExceptionB)] object creation of type ExceptionC | +| Finally.cs:209:25:209:47 | [finally: exception(Exception), finally(1): exception(Exception)] throw ...; | Finally.cs:209:31:209:46 | [finally: exception(Exception), finally(1): exception(Exception)] object creation of type ExceptionC | +| Finally.cs:209:25:209:47 | [finally: exception(Exception), finally(1): exception(ExceptionB)] throw ...; | Finally.cs:209:31:209:46 | [finally: exception(Exception), finally(1): exception(ExceptionB)] object creation of type ExceptionC | | Finally.cs:209:25:209:47 | [finally: exception(Exception)] throw ...; | Finally.cs:209:31:209:46 | [finally: exception(Exception)] object creation of type ExceptionC | -| Finally.cs:209:25:209:47 | [finally: exception(ExceptionA), finally(2): exception(Exception)] throw ...; | Finally.cs:209:31:209:46 | [finally: exception(ExceptionA), finally(2): exception(Exception)] object creation of type ExceptionC | -| Finally.cs:209:25:209:47 | [finally: exception(ExceptionA), finally(2): exception(ExceptionB)] throw ...; | Finally.cs:209:31:209:46 | [finally: exception(ExceptionA), finally(2): exception(ExceptionB)] object creation of type ExceptionC | +| Finally.cs:209:25:209:47 | [finally: exception(ExceptionA), finally(1): exception(Exception)] throw ...; | Finally.cs:209:31:209:46 | [finally: exception(ExceptionA), finally(1): exception(Exception)] object creation of type ExceptionC | +| Finally.cs:209:25:209:47 | [finally: exception(ExceptionA), finally(1): exception(ExceptionB)] throw ...; | Finally.cs:209:31:209:46 | [finally: exception(ExceptionA), finally(1): exception(ExceptionB)] object creation of type ExceptionC | | Finally.cs:209:25:209:47 | [finally: exception(ExceptionA)] throw ...; | Finally.cs:209:31:209:46 | [finally: exception(ExceptionA)] object creation of type ExceptionC | | Finally.cs:209:25:209:47 | throw ...; | Finally.cs:209:31:209:46 | object creation of type ExceptionC | | Finally.cs:211:13:211:16 | [finally: exception(Exception)] this access | Finally.cs:211:13:211:29 | [finally: exception(Exception)] ...; | @@ -6201,6 +6391,7 @@ postDominance | Finally.cs:217:5:231:5 | {...} | Finally.cs:216:10:216:12 | enter M11 | | Finally.cs:218:9:229:9 | try {...} ... | Finally.cs:217:5:231:5 | {...} | | Finally.cs:219:9:221:9 | {...} | Finally.cs:218:9:229:9 | try {...} ... | +| Finally.cs:220:13:220:36 | call to method WriteLine | Finally.cs:220:31:220:35 | "Try" | | Finally.cs:220:13:220:37 | ...; | Finally.cs:219:9:221:9 | {...} | | Finally.cs:220:31:220:35 | "Try" | Finally.cs:220:13:220:37 | ...; | | Finally.cs:223:9:225:9 | {...} | Finally.cs:222:9:225:9 | catch {...} | @@ -6215,6 +6406,100 @@ postDominance | Finally.cs:230:9:230:33 | call to method WriteLine | Finally.cs:230:27:230:32 | "Done" | | Finally.cs:230:9:230:34 | ...; | Finally.cs:228:13:228:40 | call to method WriteLine | | Finally.cs:230:27:230:32 | "Done" | Finally.cs:230:9:230:34 | ...; | +| Finally.cs:233:10:233:12 | exit M12 (normal) | Finally.cs:260:9:260:33 | call to method WriteLine | +| Finally.cs:234:5:261:5 | {...} | Finally.cs:233:10:233:12 | enter M12 | +| Finally.cs:235:9:259:9 | try {...} ... | Finally.cs:234:5:261:5 | {...} | +| Finally.cs:236:9:255:9 | {...} | Finally.cs:235:9:259:9 | try {...} ... | +| Finally.cs:237:13:253:13 | try {...} ... | Finally.cs:236:9:255:9 | {...} | +| Finally.cs:238:13:241:13 | {...} | Finally.cs:237:13:253:13 | try {...} ... | +| Finally.cs:239:17:240:43 | if (...) ... | Finally.cs:238:13:241:13 | {...} | +| Finally.cs:239:21:239:22 | access to parameter b1 | Finally.cs:239:17:240:43 | if (...) ... | +| Finally.cs:243:13:253:13 | [finally: exception(ExceptionA)] {...} | Finally.cs:240:21:240:43 | throw ...; | +| Finally.cs:243:13:253:13 | {...} | Finally.cs:239:21:239:22 | access to parameter b1 | +| Finally.cs:244:17:252:17 | [finally: exception(Exception)] try {...} ... | Finally.cs:243:13:253:13 | [finally: exception(Exception)] {...} | +| Finally.cs:244:17:252:17 | [finally: exception(ExceptionA)] try {...} ... | Finally.cs:243:13:253:13 | [finally: exception(ExceptionA)] {...} | +| Finally.cs:244:17:252:17 | try {...} ... | Finally.cs:243:13:253:13 | {...} | +| Finally.cs:245:17:248:17 | [finally: exception(Exception)] {...} | Finally.cs:244:17:252:17 | [finally: exception(Exception)] try {...} ... | +| Finally.cs:245:17:248:17 | [finally: exception(ExceptionA)] {...} | Finally.cs:244:17:252:17 | [finally: exception(ExceptionA)] try {...} ... | +| Finally.cs:245:17:248:17 | {...} | Finally.cs:244:17:252:17 | try {...} ... | +| Finally.cs:246:21:247:47 | [finally: exception(Exception)] if (...) ... | Finally.cs:245:17:248:17 | [finally: exception(Exception)] {...} | +| Finally.cs:246:21:247:47 | [finally: exception(ExceptionA)] if (...) ... | Finally.cs:245:17:248:17 | [finally: exception(ExceptionA)] {...} | +| Finally.cs:246:21:247:47 | if (...) ... | Finally.cs:245:17:248:17 | {...} | +| Finally.cs:246:25:246:26 | [finally: exception(Exception)] access to parameter b2 | Finally.cs:246:21:247:47 | [finally: exception(Exception)] if (...) ... | +| Finally.cs:246:25:246:26 | [finally: exception(ExceptionA)] access to parameter b2 | Finally.cs:246:21:247:47 | [finally: exception(ExceptionA)] if (...) ... | +| Finally.cs:246:25:246:26 | access to parameter b2 | Finally.cs:246:21:247:47 | if (...) ... | +| Finally.cs:250:17:252:17 | [finally(1): exception(ExceptionA)] {...} | Finally.cs:247:25:247:47 | throw ...; | +| Finally.cs:250:17:252:17 | [finally: exception(Exception), finally(1): exception(ExceptionA)] {...} | Finally.cs:247:25:247:47 | [finally: exception(Exception)] throw ...; | +| Finally.cs:250:17:252:17 | [finally: exception(ExceptionA), finally(1): exception(ExceptionA)] {...} | Finally.cs:247:25:247:47 | [finally: exception(ExceptionA)] throw ...; | +| Finally.cs:250:17:252:17 | {...} | Finally.cs:246:25:246:26 | access to parameter b2 | +| Finally.cs:251:21:251:54 | [finally(1): exception(Exception)] call to method WriteLine | Finally.cs:251:39:251:53 | [finally(1): exception(Exception)] "Inner finally" | +| Finally.cs:251:21:251:54 | [finally(1): exception(ExceptionA)] call to method WriteLine | Finally.cs:251:39:251:53 | [finally(1): exception(ExceptionA)] "Inner finally" | +| Finally.cs:251:21:251:54 | [finally: exception(Exception), finally(1): exception(Exception)] call to method WriteLine | Finally.cs:251:39:251:53 | [finally: exception(Exception), finally(1): exception(Exception)] "Inner finally" | +| Finally.cs:251:21:251:54 | [finally: exception(Exception), finally(1): exception(ExceptionA)] call to method WriteLine | Finally.cs:251:39:251:53 | [finally: exception(Exception), finally(1): exception(ExceptionA)] "Inner finally" | +| Finally.cs:251:21:251:54 | [finally: exception(Exception)] call to method WriteLine | Finally.cs:251:39:251:53 | [finally: exception(Exception)] "Inner finally" | +| Finally.cs:251:21:251:54 | [finally: exception(ExceptionA), finally(1): exception(Exception)] call to method WriteLine | Finally.cs:251:39:251:53 | [finally: exception(ExceptionA), finally(1): exception(Exception)] "Inner finally" | +| Finally.cs:251:21:251:54 | [finally: exception(ExceptionA), finally(1): exception(ExceptionA)] call to method WriteLine | Finally.cs:251:39:251:53 | [finally: exception(ExceptionA), finally(1): exception(ExceptionA)] "Inner finally" | +| Finally.cs:251:21:251:54 | [finally: exception(ExceptionA)] call to method WriteLine | Finally.cs:251:39:251:53 | [finally: exception(ExceptionA)] "Inner finally" | +| Finally.cs:251:21:251:54 | call to method WriteLine | Finally.cs:251:39:251:53 | "Inner finally" | +| Finally.cs:251:21:251:55 | ...; | Finally.cs:250:17:252:17 | {...} | +| Finally.cs:251:21:251:55 | [finally(1): exception(Exception)] ...; | Finally.cs:250:17:252:17 | [finally(1): exception(Exception)] {...} | +| Finally.cs:251:21:251:55 | [finally(1): exception(ExceptionA)] ...; | Finally.cs:250:17:252:17 | [finally(1): exception(ExceptionA)] {...} | +| Finally.cs:251:21:251:55 | [finally: exception(Exception), finally(1): exception(Exception)] ...; | Finally.cs:250:17:252:17 | [finally: exception(Exception), finally(1): exception(Exception)] {...} | +| Finally.cs:251:21:251:55 | [finally: exception(Exception), finally(1): exception(ExceptionA)] ...; | Finally.cs:250:17:252:17 | [finally: exception(Exception), finally(1): exception(ExceptionA)] {...} | +| Finally.cs:251:21:251:55 | [finally: exception(Exception)] ...; | Finally.cs:250:17:252:17 | [finally: exception(Exception)] {...} | +| Finally.cs:251:21:251:55 | [finally: exception(ExceptionA), finally(1): exception(Exception)] ...; | Finally.cs:250:17:252:17 | [finally: exception(ExceptionA), finally(1): exception(Exception)] {...} | +| Finally.cs:251:21:251:55 | [finally: exception(ExceptionA), finally(1): exception(ExceptionA)] ...; | Finally.cs:250:17:252:17 | [finally: exception(ExceptionA), finally(1): exception(ExceptionA)] {...} | +| Finally.cs:251:21:251:55 | [finally: exception(ExceptionA)] ...; | Finally.cs:250:17:252:17 | [finally: exception(ExceptionA)] {...} | +| Finally.cs:251:39:251:53 | "Inner finally" | Finally.cs:251:21:251:55 | ...; | +| Finally.cs:251:39:251:53 | [finally(1): exception(Exception)] "Inner finally" | Finally.cs:251:21:251:55 | [finally(1): exception(Exception)] ...; | +| Finally.cs:251:39:251:53 | [finally(1): exception(ExceptionA)] "Inner finally" | Finally.cs:251:21:251:55 | [finally(1): exception(ExceptionA)] ...; | +| Finally.cs:251:39:251:53 | [finally: exception(Exception), finally(1): exception(Exception)] "Inner finally" | Finally.cs:251:21:251:55 | [finally: exception(Exception), finally(1): exception(Exception)] ...; | +| Finally.cs:251:39:251:53 | [finally: exception(Exception), finally(1): exception(ExceptionA)] "Inner finally" | Finally.cs:251:21:251:55 | [finally: exception(Exception), finally(1): exception(ExceptionA)] ...; | +| Finally.cs:251:39:251:53 | [finally: exception(Exception)] "Inner finally" | Finally.cs:251:21:251:55 | [finally: exception(Exception)] ...; | +| Finally.cs:251:39:251:53 | [finally: exception(ExceptionA), finally(1): exception(Exception)] "Inner finally" | Finally.cs:251:21:251:55 | [finally: exception(ExceptionA), finally(1): exception(Exception)] ...; | +| Finally.cs:251:39:251:53 | [finally: exception(ExceptionA), finally(1): exception(ExceptionA)] "Inner finally" | Finally.cs:251:21:251:55 | [finally: exception(ExceptionA), finally(1): exception(ExceptionA)] ...; | +| Finally.cs:251:39:251:53 | [finally: exception(ExceptionA)] "Inner finally" | Finally.cs:251:21:251:55 | [finally: exception(ExceptionA)] ...; | +| Finally.cs:254:13:254:44 | call to method WriteLine | Finally.cs:254:31:254:43 | "Mid finally" | +| Finally.cs:254:13:254:45 | ...; | Finally.cs:251:21:251:54 | call to method WriteLine | +| Finally.cs:254:31:254:43 | "Mid finally" | Finally.cs:254:13:254:45 | ...; | +| Finally.cs:257:9:259:9 | {...} | Finally.cs:254:13:254:44 | call to method WriteLine | +| Finally.cs:258:13:258:46 | [finally: exception(Exception)] call to method WriteLine | Finally.cs:258:31:258:45 | [finally: exception(Exception)] "Outer finally" | +| Finally.cs:258:13:258:46 | [finally: exception(ExceptionA)] call to method WriteLine | Finally.cs:258:31:258:45 | [finally: exception(ExceptionA)] "Outer finally" | +| Finally.cs:258:13:258:46 | call to method WriteLine | Finally.cs:258:31:258:45 | "Outer finally" | +| Finally.cs:258:13:258:47 | ...; | Finally.cs:257:9:259:9 | {...} | +| Finally.cs:258:13:258:47 | [finally: exception(Exception)] ...; | Finally.cs:257:9:259:9 | [finally: exception(Exception)] {...} | +| Finally.cs:258:13:258:47 | [finally: exception(ExceptionA)] ...; | Finally.cs:257:9:259:9 | [finally: exception(ExceptionA)] {...} | +| Finally.cs:258:31:258:45 | "Outer finally" | Finally.cs:258:13:258:47 | ...; | +| Finally.cs:258:31:258:45 | [finally: exception(Exception)] "Outer finally" | Finally.cs:258:13:258:47 | [finally: exception(Exception)] ...; | +| Finally.cs:258:31:258:45 | [finally: exception(ExceptionA)] "Outer finally" | Finally.cs:258:13:258:47 | [finally: exception(ExceptionA)] ...; | +| Finally.cs:260:9:260:33 | call to method WriteLine | Finally.cs:260:27:260:32 | "Done" | +| Finally.cs:260:9:260:34 | ...; | Finally.cs:258:13:258:46 | call to method WriteLine | +| Finally.cs:260:27:260:32 | "Done" | Finally.cs:260:9:260:34 | ...; | +| Finally.cs:263:10:263:12 | exit M13 (abnormal) | Finally.cs:272:13:272:18 | [finally: exception(Exception)] ... = ... | +| Finally.cs:263:10:263:12 | exit M13 (normal) | Finally.cs:272:13:272:18 | ... = ... | +| Finally.cs:264:5:274:5 | {...} | Finally.cs:263:10:263:12 | enter M13 | +| Finally.cs:265:9:273:9 | try {...} ... | Finally.cs:264:5:274:5 | {...} | +| Finally.cs:266:9:268:9 | {...} | Finally.cs:265:9:273:9 | try {...} ... | +| Finally.cs:267:13:267:34 | call to method WriteLine | Finally.cs:267:31:267:33 | "1" | +| Finally.cs:267:13:267:35 | ...; | Finally.cs:266:9:268:9 | {...} | +| Finally.cs:267:31:267:33 | "1" | Finally.cs:267:13:267:35 | ...; | +| Finally.cs:270:9:273:9 | {...} | Finally.cs:267:13:267:34 | call to method WriteLine | +| Finally.cs:271:13:271:34 | [finally: exception(Exception)] call to method WriteLine | Finally.cs:271:31:271:33 | [finally: exception(Exception)] "3" | +| Finally.cs:271:13:271:34 | call to method WriteLine | Finally.cs:271:31:271:33 | "3" | +| Finally.cs:271:13:271:35 | ...; | Finally.cs:270:9:273:9 | {...} | +| Finally.cs:271:13:271:35 | [finally: exception(Exception)] ...; | Finally.cs:270:9:273:9 | [finally: exception(Exception)] {...} | +| Finally.cs:271:31:271:33 | "3" | Finally.cs:271:13:271:35 | ...; | +| Finally.cs:271:31:271:33 | [finally: exception(Exception)] "3" | Finally.cs:271:13:271:35 | [finally: exception(Exception)] ...; | +| Finally.cs:272:13:272:13 | [finally: exception(Exception)] access to parameter i | Finally.cs:272:13:272:19 | [finally: exception(Exception)] ...; | +| Finally.cs:272:13:272:13 | access to parameter i | Finally.cs:272:13:272:19 | ...; | +| Finally.cs:272:13:272:18 | ... + ... | Finally.cs:272:18:272:18 | 3 | +| Finally.cs:272:13:272:18 | ... = ... | Finally.cs:272:13:272:18 | ... + ... | +| Finally.cs:272:13:272:18 | [finally: exception(Exception)] ... + ... | Finally.cs:272:18:272:18 | [finally: exception(Exception)] 3 | +| Finally.cs:272:13:272:18 | [finally: exception(Exception)] ... = ... | Finally.cs:272:13:272:18 | [finally: exception(Exception)] ... + ... | +| Finally.cs:272:13:272:19 | ...; | Finally.cs:271:13:271:34 | call to method WriteLine | +| Finally.cs:272:13:272:19 | [finally: exception(Exception)] ...; | Finally.cs:271:13:271:34 | [finally: exception(Exception)] call to method WriteLine | +| Finally.cs:272:18:272:18 | 3 | Finally.cs:272:13:272:13 | access to parameter i | +| Finally.cs:272:18:272:18 | [finally: exception(Exception)] 3 | Finally.cs:272:13:272:13 | [finally: exception(Exception)] access to parameter i | | Foreach.cs:6:10:6:11 | exit M1 | Foreach.cs:6:10:6:11 | exit M1 (normal) | | Foreach.cs:6:10:6:11 | exit M1 (normal) | Foreach.cs:8:9:9:13 | foreach (... ... in ...) ... | | Foreach.cs:7:5:10:5 | {...} | Foreach.cs:6:10:6:11 | enter M1 | @@ -6849,35 +7134,37 @@ postDominance | NullCoalescing.cs:17:13:17:19 | (...) ... | NullCoalescing.cs:17:19:17:19 | access to parameter i | | NullCoalescing.cs:17:13:17:24 | ... ?? ... | NullCoalescing.cs:17:13:17:19 | (...) ... | | NullCoalescing.cs:17:19:17:19 | access to parameter i | NullCoalescing.cs:17:9:17:25 | ...; | -| Patterns.cs:5:10:5:13 | exit Test | Patterns.cs:5:10:5:13 | exit Test (normal) | -| Patterns.cs:5:10:5:13 | exit Test (normal) | Patterns.cs:40:17:40:17 | access to local variable o | -| Patterns.cs:6:5:43:5 | {...} | Patterns.cs:5:10:5:13 | enter Test | +| Patterns.cs:5:10:5:11 | exit M1 | Patterns.cs:5:10:5:11 | exit M1 (normal) | +| Patterns.cs:5:10:5:11 | exit M1 (normal) | Patterns.cs:40:17:40:17 | access to local variable o | +| Patterns.cs:6:5:43:5 | {...} | Patterns.cs:5:10:5:11 | enter M1 | | Patterns.cs:7:9:7:24 | ... ...; | Patterns.cs:6:5:43:5 | {...} | | Patterns.cs:7:16:7:23 | Object o = ... | Patterns.cs:7:20:7:23 | null | | Patterns.cs:7:20:7:23 | null | Patterns.cs:7:9:7:24 | ... ...; | | Patterns.cs:8:9:18:9 | if (...) ... | Patterns.cs:7:16:7:23 | Object o = ... | | Patterns.cs:8:13:8:13 | access to local variable o | Patterns.cs:8:9:18:9 | if (...) ... | -| Patterns.cs:8:13:8:23 | ... is ... | Patterns.cs:8:18:8:23 | Int32 i1 | | Patterns.cs:8:18:8:23 | Int32 i1 | Patterns.cs:8:13:8:13 | access to local variable o | +| Patterns.cs:9:9:11:9 | {...} | Patterns.cs:8:13:8:23 | [true] ... is ... | | Patterns.cs:10:13:10:42 | call to method WriteLine | Patterns.cs:10:31:10:41 | $"..." | | Patterns.cs:10:13:10:43 | ...; | Patterns.cs:9:9:11:9 | {...} | | Patterns.cs:10:31:10:41 | $"..." | Patterns.cs:10:38:10:39 | access to local variable i1 | | Patterns.cs:10:33:10:36 | "int " | Patterns.cs:10:13:10:43 | ...; | | Patterns.cs:10:38:10:39 | access to local variable i1 | Patterns.cs:10:33:10:36 | "int " | +| Patterns.cs:12:14:18:9 | if (...) ... | Patterns.cs:8:13:8:23 | [false] ... is ... | | Patterns.cs:12:18:12:18 | access to local variable o | Patterns.cs:12:14:18:9 | if (...) ... | -| Patterns.cs:12:18:12:31 | ... is ... | Patterns.cs:12:23:12:31 | String s1 | | Patterns.cs:12:23:12:31 | String s1 | Patterns.cs:12:18:12:18 | access to local variable o | +| Patterns.cs:13:9:15:9 | {...} | Patterns.cs:12:18:12:31 | [true] ... is ... | | Patterns.cs:14:13:14:45 | call to method WriteLine | Patterns.cs:14:31:14:44 | $"..." | | Patterns.cs:14:13:14:46 | ...; | Patterns.cs:13:9:15:9 | {...} | | Patterns.cs:14:31:14:44 | $"..." | Patterns.cs:14:41:14:42 | access to local variable s1 | | Patterns.cs:14:33:14:39 | "string " | Patterns.cs:14:13:14:46 | ...; | | Patterns.cs:14:41:14:42 | access to local variable s1 | Patterns.cs:14:33:14:39 | "string " | +| Patterns.cs:16:14:18:9 | if (...) ... | Patterns.cs:12:18:12:31 | [false] ... is ... | | Patterns.cs:16:18:16:18 | access to local variable o | Patterns.cs:16:14:18:9 | if (...) ... | -| Patterns.cs:16:18:16:28 | ... is ... | Patterns.cs:16:23:16:28 | Object v1 | | Patterns.cs:16:23:16:28 | Object v1 | Patterns.cs:16:18:16:18 | access to local variable o | +| Patterns.cs:17:9:18:9 | {...} | Patterns.cs:16:18:16:28 | [true] ... is ... | | Patterns.cs:20:9:38:9 | switch (...) {...} | Patterns.cs:10:13:10:42 | call to method WriteLine | | Patterns.cs:20:9:38:9 | switch (...) {...} | Patterns.cs:14:13:14:45 | call to method WriteLine | -| Patterns.cs:20:9:38:9 | switch (...) {...} | Patterns.cs:16:18:16:28 | ... is ... | +| Patterns.cs:20:9:38:9 | switch (...) {...} | Patterns.cs:16:18:16:28 | [false] ... is ... | | Patterns.cs:20:9:38:9 | switch (...) {...} | Patterns.cs:17:9:18:9 | {...} | | Patterns.cs:20:17:20:17 | access to local variable o | Patterns.cs:20:9:38:9 | switch (...) {...} | | Patterns.cs:22:13:22:23 | case ...: | Patterns.cs:20:17:20:17 | access to local variable o | @@ -6914,6 +7201,117 @@ postDominance | Patterns.cs:40:9:42:9 | switch (...) {...} | Patterns.cs:34:17:34:22 | break; | | Patterns.cs:40:9:42:9 | switch (...) {...} | Patterns.cs:37:17:37:22 | break; | | Patterns.cs:40:17:40:17 | access to local variable o | Patterns.cs:40:9:42:9 | switch (...) {...} | +| Patterns.cs:47:24:47:25 | exit M2 | Patterns.cs:47:24:47:25 | exit M2 (normal) | +| Patterns.cs:47:24:47:25 | exit M2 (normal) | Patterns.cs:48:9:48:20 | ... is ... | +| Patterns.cs:48:9:48:9 | access to parameter c | Patterns.cs:47:24:47:25 | enter M2 | +| Patterns.cs:48:9:48:20 | ... is ... | Patterns.cs:48:14:48:20 | not ... | +| Patterns.cs:48:14:48:20 | not ... | Patterns.cs:48:18:48:20 | a | +| Patterns.cs:48:18:48:20 | a | Patterns.cs:48:9:48:9 | access to parameter c | +| Patterns.cs:50:24:50:25 | exit M3 | Patterns.cs:50:24:50:25 | exit M3 (normal) | +| Patterns.cs:50:24:50:25 | exit M3 (normal) | Patterns.cs:51:9:51:39 | ... ? ... : ... | +| Patterns.cs:51:9:51:9 | access to parameter c | Patterns.cs:50:24:50:25 | enter M3 | +| Patterns.cs:51:9:51:21 | [false] ... is ... | Patterns.cs:51:14:51:21 | [no-match] not ... | +| Patterns.cs:51:9:51:21 | [true] ... is ... | Patterns.cs:51:14:51:21 | [match] not ... | +| Patterns.cs:51:9:51:39 | ... ? ... : ... | Patterns.cs:51:25:51:30 | ... is ... | +| Patterns.cs:51:9:51:39 | ... ? ... : ... | Patterns.cs:51:34:51:39 | ... is ... | +| Patterns.cs:51:18:51:21 | null | Patterns.cs:51:9:51:9 | access to parameter c | +| Patterns.cs:51:25:51:25 | access to parameter c | Patterns.cs:51:9:51:21 | [true] ... is ... | +| Patterns.cs:51:25:51:30 | ... is ... | Patterns.cs:51:30:51:30 | 1 | +| Patterns.cs:51:30:51:30 | 1 | Patterns.cs:51:25:51:25 | access to parameter c | +| Patterns.cs:51:34:51:34 | access to parameter c | Patterns.cs:51:9:51:21 | [false] ... is ... | +| Patterns.cs:51:34:51:39 | ... is ... | Patterns.cs:51:39:51:39 | 2 | +| Patterns.cs:51:39:51:39 | 2 | Patterns.cs:51:34:51:34 | access to parameter c | +| Patterns.cs:53:24:53:25 | exit M4 | Patterns.cs:53:24:53:25 | exit M4 (normal) | +| Patterns.cs:53:24:53:25 | exit M4 (normal) | Patterns.cs:54:9:54:37 | ... is ... | +| Patterns.cs:54:9:54:9 | access to parameter c | Patterns.cs:53:24:53:25 | enter M4 | +| Patterns.cs:54:9:54:37 | ... is ... | Patterns.cs:54:14:54:37 | not ... | +| Patterns.cs:54:14:54:37 | not ... | Patterns.cs:54:18:54:37 | { ... } | +| Patterns.cs:54:18:54:37 | Patterns u | Patterns.cs:54:9:54:9 | access to parameter c | +| Patterns.cs:54:18:54:37 | { ... } | Patterns.cs:54:18:54:37 | Patterns u | +| Patterns.cs:54:18:54:37 | { ... } | Patterns.cs:54:27:54:35 | [match] { ... } | +| Patterns.cs:54:18:54:37 | { ... } | Patterns.cs:54:27:54:35 | [no-match] { ... } | +| Patterns.cs:56:26:56:27 | exit M5 | Patterns.cs:56:26:56:27 | exit M5 (normal) | +| Patterns.cs:56:26:56:27 | exit M5 (normal) | Patterns.cs:58:9:62:10 | return ...; | +| Patterns.cs:57:5:63:5 | {...} | Patterns.cs:56:26:56:27 | enter M5 | +| Patterns.cs:58:9:62:10 | return ...; | Patterns.cs:58:16:62:9 | ... switch { ... } | +| Patterns.cs:58:16:58:16 | access to parameter i | Patterns.cs:57:5:63:5 | {...} | +| Patterns.cs:58:16:62:9 | ... switch { ... } | Patterns.cs:60:13:60:28 | ... => ... | +| Patterns.cs:58:16:62:9 | ... switch { ... } | Patterns.cs:61:13:61:24 | ... => ... | +| Patterns.cs:60:13:60:28 | ... => ... | Patterns.cs:60:22:60:28 | "not 1" | +| Patterns.cs:60:17:60:17 | 1 | Patterns.cs:58:16:58:16 | access to parameter i | +| Patterns.cs:60:22:60:28 | "not 1" | Patterns.cs:60:13:60:17 | [match] not ... | +| Patterns.cs:61:13:61:13 | _ | Patterns.cs:60:13:60:17 | [no-match] not ... | +| Patterns.cs:61:13:61:24 | ... => ... | Patterns.cs:61:18:61:24 | "other" | +| Patterns.cs:61:18:61:24 | "other" | Patterns.cs:61:13:61:13 | _ | +| Patterns.cs:65:26:65:27 | exit M6 | Patterns.cs:65:26:65:27 | exit M6 (normal) | +| Patterns.cs:65:26:65:27 | exit M6 (normal) | Patterns.cs:67:9:71:10 | return ...; | +| Patterns.cs:66:5:72:5 | {...} | Patterns.cs:65:26:65:27 | enter M6 | +| Patterns.cs:67:9:71:10 | return ...; | Patterns.cs:67:16:71:9 | ... switch { ... } | +| Patterns.cs:67:16:67:16 | 2 | Patterns.cs:66:5:72:5 | {...} | +| Patterns.cs:67:16:71:9 | ... switch { ... } | Patterns.cs:70:13:70:27 | ... => ... | +| Patterns.cs:69:13:69:17 | [no-match] not ... | Patterns.cs:69:17:69:17 | 2 | +| Patterns.cs:69:17:69:17 | 2 | Patterns.cs:67:16:67:16 | 2 | +| Patterns.cs:70:13:70:13 | 2 | Patterns.cs:69:13:69:17 | [no-match] not ... | +| Patterns.cs:70:13:70:27 | ... => ... | Patterns.cs:70:18:70:27 | "possible" | +| Patterns.cs:70:18:70:27 | "possible" | Patterns.cs:70:13:70:13 | 2 | +| Patterns.cs:74:26:74:27 | exit M7 | Patterns.cs:74:26:74:27 | exit M7 (normal) | +| Patterns.cs:74:26:74:27 | exit M7 (normal) | Patterns.cs:76:9:82:10 | return ...; | +| Patterns.cs:75:5:83:5 | {...} | Patterns.cs:74:26:74:27 | enter M7 | +| Patterns.cs:76:9:82:10 | return ...; | Patterns.cs:76:16:82:9 | ... switch { ... } | +| Patterns.cs:76:16:76:16 | access to parameter i | Patterns.cs:75:5:83:5 | {...} | +| Patterns.cs:76:16:82:9 | ... switch { ... } | Patterns.cs:78:13:78:24 | ... => ... | +| Patterns.cs:76:16:82:9 | ... switch { ... } | Patterns.cs:79:13:79:24 | ... => ... | +| Patterns.cs:76:16:82:9 | ... switch { ... } | Patterns.cs:80:13:80:20 | ... => ... | +| Patterns.cs:76:16:82:9 | ... switch { ... } | Patterns.cs:81:13:81:20 | ... => ... | +| Patterns.cs:78:13:78:15 | > ... | Patterns.cs:78:15:78:15 | 1 | +| Patterns.cs:78:13:78:24 | ... => ... | Patterns.cs:78:20:78:24 | "> 1" | +| Patterns.cs:78:15:78:15 | 1 | Patterns.cs:76:16:76:16 | access to parameter i | +| Patterns.cs:79:13:79:15 | < ... | Patterns.cs:79:15:79:15 | 0 | +| Patterns.cs:79:13:79:24 | ... => ... | Patterns.cs:79:20:79:24 | "< 0" | +| Patterns.cs:80:13:80:20 | ... => ... | Patterns.cs:80:18:80:20 | "1" | +| Patterns.cs:81:13:81:20 | ... => ... | Patterns.cs:81:18:81:20 | "0" | +| Patterns.cs:81:18:81:20 | "0" | Patterns.cs:81:13:81:13 | _ | +| Patterns.cs:85:26:85:27 | exit M8 | Patterns.cs:85:26:85:27 | exit M8 (normal) | +| Patterns.cs:85:26:85:27 | exit M8 (normal) | Patterns.cs:85:39:85:69 | ... ? ... : ... | +| Patterns.cs:85:39:85:39 | access to parameter i | Patterns.cs:85:26:85:27 | enter M8 | +| Patterns.cs:85:39:85:53 | [false] ... is ... | Patterns.cs:85:44:85:53 | [no-match] ... or ... | +| Patterns.cs:85:39:85:53 | [true] ... is ... | Patterns.cs:85:44:85:53 | [match] ... or ... | +| Patterns.cs:85:39:85:69 | ... ? ... : ... | Patterns.cs:85:57:85:63 | "not 2" | +| Patterns.cs:85:39:85:69 | ... ? ... : ... | Patterns.cs:85:67:85:69 | "2" | +| Patterns.cs:85:44:85:44 | 1 | Patterns.cs:85:39:85:39 | access to parameter i | +| Patterns.cs:85:44:85:53 | [match] ... or ... | Patterns.cs:85:49:85:53 | [match] not ... | +| Patterns.cs:85:44:85:53 | [no-match] ... or ... | Patterns.cs:85:49:85:53 | [no-match] not ... | +| Patterns.cs:85:57:85:63 | "not 2" | Patterns.cs:85:39:85:53 | [true] ... is ... | +| Patterns.cs:85:67:85:69 | "2" | Patterns.cs:85:39:85:53 | [false] ... is ... | +| Patterns.cs:87:26:87:27 | exit M9 | Patterns.cs:87:26:87:27 | exit M9 (normal) | +| Patterns.cs:87:26:87:27 | exit M9 (normal) | Patterns.cs:87:39:87:70 | ... ? ... : ... | +| Patterns.cs:87:39:87:39 | access to parameter i | Patterns.cs:87:26:87:27 | enter M9 | +| Patterns.cs:87:39:87:54 | [false] ... is ... | Patterns.cs:87:44:87:54 | [no-match] ... and ... | +| Patterns.cs:87:39:87:54 | [true] ... is ... | Patterns.cs:87:44:87:54 | [match] ... and ... | +| Patterns.cs:87:39:87:70 | ... ? ... : ... | Patterns.cs:87:58:87:60 | "1" | +| Patterns.cs:87:39:87:70 | ... ? ... : ... | Patterns.cs:87:64:87:70 | "not 1" | +| Patterns.cs:87:44:87:44 | 1 | Patterns.cs:87:39:87:39 | access to parameter i | +| Patterns.cs:87:44:87:54 | [match] ... and ... | Patterns.cs:87:50:87:54 | [match] not ... | +| Patterns.cs:87:44:87:54 | [no-match] ... and ... | Patterns.cs:87:50:87:54 | [no-match] not ... | +| Patterns.cs:87:58:87:60 | "1" | Patterns.cs:87:39:87:54 | [true] ... is ... | +| Patterns.cs:87:64:87:70 | "not 1" | Patterns.cs:87:39:87:54 | [false] ... is ... | +| Patterns.cs:93:17:93:19 | exit M10 | Patterns.cs:93:17:93:19 | exit M10 (normal) | +| Patterns.cs:93:17:93:19 | exit M10 (normal) | Patterns.cs:95:13:95:40 | [false] ... is ... | +| Patterns.cs:93:17:93:19 | exit M10 (normal) | Patterns.cs:97:13:97:38 | call to method WriteLine | +| Patterns.cs:94:5:99:5 | {...} | Patterns.cs:93:17:93:19 | enter M10 | +| Patterns.cs:95:9:98:9 | if (...) ... | Patterns.cs:94:5:99:5 | {...} | +| Patterns.cs:95:13:95:16 | this access | Patterns.cs:95:9:98:9 | if (...) ... | +| Patterns.cs:95:13:95:40 | [false] ... is ... | Patterns.cs:95:21:95:40 | [no-match] { ... } | +| Patterns.cs:95:13:95:40 | [true] ... is ... | Patterns.cs:95:21:95:40 | [match] { ... } | +| Patterns.cs:95:21:95:40 | [match] { ... } | Patterns.cs:95:21:95:40 | [match] { ... } | +| Patterns.cs:95:21:95:40 | [match] { ... } | Patterns.cs:95:29:95:38 | [match] ... or ... | +| Patterns.cs:95:21:95:40 | [no-match] { ... } | Patterns.cs:95:21:95:40 | [no-match] { ... } | +| Patterns.cs:95:21:95:40 | [no-match] { ... } | Patterns.cs:95:29:95:38 | [no-match] ... or ... | +| Patterns.cs:95:29:95:31 | access to constant A | Patterns.cs:95:13:95:16 | this access | +| Patterns.cs:96:9:98:9 | {...} | Patterns.cs:95:13:95:40 | [true] ... is ... | +| Patterns.cs:97:13:97:38 | call to method WriteLine | Patterns.cs:97:31:97:37 | "not C" | +| Patterns.cs:97:13:97:39 | ...; | Patterns.cs:96:9:98:9 | {...} | +| Patterns.cs:97:31:97:37 | "not C" | Patterns.cs:97:13:97:39 | ...; | | PostDominance.cs:5:10:5:11 | exit M1 | PostDominance.cs:5:10:5:11 | exit M1 (normal) | | PostDominance.cs:5:10:5:11 | exit M1 (normal) | PostDominance.cs:7:9:7:28 | call to method WriteLine | | PostDominance.cs:6:5:8:5 | {...} | PostDominance.cs:5:10:5:11 | enter M1 | @@ -6926,21 +7324,22 @@ postDominance | PostDominance.cs:11:5:15:5 | {...} | PostDominance.cs:10:10:10:11 | enter M2 | | PostDominance.cs:12:9:13:19 | if (...) ... | PostDominance.cs:11:5:15:5 | {...} | | PostDominance.cs:12:13:12:13 | access to parameter s | PostDominance.cs:12:9:13:19 | if (...) ... | -| PostDominance.cs:12:13:12:21 | ... is ... | PostDominance.cs:12:18:12:21 | null | | PostDominance.cs:12:18:12:21 | null | PostDominance.cs:12:13:12:13 | access to parameter s | +| PostDominance.cs:13:13:13:19 | return ...; | PostDominance.cs:12:13:12:21 | [true] ... is ... | | PostDominance.cs:14:9:14:28 | call to method WriteLine | PostDominance.cs:14:27:14:27 | access to parameter s | +| PostDominance.cs:14:9:14:29 | ...; | PostDominance.cs:12:13:12:21 | [false] ... is ... | | PostDominance.cs:14:27:14:27 | access to parameter s | PostDominance.cs:14:9:14:29 | ...; | | PostDominance.cs:17:10:17:11 | exit M3 (abnormal) | PostDominance.cs:20:13:20:55 | throw ...; | | PostDominance.cs:17:10:17:11 | exit M3 (normal) | PostDominance.cs:21:9:21:28 | call to method WriteLine | | PostDominance.cs:18:5:22:5 | {...} | PostDominance.cs:17:10:17:11 | enter M3 | | PostDominance.cs:19:9:20:55 | if (...) ... | PostDominance.cs:18:5:22:5 | {...} | | PostDominance.cs:19:13:19:13 | access to parameter s | PostDominance.cs:19:9:20:55 | if (...) ... | -| PostDominance.cs:19:13:19:21 | ... is ... | PostDominance.cs:19:18:19:21 | null | +| PostDominance.cs:19:13:19:21 | [false] ... is ... | PostDominance.cs:19:18:19:21 | null | | PostDominance.cs:19:18:19:21 | null | PostDominance.cs:19:13:19:13 | access to parameter s | | PostDominance.cs:20:13:20:55 | throw ...; | PostDominance.cs:20:19:20:54 | object creation of type ArgumentNullException | | PostDominance.cs:20:19:20:54 | object creation of type ArgumentNullException | PostDominance.cs:20:45:20:53 | nameof(...) | | PostDominance.cs:21:9:21:28 | call to method WriteLine | PostDominance.cs:21:27:21:27 | access to parameter s | -| PostDominance.cs:21:9:21:29 | ...; | PostDominance.cs:19:13:19:21 | ... is ... | +| PostDominance.cs:21:9:21:29 | ...; | PostDominance.cs:19:13:19:21 | [false] ... is ... | | PostDominance.cs:21:27:21:27 | access to parameter s | PostDominance.cs:21:9:21:29 | ...; | | Qualifiers.cs:7:16:7:21 | exit Method | Qualifiers.cs:7:16:7:21 | exit Method (normal) | | Qualifiers.cs:7:16:7:21 | exit Method (normal) | Qualifiers.cs:7:28:7:31 | null | @@ -7243,9 +7642,9 @@ postDominance | TypeAccesses.cs:6:13:6:23 | ... as ... | TypeAccesses.cs:6:13:6:13 | access to parameter o | | TypeAccesses.cs:7:9:7:25 | if (...) ... | TypeAccesses.cs:6:9:6:23 | ... = ... | | TypeAccesses.cs:7:13:7:13 | access to parameter o | TypeAccesses.cs:7:9:7:25 | if (...) ... | -| TypeAccesses.cs:7:13:7:22 | ... is ... | TypeAccesses.cs:7:18:7:22 | Int32 j | | TypeAccesses.cs:7:18:7:22 | Int32 j | TypeAccesses.cs:7:13:7:13 | access to parameter o | -| TypeAccesses.cs:8:9:8:28 | ... ...; | TypeAccesses.cs:7:13:7:22 | ... is ... | +| TypeAccesses.cs:7:25:7:25 | ; | TypeAccesses.cs:7:13:7:22 | [true] ... is ... | +| TypeAccesses.cs:8:9:8:28 | ... ...; | TypeAccesses.cs:7:13:7:22 | [false] ... is ... | | TypeAccesses.cs:8:9:8:28 | ... ...; | TypeAccesses.cs:7:25:7:25 | ; | | TypeAccesses.cs:8:13:8:27 | Type t = ... | TypeAccesses.cs:8:17:8:27 | typeof(...) | | TypeAccesses.cs:8:17:8:27 | typeof(...) | TypeAccesses.cs:8:9:8:28 | ... ...; | @@ -9748,125 +10147,110 @@ blockDominance | Conditions.cs:145:27:145:29 | [b (line 143): false] "b" | Conditions.cs:149:13:149:49 | ...; | | Conditions.cs:147:13:147:49 | ...; | Conditions.cs:147:13:147:49 | ...; | | Conditions.cs:149:13:149:49 | ...; | Conditions.cs:149:13:149:49 | ...; | -| ExitMethods.cs:7:10:7:11 | enter M1 | ExitMethods.cs:7:10:7:11 | enter M1 | -| ExitMethods.cs:13:10:13:11 | enter M2 | ExitMethods.cs:13:10:13:11 | enter M2 | -| ExitMethods.cs:19:10:19:11 | enter M3 | ExitMethods.cs:19:10:19:11 | enter M3 | -| ExitMethods.cs:25:10:25:11 | enter M4 | ExitMethods.cs:25:10:25:11 | enter M4 | -| ExitMethods.cs:31:10:31:11 | enter M5 | ExitMethods.cs:31:10:31:11 | enter M5 | -| ExitMethods.cs:37:10:37:11 | enter M6 | ExitMethods.cs:37:10:37:11 | enter M6 | -| ExitMethods.cs:37:10:37:11 | enter M6 | ExitMethods.cs:37:10:37:11 | exit M6 (normal) | -| ExitMethods.cs:37:10:37:11 | enter M6 | ExitMethods.cs:43:9:46:9 | [exception: ArgumentException] catch (...) {...} | -| ExitMethods.cs:37:10:37:11 | enter M6 | ExitMethods.cs:43:9:46:9 | [exception: Exception] catch (...) {...} | -| ExitMethods.cs:37:10:37:11 | enter M6 | ExitMethods.cs:44:9:46:9 | {...} | -| ExitMethods.cs:37:10:37:11 | enter M6 | ExitMethods.cs:47:9:50:9 | [exception: Exception] catch (...) {...} | -| ExitMethods.cs:37:10:37:11 | enter M6 | ExitMethods.cs:48:9:50:9 | {...} | -| ExitMethods.cs:37:10:37:11 | exit M6 (normal) | ExitMethods.cs:37:10:37:11 | exit M6 (normal) | -| ExitMethods.cs:43:9:46:9 | [exception: ArgumentException] catch (...) {...} | ExitMethods.cs:43:9:46:9 | [exception: ArgumentException] catch (...) {...} | -| ExitMethods.cs:43:9:46:9 | [exception: Exception] catch (...) {...} | ExitMethods.cs:43:9:46:9 | [exception: Exception] catch (...) {...} | -| ExitMethods.cs:43:9:46:9 | [exception: Exception] catch (...) {...} | ExitMethods.cs:47:9:50:9 | [exception: Exception] catch (...) {...} | -| ExitMethods.cs:43:9:46:9 | [exception: Exception] catch (...) {...} | ExitMethods.cs:48:9:50:9 | {...} | -| ExitMethods.cs:44:9:46:9 | {...} | ExitMethods.cs:44:9:46:9 | {...} | -| ExitMethods.cs:47:9:50:9 | [exception: Exception] catch (...) {...} | ExitMethods.cs:47:9:50:9 | [exception: Exception] catch (...) {...} | -| ExitMethods.cs:47:9:50:9 | [exception: Exception] catch (...) {...} | ExitMethods.cs:48:9:50:9 | {...} | -| ExitMethods.cs:48:9:50:9 | {...} | ExitMethods.cs:48:9:50:9 | {...} | -| ExitMethods.cs:53:10:53:11 | enter M7 | ExitMethods.cs:53:10:53:11 | enter M7 | -| ExitMethods.cs:59:10:59:11 | enter M8 | ExitMethods.cs:59:10:59:11 | enter M8 | -| ExitMethods.cs:65:17:65:26 | enter ErrorMaybe | ExitMethods.cs:65:17:65:26 | enter ErrorMaybe | -| ExitMethods.cs:65:17:65:26 | enter ErrorMaybe | ExitMethods.cs:65:17:65:26 | exit ErrorMaybe | -| ExitMethods.cs:65:17:65:26 | enter ErrorMaybe | ExitMethods.cs:65:17:65:26 | exit ErrorMaybe (normal) | -| ExitMethods.cs:65:17:65:26 | enter ErrorMaybe | ExitMethods.cs:68:19:68:33 | object creation of type Exception | -| ExitMethods.cs:65:17:65:26 | exit ErrorMaybe | ExitMethods.cs:65:17:65:26 | exit ErrorMaybe | -| ExitMethods.cs:65:17:65:26 | exit ErrorMaybe (normal) | ExitMethods.cs:65:17:65:26 | exit ErrorMaybe (normal) | -| ExitMethods.cs:68:19:68:33 | object creation of type Exception | ExitMethods.cs:68:19:68:33 | object creation of type Exception | -| ExitMethods.cs:71:17:71:27 | enter ErrorAlways | ExitMethods.cs:71:17:71:27 | enter ErrorAlways | -| ExitMethods.cs:71:17:71:27 | enter ErrorAlways | ExitMethods.cs:71:17:71:27 | exit ErrorAlways (abnormal) | -| ExitMethods.cs:71:17:71:27 | enter ErrorAlways | ExitMethods.cs:74:19:74:33 | object creation of type Exception | -| ExitMethods.cs:71:17:71:27 | enter ErrorAlways | ExitMethods.cs:76:41:76:43 | "b" | -| ExitMethods.cs:71:17:71:27 | exit ErrorAlways (abnormal) | ExitMethods.cs:71:17:71:27 | exit ErrorAlways (abnormal) | -| ExitMethods.cs:74:19:74:33 | object creation of type Exception | ExitMethods.cs:74:19:74:33 | object creation of type Exception | -| ExitMethods.cs:76:41:76:43 | "b" | ExitMethods.cs:76:41:76:43 | "b" | -| ExitMethods.cs:79:17:79:28 | enter ErrorAlways2 | ExitMethods.cs:79:17:79:28 | enter ErrorAlways2 | -| ExitMethods.cs:84:17:84:28 | enter ErrorAlways3 | ExitMethods.cs:84:17:84:28 | enter ErrorAlways3 | -| ExitMethods.cs:86:10:86:13 | enter Exit | ExitMethods.cs:86:10:86:13 | enter Exit | -| ExitMethods.cs:91:10:91:18 | enter ExitInTry | ExitMethods.cs:91:10:91:18 | enter ExitInTry | -| ExitMethods.cs:104:10:104:24 | enter ApplicationExit | ExitMethods.cs:104:10:104:24 | enter ApplicationExit | -| ExitMethods.cs:109:13:109:21 | enter ThrowExpr | ExitMethods.cs:109:13:109:21 | enter ThrowExpr | -| ExitMethods.cs:109:13:109:21 | enter ThrowExpr | ExitMethods.cs:109:13:109:21 | exit ThrowExpr | -| ExitMethods.cs:109:13:109:21 | enter ThrowExpr | ExitMethods.cs:111:29:111:29 | 1 | -| ExitMethods.cs:109:13:109:21 | enter ThrowExpr | ExitMethods.cs:111:69:111:75 | "input" | -| ExitMethods.cs:109:13:109:21 | exit ThrowExpr | ExitMethods.cs:109:13:109:21 | exit ThrowExpr | -| ExitMethods.cs:111:29:111:29 | 1 | ExitMethods.cs:111:29:111:29 | 1 | -| ExitMethods.cs:111:69:111:75 | "input" | ExitMethods.cs:111:69:111:75 | "input" | -| ExitMethods.cs:114:16:114:34 | enter ExtensionMethodCall | ExitMethods.cs:114:16:114:34 | enter ExtensionMethodCall | -| ExitMethods.cs:114:16:114:34 | enter ExtensionMethodCall | ExitMethods.cs:116:16:116:38 | ... ? ... : ... | -| ExitMethods.cs:114:16:114:34 | enter ExtensionMethodCall | ExitMethods.cs:116:34:116:34 | 0 | -| ExitMethods.cs:114:16:114:34 | enter ExtensionMethodCall | ExitMethods.cs:116:38:116:38 | 1 | -| ExitMethods.cs:116:16:116:38 | ... ? ... : ... | ExitMethods.cs:116:16:116:38 | ... ? ... : ... | -| ExitMethods.cs:116:34:116:34 | 0 | ExitMethods.cs:116:34:116:34 | 0 | -| ExitMethods.cs:116:38:116:38 | 1 | ExitMethods.cs:116:38:116:38 | 1 | -| ExitMethods.cs:119:17:119:32 | enter FailingAssertion | ExitMethods.cs:119:17:119:32 | enter FailingAssertion | -| ExitMethods.cs:119:17:119:32 | enter FailingAssertion | ExitMethods.cs:121:9:121:28 | [assertion failure] call to method IsTrue | -| ExitMethods.cs:121:9:121:28 | [assertion failure] call to method IsTrue | ExitMethods.cs:121:9:121:28 | [assertion failure] call to method IsTrue | -| ExitMethods.cs:125:17:125:33 | enter FailingAssertion2 | ExitMethods.cs:125:17:125:33 | enter FailingAssertion2 | -| ExitMethods.cs:131:10:131:20 | enter AssertFalse | ExitMethods.cs:131:10:131:20 | enter AssertFalse | -| ExitMethods.cs:131:10:131:20 | enter AssertFalse | ExitMethods.cs:131:10:131:20 | exit AssertFalse | -| ExitMethods.cs:131:10:131:20 | enter AssertFalse | ExitMethods.cs:131:33:131:49 | [assertion failure] call to method IsFalse | -| ExitMethods.cs:131:10:131:20 | enter AssertFalse | ExitMethods.cs:131:33:131:49 | [assertion success] call to method IsFalse | -| ExitMethods.cs:131:10:131:20 | exit AssertFalse | ExitMethods.cs:131:10:131:20 | exit AssertFalse | -| ExitMethods.cs:131:33:131:49 | [assertion failure] call to method IsFalse | ExitMethods.cs:131:33:131:49 | [assertion failure] call to method IsFalse | -| ExitMethods.cs:131:33:131:49 | [assertion success] call to method IsFalse | ExitMethods.cs:131:33:131:49 | [assertion success] call to method IsFalse | -| ExitMethods.cs:133:17:133:33 | enter FailingAssertion3 | ExitMethods.cs:133:17:133:33 | enter FailingAssertion3 | -| ExitMethods.cs:133:17:133:33 | enter FailingAssertion3 | ExitMethods.cs:135:9:135:25 | [assertion failure] call to method AssertFalse | -| ExitMethods.cs:135:9:135:25 | [assertion failure] call to method AssertFalse | ExitMethods.cs:135:9:135:25 | [assertion failure] call to method AssertFalse | +| ExitMethods.cs:8:10:8:11 | enter M1 | ExitMethods.cs:8:10:8:11 | enter M1 | +| ExitMethods.cs:14:10:14:11 | enter M2 | ExitMethods.cs:14:10:14:11 | enter M2 | +| ExitMethods.cs:20:10:20:11 | enter M3 | ExitMethods.cs:20:10:20:11 | enter M3 | +| ExitMethods.cs:26:10:26:11 | enter M4 | ExitMethods.cs:26:10:26:11 | enter M4 | +| ExitMethods.cs:32:10:32:11 | enter M5 | ExitMethods.cs:32:10:32:11 | enter M5 | +| ExitMethods.cs:38:10:38:11 | enter M6 | ExitMethods.cs:38:10:38:11 | enter M6 | +| ExitMethods.cs:38:10:38:11 | enter M6 | ExitMethods.cs:38:10:38:11 | exit M6 (normal) | +| ExitMethods.cs:38:10:38:11 | enter M6 | ExitMethods.cs:44:9:47:9 | [exception: ArgumentException] catch (...) {...} | +| ExitMethods.cs:38:10:38:11 | enter M6 | ExitMethods.cs:44:9:47:9 | [exception: Exception] catch (...) {...} | +| ExitMethods.cs:38:10:38:11 | enter M6 | ExitMethods.cs:45:9:47:9 | {...} | +| ExitMethods.cs:38:10:38:11 | enter M6 | ExitMethods.cs:48:9:51:9 | [exception: Exception] catch (...) {...} | +| ExitMethods.cs:38:10:38:11 | enter M6 | ExitMethods.cs:49:9:51:9 | {...} | +| ExitMethods.cs:38:10:38:11 | exit M6 (normal) | ExitMethods.cs:38:10:38:11 | exit M6 (normal) | +| ExitMethods.cs:44:9:47:9 | [exception: ArgumentException] catch (...) {...} | ExitMethods.cs:44:9:47:9 | [exception: ArgumentException] catch (...) {...} | +| ExitMethods.cs:44:9:47:9 | [exception: Exception] catch (...) {...} | ExitMethods.cs:44:9:47:9 | [exception: Exception] catch (...) {...} | +| ExitMethods.cs:44:9:47:9 | [exception: Exception] catch (...) {...} | ExitMethods.cs:48:9:51:9 | [exception: Exception] catch (...) {...} | +| ExitMethods.cs:44:9:47:9 | [exception: Exception] catch (...) {...} | ExitMethods.cs:49:9:51:9 | {...} | +| ExitMethods.cs:45:9:47:9 | {...} | ExitMethods.cs:45:9:47:9 | {...} | +| ExitMethods.cs:48:9:51:9 | [exception: Exception] catch (...) {...} | ExitMethods.cs:48:9:51:9 | [exception: Exception] catch (...) {...} | +| ExitMethods.cs:48:9:51:9 | [exception: Exception] catch (...) {...} | ExitMethods.cs:49:9:51:9 | {...} | +| ExitMethods.cs:49:9:51:9 | {...} | ExitMethods.cs:49:9:51:9 | {...} | +| ExitMethods.cs:54:10:54:11 | enter M7 | ExitMethods.cs:54:10:54:11 | enter M7 | +| ExitMethods.cs:60:10:60:11 | enter M8 | ExitMethods.cs:60:10:60:11 | enter M8 | +| ExitMethods.cs:66:17:66:26 | enter ErrorMaybe | ExitMethods.cs:66:17:66:26 | enter ErrorMaybe | +| ExitMethods.cs:66:17:66:26 | enter ErrorMaybe | ExitMethods.cs:66:17:66:26 | exit ErrorMaybe | +| ExitMethods.cs:66:17:66:26 | enter ErrorMaybe | ExitMethods.cs:66:17:66:26 | exit ErrorMaybe (normal) | +| ExitMethods.cs:66:17:66:26 | enter ErrorMaybe | ExitMethods.cs:69:19:69:33 | object creation of type Exception | +| ExitMethods.cs:66:17:66:26 | exit ErrorMaybe | ExitMethods.cs:66:17:66:26 | exit ErrorMaybe | +| ExitMethods.cs:66:17:66:26 | exit ErrorMaybe (normal) | ExitMethods.cs:66:17:66:26 | exit ErrorMaybe (normal) | +| ExitMethods.cs:69:19:69:33 | object creation of type Exception | ExitMethods.cs:69:19:69:33 | object creation of type Exception | +| ExitMethods.cs:72:17:72:27 | enter ErrorAlways | ExitMethods.cs:72:17:72:27 | enter ErrorAlways | +| ExitMethods.cs:72:17:72:27 | enter ErrorAlways | ExitMethods.cs:72:17:72:27 | exit ErrorAlways (abnormal) | +| ExitMethods.cs:72:17:72:27 | enter ErrorAlways | ExitMethods.cs:75:19:75:33 | object creation of type Exception | +| ExitMethods.cs:72:17:72:27 | enter ErrorAlways | ExitMethods.cs:77:41:77:43 | "b" | +| ExitMethods.cs:72:17:72:27 | exit ErrorAlways (abnormal) | ExitMethods.cs:72:17:72:27 | exit ErrorAlways (abnormal) | +| ExitMethods.cs:75:19:75:33 | object creation of type Exception | ExitMethods.cs:75:19:75:33 | object creation of type Exception | +| ExitMethods.cs:77:41:77:43 | "b" | ExitMethods.cs:77:41:77:43 | "b" | +| ExitMethods.cs:80:17:80:28 | enter ErrorAlways2 | ExitMethods.cs:80:17:80:28 | enter ErrorAlways2 | +| ExitMethods.cs:85:17:85:28 | enter ErrorAlways3 | ExitMethods.cs:85:17:85:28 | enter ErrorAlways3 | +| ExitMethods.cs:87:10:87:13 | enter Exit | ExitMethods.cs:87:10:87:13 | enter Exit | +| ExitMethods.cs:92:10:92:18 | enter ExitInTry | ExitMethods.cs:92:10:92:18 | enter ExitInTry | +| ExitMethods.cs:105:10:105:24 | enter ApplicationExit | ExitMethods.cs:105:10:105:24 | enter ApplicationExit | +| ExitMethods.cs:110:13:110:21 | enter ThrowExpr | ExitMethods.cs:110:13:110:21 | enter ThrowExpr | +| ExitMethods.cs:110:13:110:21 | enter ThrowExpr | ExitMethods.cs:110:13:110:21 | exit ThrowExpr | +| ExitMethods.cs:110:13:110:21 | enter ThrowExpr | ExitMethods.cs:112:29:112:29 | 1 | +| ExitMethods.cs:110:13:110:21 | enter ThrowExpr | ExitMethods.cs:112:69:112:75 | "input" | +| ExitMethods.cs:110:13:110:21 | exit ThrowExpr | ExitMethods.cs:110:13:110:21 | exit ThrowExpr | +| ExitMethods.cs:112:29:112:29 | 1 | ExitMethods.cs:112:29:112:29 | 1 | +| ExitMethods.cs:112:69:112:75 | "input" | ExitMethods.cs:112:69:112:75 | "input" | +| ExitMethods.cs:115:16:115:34 | enter ExtensionMethodCall | ExitMethods.cs:115:16:115:34 | enter ExtensionMethodCall | +| ExitMethods.cs:115:16:115:34 | enter ExtensionMethodCall | ExitMethods.cs:117:16:117:38 | ... ? ... : ... | +| ExitMethods.cs:115:16:115:34 | enter ExtensionMethodCall | ExitMethods.cs:117:34:117:34 | 0 | +| ExitMethods.cs:115:16:115:34 | enter ExtensionMethodCall | ExitMethods.cs:117:38:117:38 | 1 | +| ExitMethods.cs:117:16:117:38 | ... ? ... : ... | ExitMethods.cs:117:16:117:38 | ... ? ... : ... | +| ExitMethods.cs:117:34:117:34 | 0 | ExitMethods.cs:117:34:117:34 | 0 | +| ExitMethods.cs:117:38:117:38 | 1 | ExitMethods.cs:117:38:117:38 | 1 | +| ExitMethods.cs:120:17:120:32 | enter FailingAssertion | ExitMethods.cs:120:17:120:32 | enter FailingAssertion | +| ExitMethods.cs:120:17:120:32 | enter FailingAssertion | ExitMethods.cs:122:9:122:28 | [assertion failure] call to method IsTrue | +| ExitMethods.cs:122:9:122:28 | [assertion failure] call to method IsTrue | ExitMethods.cs:122:9:122:28 | [assertion failure] call to method IsTrue | +| ExitMethods.cs:126:17:126:33 | enter FailingAssertion2 | ExitMethods.cs:126:17:126:33 | enter FailingAssertion2 | +| ExitMethods.cs:132:10:132:20 | enter AssertFalse | ExitMethods.cs:132:10:132:20 | enter AssertFalse | +| ExitMethods.cs:132:10:132:20 | enter AssertFalse | ExitMethods.cs:132:10:132:20 | exit AssertFalse | +| ExitMethods.cs:132:10:132:20 | enter AssertFalse | ExitMethods.cs:132:33:132:49 | [assertion failure] call to method IsFalse | +| ExitMethods.cs:132:10:132:20 | enter AssertFalse | ExitMethods.cs:132:33:132:49 | [assertion success] call to method IsFalse | +| ExitMethods.cs:132:10:132:20 | exit AssertFalse | ExitMethods.cs:132:10:132:20 | exit AssertFalse | +| ExitMethods.cs:132:33:132:49 | [assertion failure] call to method IsFalse | ExitMethods.cs:132:33:132:49 | [assertion failure] call to method IsFalse | +| ExitMethods.cs:132:33:132:49 | [assertion success] call to method IsFalse | ExitMethods.cs:132:33:132:49 | [assertion success] call to method IsFalse | +| ExitMethods.cs:134:17:134:33 | enter FailingAssertion3 | ExitMethods.cs:134:17:134:33 | enter FailingAssertion3 | +| ExitMethods.cs:134:17:134:33 | enter FailingAssertion3 | ExitMethods.cs:136:9:136:25 | [assertion failure] call to method AssertFalse | +| ExitMethods.cs:136:9:136:25 | [assertion failure] call to method AssertFalse | ExitMethods.cs:136:9:136:25 | [assertion failure] call to method AssertFalse | +| ExitMethods.cs:140:17:140:42 | enter ExceptionDispatchInfoThrow | ExitMethods.cs:140:17:140:42 | enter ExceptionDispatchInfoThrow | +| ExitMethods.cs:140:17:140:42 | enter ExceptionDispatchInfoThrow | ExitMethods.cs:140:17:140:42 | exit ExceptionDispatchInfoThrow (abnormal) | +| ExitMethods.cs:140:17:140:42 | enter ExceptionDispatchInfoThrow | ExitMethods.cs:143:13:143:43 | ...; | +| ExitMethods.cs:140:17:140:42 | enter ExceptionDispatchInfoThrow | ExitMethods.cs:145:13:145:53 | ...; | +| ExitMethods.cs:140:17:140:42 | exit ExceptionDispatchInfoThrow (abnormal) | ExitMethods.cs:140:17:140:42 | exit ExceptionDispatchInfoThrow (abnormal) | +| ExitMethods.cs:143:13:143:43 | ...; | ExitMethods.cs:143:13:143:43 | ...; | +| ExitMethods.cs:145:13:145:53 | ...; | ExitMethods.cs:145:13:145:53 | ...; | | Extensions.cs:5:23:5:29 | enter ToInt32 | Extensions.cs:5:23:5:29 | enter ToInt32 | | Extensions.cs:10:24:10:29 | enter ToBool | Extensions.cs:10:24:10:29 | enter ToBool | | Extensions.cs:15:23:15:33 | enter CallToInt32 | Extensions.cs:15:23:15:33 | enter CallToInt32 | | Extensions.cs:20:17:20:20 | enter Main | Extensions.cs:20:17:20:20 | enter Main | | Finally.cs:7:10:7:11 | enter M1 | Finally.cs:7:10:7:11 | enter M1 | | Finally.cs:7:10:7:11 | enter M1 | Finally.cs:7:10:7:11 | exit M1 | -| Finally.cs:7:10:7:11 | enter M1 | Finally.cs:7:10:7:11 | exit M1 (abnormal) | -| Finally.cs:7:10:7:11 | enter M1 | Finally.cs:11:13:11:37 | call to method WriteLine | | Finally.cs:7:10:7:11 | enter M1 | Finally.cs:14:9:16:9 | [finally: exception(Exception)] {...} | -| Finally.cs:7:10:7:11 | enter M1 | Finally.cs:14:9:16:9 | [finally: exception(OutOfMemoryException)] {...} | | Finally.cs:7:10:7:11 | enter M1 | Finally.cs:14:9:16:9 | {...} | | Finally.cs:7:10:7:11 | exit M1 | Finally.cs:7:10:7:11 | exit M1 | -| Finally.cs:7:10:7:11 | exit M1 (abnormal) | Finally.cs:7:10:7:11 | exit M1 (abnormal) | -| Finally.cs:11:13:11:37 | call to method WriteLine | Finally.cs:11:13:11:37 | call to method WriteLine | -| Finally.cs:11:13:11:37 | call to method WriteLine | Finally.cs:14:9:16:9 | [finally: exception(Exception)] {...} | -| Finally.cs:11:13:11:37 | call to method WriteLine | Finally.cs:14:9:16:9 | {...} | | Finally.cs:14:9:16:9 | [finally: exception(Exception)] {...} | Finally.cs:14:9:16:9 | [finally: exception(Exception)] {...} | -| Finally.cs:14:9:16:9 | [finally: exception(OutOfMemoryException)] {...} | Finally.cs:14:9:16:9 | [finally: exception(OutOfMemoryException)] {...} | | Finally.cs:14:9:16:9 | {...} | Finally.cs:14:9:16:9 | {...} | | Finally.cs:19:10:19:11 | enter M2 | Finally.cs:19:10:19:11 | enter M2 | | Finally.cs:19:10:19:11 | enter M2 | Finally.cs:19:10:19:11 | exit M2 | | Finally.cs:19:10:19:11 | enter M2 | Finally.cs:19:10:19:11 | exit M2 (abnormal) | | Finally.cs:19:10:19:11 | enter M2 | Finally.cs:19:10:19:11 | exit M2 (normal) | -| Finally.cs:19:10:19:11 | enter M2 | Finally.cs:23:13:23:37 | call to method WriteLine | | Finally.cs:19:10:19:11 | enter M2 | Finally.cs:24:13:24:19 | return ...; | | Finally.cs:19:10:19:11 | enter M2 | Finally.cs:26:9:29:9 | [exception: Exception] catch (...) {...} | -| Finally.cs:19:10:19:11 | enter M2 | Finally.cs:26:9:29:9 | [exception: OutOfMemoryException] catch (...) {...} | | Finally.cs:19:10:19:11 | enter M2 | Finally.cs:26:38:26:39 | [exception: Exception] IOException ex | | Finally.cs:19:10:19:11 | enter M2 | Finally.cs:27:9:29:9 | {...} | | Finally.cs:19:10:19:11 | enter M2 | Finally.cs:30:9:40:9 | [exception: Exception] catch (...) {...} | -| Finally.cs:19:10:19:11 | enter M2 | Finally.cs:30:9:40:9 | [exception: OutOfMemoryException] catch (...) {...} | | Finally.cs:19:10:19:11 | enter M2 | Finally.cs:30:41:30:42 | [exception: Exception] ArgumentException ex | | Finally.cs:19:10:19:11 | enter M2 | Finally.cs:34:27:34:32 | throw ...; | | Finally.cs:19:10:19:11 | enter M2 | Finally.cs:41:9:43:9 | [exception: Exception] catch (...) {...} | -| Finally.cs:19:10:19:11 | enter M2 | Finally.cs:41:9:43:9 | [exception: OutOfMemoryException] catch (...) {...} | | Finally.cs:19:10:19:11 | enter M2 | Finally.cs:42:9:43:9 | {...} | | Finally.cs:19:10:19:11 | exit M2 | Finally.cs:19:10:19:11 | exit M2 | | Finally.cs:19:10:19:11 | exit M2 (abnormal) | Finally.cs:19:10:19:11 | exit M2 (abnormal) | | Finally.cs:19:10:19:11 | exit M2 (normal) | Finally.cs:19:10:19:11 | exit M2 (normal) | -| Finally.cs:23:13:23:37 | call to method WriteLine | Finally.cs:19:10:19:11 | exit M2 (abnormal) | -| Finally.cs:23:13:23:37 | call to method WriteLine | Finally.cs:23:13:23:37 | call to method WriteLine | -| Finally.cs:23:13:23:37 | call to method WriteLine | Finally.cs:24:13:24:19 | return ...; | -| Finally.cs:23:13:23:37 | call to method WriteLine | Finally.cs:26:9:29:9 | [exception: Exception] catch (...) {...} | -| Finally.cs:23:13:23:37 | call to method WriteLine | Finally.cs:26:38:26:39 | [exception: Exception] IOException ex | -| Finally.cs:23:13:23:37 | call to method WriteLine | Finally.cs:27:9:29:9 | {...} | -| Finally.cs:23:13:23:37 | call to method WriteLine | Finally.cs:30:9:40:9 | [exception: Exception] catch (...) {...} | -| Finally.cs:23:13:23:37 | call to method WriteLine | Finally.cs:30:41:30:42 | [exception: Exception] ArgumentException ex | -| Finally.cs:23:13:23:37 | call to method WriteLine | Finally.cs:34:27:34:32 | throw ...; | -| Finally.cs:23:13:23:37 | call to method WriteLine | Finally.cs:41:9:43:9 | [exception: Exception] catch (...) {...} | | Finally.cs:24:13:24:19 | return ...; | Finally.cs:24:13:24:19 | return ...; | | Finally.cs:26:9:29:9 | [exception: Exception] catch (...) {...} | Finally.cs:19:10:19:11 | exit M2 (abnormal) | | Finally.cs:26:9:29:9 | [exception: Exception] catch (...) {...} | Finally.cs:26:9:29:9 | [exception: Exception] catch (...) {...} | @@ -9876,9 +10260,7 @@ blockDominance | Finally.cs:26:9:29:9 | [exception: Exception] catch (...) {...} | Finally.cs:30:41:30:42 | [exception: Exception] ArgumentException ex | | Finally.cs:26:9:29:9 | [exception: Exception] catch (...) {...} | Finally.cs:34:27:34:32 | throw ...; | | Finally.cs:26:9:29:9 | [exception: Exception] catch (...) {...} | Finally.cs:41:9:43:9 | [exception: Exception] catch (...) {...} | -| Finally.cs:26:9:29:9 | [exception: OutOfMemoryException] catch (...) {...} | Finally.cs:26:9:29:9 | [exception: OutOfMemoryException] catch (...) {...} | -| Finally.cs:26:9:29:9 | [exception: OutOfMemoryException] catch (...) {...} | Finally.cs:30:9:40:9 | [exception: OutOfMemoryException] catch (...) {...} | -| Finally.cs:26:9:29:9 | [exception: OutOfMemoryException] catch (...) {...} | Finally.cs:41:9:43:9 | [exception: OutOfMemoryException] catch (...) {...} | +| Finally.cs:26:9:29:9 | [exception: Exception] catch (...) {...} | Finally.cs:42:9:43:9 | {...} | | Finally.cs:26:38:26:39 | [exception: Exception] IOException ex | Finally.cs:26:38:26:39 | [exception: Exception] IOException ex | | Finally.cs:26:38:26:39 | [exception: Exception] IOException ex | Finally.cs:27:9:29:9 | {...} | | Finally.cs:27:9:29:9 | {...} | Finally.cs:27:9:29:9 | {...} | @@ -9886,69 +10268,49 @@ blockDominance | Finally.cs:30:9:40:9 | [exception: Exception] catch (...) {...} | Finally.cs:30:41:30:42 | [exception: Exception] ArgumentException ex | | Finally.cs:30:9:40:9 | [exception: Exception] catch (...) {...} | Finally.cs:34:27:34:32 | throw ...; | | Finally.cs:30:9:40:9 | [exception: Exception] catch (...) {...} | Finally.cs:41:9:43:9 | [exception: Exception] catch (...) {...} | -| Finally.cs:30:9:40:9 | [exception: OutOfMemoryException] catch (...) {...} | Finally.cs:30:9:40:9 | [exception: OutOfMemoryException] catch (...) {...} | -| Finally.cs:30:9:40:9 | [exception: OutOfMemoryException] catch (...) {...} | Finally.cs:41:9:43:9 | [exception: OutOfMemoryException] catch (...) {...} | +| Finally.cs:30:9:40:9 | [exception: Exception] catch (...) {...} | Finally.cs:42:9:43:9 | {...} | | Finally.cs:30:41:30:42 | [exception: Exception] ArgumentException ex | Finally.cs:30:41:30:42 | [exception: Exception] ArgumentException ex | | Finally.cs:30:41:30:42 | [exception: Exception] ArgumentException ex | Finally.cs:34:27:34:32 | throw ...; | | Finally.cs:34:27:34:32 | throw ...; | Finally.cs:34:27:34:32 | throw ...; | | Finally.cs:41:9:43:9 | [exception: Exception] catch (...) {...} | Finally.cs:41:9:43:9 | [exception: Exception] catch (...) {...} | -| Finally.cs:41:9:43:9 | [exception: OutOfMemoryException] catch (...) {...} | Finally.cs:41:9:43:9 | [exception: OutOfMemoryException] catch (...) {...} | +| Finally.cs:41:9:43:9 | [exception: Exception] catch (...) {...} | Finally.cs:42:9:43:9 | {...} | | Finally.cs:42:9:43:9 | {...} | Finally.cs:42:9:43:9 | {...} | | Finally.cs:54:10:54:11 | enter M3 | Finally.cs:54:10:54:11 | enter M3 | | Finally.cs:54:10:54:11 | enter M3 | Finally.cs:54:10:54:11 | exit M3 | | Finally.cs:54:10:54:11 | enter M3 | Finally.cs:54:10:54:11 | exit M3 (abnormal) | | Finally.cs:54:10:54:11 | enter M3 | Finally.cs:54:10:54:11 | exit M3 (normal) | -| Finally.cs:54:10:54:11 | enter M3 | Finally.cs:58:13:58:37 | call to method WriteLine | | Finally.cs:54:10:54:11 | enter M3 | Finally.cs:59:13:59:19 | return ...; | | Finally.cs:54:10:54:11 | enter M3 | Finally.cs:61:9:64:9 | [exception: Exception] catch (...) {...} | -| Finally.cs:54:10:54:11 | enter M3 | Finally.cs:61:9:64:9 | [exception: OutOfMemoryException] catch (...) {...} | | Finally.cs:54:10:54:11 | enter M3 | Finally.cs:61:38:61:39 | [exception: Exception] IOException ex | | Finally.cs:54:10:54:11 | enter M3 | Finally.cs:62:9:64:9 | {...} | | Finally.cs:54:10:54:11 | enter M3 | Finally.cs:65:9:67:9 | [exception: Exception] catch (...) {...} | -| Finally.cs:54:10:54:11 | enter M3 | Finally.cs:65:9:67:9 | [exception: OutOfMemoryException] catch (...) {...} | | Finally.cs:54:10:54:11 | enter M3 | Finally.cs:65:26:65:26 | [exception: Exception] Exception e | -| Finally.cs:54:10:54:11 | enter M3 | Finally.cs:65:26:65:26 | [exception: OutOfMemoryException] Exception e | | Finally.cs:54:10:54:11 | enter M3 | Finally.cs:66:9:67:9 | {...} | | Finally.cs:54:10:54:11 | enter M3 | Finally.cs:69:9:71:9 | [finally: exception(Exception)] {...} | -| Finally.cs:54:10:54:11 | enter M3 | Finally.cs:69:9:71:9 | [finally: exception(OutOfMemoryException)] {...} | | Finally.cs:54:10:54:11 | exit M3 | Finally.cs:54:10:54:11 | exit M3 | | Finally.cs:54:10:54:11 | exit M3 (abnormal) | Finally.cs:54:10:54:11 | exit M3 (abnormal) | | Finally.cs:54:10:54:11 | exit M3 (normal) | Finally.cs:54:10:54:11 | exit M3 (normal) | -| Finally.cs:58:13:58:37 | call to method WriteLine | Finally.cs:58:13:58:37 | call to method WriteLine | -| Finally.cs:58:13:58:37 | call to method WriteLine | Finally.cs:59:13:59:19 | return ...; | -| Finally.cs:58:13:58:37 | call to method WriteLine | Finally.cs:61:9:64:9 | [exception: Exception] catch (...) {...} | -| Finally.cs:58:13:58:37 | call to method WriteLine | Finally.cs:61:38:61:39 | [exception: Exception] IOException ex | -| Finally.cs:58:13:58:37 | call to method WriteLine | Finally.cs:62:9:64:9 | {...} | -| Finally.cs:58:13:58:37 | call to method WriteLine | Finally.cs:65:9:67:9 | [exception: Exception] catch (...) {...} | -| Finally.cs:58:13:58:37 | call to method WriteLine | Finally.cs:65:26:65:26 | [exception: Exception] Exception e | -| Finally.cs:58:13:58:37 | call to method WriteLine | Finally.cs:69:9:71:9 | [finally: exception(Exception)] {...} | | Finally.cs:59:13:59:19 | return ...; | Finally.cs:59:13:59:19 | return ...; | +| Finally.cs:61:9:64:9 | [exception: Exception] catch (...) {...} | Finally.cs:54:10:54:11 | exit M3 (abnormal) | | Finally.cs:61:9:64:9 | [exception: Exception] catch (...) {...} | Finally.cs:61:9:64:9 | [exception: Exception] catch (...) {...} | | Finally.cs:61:9:64:9 | [exception: Exception] catch (...) {...} | Finally.cs:61:38:61:39 | [exception: Exception] IOException ex | | Finally.cs:61:9:64:9 | [exception: Exception] catch (...) {...} | Finally.cs:62:9:64:9 | {...} | | Finally.cs:61:9:64:9 | [exception: Exception] catch (...) {...} | Finally.cs:65:9:67:9 | [exception: Exception] catch (...) {...} | | Finally.cs:61:9:64:9 | [exception: Exception] catch (...) {...} | Finally.cs:65:26:65:26 | [exception: Exception] Exception e | +| Finally.cs:61:9:64:9 | [exception: Exception] catch (...) {...} | Finally.cs:66:9:67:9 | {...} | | Finally.cs:61:9:64:9 | [exception: Exception] catch (...) {...} | Finally.cs:69:9:71:9 | [finally: exception(Exception)] {...} | -| Finally.cs:61:9:64:9 | [exception: OutOfMemoryException] catch (...) {...} | Finally.cs:61:9:64:9 | [exception: OutOfMemoryException] catch (...) {...} | -| Finally.cs:61:9:64:9 | [exception: OutOfMemoryException] catch (...) {...} | Finally.cs:65:9:67:9 | [exception: OutOfMemoryException] catch (...) {...} | -| Finally.cs:61:9:64:9 | [exception: OutOfMemoryException] catch (...) {...} | Finally.cs:65:26:65:26 | [exception: OutOfMemoryException] Exception e | -| Finally.cs:61:9:64:9 | [exception: OutOfMemoryException] catch (...) {...} | Finally.cs:69:9:71:9 | [finally: exception(OutOfMemoryException)] {...} | | Finally.cs:61:38:61:39 | [exception: Exception] IOException ex | Finally.cs:61:38:61:39 | [exception: Exception] IOException ex | | Finally.cs:61:38:61:39 | [exception: Exception] IOException ex | Finally.cs:62:9:64:9 | {...} | | Finally.cs:62:9:64:9 | {...} | Finally.cs:62:9:64:9 | {...} | | Finally.cs:65:9:67:9 | [exception: Exception] catch (...) {...} | Finally.cs:65:9:67:9 | [exception: Exception] catch (...) {...} | | Finally.cs:65:9:67:9 | [exception: Exception] catch (...) {...} | Finally.cs:65:26:65:26 | [exception: Exception] Exception e | +| Finally.cs:65:9:67:9 | [exception: Exception] catch (...) {...} | Finally.cs:66:9:67:9 | {...} | | Finally.cs:65:9:67:9 | [exception: Exception] catch (...) {...} | Finally.cs:69:9:71:9 | [finally: exception(Exception)] {...} | -| Finally.cs:65:9:67:9 | [exception: OutOfMemoryException] catch (...) {...} | Finally.cs:65:9:67:9 | [exception: OutOfMemoryException] catch (...) {...} | -| Finally.cs:65:9:67:9 | [exception: OutOfMemoryException] catch (...) {...} | Finally.cs:65:26:65:26 | [exception: OutOfMemoryException] Exception e | -| Finally.cs:65:9:67:9 | [exception: OutOfMemoryException] catch (...) {...} | Finally.cs:69:9:71:9 | [finally: exception(OutOfMemoryException)] {...} | | Finally.cs:65:26:65:26 | [exception: Exception] Exception e | Finally.cs:65:26:65:26 | [exception: Exception] Exception e | +| Finally.cs:65:26:65:26 | [exception: Exception] Exception e | Finally.cs:66:9:67:9 | {...} | | Finally.cs:65:26:65:26 | [exception: Exception] Exception e | Finally.cs:69:9:71:9 | [finally: exception(Exception)] {...} | -| Finally.cs:65:26:65:26 | [exception: OutOfMemoryException] Exception e | Finally.cs:65:26:65:26 | [exception: OutOfMemoryException] Exception e | -| Finally.cs:65:26:65:26 | [exception: OutOfMemoryException] Exception e | Finally.cs:69:9:71:9 | [finally: exception(OutOfMemoryException)] {...} | | Finally.cs:66:9:67:9 | {...} | Finally.cs:66:9:67:9 | {...} | | Finally.cs:69:9:71:9 | [finally: exception(Exception)] {...} | Finally.cs:69:9:71:9 | [finally: exception(Exception)] {...} | -| Finally.cs:69:9:71:9 | [finally: exception(OutOfMemoryException)] {...} | Finally.cs:69:9:71:9 | [finally: exception(OutOfMemoryException)] {...} | | Finally.cs:74:10:74:11 | enter M4 | Finally.cs:74:10:74:11 | enter M4 | | Finally.cs:74:10:74:11 | enter M4 | Finally.cs:74:10:74:11 | exit M4 | | Finally.cs:74:10:74:11 | enter M4 | Finally.cs:74:10:74:11 | exit M4 (abnormal) | @@ -9969,12 +10331,12 @@ blockDominance | Finally.cs:74:10:74:11 | enter M4 | Finally.cs:93:31:93:45 | [finally: continue] object creation of type Exception | | Finally.cs:74:10:74:11 | enter M4 | Finally.cs:93:31:93:45 | [finally: return] object creation of type Exception | | Finally.cs:74:10:74:11 | enter M4 | Finally.cs:93:31:93:45 | object creation of type Exception | -| Finally.cs:74:10:74:11 | enter M4 | Finally.cs:96:17:98:17 | [finally(2): exception(Exception)] {...} | -| Finally.cs:74:10:74:11 | enter M4 | Finally.cs:96:17:98:17 | [finally: break, finally(2): exception(Exception)] {...} | +| Finally.cs:74:10:74:11 | enter M4 | Finally.cs:96:17:98:17 | [finally(1): exception(Exception)] {...} | +| Finally.cs:74:10:74:11 | enter M4 | Finally.cs:96:17:98:17 | [finally: break, finally(1): exception(Exception)] {...} | | Finally.cs:74:10:74:11 | enter M4 | Finally.cs:96:17:98:17 | [finally: break] {...} | -| Finally.cs:74:10:74:11 | enter M4 | Finally.cs:96:17:98:17 | [finally: continue, finally(2): exception(Exception)] {...} | +| Finally.cs:74:10:74:11 | enter M4 | Finally.cs:96:17:98:17 | [finally: continue, finally(1): exception(Exception)] {...} | | Finally.cs:74:10:74:11 | enter M4 | Finally.cs:96:17:98:17 | [finally: continue] {...} | -| Finally.cs:74:10:74:11 | enter M4 | Finally.cs:96:17:98:17 | [finally: return, finally(2): exception(Exception)] {...} | +| Finally.cs:74:10:74:11 | enter M4 | Finally.cs:96:17:98:17 | [finally: return, finally(1): exception(Exception)] {...} | | Finally.cs:74:10:74:11 | enter M4 | Finally.cs:96:17:98:17 | [finally: return] {...} | | Finally.cs:74:10:74:11 | enter M4 | Finally.cs:96:17:98:17 | {...} | | Finally.cs:74:10:74:11 | exit M4 | Finally.cs:74:10:74:11 | exit M4 | @@ -9999,12 +10361,12 @@ blockDominance | Finally.cs:77:16:77:16 | access to local variable i | Finally.cs:93:31:93:45 | [finally: continue] object creation of type Exception | | Finally.cs:77:16:77:16 | access to local variable i | Finally.cs:93:31:93:45 | [finally: return] object creation of type Exception | | Finally.cs:77:16:77:16 | access to local variable i | Finally.cs:93:31:93:45 | object creation of type Exception | -| Finally.cs:77:16:77:16 | access to local variable i | Finally.cs:96:17:98:17 | [finally(2): exception(Exception)] {...} | -| Finally.cs:77:16:77:16 | access to local variable i | Finally.cs:96:17:98:17 | [finally: break, finally(2): exception(Exception)] {...} | +| Finally.cs:77:16:77:16 | access to local variable i | Finally.cs:96:17:98:17 | [finally(1): exception(Exception)] {...} | +| Finally.cs:77:16:77:16 | access to local variable i | Finally.cs:96:17:98:17 | [finally: break, finally(1): exception(Exception)] {...} | | Finally.cs:77:16:77:16 | access to local variable i | Finally.cs:96:17:98:17 | [finally: break] {...} | -| Finally.cs:77:16:77:16 | access to local variable i | Finally.cs:96:17:98:17 | [finally: continue, finally(2): exception(Exception)] {...} | +| Finally.cs:77:16:77:16 | access to local variable i | Finally.cs:96:17:98:17 | [finally: continue, finally(1): exception(Exception)] {...} | | Finally.cs:77:16:77:16 | access to local variable i | Finally.cs:96:17:98:17 | [finally: continue] {...} | -| Finally.cs:77:16:77:16 | access to local variable i | Finally.cs:96:17:98:17 | [finally: return, finally(2): exception(Exception)] {...} | +| Finally.cs:77:16:77:16 | access to local variable i | Finally.cs:96:17:98:17 | [finally: return, finally(1): exception(Exception)] {...} | | Finally.cs:77:16:77:16 | access to local variable i | Finally.cs:96:17:98:17 | [finally: return] {...} | | Finally.cs:77:16:77:16 | access to local variable i | Finally.cs:96:17:98:17 | {...} | | Finally.cs:78:9:100:9 | {...} | Finally.cs:74:10:74:11 | exit M4 (abnormal) | @@ -10023,18 +10385,18 @@ blockDominance | Finally.cs:78:9:100:9 | {...} | Finally.cs:93:31:93:45 | [finally: continue] object creation of type Exception | | Finally.cs:78:9:100:9 | {...} | Finally.cs:93:31:93:45 | [finally: return] object creation of type Exception | | Finally.cs:78:9:100:9 | {...} | Finally.cs:93:31:93:45 | object creation of type Exception | -| Finally.cs:78:9:100:9 | {...} | Finally.cs:96:17:98:17 | [finally(2): exception(Exception)] {...} | -| Finally.cs:78:9:100:9 | {...} | Finally.cs:96:17:98:17 | [finally: break, finally(2): exception(Exception)] {...} | +| Finally.cs:78:9:100:9 | {...} | Finally.cs:96:17:98:17 | [finally(1): exception(Exception)] {...} | +| Finally.cs:78:9:100:9 | {...} | Finally.cs:96:17:98:17 | [finally: break, finally(1): exception(Exception)] {...} | | Finally.cs:78:9:100:9 | {...} | Finally.cs:96:17:98:17 | [finally: break] {...} | -| Finally.cs:78:9:100:9 | {...} | Finally.cs:96:17:98:17 | [finally: continue, finally(2): exception(Exception)] {...} | +| Finally.cs:78:9:100:9 | {...} | Finally.cs:96:17:98:17 | [finally: continue, finally(1): exception(Exception)] {...} | | Finally.cs:78:9:100:9 | {...} | Finally.cs:96:17:98:17 | [finally: continue] {...} | -| Finally.cs:78:9:100:9 | {...} | Finally.cs:96:17:98:17 | [finally: return, finally(2): exception(Exception)] {...} | +| Finally.cs:78:9:100:9 | {...} | Finally.cs:96:17:98:17 | [finally: return, finally(1): exception(Exception)] {...} | | Finally.cs:78:9:100:9 | {...} | Finally.cs:96:17:98:17 | [finally: return] {...} | | Finally.cs:78:9:100:9 | {...} | Finally.cs:96:17:98:17 | {...} | | Finally.cs:82:21:82:27 | return ...; | Finally.cs:82:21:82:27 | return ...; | | Finally.cs:82:21:82:27 | return ...; | Finally.cs:93:25:93:46 | [finally: return] throw ...; | | Finally.cs:82:21:82:27 | return ...; | Finally.cs:93:31:93:45 | [finally: return] object creation of type Exception | -| Finally.cs:82:21:82:27 | return ...; | Finally.cs:96:17:98:17 | [finally: return, finally(2): exception(Exception)] {...} | +| Finally.cs:82:21:82:27 | return ...; | Finally.cs:96:17:98:17 | [finally: return, finally(1): exception(Exception)] {...} | | Finally.cs:82:21:82:27 | return ...; | Finally.cs:96:17:98:17 | [finally: return] {...} | | Finally.cs:83:17:84:29 | if (...) ... | Finally.cs:83:17:84:29 | if (...) ... | | Finally.cs:83:17:84:29 | if (...) ... | Finally.cs:84:21:84:29 | continue; | @@ -10047,16 +10409,16 @@ blockDominance | Finally.cs:83:17:84:29 | if (...) ... | Finally.cs:93:31:93:45 | [finally: break] object creation of type Exception | | Finally.cs:83:17:84:29 | if (...) ... | Finally.cs:93:31:93:45 | [finally: continue] object creation of type Exception | | Finally.cs:83:17:84:29 | if (...) ... | Finally.cs:93:31:93:45 | object creation of type Exception | -| Finally.cs:83:17:84:29 | if (...) ... | Finally.cs:96:17:98:17 | [finally(2): exception(Exception)] {...} | -| Finally.cs:83:17:84:29 | if (...) ... | Finally.cs:96:17:98:17 | [finally: break, finally(2): exception(Exception)] {...} | +| Finally.cs:83:17:84:29 | if (...) ... | Finally.cs:96:17:98:17 | [finally(1): exception(Exception)] {...} | +| Finally.cs:83:17:84:29 | if (...) ... | Finally.cs:96:17:98:17 | [finally: break, finally(1): exception(Exception)] {...} | | Finally.cs:83:17:84:29 | if (...) ... | Finally.cs:96:17:98:17 | [finally: break] {...} | -| Finally.cs:83:17:84:29 | if (...) ... | Finally.cs:96:17:98:17 | [finally: continue, finally(2): exception(Exception)] {...} | +| Finally.cs:83:17:84:29 | if (...) ... | Finally.cs:96:17:98:17 | [finally: continue, finally(1): exception(Exception)] {...} | | Finally.cs:83:17:84:29 | if (...) ... | Finally.cs:96:17:98:17 | [finally: continue] {...} | | Finally.cs:83:17:84:29 | if (...) ... | Finally.cs:96:17:98:17 | {...} | | Finally.cs:84:21:84:29 | continue; | Finally.cs:84:21:84:29 | continue; | | Finally.cs:84:21:84:29 | continue; | Finally.cs:93:25:93:46 | [finally: continue] throw ...; | | Finally.cs:84:21:84:29 | continue; | Finally.cs:93:31:93:45 | [finally: continue] object creation of type Exception | -| Finally.cs:84:21:84:29 | continue; | Finally.cs:96:17:98:17 | [finally: continue, finally(2): exception(Exception)] {...} | +| Finally.cs:84:21:84:29 | continue; | Finally.cs:96:17:98:17 | [finally: continue, finally(1): exception(Exception)] {...} | | Finally.cs:84:21:84:29 | continue; | Finally.cs:96:17:98:17 | [finally: continue] {...} | | Finally.cs:85:17:86:26 | if (...) ... | Finally.cs:85:17:86:26 | if (...) ... | | Finally.cs:85:17:86:26 | if (...) ... | Finally.cs:86:21:86:26 | break; | @@ -10065,19 +10427,19 @@ blockDominance | Finally.cs:85:17:86:26 | if (...) ... | Finally.cs:93:25:93:46 | throw ...; | | Finally.cs:85:17:86:26 | if (...) ... | Finally.cs:93:31:93:45 | [finally: break] object creation of type Exception | | Finally.cs:85:17:86:26 | if (...) ... | Finally.cs:93:31:93:45 | object creation of type Exception | -| Finally.cs:85:17:86:26 | if (...) ... | Finally.cs:96:17:98:17 | [finally(2): exception(Exception)] {...} | -| Finally.cs:85:17:86:26 | if (...) ... | Finally.cs:96:17:98:17 | [finally: break, finally(2): exception(Exception)] {...} | +| Finally.cs:85:17:86:26 | if (...) ... | Finally.cs:96:17:98:17 | [finally(1): exception(Exception)] {...} | +| Finally.cs:85:17:86:26 | if (...) ... | Finally.cs:96:17:98:17 | [finally: break, finally(1): exception(Exception)] {...} | | Finally.cs:85:17:86:26 | if (...) ... | Finally.cs:96:17:98:17 | [finally: break] {...} | | Finally.cs:85:17:86:26 | if (...) ... | Finally.cs:96:17:98:17 | {...} | | Finally.cs:86:21:86:26 | break; | Finally.cs:86:21:86:26 | break; | | Finally.cs:86:21:86:26 | break; | Finally.cs:93:25:93:46 | [finally: break] throw ...; | | Finally.cs:86:21:86:26 | break; | Finally.cs:93:31:93:45 | [finally: break] object creation of type Exception | -| Finally.cs:86:21:86:26 | break; | Finally.cs:96:17:98:17 | [finally: break, finally(2): exception(Exception)] {...} | +| Finally.cs:86:21:86:26 | break; | Finally.cs:96:17:98:17 | [finally: break, finally(1): exception(Exception)] {...} | | Finally.cs:86:21:86:26 | break; | Finally.cs:96:17:98:17 | [finally: break] {...} | | Finally.cs:89:13:99:13 | {...} | Finally.cs:89:13:99:13 | {...} | | Finally.cs:89:13:99:13 | {...} | Finally.cs:93:25:93:46 | throw ...; | | Finally.cs:89:13:99:13 | {...} | Finally.cs:93:31:93:45 | object creation of type Exception | -| Finally.cs:89:13:99:13 | {...} | Finally.cs:96:17:98:17 | [finally(2): exception(Exception)] {...} | +| Finally.cs:89:13:99:13 | {...} | Finally.cs:96:17:98:17 | [finally(1): exception(Exception)] {...} | | Finally.cs:89:13:99:13 | {...} | Finally.cs:96:17:98:17 | {...} | | Finally.cs:93:25:93:46 | [finally: break] throw ...; | Finally.cs:93:25:93:46 | [finally: break] throw ...; | | Finally.cs:93:25:93:46 | [finally: continue] throw ...; | Finally.cs:93:25:93:46 | [finally: continue] throw ...; | @@ -10085,22 +10447,22 @@ blockDominance | Finally.cs:93:25:93:46 | throw ...; | Finally.cs:93:25:93:46 | throw ...; | | Finally.cs:93:31:93:45 | [finally: break] object creation of type Exception | Finally.cs:93:25:93:46 | [finally: break] throw ...; | | Finally.cs:93:31:93:45 | [finally: break] object creation of type Exception | Finally.cs:93:31:93:45 | [finally: break] object creation of type Exception | -| Finally.cs:93:31:93:45 | [finally: break] object creation of type Exception | Finally.cs:96:17:98:17 | [finally: break, finally(2): exception(Exception)] {...} | +| Finally.cs:93:31:93:45 | [finally: break] object creation of type Exception | Finally.cs:96:17:98:17 | [finally: break, finally(1): exception(Exception)] {...} | | Finally.cs:93:31:93:45 | [finally: continue] object creation of type Exception | Finally.cs:93:25:93:46 | [finally: continue] throw ...; | | Finally.cs:93:31:93:45 | [finally: continue] object creation of type Exception | Finally.cs:93:31:93:45 | [finally: continue] object creation of type Exception | -| Finally.cs:93:31:93:45 | [finally: continue] object creation of type Exception | Finally.cs:96:17:98:17 | [finally: continue, finally(2): exception(Exception)] {...} | +| Finally.cs:93:31:93:45 | [finally: continue] object creation of type Exception | Finally.cs:96:17:98:17 | [finally: continue, finally(1): exception(Exception)] {...} | | Finally.cs:93:31:93:45 | [finally: return] object creation of type Exception | Finally.cs:93:25:93:46 | [finally: return] throw ...; | | Finally.cs:93:31:93:45 | [finally: return] object creation of type Exception | Finally.cs:93:31:93:45 | [finally: return] object creation of type Exception | -| Finally.cs:93:31:93:45 | [finally: return] object creation of type Exception | Finally.cs:96:17:98:17 | [finally: return, finally(2): exception(Exception)] {...} | +| Finally.cs:93:31:93:45 | [finally: return] object creation of type Exception | Finally.cs:96:17:98:17 | [finally: return, finally(1): exception(Exception)] {...} | | Finally.cs:93:31:93:45 | object creation of type Exception | Finally.cs:93:25:93:46 | throw ...; | | Finally.cs:93:31:93:45 | object creation of type Exception | Finally.cs:93:31:93:45 | object creation of type Exception | -| Finally.cs:93:31:93:45 | object creation of type Exception | Finally.cs:96:17:98:17 | [finally(2): exception(Exception)] {...} | -| Finally.cs:96:17:98:17 | [finally(2): exception(Exception)] {...} | Finally.cs:96:17:98:17 | [finally(2): exception(Exception)] {...} | -| Finally.cs:96:17:98:17 | [finally: break, finally(2): exception(Exception)] {...} | Finally.cs:96:17:98:17 | [finally: break, finally(2): exception(Exception)] {...} | +| Finally.cs:93:31:93:45 | object creation of type Exception | Finally.cs:96:17:98:17 | [finally(1): exception(Exception)] {...} | +| Finally.cs:96:17:98:17 | [finally(1): exception(Exception)] {...} | Finally.cs:96:17:98:17 | [finally(1): exception(Exception)] {...} | +| Finally.cs:96:17:98:17 | [finally: break, finally(1): exception(Exception)] {...} | Finally.cs:96:17:98:17 | [finally: break, finally(1): exception(Exception)] {...} | | Finally.cs:96:17:98:17 | [finally: break] {...} | Finally.cs:96:17:98:17 | [finally: break] {...} | -| Finally.cs:96:17:98:17 | [finally: continue, finally(2): exception(Exception)] {...} | Finally.cs:96:17:98:17 | [finally: continue, finally(2): exception(Exception)] {...} | +| Finally.cs:96:17:98:17 | [finally: continue, finally(1): exception(Exception)] {...} | Finally.cs:96:17:98:17 | [finally: continue, finally(1): exception(Exception)] {...} | | Finally.cs:96:17:98:17 | [finally: continue] {...} | Finally.cs:96:17:98:17 | [finally: continue] {...} | -| Finally.cs:96:17:98:17 | [finally: return, finally(2): exception(Exception)] {...} | Finally.cs:96:17:98:17 | [finally: return, finally(2): exception(Exception)] {...} | +| Finally.cs:96:17:98:17 | [finally: return, finally(1): exception(Exception)] {...} | Finally.cs:96:17:98:17 | [finally: return, finally(1): exception(Exception)] {...} | | Finally.cs:96:17:98:17 | [finally: return] {...} | Finally.cs:96:17:98:17 | [finally: return] {...} | | Finally.cs:96:17:98:17 | {...} | Finally.cs:96:17:98:17 | {...} | | Finally.cs:103:10:103:11 | enter M5 | Finally.cs:103:10:103:11 | enter M5 | @@ -10321,16 +10683,10 @@ blockDominance | Finally.cs:121:10:121:11 | enter M6 | Finally.cs:121:10:121:11 | enter M6 | | Finally.cs:133:10:133:11 | enter M7 | Finally.cs:133:10:133:11 | enter M7 | | Finally.cs:133:10:133:11 | enter M7 | Finally.cs:133:10:133:11 | exit M7 (abnormal) | -| Finally.cs:133:10:133:11 | enter M7 | Finally.cs:137:13:137:36 | call to method WriteLine | | Finally.cs:133:10:133:11 | enter M7 | Finally.cs:140:9:143:9 | [finally: exception(Exception)] {...} | -| Finally.cs:133:10:133:11 | enter M7 | Finally.cs:140:9:143:9 | [finally: exception(OutOfMemoryException)] {...} | | Finally.cs:133:10:133:11 | enter M7 | Finally.cs:140:9:143:9 | {...} | | Finally.cs:133:10:133:11 | exit M7 (abnormal) | Finally.cs:133:10:133:11 | exit M7 (abnormal) | -| Finally.cs:137:13:137:36 | call to method WriteLine | Finally.cs:137:13:137:36 | call to method WriteLine | -| Finally.cs:137:13:137:36 | call to method WriteLine | Finally.cs:140:9:143:9 | [finally: exception(Exception)] {...} | -| Finally.cs:137:13:137:36 | call to method WriteLine | Finally.cs:140:9:143:9 | {...} | | Finally.cs:140:9:143:9 | [finally: exception(Exception)] {...} | Finally.cs:140:9:143:9 | [finally: exception(Exception)] {...} | -| Finally.cs:140:9:143:9 | [finally: exception(OutOfMemoryException)] {...} | Finally.cs:140:9:143:9 | [finally: exception(OutOfMemoryException)] {...} | | Finally.cs:140:9:143:9 | {...} | Finally.cs:140:9:143:9 | {...} | | Finally.cs:147:10:147:11 | enter M8 | Finally.cs:147:10:147:11 | enter M8 | | Finally.cs:147:10:147:11 | enter M8 | Finally.cs:147:10:147:11 | exit M8 | @@ -10346,30 +10702,21 @@ blockDominance | Finally.cs:147:10:147:11 | enter M8 | Finally.cs:159:21:159:45 | [finally: exception(ArgumentNullException)] throw ...; | | Finally.cs:147:10:147:11 | enter M8 | Finally.cs:159:21:159:45 | [finally: exception(Exception)] throw ...; | | Finally.cs:147:10:147:11 | enter M8 | Finally.cs:159:21:159:45 | throw ...; | -| Finally.cs:147:10:147:11 | enter M8 | Finally.cs:159:27:159:44 | [finally: exception(ArgumentNullException)] object creation of type Exception | -| Finally.cs:147:10:147:11 | enter M8 | Finally.cs:159:27:159:44 | [finally: exception(Exception)] object creation of type Exception | -| Finally.cs:147:10:147:11 | enter M8 | Finally.cs:159:27:159:44 | object creation of type Exception | | Finally.cs:147:10:147:11 | enter M8 | Finally.cs:159:41:159:43 | "1" | | Finally.cs:147:10:147:11 | enter M8 | Finally.cs:159:41:159:43 | [finally: exception(ArgumentNullException)] "1" | | Finally.cs:147:10:147:11 | enter M8 | Finally.cs:159:41:159:43 | [finally: exception(Exception)] "1" | | Finally.cs:147:10:147:11 | enter M8 | Finally.cs:161:13:164:13 | [exception: Exception] catch (...) {...} | | Finally.cs:147:10:147:11 | enter M8 | Finally.cs:161:13:164:13 | [exception: NullReferenceException] catch (...) {...} | -| Finally.cs:147:10:147:11 | enter M8 | Finally.cs:161:13:164:13 | [exception: OutOfMemoryException] catch (...) {...} | | Finally.cs:147:10:147:11 | enter M8 | Finally.cs:161:13:164:13 | [finally: exception(ArgumentNullException), exception: Exception] catch (...) {...} | | Finally.cs:147:10:147:11 | enter M8 | Finally.cs:161:13:164:13 | [finally: exception(ArgumentNullException), exception: NullReferenceException] catch (...) {...} | -| Finally.cs:147:10:147:11 | enter M8 | Finally.cs:161:13:164:13 | [finally: exception(ArgumentNullException), exception: OutOfMemoryException] catch (...) {...} | | Finally.cs:147:10:147:11 | enter M8 | Finally.cs:161:13:164:13 | [finally: exception(Exception), exception: Exception] catch (...) {...} | | Finally.cs:147:10:147:11 | enter M8 | Finally.cs:161:13:164:13 | [finally: exception(Exception), exception: NullReferenceException] catch (...) {...} | -| Finally.cs:147:10:147:11 | enter M8 | Finally.cs:161:13:164:13 | [finally: exception(Exception), exception: OutOfMemoryException] catch (...) {...} | | Finally.cs:147:10:147:11 | enter M8 | Finally.cs:161:30:161:30 | [exception: Exception] Exception e | | Finally.cs:147:10:147:11 | enter M8 | Finally.cs:161:30:161:30 | [exception: NullReferenceException] Exception e | -| Finally.cs:147:10:147:11 | enter M8 | Finally.cs:161:30:161:30 | [exception: OutOfMemoryException] Exception e | | Finally.cs:147:10:147:11 | enter M8 | Finally.cs:161:30:161:30 | [finally: exception(ArgumentNullException), exception: Exception] Exception e | | Finally.cs:147:10:147:11 | enter M8 | Finally.cs:161:30:161:30 | [finally: exception(ArgumentNullException), exception: NullReferenceException] Exception e | -| Finally.cs:147:10:147:11 | enter M8 | Finally.cs:161:30:161:30 | [finally: exception(ArgumentNullException), exception: OutOfMemoryException] Exception e | | Finally.cs:147:10:147:11 | enter M8 | Finally.cs:161:30:161:30 | [finally: exception(Exception), exception: Exception] Exception e | | Finally.cs:147:10:147:11 | enter M8 | Finally.cs:161:30:161:30 | [finally: exception(Exception), exception: NullReferenceException] Exception e | -| Finally.cs:147:10:147:11 | enter M8 | Finally.cs:161:30:161:30 | [finally: exception(Exception), exception: OutOfMemoryException] Exception e | | Finally.cs:147:10:147:11 | enter M8 | Finally.cs:162:13:164:13 | [finally: exception(ArgumentNullException)] {...} | | Finally.cs:147:10:147:11 | enter M8 | Finally.cs:162:13:164:13 | [finally: exception(Exception)] {...} | | Finally.cs:147:10:147:11 | enter M8 | Finally.cs:162:13:164:13 | {...} | @@ -10382,14 +10729,11 @@ blockDominance | Finally.cs:152:17:152:50 | throw ...; | Finally.cs:152:17:152:50 | throw ...; | | Finally.cs:152:17:152:50 | throw ...; | Finally.cs:158:36:158:36 | [finally: exception(ArgumentNullException)] 1 | | Finally.cs:152:17:152:50 | throw ...; | Finally.cs:159:21:159:45 | [finally: exception(ArgumentNullException)] throw ...; | -| Finally.cs:152:17:152:50 | throw ...; | Finally.cs:159:27:159:44 | [finally: exception(ArgumentNullException)] object creation of type Exception | | Finally.cs:152:17:152:50 | throw ...; | Finally.cs:159:41:159:43 | [finally: exception(ArgumentNullException)] "1" | | Finally.cs:152:17:152:50 | throw ...; | Finally.cs:161:13:164:13 | [finally: exception(ArgumentNullException), exception: Exception] catch (...) {...} | | Finally.cs:152:17:152:50 | throw ...; | Finally.cs:161:13:164:13 | [finally: exception(ArgumentNullException), exception: NullReferenceException] catch (...) {...} | -| Finally.cs:152:17:152:50 | throw ...; | Finally.cs:161:13:164:13 | [finally: exception(ArgumentNullException), exception: OutOfMemoryException] catch (...) {...} | | Finally.cs:152:17:152:50 | throw ...; | Finally.cs:161:30:161:30 | [finally: exception(ArgumentNullException), exception: Exception] Exception e | | Finally.cs:152:17:152:50 | throw ...; | Finally.cs:161:30:161:30 | [finally: exception(ArgumentNullException), exception: NullReferenceException] Exception e | -| Finally.cs:152:17:152:50 | throw ...; | Finally.cs:161:30:161:30 | [finally: exception(ArgumentNullException), exception: OutOfMemoryException] Exception e | | Finally.cs:152:17:152:50 | throw ...; | Finally.cs:162:13:164:13 | [finally: exception(ArgumentNullException)] {...} | | Finally.cs:152:17:152:50 | throw ...; | Finally.cs:165:13:168:13 | [finally: exception(ArgumentNullException)] catch {...} | | Finally.cs:152:23:152:49 | object creation of type ArgumentNullException | Finally.cs:147:10:147:11 | exit M8 (abnormal) | @@ -10400,22 +10744,16 @@ blockDominance | Finally.cs:152:23:152:49 | object creation of type ArgumentNullException | Finally.cs:158:36:158:36 | [finally: exception(Exception)] 1 | | Finally.cs:152:23:152:49 | object creation of type ArgumentNullException | Finally.cs:159:21:159:45 | [finally: exception(ArgumentNullException)] throw ...; | | Finally.cs:152:23:152:49 | object creation of type ArgumentNullException | Finally.cs:159:21:159:45 | [finally: exception(Exception)] throw ...; | -| Finally.cs:152:23:152:49 | object creation of type ArgumentNullException | Finally.cs:159:27:159:44 | [finally: exception(ArgumentNullException)] object creation of type Exception | -| Finally.cs:152:23:152:49 | object creation of type ArgumentNullException | Finally.cs:159:27:159:44 | [finally: exception(Exception)] object creation of type Exception | | Finally.cs:152:23:152:49 | object creation of type ArgumentNullException | Finally.cs:159:41:159:43 | [finally: exception(ArgumentNullException)] "1" | | Finally.cs:152:23:152:49 | object creation of type ArgumentNullException | Finally.cs:159:41:159:43 | [finally: exception(Exception)] "1" | | Finally.cs:152:23:152:49 | object creation of type ArgumentNullException | Finally.cs:161:13:164:13 | [finally: exception(ArgumentNullException), exception: Exception] catch (...) {...} | | Finally.cs:152:23:152:49 | object creation of type ArgumentNullException | Finally.cs:161:13:164:13 | [finally: exception(ArgumentNullException), exception: NullReferenceException] catch (...) {...} | -| Finally.cs:152:23:152:49 | object creation of type ArgumentNullException | Finally.cs:161:13:164:13 | [finally: exception(ArgumentNullException), exception: OutOfMemoryException] catch (...) {...} | | Finally.cs:152:23:152:49 | object creation of type ArgumentNullException | Finally.cs:161:13:164:13 | [finally: exception(Exception), exception: Exception] catch (...) {...} | | Finally.cs:152:23:152:49 | object creation of type ArgumentNullException | Finally.cs:161:13:164:13 | [finally: exception(Exception), exception: NullReferenceException] catch (...) {...} | -| Finally.cs:152:23:152:49 | object creation of type ArgumentNullException | Finally.cs:161:13:164:13 | [finally: exception(Exception), exception: OutOfMemoryException] catch (...) {...} | | Finally.cs:152:23:152:49 | object creation of type ArgumentNullException | Finally.cs:161:30:161:30 | [finally: exception(ArgumentNullException), exception: Exception] Exception e | | Finally.cs:152:23:152:49 | object creation of type ArgumentNullException | Finally.cs:161:30:161:30 | [finally: exception(ArgumentNullException), exception: NullReferenceException] Exception e | -| Finally.cs:152:23:152:49 | object creation of type ArgumentNullException | Finally.cs:161:30:161:30 | [finally: exception(ArgumentNullException), exception: OutOfMemoryException] Exception e | | Finally.cs:152:23:152:49 | object creation of type ArgumentNullException | Finally.cs:161:30:161:30 | [finally: exception(Exception), exception: Exception] Exception e | | Finally.cs:152:23:152:49 | object creation of type ArgumentNullException | Finally.cs:161:30:161:30 | [finally: exception(Exception), exception: NullReferenceException] Exception e | -| Finally.cs:152:23:152:49 | object creation of type ArgumentNullException | Finally.cs:161:30:161:30 | [finally: exception(Exception), exception: OutOfMemoryException] Exception e | | Finally.cs:152:23:152:49 | object creation of type ArgumentNullException | Finally.cs:162:13:164:13 | [finally: exception(ArgumentNullException)] {...} | | Finally.cs:152:23:152:49 | object creation of type ArgumentNullException | Finally.cs:162:13:164:13 | [finally: exception(Exception)] {...} | | Finally.cs:152:23:152:49 | object creation of type ArgumentNullException | Finally.cs:165:13:168:13 | [finally: exception(ArgumentNullException)] catch {...} | @@ -10423,99 +10761,60 @@ blockDominance | Finally.cs:155:9:169:9 | [finally: exception(Exception)] {...} | Finally.cs:155:9:169:9 | [finally: exception(Exception)] {...} | | Finally.cs:155:9:169:9 | [finally: exception(Exception)] {...} | Finally.cs:158:36:158:36 | [finally: exception(Exception)] 1 | | Finally.cs:155:9:169:9 | [finally: exception(Exception)] {...} | Finally.cs:159:21:159:45 | [finally: exception(Exception)] throw ...; | -| Finally.cs:155:9:169:9 | [finally: exception(Exception)] {...} | Finally.cs:159:27:159:44 | [finally: exception(Exception)] object creation of type Exception | | Finally.cs:155:9:169:9 | [finally: exception(Exception)] {...} | Finally.cs:159:41:159:43 | [finally: exception(Exception)] "1" | | Finally.cs:155:9:169:9 | [finally: exception(Exception)] {...} | Finally.cs:161:13:164:13 | [finally: exception(Exception), exception: Exception] catch (...) {...} | | Finally.cs:155:9:169:9 | [finally: exception(Exception)] {...} | Finally.cs:161:13:164:13 | [finally: exception(Exception), exception: NullReferenceException] catch (...) {...} | -| Finally.cs:155:9:169:9 | [finally: exception(Exception)] {...} | Finally.cs:161:13:164:13 | [finally: exception(Exception), exception: OutOfMemoryException] catch (...) {...} | | Finally.cs:155:9:169:9 | [finally: exception(Exception)] {...} | Finally.cs:161:30:161:30 | [finally: exception(Exception), exception: Exception] Exception e | | Finally.cs:155:9:169:9 | [finally: exception(Exception)] {...} | Finally.cs:161:30:161:30 | [finally: exception(Exception), exception: NullReferenceException] Exception e | -| Finally.cs:155:9:169:9 | [finally: exception(Exception)] {...} | Finally.cs:161:30:161:30 | [finally: exception(Exception), exception: OutOfMemoryException] Exception e | | Finally.cs:155:9:169:9 | [finally: exception(Exception)] {...} | Finally.cs:162:13:164:13 | [finally: exception(Exception)] {...} | | Finally.cs:155:9:169:9 | [finally: exception(Exception)] {...} | Finally.cs:165:13:168:13 | [finally: exception(Exception)] catch {...} | | Finally.cs:155:9:169:9 | {...} | Finally.cs:147:10:147:11 | exit M8 (normal) | | Finally.cs:155:9:169:9 | {...} | Finally.cs:155:9:169:9 | {...} | | Finally.cs:155:9:169:9 | {...} | Finally.cs:158:36:158:36 | 1 | | Finally.cs:155:9:169:9 | {...} | Finally.cs:159:21:159:45 | throw ...; | -| Finally.cs:155:9:169:9 | {...} | Finally.cs:159:27:159:44 | object creation of type Exception | | Finally.cs:155:9:169:9 | {...} | Finally.cs:159:41:159:43 | "1" | | Finally.cs:155:9:169:9 | {...} | Finally.cs:161:13:164:13 | [exception: Exception] catch (...) {...} | | Finally.cs:155:9:169:9 | {...} | Finally.cs:161:13:164:13 | [exception: NullReferenceException] catch (...) {...} | -| Finally.cs:155:9:169:9 | {...} | Finally.cs:161:13:164:13 | [exception: OutOfMemoryException] catch (...) {...} | | Finally.cs:155:9:169:9 | {...} | Finally.cs:161:30:161:30 | [exception: Exception] Exception e | | Finally.cs:155:9:169:9 | {...} | Finally.cs:161:30:161:30 | [exception: NullReferenceException] Exception e | -| Finally.cs:155:9:169:9 | {...} | Finally.cs:161:30:161:30 | [exception: OutOfMemoryException] Exception e | | Finally.cs:155:9:169:9 | {...} | Finally.cs:162:13:164:13 | {...} | | Finally.cs:155:9:169:9 | {...} | Finally.cs:165:13:168:13 | catch {...} | | Finally.cs:158:36:158:36 | 1 | Finally.cs:158:36:158:36 | 1 | | Finally.cs:158:36:158:36 | 1 | Finally.cs:159:21:159:45 | throw ...; | -| Finally.cs:158:36:158:36 | 1 | Finally.cs:159:27:159:44 | object creation of type Exception | | Finally.cs:158:36:158:36 | 1 | Finally.cs:159:41:159:43 | "1" | -| Finally.cs:158:36:158:36 | 1 | Finally.cs:161:13:164:13 | [exception: OutOfMemoryException] catch (...) {...} | -| Finally.cs:158:36:158:36 | 1 | Finally.cs:161:30:161:30 | [exception: OutOfMemoryException] Exception e | | Finally.cs:158:36:158:36 | [finally: exception(ArgumentNullException)] 1 | Finally.cs:158:36:158:36 | [finally: exception(ArgumentNullException)] 1 | | Finally.cs:158:36:158:36 | [finally: exception(ArgumentNullException)] 1 | Finally.cs:159:21:159:45 | [finally: exception(ArgumentNullException)] throw ...; | -| Finally.cs:158:36:158:36 | [finally: exception(ArgumentNullException)] 1 | Finally.cs:159:27:159:44 | [finally: exception(ArgumentNullException)] object creation of type Exception | | Finally.cs:158:36:158:36 | [finally: exception(ArgumentNullException)] 1 | Finally.cs:159:41:159:43 | [finally: exception(ArgumentNullException)] "1" | -| Finally.cs:158:36:158:36 | [finally: exception(ArgumentNullException)] 1 | Finally.cs:161:13:164:13 | [finally: exception(ArgumentNullException), exception: OutOfMemoryException] catch (...) {...} | -| Finally.cs:158:36:158:36 | [finally: exception(ArgumentNullException)] 1 | Finally.cs:161:30:161:30 | [finally: exception(ArgumentNullException), exception: OutOfMemoryException] Exception e | | Finally.cs:158:36:158:36 | [finally: exception(Exception)] 1 | Finally.cs:158:36:158:36 | [finally: exception(Exception)] 1 | | Finally.cs:158:36:158:36 | [finally: exception(Exception)] 1 | Finally.cs:159:21:159:45 | [finally: exception(Exception)] throw ...; | -| Finally.cs:158:36:158:36 | [finally: exception(Exception)] 1 | Finally.cs:159:27:159:44 | [finally: exception(Exception)] object creation of type Exception | | Finally.cs:158:36:158:36 | [finally: exception(Exception)] 1 | Finally.cs:159:41:159:43 | [finally: exception(Exception)] "1" | -| Finally.cs:158:36:158:36 | [finally: exception(Exception)] 1 | Finally.cs:161:13:164:13 | [finally: exception(Exception), exception: OutOfMemoryException] catch (...) {...} | -| Finally.cs:158:36:158:36 | [finally: exception(Exception)] 1 | Finally.cs:161:30:161:30 | [finally: exception(Exception), exception: OutOfMemoryException] Exception e | | Finally.cs:159:21:159:45 | [finally: exception(ArgumentNullException)] throw ...; | Finally.cs:159:21:159:45 | [finally: exception(ArgumentNullException)] throw ...; | | Finally.cs:159:21:159:45 | [finally: exception(Exception)] throw ...; | Finally.cs:159:21:159:45 | [finally: exception(Exception)] throw ...; | | Finally.cs:159:21:159:45 | throw ...; | Finally.cs:159:21:159:45 | throw ...; | -| Finally.cs:159:27:159:44 | [finally: exception(ArgumentNullException)] object creation of type Exception | Finally.cs:159:21:159:45 | [finally: exception(ArgumentNullException)] throw ...; | -| Finally.cs:159:27:159:44 | [finally: exception(ArgumentNullException)] object creation of type Exception | Finally.cs:159:27:159:44 | [finally: exception(ArgumentNullException)] object creation of type Exception | -| Finally.cs:159:27:159:44 | [finally: exception(Exception)] object creation of type Exception | Finally.cs:159:21:159:45 | [finally: exception(Exception)] throw ...; | -| Finally.cs:159:27:159:44 | [finally: exception(Exception)] object creation of type Exception | Finally.cs:159:27:159:44 | [finally: exception(Exception)] object creation of type Exception | -| Finally.cs:159:27:159:44 | object creation of type Exception | Finally.cs:159:21:159:45 | throw ...; | -| Finally.cs:159:27:159:44 | object creation of type Exception | Finally.cs:159:27:159:44 | object creation of type Exception | | Finally.cs:159:41:159:43 | "1" | Finally.cs:159:21:159:45 | throw ...; | -| Finally.cs:159:41:159:43 | "1" | Finally.cs:159:27:159:44 | object creation of type Exception | | Finally.cs:159:41:159:43 | "1" | Finally.cs:159:41:159:43 | "1" | -| Finally.cs:159:41:159:43 | "1" | Finally.cs:161:13:164:13 | [exception: OutOfMemoryException] catch (...) {...} | -| Finally.cs:159:41:159:43 | "1" | Finally.cs:161:30:161:30 | [exception: OutOfMemoryException] Exception e | | Finally.cs:159:41:159:43 | [finally: exception(ArgumentNullException)] "1" | Finally.cs:159:21:159:45 | [finally: exception(ArgumentNullException)] throw ...; | -| Finally.cs:159:41:159:43 | [finally: exception(ArgumentNullException)] "1" | Finally.cs:159:27:159:44 | [finally: exception(ArgumentNullException)] object creation of type Exception | | Finally.cs:159:41:159:43 | [finally: exception(ArgumentNullException)] "1" | Finally.cs:159:41:159:43 | [finally: exception(ArgumentNullException)] "1" | -| Finally.cs:159:41:159:43 | [finally: exception(ArgumentNullException)] "1" | Finally.cs:161:13:164:13 | [finally: exception(ArgumentNullException), exception: OutOfMemoryException] catch (...) {...} | -| Finally.cs:159:41:159:43 | [finally: exception(ArgumentNullException)] "1" | Finally.cs:161:30:161:30 | [finally: exception(ArgumentNullException), exception: OutOfMemoryException] Exception e | | Finally.cs:159:41:159:43 | [finally: exception(Exception)] "1" | Finally.cs:159:21:159:45 | [finally: exception(Exception)] throw ...; | -| Finally.cs:159:41:159:43 | [finally: exception(Exception)] "1" | Finally.cs:159:27:159:44 | [finally: exception(Exception)] object creation of type Exception | | Finally.cs:159:41:159:43 | [finally: exception(Exception)] "1" | Finally.cs:159:41:159:43 | [finally: exception(Exception)] "1" | -| Finally.cs:159:41:159:43 | [finally: exception(Exception)] "1" | Finally.cs:161:13:164:13 | [finally: exception(Exception), exception: OutOfMemoryException] catch (...) {...} | -| Finally.cs:159:41:159:43 | [finally: exception(Exception)] "1" | Finally.cs:161:30:161:30 | [finally: exception(Exception), exception: OutOfMemoryException] Exception e | | Finally.cs:161:13:164:13 | [exception: Exception] catch (...) {...} | Finally.cs:161:13:164:13 | [exception: Exception] catch (...) {...} | | Finally.cs:161:13:164:13 | [exception: Exception] catch (...) {...} | Finally.cs:161:30:161:30 | [exception: Exception] Exception e | | Finally.cs:161:13:164:13 | [exception: NullReferenceException] catch (...) {...} | Finally.cs:161:13:164:13 | [exception: NullReferenceException] catch (...) {...} | | Finally.cs:161:13:164:13 | [exception: NullReferenceException] catch (...) {...} | Finally.cs:161:30:161:30 | [exception: NullReferenceException] Exception e | -| Finally.cs:161:13:164:13 | [exception: OutOfMemoryException] catch (...) {...} | Finally.cs:161:13:164:13 | [exception: OutOfMemoryException] catch (...) {...} | -| Finally.cs:161:13:164:13 | [exception: OutOfMemoryException] catch (...) {...} | Finally.cs:161:30:161:30 | [exception: OutOfMemoryException] Exception e | | Finally.cs:161:13:164:13 | [finally: exception(ArgumentNullException), exception: Exception] catch (...) {...} | Finally.cs:161:13:164:13 | [finally: exception(ArgumentNullException), exception: Exception] catch (...) {...} | | Finally.cs:161:13:164:13 | [finally: exception(ArgumentNullException), exception: Exception] catch (...) {...} | Finally.cs:161:30:161:30 | [finally: exception(ArgumentNullException), exception: Exception] Exception e | | Finally.cs:161:13:164:13 | [finally: exception(ArgumentNullException), exception: NullReferenceException] catch (...) {...} | Finally.cs:161:13:164:13 | [finally: exception(ArgumentNullException), exception: NullReferenceException] catch (...) {...} | | Finally.cs:161:13:164:13 | [finally: exception(ArgumentNullException), exception: NullReferenceException] catch (...) {...} | Finally.cs:161:30:161:30 | [finally: exception(ArgumentNullException), exception: NullReferenceException] Exception e | -| Finally.cs:161:13:164:13 | [finally: exception(ArgumentNullException), exception: OutOfMemoryException] catch (...) {...} | Finally.cs:161:13:164:13 | [finally: exception(ArgumentNullException), exception: OutOfMemoryException] catch (...) {...} | -| Finally.cs:161:13:164:13 | [finally: exception(ArgumentNullException), exception: OutOfMemoryException] catch (...) {...} | Finally.cs:161:30:161:30 | [finally: exception(ArgumentNullException), exception: OutOfMemoryException] Exception e | | Finally.cs:161:13:164:13 | [finally: exception(Exception), exception: Exception] catch (...) {...} | Finally.cs:161:13:164:13 | [finally: exception(Exception), exception: Exception] catch (...) {...} | | Finally.cs:161:13:164:13 | [finally: exception(Exception), exception: Exception] catch (...) {...} | Finally.cs:161:30:161:30 | [finally: exception(Exception), exception: Exception] Exception e | | Finally.cs:161:13:164:13 | [finally: exception(Exception), exception: NullReferenceException] catch (...) {...} | Finally.cs:161:13:164:13 | [finally: exception(Exception), exception: NullReferenceException] catch (...) {...} | | Finally.cs:161:13:164:13 | [finally: exception(Exception), exception: NullReferenceException] catch (...) {...} | Finally.cs:161:30:161:30 | [finally: exception(Exception), exception: NullReferenceException] Exception e | -| Finally.cs:161:13:164:13 | [finally: exception(Exception), exception: OutOfMemoryException] catch (...) {...} | Finally.cs:161:13:164:13 | [finally: exception(Exception), exception: OutOfMemoryException] catch (...) {...} | -| Finally.cs:161:13:164:13 | [finally: exception(Exception), exception: OutOfMemoryException] catch (...) {...} | Finally.cs:161:30:161:30 | [finally: exception(Exception), exception: OutOfMemoryException] Exception e | | Finally.cs:161:30:161:30 | [exception: Exception] Exception e | Finally.cs:161:30:161:30 | [exception: Exception] Exception e | | Finally.cs:161:30:161:30 | [exception: NullReferenceException] Exception e | Finally.cs:161:30:161:30 | [exception: NullReferenceException] Exception e | -| Finally.cs:161:30:161:30 | [exception: OutOfMemoryException] Exception e | Finally.cs:161:30:161:30 | [exception: OutOfMemoryException] Exception e | | Finally.cs:161:30:161:30 | [finally: exception(ArgumentNullException), exception: Exception] Exception e | Finally.cs:161:30:161:30 | [finally: exception(ArgumentNullException), exception: Exception] Exception e | | Finally.cs:161:30:161:30 | [finally: exception(ArgumentNullException), exception: NullReferenceException] Exception e | Finally.cs:161:30:161:30 | [finally: exception(ArgumentNullException), exception: NullReferenceException] Exception e | -| Finally.cs:161:30:161:30 | [finally: exception(ArgumentNullException), exception: OutOfMemoryException] Exception e | Finally.cs:161:30:161:30 | [finally: exception(ArgumentNullException), exception: OutOfMemoryException] Exception e | | Finally.cs:161:30:161:30 | [finally: exception(Exception), exception: Exception] Exception e | Finally.cs:161:30:161:30 | [finally: exception(Exception), exception: Exception] Exception e | | Finally.cs:161:30:161:30 | [finally: exception(Exception), exception: NullReferenceException] Exception e | Finally.cs:161:30:161:30 | [finally: exception(Exception), exception: NullReferenceException] Exception e | -| Finally.cs:161:30:161:30 | [finally: exception(Exception), exception: OutOfMemoryException] Exception e | Finally.cs:161:30:161:30 | [finally: exception(Exception), exception: OutOfMemoryException] Exception e | | Finally.cs:162:13:164:13 | [finally: exception(ArgumentNullException)] {...} | Finally.cs:162:13:164:13 | [finally: exception(ArgumentNullException)] {...} | | Finally.cs:162:13:164:13 | [finally: exception(Exception)] {...} | Finally.cs:162:13:164:13 | [finally: exception(Exception)] {...} | | Finally.cs:162:13:164:13 | {...} | Finally.cs:162:13:164:13 | {...} | @@ -10652,19 +10951,19 @@ blockDominance | Finally.cs:195:10:195:12 | enter M10 | Finally.cs:205:31:205:46 | [finally: exception(Exception)] object creation of type ExceptionB | | Finally.cs:195:10:195:12 | enter M10 | Finally.cs:205:31:205:46 | [finally: exception(ExceptionA)] object creation of type ExceptionB | | Finally.cs:195:10:195:12 | enter M10 | Finally.cs:205:31:205:46 | object creation of type ExceptionB | -| Finally.cs:195:10:195:12 | enter M10 | Finally.cs:208:13:210:13 | [finally(2): exception(Exception)] {...} | -| Finally.cs:195:10:195:12 | enter M10 | Finally.cs:208:13:210:13 | [finally: exception(Exception), finally(2): exception(Exception)] {...} | +| Finally.cs:195:10:195:12 | enter M10 | Finally.cs:208:13:210:13 | [finally(1): exception(Exception)] {...} | +| Finally.cs:195:10:195:12 | enter M10 | Finally.cs:208:13:210:13 | [finally: exception(Exception), finally(1): exception(Exception)] {...} | | Finally.cs:195:10:195:12 | enter M10 | Finally.cs:208:13:210:13 | [finally: exception(Exception)] {...} | -| Finally.cs:195:10:195:12 | enter M10 | Finally.cs:208:13:210:13 | [finally: exception(ExceptionA), finally(2): exception(Exception)] {...} | +| Finally.cs:195:10:195:12 | enter M10 | Finally.cs:208:13:210:13 | [finally: exception(ExceptionA), finally(1): exception(Exception)] {...} | | Finally.cs:195:10:195:12 | enter M10 | Finally.cs:208:13:210:13 | [finally: exception(ExceptionA)] {...} | | Finally.cs:195:10:195:12 | enter M10 | Finally.cs:208:13:210:13 | {...} | -| Finally.cs:195:10:195:12 | enter M10 | Finally.cs:209:31:209:46 | [finally(2): exception(Exception)] object creation of type ExceptionC | -| Finally.cs:195:10:195:12 | enter M10 | Finally.cs:209:31:209:46 | [finally(2): exception(ExceptionB)] object creation of type ExceptionC | -| Finally.cs:195:10:195:12 | enter M10 | Finally.cs:209:31:209:46 | [finally: exception(Exception), finally(2): exception(Exception)] object creation of type ExceptionC | -| Finally.cs:195:10:195:12 | enter M10 | Finally.cs:209:31:209:46 | [finally: exception(Exception), finally(2): exception(ExceptionB)] object creation of type ExceptionC | +| Finally.cs:195:10:195:12 | enter M10 | Finally.cs:209:31:209:46 | [finally(1): exception(Exception)] object creation of type ExceptionC | +| Finally.cs:195:10:195:12 | enter M10 | Finally.cs:209:31:209:46 | [finally(1): exception(ExceptionB)] object creation of type ExceptionC | +| Finally.cs:195:10:195:12 | enter M10 | Finally.cs:209:31:209:46 | [finally: exception(Exception), finally(1): exception(Exception)] object creation of type ExceptionC | +| Finally.cs:195:10:195:12 | enter M10 | Finally.cs:209:31:209:46 | [finally: exception(Exception), finally(1): exception(ExceptionB)] object creation of type ExceptionC | | Finally.cs:195:10:195:12 | enter M10 | Finally.cs:209:31:209:46 | [finally: exception(Exception)] object creation of type ExceptionC | -| Finally.cs:195:10:195:12 | enter M10 | Finally.cs:209:31:209:46 | [finally: exception(ExceptionA), finally(2): exception(Exception)] object creation of type ExceptionC | -| Finally.cs:195:10:195:12 | enter M10 | Finally.cs:209:31:209:46 | [finally: exception(ExceptionA), finally(2): exception(ExceptionB)] object creation of type ExceptionC | +| Finally.cs:195:10:195:12 | enter M10 | Finally.cs:209:31:209:46 | [finally: exception(ExceptionA), finally(1): exception(Exception)] object creation of type ExceptionC | +| Finally.cs:195:10:195:12 | enter M10 | Finally.cs:209:31:209:46 | [finally: exception(ExceptionA), finally(1): exception(ExceptionB)] object creation of type ExceptionC | | Finally.cs:195:10:195:12 | enter M10 | Finally.cs:209:31:209:46 | [finally: exception(ExceptionA)] object creation of type ExceptionC | | Finally.cs:195:10:195:12 | enter M10 | Finally.cs:209:31:209:46 | object creation of type ExceptionC | | Finally.cs:195:10:195:12 | enter M10 | Finally.cs:211:13:211:29 | ...; | @@ -10675,10 +10974,10 @@ blockDominance | Finally.cs:199:21:199:43 | throw ...; | Finally.cs:199:21:199:43 | throw ...; | | Finally.cs:199:21:199:43 | throw ...; | Finally.cs:205:25:205:47 | [finally: exception(ExceptionA)] throw ...; | | Finally.cs:199:21:199:43 | throw ...; | Finally.cs:205:31:205:46 | [finally: exception(ExceptionA)] object creation of type ExceptionB | -| Finally.cs:199:21:199:43 | throw ...; | Finally.cs:208:13:210:13 | [finally: exception(ExceptionA), finally(2): exception(Exception)] {...} | +| Finally.cs:199:21:199:43 | throw ...; | Finally.cs:208:13:210:13 | [finally: exception(ExceptionA), finally(1): exception(Exception)] {...} | | Finally.cs:199:21:199:43 | throw ...; | Finally.cs:208:13:210:13 | [finally: exception(ExceptionA)] {...} | -| Finally.cs:199:21:199:43 | throw ...; | Finally.cs:209:31:209:46 | [finally: exception(ExceptionA), finally(2): exception(Exception)] object creation of type ExceptionC | -| Finally.cs:199:21:199:43 | throw ...; | Finally.cs:209:31:209:46 | [finally: exception(ExceptionA), finally(2): exception(ExceptionB)] object creation of type ExceptionC | +| Finally.cs:199:21:199:43 | throw ...; | Finally.cs:209:31:209:46 | [finally: exception(ExceptionA), finally(1): exception(Exception)] object creation of type ExceptionC | +| Finally.cs:199:21:199:43 | throw ...; | Finally.cs:209:31:209:46 | [finally: exception(ExceptionA), finally(1): exception(ExceptionB)] object creation of type ExceptionC | | Finally.cs:199:21:199:43 | throw ...; | Finally.cs:209:31:209:46 | [finally: exception(ExceptionA)] object creation of type ExceptionC | | Finally.cs:199:21:199:43 | throw ...; | Finally.cs:211:13:211:29 | [finally: exception(ExceptionA)] ...; | | Finally.cs:199:27:199:42 | object creation of type ExceptionA | Finally.cs:199:21:199:43 | throw ...; | @@ -10688,91 +10987,169 @@ blockDominance | Finally.cs:199:27:199:42 | object creation of type ExceptionA | Finally.cs:205:25:205:47 | [finally: exception(ExceptionA)] throw ...; | | Finally.cs:199:27:199:42 | object creation of type ExceptionA | Finally.cs:205:31:205:46 | [finally: exception(Exception)] object creation of type ExceptionB | | Finally.cs:199:27:199:42 | object creation of type ExceptionA | Finally.cs:205:31:205:46 | [finally: exception(ExceptionA)] object creation of type ExceptionB | -| Finally.cs:199:27:199:42 | object creation of type ExceptionA | Finally.cs:208:13:210:13 | [finally: exception(Exception), finally(2): exception(Exception)] {...} | +| Finally.cs:199:27:199:42 | object creation of type ExceptionA | Finally.cs:208:13:210:13 | [finally: exception(Exception), finally(1): exception(Exception)] {...} | | Finally.cs:199:27:199:42 | object creation of type ExceptionA | Finally.cs:208:13:210:13 | [finally: exception(Exception)] {...} | -| Finally.cs:199:27:199:42 | object creation of type ExceptionA | Finally.cs:208:13:210:13 | [finally: exception(ExceptionA), finally(2): exception(Exception)] {...} | +| Finally.cs:199:27:199:42 | object creation of type ExceptionA | Finally.cs:208:13:210:13 | [finally: exception(ExceptionA), finally(1): exception(Exception)] {...} | | Finally.cs:199:27:199:42 | object creation of type ExceptionA | Finally.cs:208:13:210:13 | [finally: exception(ExceptionA)] {...} | -| Finally.cs:199:27:199:42 | object creation of type ExceptionA | Finally.cs:209:31:209:46 | [finally: exception(Exception), finally(2): exception(Exception)] object creation of type ExceptionC | -| Finally.cs:199:27:199:42 | object creation of type ExceptionA | Finally.cs:209:31:209:46 | [finally: exception(Exception), finally(2): exception(ExceptionB)] object creation of type ExceptionC | +| Finally.cs:199:27:199:42 | object creation of type ExceptionA | Finally.cs:209:31:209:46 | [finally: exception(Exception), finally(1): exception(Exception)] object creation of type ExceptionC | +| Finally.cs:199:27:199:42 | object creation of type ExceptionA | Finally.cs:209:31:209:46 | [finally: exception(Exception), finally(1): exception(ExceptionB)] object creation of type ExceptionC | | Finally.cs:199:27:199:42 | object creation of type ExceptionA | Finally.cs:209:31:209:46 | [finally: exception(Exception)] object creation of type ExceptionC | -| Finally.cs:199:27:199:42 | object creation of type ExceptionA | Finally.cs:209:31:209:46 | [finally: exception(ExceptionA), finally(2): exception(Exception)] object creation of type ExceptionC | -| Finally.cs:199:27:199:42 | object creation of type ExceptionA | Finally.cs:209:31:209:46 | [finally: exception(ExceptionA), finally(2): exception(ExceptionB)] object creation of type ExceptionC | +| Finally.cs:199:27:199:42 | object creation of type ExceptionA | Finally.cs:209:31:209:46 | [finally: exception(ExceptionA), finally(1): exception(Exception)] object creation of type ExceptionC | +| Finally.cs:199:27:199:42 | object creation of type ExceptionA | Finally.cs:209:31:209:46 | [finally: exception(ExceptionA), finally(1): exception(ExceptionB)] object creation of type ExceptionC | | Finally.cs:199:27:199:42 | object creation of type ExceptionA | Finally.cs:209:31:209:46 | [finally: exception(ExceptionA)] object creation of type ExceptionC | | Finally.cs:199:27:199:42 | object creation of type ExceptionA | Finally.cs:211:13:211:29 | [finally: exception(Exception)] ...; | | Finally.cs:199:27:199:42 | object creation of type ExceptionA | Finally.cs:211:13:211:29 | [finally: exception(ExceptionA)] ...; | | Finally.cs:202:9:212:9 | [finally: exception(Exception)] {...} | Finally.cs:202:9:212:9 | [finally: exception(Exception)] {...} | | Finally.cs:202:9:212:9 | [finally: exception(Exception)] {...} | Finally.cs:205:25:205:47 | [finally: exception(Exception)] throw ...; | | Finally.cs:202:9:212:9 | [finally: exception(Exception)] {...} | Finally.cs:205:31:205:46 | [finally: exception(Exception)] object creation of type ExceptionB | -| Finally.cs:202:9:212:9 | [finally: exception(Exception)] {...} | Finally.cs:208:13:210:13 | [finally: exception(Exception), finally(2): exception(Exception)] {...} | +| Finally.cs:202:9:212:9 | [finally: exception(Exception)] {...} | Finally.cs:208:13:210:13 | [finally: exception(Exception), finally(1): exception(Exception)] {...} | | Finally.cs:202:9:212:9 | [finally: exception(Exception)] {...} | Finally.cs:208:13:210:13 | [finally: exception(Exception)] {...} | -| Finally.cs:202:9:212:9 | [finally: exception(Exception)] {...} | Finally.cs:209:31:209:46 | [finally: exception(Exception), finally(2): exception(Exception)] object creation of type ExceptionC | -| Finally.cs:202:9:212:9 | [finally: exception(Exception)] {...} | Finally.cs:209:31:209:46 | [finally: exception(Exception), finally(2): exception(ExceptionB)] object creation of type ExceptionC | +| Finally.cs:202:9:212:9 | [finally: exception(Exception)] {...} | Finally.cs:209:31:209:46 | [finally: exception(Exception), finally(1): exception(Exception)] object creation of type ExceptionC | +| Finally.cs:202:9:212:9 | [finally: exception(Exception)] {...} | Finally.cs:209:31:209:46 | [finally: exception(Exception), finally(1): exception(ExceptionB)] object creation of type ExceptionC | | Finally.cs:202:9:212:9 | [finally: exception(Exception)] {...} | Finally.cs:209:31:209:46 | [finally: exception(Exception)] object creation of type ExceptionC | | Finally.cs:202:9:212:9 | [finally: exception(Exception)] {...} | Finally.cs:211:13:211:29 | [finally: exception(Exception)] ...; | | Finally.cs:202:9:212:9 | {...} | Finally.cs:202:9:212:9 | {...} | | Finally.cs:202:9:212:9 | {...} | Finally.cs:205:25:205:47 | throw ...; | | Finally.cs:202:9:212:9 | {...} | Finally.cs:205:31:205:46 | object creation of type ExceptionB | -| Finally.cs:202:9:212:9 | {...} | Finally.cs:208:13:210:13 | [finally(2): exception(Exception)] {...} | +| Finally.cs:202:9:212:9 | {...} | Finally.cs:208:13:210:13 | [finally(1): exception(Exception)] {...} | | Finally.cs:202:9:212:9 | {...} | Finally.cs:208:13:210:13 | {...} | -| Finally.cs:202:9:212:9 | {...} | Finally.cs:209:31:209:46 | [finally(2): exception(Exception)] object creation of type ExceptionC | -| Finally.cs:202:9:212:9 | {...} | Finally.cs:209:31:209:46 | [finally(2): exception(ExceptionB)] object creation of type ExceptionC | +| Finally.cs:202:9:212:9 | {...} | Finally.cs:209:31:209:46 | [finally(1): exception(Exception)] object creation of type ExceptionC | +| Finally.cs:202:9:212:9 | {...} | Finally.cs:209:31:209:46 | [finally(1): exception(ExceptionB)] object creation of type ExceptionC | | Finally.cs:202:9:212:9 | {...} | Finally.cs:209:31:209:46 | object creation of type ExceptionC | | Finally.cs:202:9:212:9 | {...} | Finally.cs:211:13:211:29 | ...; | | Finally.cs:205:25:205:47 | [finally: exception(Exception)] throw ...; | Finally.cs:205:25:205:47 | [finally: exception(Exception)] throw ...; | -| Finally.cs:205:25:205:47 | [finally: exception(Exception)] throw ...; | Finally.cs:209:31:209:46 | [finally: exception(Exception), finally(2): exception(ExceptionB)] object creation of type ExceptionC | +| Finally.cs:205:25:205:47 | [finally: exception(Exception)] throw ...; | Finally.cs:209:31:209:46 | [finally: exception(Exception), finally(1): exception(ExceptionB)] object creation of type ExceptionC | | Finally.cs:205:25:205:47 | [finally: exception(ExceptionA)] throw ...; | Finally.cs:205:25:205:47 | [finally: exception(ExceptionA)] throw ...; | -| Finally.cs:205:25:205:47 | [finally: exception(ExceptionA)] throw ...; | Finally.cs:209:31:209:46 | [finally: exception(ExceptionA), finally(2): exception(ExceptionB)] object creation of type ExceptionC | +| Finally.cs:205:25:205:47 | [finally: exception(ExceptionA)] throw ...; | Finally.cs:209:31:209:46 | [finally: exception(ExceptionA), finally(1): exception(ExceptionB)] object creation of type ExceptionC | | Finally.cs:205:25:205:47 | throw ...; | Finally.cs:205:25:205:47 | throw ...; | -| Finally.cs:205:25:205:47 | throw ...; | Finally.cs:209:31:209:46 | [finally(2): exception(ExceptionB)] object creation of type ExceptionC | +| Finally.cs:205:25:205:47 | throw ...; | Finally.cs:209:31:209:46 | [finally(1): exception(ExceptionB)] object creation of type ExceptionC | | Finally.cs:205:31:205:46 | [finally: exception(Exception)] object creation of type ExceptionB | Finally.cs:205:25:205:47 | [finally: exception(Exception)] throw ...; | | Finally.cs:205:31:205:46 | [finally: exception(Exception)] object creation of type ExceptionB | Finally.cs:205:31:205:46 | [finally: exception(Exception)] object creation of type ExceptionB | -| Finally.cs:205:31:205:46 | [finally: exception(Exception)] object creation of type ExceptionB | Finally.cs:208:13:210:13 | [finally: exception(Exception), finally(2): exception(Exception)] {...} | -| Finally.cs:205:31:205:46 | [finally: exception(Exception)] object creation of type ExceptionB | Finally.cs:209:31:209:46 | [finally: exception(Exception), finally(2): exception(Exception)] object creation of type ExceptionC | -| Finally.cs:205:31:205:46 | [finally: exception(Exception)] object creation of type ExceptionB | Finally.cs:209:31:209:46 | [finally: exception(Exception), finally(2): exception(ExceptionB)] object creation of type ExceptionC | +| Finally.cs:205:31:205:46 | [finally: exception(Exception)] object creation of type ExceptionB | Finally.cs:208:13:210:13 | [finally: exception(Exception), finally(1): exception(Exception)] {...} | +| Finally.cs:205:31:205:46 | [finally: exception(Exception)] object creation of type ExceptionB | Finally.cs:209:31:209:46 | [finally: exception(Exception), finally(1): exception(Exception)] object creation of type ExceptionC | +| Finally.cs:205:31:205:46 | [finally: exception(Exception)] object creation of type ExceptionB | Finally.cs:209:31:209:46 | [finally: exception(Exception), finally(1): exception(ExceptionB)] object creation of type ExceptionC | | Finally.cs:205:31:205:46 | [finally: exception(ExceptionA)] object creation of type ExceptionB | Finally.cs:205:25:205:47 | [finally: exception(ExceptionA)] throw ...; | | Finally.cs:205:31:205:46 | [finally: exception(ExceptionA)] object creation of type ExceptionB | Finally.cs:205:31:205:46 | [finally: exception(ExceptionA)] object creation of type ExceptionB | -| Finally.cs:205:31:205:46 | [finally: exception(ExceptionA)] object creation of type ExceptionB | Finally.cs:208:13:210:13 | [finally: exception(ExceptionA), finally(2): exception(Exception)] {...} | -| Finally.cs:205:31:205:46 | [finally: exception(ExceptionA)] object creation of type ExceptionB | Finally.cs:209:31:209:46 | [finally: exception(ExceptionA), finally(2): exception(Exception)] object creation of type ExceptionC | -| Finally.cs:205:31:205:46 | [finally: exception(ExceptionA)] object creation of type ExceptionB | Finally.cs:209:31:209:46 | [finally: exception(ExceptionA), finally(2): exception(ExceptionB)] object creation of type ExceptionC | +| Finally.cs:205:31:205:46 | [finally: exception(ExceptionA)] object creation of type ExceptionB | Finally.cs:208:13:210:13 | [finally: exception(ExceptionA), finally(1): exception(Exception)] {...} | +| Finally.cs:205:31:205:46 | [finally: exception(ExceptionA)] object creation of type ExceptionB | Finally.cs:209:31:209:46 | [finally: exception(ExceptionA), finally(1): exception(Exception)] object creation of type ExceptionC | +| Finally.cs:205:31:205:46 | [finally: exception(ExceptionA)] object creation of type ExceptionB | Finally.cs:209:31:209:46 | [finally: exception(ExceptionA), finally(1): exception(ExceptionB)] object creation of type ExceptionC | | Finally.cs:205:31:205:46 | object creation of type ExceptionB | Finally.cs:205:25:205:47 | throw ...; | | Finally.cs:205:31:205:46 | object creation of type ExceptionB | Finally.cs:205:31:205:46 | object creation of type ExceptionB | -| Finally.cs:205:31:205:46 | object creation of type ExceptionB | Finally.cs:208:13:210:13 | [finally(2): exception(Exception)] {...} | -| Finally.cs:205:31:205:46 | object creation of type ExceptionB | Finally.cs:209:31:209:46 | [finally(2): exception(Exception)] object creation of type ExceptionC | -| Finally.cs:205:31:205:46 | object creation of type ExceptionB | Finally.cs:209:31:209:46 | [finally(2): exception(ExceptionB)] object creation of type ExceptionC | -| Finally.cs:208:13:210:13 | [finally(2): exception(Exception)] {...} | Finally.cs:208:13:210:13 | [finally(2): exception(Exception)] {...} | -| Finally.cs:208:13:210:13 | [finally(2): exception(Exception)] {...} | Finally.cs:209:31:209:46 | [finally(2): exception(Exception)] object creation of type ExceptionC | -| Finally.cs:208:13:210:13 | [finally: exception(Exception), finally(2): exception(Exception)] {...} | Finally.cs:208:13:210:13 | [finally: exception(Exception), finally(2): exception(Exception)] {...} | -| Finally.cs:208:13:210:13 | [finally: exception(Exception), finally(2): exception(Exception)] {...} | Finally.cs:209:31:209:46 | [finally: exception(Exception), finally(2): exception(Exception)] object creation of type ExceptionC | +| Finally.cs:205:31:205:46 | object creation of type ExceptionB | Finally.cs:208:13:210:13 | [finally(1): exception(Exception)] {...} | +| Finally.cs:205:31:205:46 | object creation of type ExceptionB | Finally.cs:209:31:209:46 | [finally(1): exception(Exception)] object creation of type ExceptionC | +| Finally.cs:205:31:205:46 | object creation of type ExceptionB | Finally.cs:209:31:209:46 | [finally(1): exception(ExceptionB)] object creation of type ExceptionC | +| Finally.cs:208:13:210:13 | [finally(1): exception(Exception)] {...} | Finally.cs:208:13:210:13 | [finally(1): exception(Exception)] {...} | +| Finally.cs:208:13:210:13 | [finally(1): exception(Exception)] {...} | Finally.cs:209:31:209:46 | [finally(1): exception(Exception)] object creation of type ExceptionC | +| Finally.cs:208:13:210:13 | [finally: exception(Exception), finally(1): exception(Exception)] {...} | Finally.cs:208:13:210:13 | [finally: exception(Exception), finally(1): exception(Exception)] {...} | +| Finally.cs:208:13:210:13 | [finally: exception(Exception), finally(1): exception(Exception)] {...} | Finally.cs:209:31:209:46 | [finally: exception(Exception), finally(1): exception(Exception)] object creation of type ExceptionC | | Finally.cs:208:13:210:13 | [finally: exception(Exception)] {...} | Finally.cs:208:13:210:13 | [finally: exception(Exception)] {...} | | Finally.cs:208:13:210:13 | [finally: exception(Exception)] {...} | Finally.cs:209:31:209:46 | [finally: exception(Exception)] object creation of type ExceptionC | | Finally.cs:208:13:210:13 | [finally: exception(Exception)] {...} | Finally.cs:211:13:211:29 | [finally: exception(Exception)] ...; | -| Finally.cs:208:13:210:13 | [finally: exception(ExceptionA), finally(2): exception(Exception)] {...} | Finally.cs:208:13:210:13 | [finally: exception(ExceptionA), finally(2): exception(Exception)] {...} | -| Finally.cs:208:13:210:13 | [finally: exception(ExceptionA), finally(2): exception(Exception)] {...} | Finally.cs:209:31:209:46 | [finally: exception(ExceptionA), finally(2): exception(Exception)] object creation of type ExceptionC | +| Finally.cs:208:13:210:13 | [finally: exception(ExceptionA), finally(1): exception(Exception)] {...} | Finally.cs:208:13:210:13 | [finally: exception(ExceptionA), finally(1): exception(Exception)] {...} | +| Finally.cs:208:13:210:13 | [finally: exception(ExceptionA), finally(1): exception(Exception)] {...} | Finally.cs:209:31:209:46 | [finally: exception(ExceptionA), finally(1): exception(Exception)] object creation of type ExceptionC | | Finally.cs:208:13:210:13 | [finally: exception(ExceptionA)] {...} | Finally.cs:208:13:210:13 | [finally: exception(ExceptionA)] {...} | | Finally.cs:208:13:210:13 | [finally: exception(ExceptionA)] {...} | Finally.cs:209:31:209:46 | [finally: exception(ExceptionA)] object creation of type ExceptionC | | Finally.cs:208:13:210:13 | [finally: exception(ExceptionA)] {...} | Finally.cs:211:13:211:29 | [finally: exception(ExceptionA)] ...; | | Finally.cs:208:13:210:13 | {...} | Finally.cs:208:13:210:13 | {...} | | Finally.cs:208:13:210:13 | {...} | Finally.cs:209:31:209:46 | object creation of type ExceptionC | | Finally.cs:208:13:210:13 | {...} | Finally.cs:211:13:211:29 | ...; | -| Finally.cs:209:31:209:46 | [finally(2): exception(Exception)] object creation of type ExceptionC | Finally.cs:209:31:209:46 | [finally(2): exception(Exception)] object creation of type ExceptionC | -| Finally.cs:209:31:209:46 | [finally(2): exception(ExceptionB)] object creation of type ExceptionC | Finally.cs:209:31:209:46 | [finally(2): exception(ExceptionB)] object creation of type ExceptionC | -| Finally.cs:209:31:209:46 | [finally: exception(Exception), finally(2): exception(Exception)] object creation of type ExceptionC | Finally.cs:209:31:209:46 | [finally: exception(Exception), finally(2): exception(Exception)] object creation of type ExceptionC | -| Finally.cs:209:31:209:46 | [finally: exception(Exception), finally(2): exception(ExceptionB)] object creation of type ExceptionC | Finally.cs:209:31:209:46 | [finally: exception(Exception), finally(2): exception(ExceptionB)] object creation of type ExceptionC | +| Finally.cs:209:31:209:46 | [finally(1): exception(Exception)] object creation of type ExceptionC | Finally.cs:209:31:209:46 | [finally(1): exception(Exception)] object creation of type ExceptionC | +| Finally.cs:209:31:209:46 | [finally(1): exception(ExceptionB)] object creation of type ExceptionC | Finally.cs:209:31:209:46 | [finally(1): exception(ExceptionB)] object creation of type ExceptionC | +| Finally.cs:209:31:209:46 | [finally: exception(Exception), finally(1): exception(Exception)] object creation of type ExceptionC | Finally.cs:209:31:209:46 | [finally: exception(Exception), finally(1): exception(Exception)] object creation of type ExceptionC | +| Finally.cs:209:31:209:46 | [finally: exception(Exception), finally(1): exception(ExceptionB)] object creation of type ExceptionC | Finally.cs:209:31:209:46 | [finally: exception(Exception), finally(1): exception(ExceptionB)] object creation of type ExceptionC | | Finally.cs:209:31:209:46 | [finally: exception(Exception)] object creation of type ExceptionC | Finally.cs:209:31:209:46 | [finally: exception(Exception)] object creation of type ExceptionC | -| Finally.cs:209:31:209:46 | [finally: exception(ExceptionA), finally(2): exception(Exception)] object creation of type ExceptionC | Finally.cs:209:31:209:46 | [finally: exception(ExceptionA), finally(2): exception(Exception)] object creation of type ExceptionC | -| Finally.cs:209:31:209:46 | [finally: exception(ExceptionA), finally(2): exception(ExceptionB)] object creation of type ExceptionC | Finally.cs:209:31:209:46 | [finally: exception(ExceptionA), finally(2): exception(ExceptionB)] object creation of type ExceptionC | +| Finally.cs:209:31:209:46 | [finally: exception(ExceptionA), finally(1): exception(Exception)] object creation of type ExceptionC | Finally.cs:209:31:209:46 | [finally: exception(ExceptionA), finally(1): exception(Exception)] object creation of type ExceptionC | +| Finally.cs:209:31:209:46 | [finally: exception(ExceptionA), finally(1): exception(ExceptionB)] object creation of type ExceptionC | Finally.cs:209:31:209:46 | [finally: exception(ExceptionA), finally(1): exception(ExceptionB)] object creation of type ExceptionC | | Finally.cs:209:31:209:46 | [finally: exception(ExceptionA)] object creation of type ExceptionC | Finally.cs:209:31:209:46 | [finally: exception(ExceptionA)] object creation of type ExceptionC | | Finally.cs:209:31:209:46 | object creation of type ExceptionC | Finally.cs:209:31:209:46 | object creation of type ExceptionC | | Finally.cs:211:13:211:29 | ...; | Finally.cs:211:13:211:29 | ...; | | Finally.cs:211:13:211:29 | [finally: exception(Exception)] ...; | Finally.cs:211:13:211:29 | [finally: exception(Exception)] ...; | | Finally.cs:211:13:211:29 | [finally: exception(ExceptionA)] ...; | Finally.cs:211:13:211:29 | [finally: exception(ExceptionA)] ...; | | Finally.cs:216:10:216:12 | enter M11 | Finally.cs:216:10:216:12 | enter M11 | -| Finally.cs:216:10:216:12 | enter M11 | Finally.cs:220:13:220:36 | call to method WriteLine | | Finally.cs:216:10:216:12 | enter M11 | Finally.cs:222:9:225:9 | catch {...} | | Finally.cs:216:10:216:12 | enter M11 | Finally.cs:227:9:229:9 | {...} | -| Finally.cs:220:13:220:36 | call to method WriteLine | Finally.cs:220:13:220:36 | call to method WriteLine | | Finally.cs:222:9:225:9 | catch {...} | Finally.cs:222:9:225:9 | catch {...} | | Finally.cs:227:9:229:9 | {...} | Finally.cs:227:9:229:9 | {...} | +| Finally.cs:233:10:233:12 | enter M12 | Finally.cs:233:10:233:12 | enter M12 | +| Finally.cs:233:10:233:12 | enter M12 | Finally.cs:233:10:233:12 | exit M12 | +| Finally.cs:233:10:233:12 | enter M12 | Finally.cs:233:10:233:12 | exit M12 (abnormal) | +| Finally.cs:233:10:233:12 | enter M12 | Finally.cs:240:21:240:43 | throw ...; | +| Finally.cs:233:10:233:12 | enter M12 | Finally.cs:240:27:240:42 | object creation of type ExceptionA | +| Finally.cs:233:10:233:12 | enter M12 | Finally.cs:243:13:253:13 | [finally: exception(Exception)] {...} | +| Finally.cs:233:10:233:12 | enter M12 | Finally.cs:243:13:253:13 | {...} | +| Finally.cs:233:10:233:12 | enter M12 | Finally.cs:247:25:247:47 | [finally: exception(Exception)] throw ...; | +| Finally.cs:233:10:233:12 | enter M12 | Finally.cs:247:25:247:47 | [finally: exception(ExceptionA)] throw ...; | +| Finally.cs:233:10:233:12 | enter M12 | Finally.cs:247:25:247:47 | throw ...; | +| Finally.cs:233:10:233:12 | enter M12 | Finally.cs:247:31:247:46 | [finally: exception(Exception)] object creation of type ExceptionA | +| Finally.cs:233:10:233:12 | enter M12 | Finally.cs:247:31:247:46 | [finally: exception(ExceptionA)] object creation of type ExceptionA | +| Finally.cs:233:10:233:12 | enter M12 | Finally.cs:247:31:247:46 | object creation of type ExceptionA | +| Finally.cs:233:10:233:12 | enter M12 | Finally.cs:250:17:252:17 | [finally(1): exception(Exception)] {...} | +| Finally.cs:233:10:233:12 | enter M12 | Finally.cs:250:17:252:17 | [finally: exception(Exception), finally(1): exception(Exception)] {...} | +| Finally.cs:233:10:233:12 | enter M12 | Finally.cs:250:17:252:17 | [finally: exception(Exception)] {...} | +| Finally.cs:233:10:233:12 | enter M12 | Finally.cs:250:17:252:17 | [finally: exception(ExceptionA), finally(1): exception(Exception)] {...} | +| Finally.cs:233:10:233:12 | enter M12 | Finally.cs:250:17:252:17 | [finally: exception(ExceptionA)] {...} | +| Finally.cs:233:10:233:12 | enter M12 | Finally.cs:250:17:252:17 | {...} | +| Finally.cs:233:10:233:12 | enter M12 | Finally.cs:257:9:259:9 | [finally: exception(Exception)] {...} | +| Finally.cs:233:10:233:12 | enter M12 | Finally.cs:257:9:259:9 | [finally: exception(ExceptionA)] {...} | +| Finally.cs:233:10:233:12 | enter M12 | Finally.cs:257:9:259:9 | {...} | +| Finally.cs:233:10:233:12 | exit M12 | Finally.cs:233:10:233:12 | exit M12 | +| Finally.cs:233:10:233:12 | exit M12 (abnormal) | Finally.cs:233:10:233:12 | exit M12 (abnormal) | +| Finally.cs:240:21:240:43 | throw ...; | Finally.cs:240:21:240:43 | throw ...; | +| Finally.cs:240:21:240:43 | throw ...; | Finally.cs:247:25:247:47 | [finally: exception(ExceptionA)] throw ...; | +| Finally.cs:240:21:240:43 | throw ...; | Finally.cs:247:31:247:46 | [finally: exception(ExceptionA)] object creation of type ExceptionA | +| Finally.cs:240:21:240:43 | throw ...; | Finally.cs:250:17:252:17 | [finally: exception(ExceptionA), finally(1): exception(Exception)] {...} | +| Finally.cs:240:21:240:43 | throw ...; | Finally.cs:250:17:252:17 | [finally: exception(ExceptionA)] {...} | +| Finally.cs:240:27:240:42 | object creation of type ExceptionA | Finally.cs:240:21:240:43 | throw ...; | +| Finally.cs:240:27:240:42 | object creation of type ExceptionA | Finally.cs:240:27:240:42 | object creation of type ExceptionA | +| Finally.cs:240:27:240:42 | object creation of type ExceptionA | Finally.cs:243:13:253:13 | [finally: exception(Exception)] {...} | +| Finally.cs:240:27:240:42 | object creation of type ExceptionA | Finally.cs:247:25:247:47 | [finally: exception(Exception)] throw ...; | +| Finally.cs:240:27:240:42 | object creation of type ExceptionA | Finally.cs:247:25:247:47 | [finally: exception(ExceptionA)] throw ...; | +| Finally.cs:240:27:240:42 | object creation of type ExceptionA | Finally.cs:247:31:247:46 | [finally: exception(Exception)] object creation of type ExceptionA | +| Finally.cs:240:27:240:42 | object creation of type ExceptionA | Finally.cs:247:31:247:46 | [finally: exception(ExceptionA)] object creation of type ExceptionA | +| Finally.cs:240:27:240:42 | object creation of type ExceptionA | Finally.cs:250:17:252:17 | [finally: exception(Exception), finally(1): exception(Exception)] {...} | +| Finally.cs:240:27:240:42 | object creation of type ExceptionA | Finally.cs:250:17:252:17 | [finally: exception(Exception)] {...} | +| Finally.cs:240:27:240:42 | object creation of type ExceptionA | Finally.cs:250:17:252:17 | [finally: exception(ExceptionA), finally(1): exception(Exception)] {...} | +| Finally.cs:240:27:240:42 | object creation of type ExceptionA | Finally.cs:250:17:252:17 | [finally: exception(ExceptionA)] {...} | +| Finally.cs:243:13:253:13 | [finally: exception(Exception)] {...} | Finally.cs:243:13:253:13 | [finally: exception(Exception)] {...} | +| Finally.cs:243:13:253:13 | [finally: exception(Exception)] {...} | Finally.cs:247:25:247:47 | [finally: exception(Exception)] throw ...; | +| Finally.cs:243:13:253:13 | [finally: exception(Exception)] {...} | Finally.cs:247:31:247:46 | [finally: exception(Exception)] object creation of type ExceptionA | +| Finally.cs:243:13:253:13 | [finally: exception(Exception)] {...} | Finally.cs:250:17:252:17 | [finally: exception(Exception), finally(1): exception(Exception)] {...} | +| Finally.cs:243:13:253:13 | [finally: exception(Exception)] {...} | Finally.cs:250:17:252:17 | [finally: exception(Exception)] {...} | +| Finally.cs:243:13:253:13 | {...} | Finally.cs:243:13:253:13 | {...} | +| Finally.cs:243:13:253:13 | {...} | Finally.cs:247:25:247:47 | throw ...; | +| Finally.cs:243:13:253:13 | {...} | Finally.cs:247:31:247:46 | object creation of type ExceptionA | +| Finally.cs:243:13:253:13 | {...} | Finally.cs:250:17:252:17 | [finally(1): exception(Exception)] {...} | +| Finally.cs:243:13:253:13 | {...} | Finally.cs:250:17:252:17 | {...} | +| Finally.cs:243:13:253:13 | {...} | Finally.cs:257:9:259:9 | {...} | +| Finally.cs:247:25:247:47 | [finally: exception(Exception)] throw ...; | Finally.cs:247:25:247:47 | [finally: exception(Exception)] throw ...; | +| Finally.cs:247:25:247:47 | [finally: exception(ExceptionA)] throw ...; | Finally.cs:247:25:247:47 | [finally: exception(ExceptionA)] throw ...; | +| Finally.cs:247:25:247:47 | throw ...; | Finally.cs:247:25:247:47 | throw ...; | +| Finally.cs:247:31:247:46 | [finally: exception(Exception)] object creation of type ExceptionA | Finally.cs:247:25:247:47 | [finally: exception(Exception)] throw ...; | +| Finally.cs:247:31:247:46 | [finally: exception(Exception)] object creation of type ExceptionA | Finally.cs:247:31:247:46 | [finally: exception(Exception)] object creation of type ExceptionA | +| Finally.cs:247:31:247:46 | [finally: exception(Exception)] object creation of type ExceptionA | Finally.cs:250:17:252:17 | [finally: exception(Exception), finally(1): exception(Exception)] {...} | +| Finally.cs:247:31:247:46 | [finally: exception(ExceptionA)] object creation of type ExceptionA | Finally.cs:247:25:247:47 | [finally: exception(ExceptionA)] throw ...; | +| Finally.cs:247:31:247:46 | [finally: exception(ExceptionA)] object creation of type ExceptionA | Finally.cs:247:31:247:46 | [finally: exception(ExceptionA)] object creation of type ExceptionA | +| Finally.cs:247:31:247:46 | [finally: exception(ExceptionA)] object creation of type ExceptionA | Finally.cs:250:17:252:17 | [finally: exception(ExceptionA), finally(1): exception(Exception)] {...} | +| Finally.cs:247:31:247:46 | object creation of type ExceptionA | Finally.cs:247:25:247:47 | throw ...; | +| Finally.cs:247:31:247:46 | object creation of type ExceptionA | Finally.cs:247:31:247:46 | object creation of type ExceptionA | +| Finally.cs:247:31:247:46 | object creation of type ExceptionA | Finally.cs:250:17:252:17 | [finally(1): exception(Exception)] {...} | +| Finally.cs:250:17:252:17 | [finally(1): exception(Exception)] {...} | Finally.cs:250:17:252:17 | [finally(1): exception(Exception)] {...} | +| Finally.cs:250:17:252:17 | [finally: exception(Exception), finally(1): exception(Exception)] {...} | Finally.cs:250:17:252:17 | [finally: exception(Exception), finally(1): exception(Exception)] {...} | +| Finally.cs:250:17:252:17 | [finally: exception(Exception)] {...} | Finally.cs:250:17:252:17 | [finally: exception(Exception)] {...} | +| Finally.cs:250:17:252:17 | [finally: exception(ExceptionA), finally(1): exception(Exception)] {...} | Finally.cs:250:17:252:17 | [finally: exception(ExceptionA), finally(1): exception(Exception)] {...} | +| Finally.cs:250:17:252:17 | [finally: exception(ExceptionA)] {...} | Finally.cs:250:17:252:17 | [finally: exception(ExceptionA)] {...} | +| Finally.cs:250:17:252:17 | {...} | Finally.cs:250:17:252:17 | {...} | +| Finally.cs:250:17:252:17 | {...} | Finally.cs:257:9:259:9 | {...} | +| Finally.cs:257:9:259:9 | [finally: exception(Exception)] {...} | Finally.cs:257:9:259:9 | [finally: exception(Exception)] {...} | +| Finally.cs:257:9:259:9 | [finally: exception(ExceptionA)] {...} | Finally.cs:257:9:259:9 | [finally: exception(ExceptionA)] {...} | +| Finally.cs:257:9:259:9 | {...} | Finally.cs:257:9:259:9 | {...} | +| Finally.cs:263:10:263:12 | enter M13 | Finally.cs:263:10:263:12 | enter M13 | +| Finally.cs:263:10:263:12 | enter M13 | Finally.cs:263:10:263:12 | exit M13 | +| Finally.cs:263:10:263:12 | enter M13 | Finally.cs:270:9:273:9 | [finally: exception(Exception)] {...} | +| Finally.cs:263:10:263:12 | enter M13 | Finally.cs:270:9:273:9 | {...} | +| Finally.cs:263:10:263:12 | exit M13 | Finally.cs:263:10:263:12 | exit M13 | +| Finally.cs:270:9:273:9 | [finally: exception(Exception)] {...} | Finally.cs:270:9:273:9 | [finally: exception(Exception)] {...} | +| Finally.cs:270:9:273:9 | {...} | Finally.cs:270:9:273:9 | {...} | | Foreach.cs:6:10:6:11 | enter M1 | Foreach.cs:6:10:6:11 | enter M1 | | Foreach.cs:6:10:6:11 | enter M1 | Foreach.cs:6:10:6:11 | exit M1 (normal) | | Foreach.cs:6:10:6:11 | enter M1 | Foreach.cs:8:9:9:13 | foreach (... ... in ...) ... | @@ -11296,33 +11673,66 @@ blockDominance | NullCoalescing.cs:16:17:16:25 | ... ?? ... | NullCoalescing.cs:16:17:16:25 | ... ?? ... | | NullCoalescing.cs:16:17:16:25 | ... ?? ... | NullCoalescing.cs:17:13:17:24 | ... ?? ... | | NullCoalescing.cs:17:13:17:24 | ... ?? ... | NullCoalescing.cs:17:13:17:24 | ... ?? ... | -| Patterns.cs:5:10:5:13 | enter Test | Patterns.cs:5:10:5:13 | enter Test | -| Patterns.cs:5:10:5:13 | enter Test | Patterns.cs:9:9:11:9 | {...} | -| Patterns.cs:5:10:5:13 | enter Test | Patterns.cs:12:14:18:9 | if (...) ... | -| Patterns.cs:5:10:5:13 | enter Test | Patterns.cs:13:9:15:9 | {...} | -| Patterns.cs:5:10:5:13 | enter Test | Patterns.cs:16:14:18:9 | if (...) ... | -| Patterns.cs:5:10:5:13 | enter Test | Patterns.cs:17:9:18:9 | {...} | -| Patterns.cs:5:10:5:13 | enter Test | Patterns.cs:20:9:38:9 | switch (...) {...} | -| Patterns.cs:5:10:5:13 | enter Test | Patterns.cs:23:17:23:22 | break; | -| Patterns.cs:5:10:5:13 | enter Test | Patterns.cs:24:13:24:36 | case ...: | -| Patterns.cs:5:10:5:13 | enter Test | Patterns.cs:24:30:24:31 | access to local variable i2 | -| Patterns.cs:5:10:5:13 | enter Test | Patterns.cs:25:17:25:52 | ...; | -| Patterns.cs:5:10:5:13 | enter Test | Patterns.cs:27:13:27:24 | case ...: | -| Patterns.cs:5:10:5:13 | enter Test | Patterns.cs:28:17:28:47 | ...; | -| Patterns.cs:5:10:5:13 | enter Test | Patterns.cs:30:13:30:27 | case ...: | -| Patterns.cs:5:10:5:13 | enter Test | Patterns.cs:31:17:31:50 | ...; | -| Patterns.cs:5:10:5:13 | enter Test | Patterns.cs:33:13:33:24 | case ...: | -| Patterns.cs:5:10:5:13 | enter Test | Patterns.cs:34:17:34:22 | break; | -| Patterns.cs:5:10:5:13 | enter Test | Patterns.cs:35:13:35:20 | default: | -| Patterns.cs:5:10:5:13 | enter Test | Patterns.cs:40:9:42:9 | switch (...) {...} | +| Patterns.cs:5:10:5:11 | enter M1 | Patterns.cs:5:10:5:11 | enter M1 | +| Patterns.cs:5:10:5:11 | enter M1 | Patterns.cs:8:13:8:23 | [false] ... is ... | +| Patterns.cs:5:10:5:11 | enter M1 | Patterns.cs:8:13:8:23 | [true] ... is ... | +| Patterns.cs:5:10:5:11 | enter M1 | Patterns.cs:9:9:11:9 | {...} | +| Patterns.cs:5:10:5:11 | enter M1 | Patterns.cs:12:14:18:9 | if (...) ... | +| Patterns.cs:5:10:5:11 | enter M1 | Patterns.cs:12:18:12:31 | [false] ... is ... | +| Patterns.cs:5:10:5:11 | enter M1 | Patterns.cs:12:18:12:31 | [true] ... is ... | +| Patterns.cs:5:10:5:11 | enter M1 | Patterns.cs:13:9:15:9 | {...} | +| Patterns.cs:5:10:5:11 | enter M1 | Patterns.cs:16:14:18:9 | if (...) ... | +| Patterns.cs:5:10:5:11 | enter M1 | Patterns.cs:16:18:16:28 | [false] ... is ... | +| Patterns.cs:5:10:5:11 | enter M1 | Patterns.cs:16:18:16:28 | [true] ... is ... | +| Patterns.cs:5:10:5:11 | enter M1 | Patterns.cs:17:9:18:9 | {...} | +| Patterns.cs:5:10:5:11 | enter M1 | Patterns.cs:20:9:38:9 | switch (...) {...} | +| Patterns.cs:5:10:5:11 | enter M1 | Patterns.cs:23:17:23:22 | break; | +| Patterns.cs:5:10:5:11 | enter M1 | Patterns.cs:24:13:24:36 | case ...: | +| Patterns.cs:5:10:5:11 | enter M1 | Patterns.cs:24:30:24:31 | access to local variable i2 | +| Patterns.cs:5:10:5:11 | enter M1 | Patterns.cs:25:17:25:52 | ...; | +| Patterns.cs:5:10:5:11 | enter M1 | Patterns.cs:27:13:27:24 | case ...: | +| Patterns.cs:5:10:5:11 | enter M1 | Patterns.cs:28:17:28:47 | ...; | +| Patterns.cs:5:10:5:11 | enter M1 | Patterns.cs:30:13:30:27 | case ...: | +| Patterns.cs:5:10:5:11 | enter M1 | Patterns.cs:31:17:31:50 | ...; | +| Patterns.cs:5:10:5:11 | enter M1 | Patterns.cs:33:13:33:24 | case ...: | +| Patterns.cs:5:10:5:11 | enter M1 | Patterns.cs:34:17:34:22 | break; | +| Patterns.cs:5:10:5:11 | enter M1 | Patterns.cs:35:13:35:20 | default: | +| Patterns.cs:5:10:5:11 | enter M1 | Patterns.cs:40:9:42:9 | switch (...) {...} | +| Patterns.cs:8:13:8:23 | [false] ... is ... | Patterns.cs:8:13:8:23 | [false] ... is ... | +| Patterns.cs:8:13:8:23 | [false] ... is ... | Patterns.cs:12:14:18:9 | if (...) ... | +| Patterns.cs:8:13:8:23 | [false] ... is ... | Patterns.cs:12:18:12:31 | [false] ... is ... | +| Patterns.cs:8:13:8:23 | [false] ... is ... | Patterns.cs:12:18:12:31 | [true] ... is ... | +| Patterns.cs:8:13:8:23 | [false] ... is ... | Patterns.cs:13:9:15:9 | {...} | +| Patterns.cs:8:13:8:23 | [false] ... is ... | Patterns.cs:16:14:18:9 | if (...) ... | +| Patterns.cs:8:13:8:23 | [false] ... is ... | Patterns.cs:16:18:16:28 | [false] ... is ... | +| Patterns.cs:8:13:8:23 | [false] ... is ... | Patterns.cs:16:18:16:28 | [true] ... is ... | +| Patterns.cs:8:13:8:23 | [false] ... is ... | Patterns.cs:17:9:18:9 | {...} | +| Patterns.cs:8:13:8:23 | [true] ... is ... | Patterns.cs:8:13:8:23 | [true] ... is ... | +| Patterns.cs:8:13:8:23 | [true] ... is ... | Patterns.cs:9:9:11:9 | {...} | | Patterns.cs:9:9:11:9 | {...} | Patterns.cs:9:9:11:9 | {...} | | Patterns.cs:12:14:18:9 | if (...) ... | Patterns.cs:12:14:18:9 | if (...) ... | +| Patterns.cs:12:14:18:9 | if (...) ... | Patterns.cs:12:18:12:31 | [false] ... is ... | +| Patterns.cs:12:14:18:9 | if (...) ... | Patterns.cs:12:18:12:31 | [true] ... is ... | | Patterns.cs:12:14:18:9 | if (...) ... | Patterns.cs:13:9:15:9 | {...} | | Patterns.cs:12:14:18:9 | if (...) ... | Patterns.cs:16:14:18:9 | if (...) ... | +| Patterns.cs:12:14:18:9 | if (...) ... | Patterns.cs:16:18:16:28 | [false] ... is ... | +| Patterns.cs:12:14:18:9 | if (...) ... | Patterns.cs:16:18:16:28 | [true] ... is ... | | Patterns.cs:12:14:18:9 | if (...) ... | Patterns.cs:17:9:18:9 | {...} | +| Patterns.cs:12:18:12:31 | [false] ... is ... | Patterns.cs:12:18:12:31 | [false] ... is ... | +| Patterns.cs:12:18:12:31 | [false] ... is ... | Patterns.cs:16:14:18:9 | if (...) ... | +| Patterns.cs:12:18:12:31 | [false] ... is ... | Patterns.cs:16:18:16:28 | [false] ... is ... | +| Patterns.cs:12:18:12:31 | [false] ... is ... | Patterns.cs:16:18:16:28 | [true] ... is ... | +| Patterns.cs:12:18:12:31 | [false] ... is ... | Patterns.cs:17:9:18:9 | {...} | +| Patterns.cs:12:18:12:31 | [true] ... is ... | Patterns.cs:12:18:12:31 | [true] ... is ... | +| Patterns.cs:12:18:12:31 | [true] ... is ... | Patterns.cs:13:9:15:9 | {...} | | Patterns.cs:13:9:15:9 | {...} | Patterns.cs:13:9:15:9 | {...} | | Patterns.cs:16:14:18:9 | if (...) ... | Patterns.cs:16:14:18:9 | if (...) ... | +| Patterns.cs:16:14:18:9 | if (...) ... | Patterns.cs:16:18:16:28 | [false] ... is ... | +| Patterns.cs:16:14:18:9 | if (...) ... | Patterns.cs:16:18:16:28 | [true] ... is ... | | Patterns.cs:16:14:18:9 | if (...) ... | Patterns.cs:17:9:18:9 | {...} | +| Patterns.cs:16:18:16:28 | [false] ... is ... | Patterns.cs:16:18:16:28 | [false] ... is ... | +| Patterns.cs:16:18:16:28 | [true] ... is ... | Patterns.cs:16:18:16:28 | [true] ... is ... | +| Patterns.cs:16:18:16:28 | [true] ... is ... | Patterns.cs:17:9:18:9 | {...} | | Patterns.cs:17:9:18:9 | {...} | Patterns.cs:17:9:18:9 | {...} | | Patterns.cs:20:9:38:9 | switch (...) {...} | Patterns.cs:20:9:38:9 | switch (...) {...} | | Patterns.cs:20:9:38:9 | switch (...) {...} | Patterns.cs:23:17:23:22 | break; | @@ -11371,19 +11781,230 @@ blockDominance | Patterns.cs:34:17:34:22 | break; | Patterns.cs:34:17:34:22 | break; | | Patterns.cs:35:13:35:20 | default: | Patterns.cs:35:13:35:20 | default: | | Patterns.cs:40:9:42:9 | switch (...) {...} | Patterns.cs:40:9:42:9 | switch (...) {...} | +| Patterns.cs:47:24:47:25 | enter M2 | Patterns.cs:47:24:47:25 | enter M2 | +| Patterns.cs:50:24:50:25 | enter M3 | Patterns.cs:50:24:50:25 | enter M3 | +| Patterns.cs:50:24:50:25 | enter M3 | Patterns.cs:51:9:51:21 | [false] ... is ... | +| Patterns.cs:50:24:50:25 | enter M3 | Patterns.cs:51:9:51:21 | [true] ... is ... | +| Patterns.cs:50:24:50:25 | enter M3 | Patterns.cs:51:9:51:39 | ... ? ... : ... | +| Patterns.cs:50:24:50:25 | enter M3 | Patterns.cs:51:14:51:21 | [match] not ... | +| Patterns.cs:50:24:50:25 | enter M3 | Patterns.cs:51:14:51:21 | [no-match] not ... | +| Patterns.cs:50:24:50:25 | enter M3 | Patterns.cs:51:25:51:25 | access to parameter c | +| Patterns.cs:50:24:50:25 | enter M3 | Patterns.cs:51:34:51:34 | access to parameter c | +| Patterns.cs:51:9:51:21 | [false] ... is ... | Patterns.cs:51:9:51:21 | [false] ... is ... | +| Patterns.cs:51:9:51:21 | [false] ... is ... | Patterns.cs:51:34:51:34 | access to parameter c | +| Patterns.cs:51:9:51:21 | [true] ... is ... | Patterns.cs:51:9:51:21 | [true] ... is ... | +| Patterns.cs:51:9:51:21 | [true] ... is ... | Patterns.cs:51:25:51:25 | access to parameter c | +| Patterns.cs:51:9:51:39 | ... ? ... : ... | Patterns.cs:51:9:51:39 | ... ? ... : ... | +| Patterns.cs:51:14:51:21 | [match] not ... | Patterns.cs:51:9:51:21 | [true] ... is ... | +| Patterns.cs:51:14:51:21 | [match] not ... | Patterns.cs:51:14:51:21 | [match] not ... | +| Patterns.cs:51:14:51:21 | [match] not ... | Patterns.cs:51:25:51:25 | access to parameter c | +| Patterns.cs:51:14:51:21 | [no-match] not ... | Patterns.cs:51:9:51:21 | [false] ... is ... | +| Patterns.cs:51:14:51:21 | [no-match] not ... | Patterns.cs:51:14:51:21 | [no-match] not ... | +| Patterns.cs:51:14:51:21 | [no-match] not ... | Patterns.cs:51:34:51:34 | access to parameter c | +| Patterns.cs:51:25:51:25 | access to parameter c | Patterns.cs:51:25:51:25 | access to parameter c | +| Patterns.cs:51:34:51:34 | access to parameter c | Patterns.cs:51:34:51:34 | access to parameter c | +| Patterns.cs:53:24:53:25 | enter M4 | Patterns.cs:53:24:53:25 | enter M4 | +| Patterns.cs:53:24:53:25 | enter M4 | Patterns.cs:54:18:54:37 | { ... } | +| Patterns.cs:53:24:53:25 | enter M4 | Patterns.cs:54:27:54:35 | [match] { ... } | +| Patterns.cs:53:24:53:25 | enter M4 | Patterns.cs:54:27:54:35 | [no-match] { ... } | +| Patterns.cs:53:24:53:25 | enter M4 | Patterns.cs:54:33:54:33 | 1 | +| Patterns.cs:54:18:54:37 | { ... } | Patterns.cs:54:18:54:37 | { ... } | +| Patterns.cs:54:27:54:35 | [match] { ... } | Patterns.cs:54:27:54:35 | [match] { ... } | +| Patterns.cs:54:27:54:35 | [no-match] { ... } | Patterns.cs:54:27:54:35 | [no-match] { ... } | +| Patterns.cs:54:33:54:33 | 1 | Patterns.cs:54:27:54:35 | [match] { ... } | +| Patterns.cs:54:33:54:33 | 1 | Patterns.cs:54:27:54:35 | [no-match] { ... } | +| Patterns.cs:54:33:54:33 | 1 | Patterns.cs:54:33:54:33 | 1 | +| Patterns.cs:56:26:56:27 | enter M5 | Patterns.cs:56:26:56:27 | enter M5 | +| Patterns.cs:56:26:56:27 | enter M5 | Patterns.cs:58:16:62:9 | ... switch { ... } | +| Patterns.cs:56:26:56:27 | enter M5 | Patterns.cs:60:13:60:17 | [match] not ... | +| Patterns.cs:56:26:56:27 | enter M5 | Patterns.cs:60:13:60:17 | [no-match] not ... | +| Patterns.cs:56:26:56:27 | enter M5 | Patterns.cs:60:22:60:28 | "not 1" | +| Patterns.cs:56:26:56:27 | enter M5 | Patterns.cs:61:13:61:13 | _ | +| Patterns.cs:56:26:56:27 | enter M5 | Patterns.cs:61:18:61:24 | "other" | +| Patterns.cs:58:16:62:9 | ... switch { ... } | Patterns.cs:58:16:62:9 | ... switch { ... } | +| Patterns.cs:60:13:60:17 | [match] not ... | Patterns.cs:60:13:60:17 | [match] not ... | +| Patterns.cs:60:13:60:17 | [match] not ... | Patterns.cs:60:22:60:28 | "not 1" | +| Patterns.cs:60:13:60:17 | [no-match] not ... | Patterns.cs:60:13:60:17 | [no-match] not ... | +| Patterns.cs:60:13:60:17 | [no-match] not ... | Patterns.cs:61:13:61:13 | _ | +| Patterns.cs:60:13:60:17 | [no-match] not ... | Patterns.cs:61:18:61:24 | "other" | +| Patterns.cs:60:22:60:28 | "not 1" | Patterns.cs:60:22:60:28 | "not 1" | +| Patterns.cs:61:13:61:13 | _ | Patterns.cs:61:13:61:13 | _ | +| Patterns.cs:61:13:61:13 | _ | Patterns.cs:61:18:61:24 | "other" | +| Patterns.cs:61:18:61:24 | "other" | Patterns.cs:61:18:61:24 | "other" | +| Patterns.cs:65:26:65:27 | enter M6 | Patterns.cs:65:26:65:27 | enter M6 | +| Patterns.cs:65:26:65:27 | enter M6 | Patterns.cs:69:13:69:17 | [no-match] not ... | +| Patterns.cs:65:26:65:27 | enter M6 | Patterns.cs:70:13:70:13 | 2 | +| Patterns.cs:65:26:65:27 | enter M6 | Patterns.cs:70:18:70:27 | "possible" | +| Patterns.cs:69:13:69:17 | [no-match] not ... | Patterns.cs:69:13:69:17 | [no-match] not ... | +| Patterns.cs:69:13:69:17 | [no-match] not ... | Patterns.cs:70:13:70:13 | 2 | +| Patterns.cs:69:13:69:17 | [no-match] not ... | Patterns.cs:70:18:70:27 | "possible" | +| Patterns.cs:70:13:70:13 | 2 | Patterns.cs:70:13:70:13 | 2 | +| Patterns.cs:70:13:70:13 | 2 | Patterns.cs:70:18:70:27 | "possible" | +| Patterns.cs:70:18:70:27 | "possible" | Patterns.cs:70:18:70:27 | "possible" | +| Patterns.cs:74:26:74:27 | enter M7 | Patterns.cs:74:26:74:27 | enter M7 | +| Patterns.cs:74:26:74:27 | enter M7 | Patterns.cs:76:16:82:9 | ... switch { ... } | +| Patterns.cs:74:26:74:27 | enter M7 | Patterns.cs:78:20:78:24 | "> 1" | +| Patterns.cs:74:26:74:27 | enter M7 | Patterns.cs:79:15:79:15 | 0 | +| Patterns.cs:74:26:74:27 | enter M7 | Patterns.cs:79:20:79:24 | "< 0" | +| Patterns.cs:74:26:74:27 | enter M7 | Patterns.cs:80:13:80:13 | 1 | +| Patterns.cs:74:26:74:27 | enter M7 | Patterns.cs:80:18:80:20 | "1" | +| Patterns.cs:74:26:74:27 | enter M7 | Patterns.cs:81:13:81:13 | _ | +| Patterns.cs:74:26:74:27 | enter M7 | Patterns.cs:81:18:81:20 | "0" | +| Patterns.cs:76:16:82:9 | ... switch { ... } | Patterns.cs:76:16:82:9 | ... switch { ... } | +| Patterns.cs:78:20:78:24 | "> 1" | Patterns.cs:78:20:78:24 | "> 1" | +| Patterns.cs:79:15:79:15 | 0 | Patterns.cs:79:15:79:15 | 0 | +| Patterns.cs:79:15:79:15 | 0 | Patterns.cs:79:20:79:24 | "< 0" | +| Patterns.cs:79:15:79:15 | 0 | Patterns.cs:80:13:80:13 | 1 | +| Patterns.cs:79:15:79:15 | 0 | Patterns.cs:80:18:80:20 | "1" | +| Patterns.cs:79:15:79:15 | 0 | Patterns.cs:81:13:81:13 | _ | +| Patterns.cs:79:15:79:15 | 0 | Patterns.cs:81:18:81:20 | "0" | +| Patterns.cs:79:20:79:24 | "< 0" | Patterns.cs:79:20:79:24 | "< 0" | +| Patterns.cs:80:13:80:13 | 1 | Patterns.cs:80:13:80:13 | 1 | +| Patterns.cs:80:13:80:13 | 1 | Patterns.cs:80:18:80:20 | "1" | +| Patterns.cs:80:13:80:13 | 1 | Patterns.cs:81:13:81:13 | _ | +| Patterns.cs:80:13:80:13 | 1 | Patterns.cs:81:18:81:20 | "0" | +| Patterns.cs:80:18:80:20 | "1" | Patterns.cs:80:18:80:20 | "1" | +| Patterns.cs:81:13:81:13 | _ | Patterns.cs:81:13:81:13 | _ | +| Patterns.cs:81:13:81:13 | _ | Patterns.cs:81:18:81:20 | "0" | +| Patterns.cs:81:18:81:20 | "0" | Patterns.cs:81:18:81:20 | "0" | +| Patterns.cs:85:26:85:27 | enter M8 | Patterns.cs:85:26:85:27 | enter M8 | +| Patterns.cs:85:26:85:27 | enter M8 | Patterns.cs:85:39:85:53 | [false] ... is ... | +| Patterns.cs:85:26:85:27 | enter M8 | Patterns.cs:85:39:85:53 | [true] ... is ... | +| Patterns.cs:85:26:85:27 | enter M8 | Patterns.cs:85:39:85:69 | ... ? ... : ... | +| Patterns.cs:85:26:85:27 | enter M8 | Patterns.cs:85:44:85:53 | [match] ... or ... | +| Patterns.cs:85:26:85:27 | enter M8 | Patterns.cs:85:44:85:53 | [no-match] ... or ... | +| Patterns.cs:85:26:85:27 | enter M8 | Patterns.cs:85:49:85:53 | [match] not ... | +| Patterns.cs:85:26:85:27 | enter M8 | Patterns.cs:85:49:85:53 | [no-match] not ... | +| Patterns.cs:85:26:85:27 | enter M8 | Patterns.cs:85:53:85:53 | 2 | +| Patterns.cs:85:26:85:27 | enter M8 | Patterns.cs:85:57:85:63 | "not 2" | +| Patterns.cs:85:26:85:27 | enter M8 | Patterns.cs:85:67:85:69 | "2" | +| Patterns.cs:85:39:85:53 | [false] ... is ... | Patterns.cs:85:39:85:53 | [false] ... is ... | +| Patterns.cs:85:39:85:53 | [false] ... is ... | Patterns.cs:85:67:85:69 | "2" | +| Patterns.cs:85:39:85:53 | [true] ... is ... | Patterns.cs:85:39:85:53 | [true] ... is ... | +| Patterns.cs:85:39:85:53 | [true] ... is ... | Patterns.cs:85:57:85:63 | "not 2" | +| Patterns.cs:85:39:85:69 | ... ? ... : ... | Patterns.cs:85:39:85:69 | ... ? ... : ... | +| Patterns.cs:85:44:85:53 | [match] ... or ... | Patterns.cs:85:39:85:53 | [true] ... is ... | +| Patterns.cs:85:44:85:53 | [match] ... or ... | Patterns.cs:85:44:85:53 | [match] ... or ... | +| Patterns.cs:85:44:85:53 | [match] ... or ... | Patterns.cs:85:57:85:63 | "not 2" | +| Patterns.cs:85:44:85:53 | [no-match] ... or ... | Patterns.cs:85:39:85:53 | [false] ... is ... | +| Patterns.cs:85:44:85:53 | [no-match] ... or ... | Patterns.cs:85:44:85:53 | [no-match] ... or ... | +| Patterns.cs:85:44:85:53 | [no-match] ... or ... | Patterns.cs:85:67:85:69 | "2" | +| Patterns.cs:85:49:85:53 | [match] not ... | Patterns.cs:85:49:85:53 | [match] not ... | +| Patterns.cs:85:49:85:53 | [no-match] not ... | Patterns.cs:85:39:85:53 | [false] ... is ... | +| Patterns.cs:85:49:85:53 | [no-match] not ... | Patterns.cs:85:44:85:53 | [no-match] ... or ... | +| Patterns.cs:85:49:85:53 | [no-match] not ... | Patterns.cs:85:49:85:53 | [no-match] not ... | +| Patterns.cs:85:49:85:53 | [no-match] not ... | Patterns.cs:85:67:85:69 | "2" | +| Patterns.cs:85:53:85:53 | 2 | Patterns.cs:85:39:85:53 | [false] ... is ... | +| Patterns.cs:85:53:85:53 | 2 | Patterns.cs:85:44:85:53 | [no-match] ... or ... | +| Patterns.cs:85:53:85:53 | 2 | Patterns.cs:85:49:85:53 | [match] not ... | +| Patterns.cs:85:53:85:53 | 2 | Patterns.cs:85:49:85:53 | [no-match] not ... | +| Patterns.cs:85:53:85:53 | 2 | Patterns.cs:85:53:85:53 | 2 | +| Patterns.cs:85:53:85:53 | 2 | Patterns.cs:85:67:85:69 | "2" | +| Patterns.cs:85:57:85:63 | "not 2" | Patterns.cs:85:57:85:63 | "not 2" | +| Patterns.cs:85:67:85:69 | "2" | Patterns.cs:85:67:85:69 | "2" | +| Patterns.cs:87:26:87:27 | enter M9 | Patterns.cs:87:26:87:27 | enter M9 | +| Patterns.cs:87:26:87:27 | enter M9 | Patterns.cs:87:39:87:54 | [false] ... is ... | +| Patterns.cs:87:26:87:27 | enter M9 | Patterns.cs:87:39:87:54 | [true] ... is ... | +| Patterns.cs:87:26:87:27 | enter M9 | Patterns.cs:87:39:87:70 | ... ? ... : ... | +| Patterns.cs:87:26:87:27 | enter M9 | Patterns.cs:87:44:87:54 | [match] ... and ... | +| Patterns.cs:87:26:87:27 | enter M9 | Patterns.cs:87:44:87:54 | [no-match] ... and ... | +| Patterns.cs:87:26:87:27 | enter M9 | Patterns.cs:87:50:87:54 | [match] not ... | +| Patterns.cs:87:26:87:27 | enter M9 | Patterns.cs:87:50:87:54 | [no-match] not ... | +| Patterns.cs:87:26:87:27 | enter M9 | Patterns.cs:87:54:87:54 | 2 | +| Patterns.cs:87:26:87:27 | enter M9 | Patterns.cs:87:58:87:60 | "1" | +| Patterns.cs:87:26:87:27 | enter M9 | Patterns.cs:87:64:87:70 | "not 1" | +| Patterns.cs:87:39:87:54 | [false] ... is ... | Patterns.cs:87:39:87:54 | [false] ... is ... | +| Patterns.cs:87:39:87:54 | [false] ... is ... | Patterns.cs:87:64:87:70 | "not 1" | +| Patterns.cs:87:39:87:54 | [true] ... is ... | Patterns.cs:87:39:87:54 | [true] ... is ... | +| Patterns.cs:87:39:87:54 | [true] ... is ... | Patterns.cs:87:58:87:60 | "1" | +| Patterns.cs:87:39:87:70 | ... ? ... : ... | Patterns.cs:87:39:87:70 | ... ? ... : ... | +| Patterns.cs:87:44:87:54 | [match] ... and ... | Patterns.cs:87:39:87:54 | [true] ... is ... | +| Patterns.cs:87:44:87:54 | [match] ... and ... | Patterns.cs:87:44:87:54 | [match] ... and ... | +| Patterns.cs:87:44:87:54 | [match] ... and ... | Patterns.cs:87:58:87:60 | "1" | +| Patterns.cs:87:44:87:54 | [no-match] ... and ... | Patterns.cs:87:39:87:54 | [false] ... is ... | +| Patterns.cs:87:44:87:54 | [no-match] ... and ... | Patterns.cs:87:44:87:54 | [no-match] ... and ... | +| Patterns.cs:87:44:87:54 | [no-match] ... and ... | Patterns.cs:87:64:87:70 | "not 1" | +| Patterns.cs:87:50:87:54 | [match] not ... | Patterns.cs:87:39:87:54 | [true] ... is ... | +| Patterns.cs:87:50:87:54 | [match] not ... | Patterns.cs:87:44:87:54 | [match] ... and ... | +| Patterns.cs:87:50:87:54 | [match] not ... | Patterns.cs:87:50:87:54 | [match] not ... | +| Patterns.cs:87:50:87:54 | [match] not ... | Patterns.cs:87:58:87:60 | "1" | +| Patterns.cs:87:50:87:54 | [no-match] not ... | Patterns.cs:87:50:87:54 | [no-match] not ... | +| Patterns.cs:87:54:87:54 | 2 | Patterns.cs:87:39:87:54 | [true] ... is ... | +| Patterns.cs:87:54:87:54 | 2 | Patterns.cs:87:44:87:54 | [match] ... and ... | +| Patterns.cs:87:54:87:54 | 2 | Patterns.cs:87:50:87:54 | [match] not ... | +| Patterns.cs:87:54:87:54 | 2 | Patterns.cs:87:50:87:54 | [no-match] not ... | +| Patterns.cs:87:54:87:54 | 2 | Patterns.cs:87:54:87:54 | 2 | +| Patterns.cs:87:54:87:54 | 2 | Patterns.cs:87:58:87:60 | "1" | +| Patterns.cs:87:58:87:60 | "1" | Patterns.cs:87:58:87:60 | "1" | +| Patterns.cs:87:64:87:70 | "not 1" | Patterns.cs:87:64:87:70 | "not 1" | +| Patterns.cs:93:17:93:19 | enter M10 | Patterns.cs:93:17:93:19 | enter M10 | +| Patterns.cs:93:17:93:19 | enter M10 | Patterns.cs:93:17:93:19 | exit M10 (normal) | +| Patterns.cs:93:17:93:19 | enter M10 | Patterns.cs:95:13:95:40 | [false] ... is ... | +| Patterns.cs:93:17:93:19 | enter M10 | Patterns.cs:95:13:95:40 | [true] ... is ... | +| Patterns.cs:93:17:93:19 | enter M10 | Patterns.cs:95:21:95:40 | [match] { ... } | +| Patterns.cs:93:17:93:19 | enter M10 | Patterns.cs:95:21:95:40 | [match] { ... } | +| Patterns.cs:93:17:93:19 | enter M10 | Patterns.cs:95:21:95:40 | [no-match] { ... } | +| Patterns.cs:93:17:93:19 | enter M10 | Patterns.cs:95:21:95:40 | [no-match] { ... } | +| Patterns.cs:93:17:93:19 | enter M10 | Patterns.cs:95:29:95:38 | [match] ... or ... | +| Patterns.cs:93:17:93:19 | enter M10 | Patterns.cs:95:29:95:38 | [no-match] ... or ... | +| Patterns.cs:93:17:93:19 | enter M10 | Patterns.cs:95:36:95:38 | access to constant B | +| Patterns.cs:93:17:93:19 | enter M10 | Patterns.cs:96:9:98:9 | {...} | +| Patterns.cs:93:17:93:19 | exit M10 (normal) | Patterns.cs:93:17:93:19 | exit M10 (normal) | +| Patterns.cs:95:13:95:40 | [false] ... is ... | Patterns.cs:95:13:95:40 | [false] ... is ... | +| Patterns.cs:95:13:95:40 | [true] ... is ... | Patterns.cs:95:13:95:40 | [true] ... is ... | +| Patterns.cs:95:13:95:40 | [true] ... is ... | Patterns.cs:96:9:98:9 | {...} | +| Patterns.cs:95:21:95:40 | [match] { ... } | Patterns.cs:95:13:95:40 | [true] ... is ... | +| Patterns.cs:95:21:95:40 | [match] { ... } | Patterns.cs:95:13:95:40 | [true] ... is ... | +| Patterns.cs:95:21:95:40 | [match] { ... } | Patterns.cs:95:21:95:40 | [match] { ... } | +| Patterns.cs:95:21:95:40 | [match] { ... } | Patterns.cs:95:21:95:40 | [match] { ... } | +| Patterns.cs:95:21:95:40 | [match] { ... } | Patterns.cs:95:21:95:40 | [match] { ... } | +| Patterns.cs:95:21:95:40 | [match] { ... } | Patterns.cs:96:9:98:9 | {...} | +| Patterns.cs:95:21:95:40 | [match] { ... } | Patterns.cs:96:9:98:9 | {...} | +| Patterns.cs:95:21:95:40 | [no-match] { ... } | Patterns.cs:95:13:95:40 | [false] ... is ... | +| Patterns.cs:95:21:95:40 | [no-match] { ... } | Patterns.cs:95:13:95:40 | [false] ... is ... | +| Patterns.cs:95:21:95:40 | [no-match] { ... } | Patterns.cs:95:21:95:40 | [no-match] { ... } | +| Patterns.cs:95:21:95:40 | [no-match] { ... } | Patterns.cs:95:21:95:40 | [no-match] { ... } | +| Patterns.cs:95:21:95:40 | [no-match] { ... } | Patterns.cs:95:21:95:40 | [no-match] { ... } | +| Patterns.cs:95:29:95:38 | [match] ... or ... | Patterns.cs:95:13:95:40 | [true] ... is ... | +| Patterns.cs:95:29:95:38 | [match] ... or ... | Patterns.cs:95:21:95:40 | [match] { ... } | +| Patterns.cs:95:29:95:38 | [match] ... or ... | Patterns.cs:95:21:95:40 | [match] { ... } | +| Patterns.cs:95:29:95:38 | [match] ... or ... | Patterns.cs:95:29:95:38 | [match] ... or ... | +| Patterns.cs:95:29:95:38 | [match] ... or ... | Patterns.cs:96:9:98:9 | {...} | +| Patterns.cs:95:29:95:38 | [no-match] ... or ... | Patterns.cs:95:13:95:40 | [false] ... is ... | +| Patterns.cs:95:29:95:38 | [no-match] ... or ... | Patterns.cs:95:21:95:40 | [no-match] { ... } | +| Patterns.cs:95:29:95:38 | [no-match] ... or ... | Patterns.cs:95:21:95:40 | [no-match] { ... } | +| Patterns.cs:95:29:95:38 | [no-match] ... or ... | Patterns.cs:95:29:95:38 | [no-match] ... or ... | +| Patterns.cs:95:36:95:38 | access to constant B | Patterns.cs:95:13:95:40 | [false] ... is ... | +| Patterns.cs:95:36:95:38 | access to constant B | Patterns.cs:95:21:95:40 | [no-match] { ... } | +| Patterns.cs:95:36:95:38 | access to constant B | Patterns.cs:95:21:95:40 | [no-match] { ... } | +| Patterns.cs:95:36:95:38 | access to constant B | Patterns.cs:95:29:95:38 | [no-match] ... or ... | +| Patterns.cs:95:36:95:38 | access to constant B | Patterns.cs:95:36:95:38 | access to constant B | +| Patterns.cs:96:9:98:9 | {...} | Patterns.cs:96:9:98:9 | {...} | | PostDominance.cs:5:10:5:11 | enter M1 | PostDominance.cs:5:10:5:11 | enter M1 | | PostDominance.cs:10:10:10:11 | enter M2 | PostDominance.cs:10:10:10:11 | enter M2 | | PostDominance.cs:10:10:10:11 | enter M2 | PostDominance.cs:10:10:10:11 | exit M2 (normal) | +| PostDominance.cs:10:10:10:11 | enter M2 | PostDominance.cs:12:13:12:21 | [false] ... is ... | +| PostDominance.cs:10:10:10:11 | enter M2 | PostDominance.cs:12:13:12:21 | [true] ... is ... | | PostDominance.cs:10:10:10:11 | enter M2 | PostDominance.cs:13:13:13:19 | return ...; | | PostDominance.cs:10:10:10:11 | enter M2 | PostDominance.cs:14:9:14:29 | ...; | | PostDominance.cs:10:10:10:11 | exit M2 (normal) | PostDominance.cs:10:10:10:11 | exit M2 (normal) | +| PostDominance.cs:12:13:12:21 | [false] ... is ... | PostDominance.cs:12:13:12:21 | [false] ... is ... | +| PostDominance.cs:12:13:12:21 | [false] ... is ... | PostDominance.cs:14:9:14:29 | ...; | +| PostDominance.cs:12:13:12:21 | [true] ... is ... | PostDominance.cs:12:13:12:21 | [true] ... is ... | +| PostDominance.cs:12:13:12:21 | [true] ... is ... | PostDominance.cs:13:13:13:19 | return ...; | | PostDominance.cs:13:13:13:19 | return ...; | PostDominance.cs:13:13:13:19 | return ...; | | PostDominance.cs:14:9:14:29 | ...; | PostDominance.cs:14:9:14:29 | ...; | | PostDominance.cs:17:10:17:11 | enter M3 | PostDominance.cs:17:10:17:11 | enter M3 | | PostDominance.cs:17:10:17:11 | enter M3 | PostDominance.cs:17:10:17:11 | exit M3 | +| PostDominance.cs:17:10:17:11 | enter M3 | PostDominance.cs:19:13:19:21 | [false] ... is ... | +| PostDominance.cs:17:10:17:11 | enter M3 | PostDominance.cs:19:13:19:21 | [true] ... is ... | | PostDominance.cs:17:10:17:11 | enter M3 | PostDominance.cs:20:45:20:53 | nameof(...) | | PostDominance.cs:17:10:17:11 | enter M3 | PostDominance.cs:21:9:21:29 | ...; | | PostDominance.cs:17:10:17:11 | exit M3 | PostDominance.cs:17:10:17:11 | exit M3 | +| PostDominance.cs:19:13:19:21 | [false] ... is ... | PostDominance.cs:19:13:19:21 | [false] ... is ... | +| PostDominance.cs:19:13:19:21 | [false] ... is ... | PostDominance.cs:21:9:21:29 | ...; | +| PostDominance.cs:19:13:19:21 | [true] ... is ... | PostDominance.cs:19:13:19:21 | [true] ... is ... | +| PostDominance.cs:19:13:19:21 | [true] ... is ... | PostDominance.cs:20:45:20:53 | nameof(...) | | PostDominance.cs:20:45:20:53 | nameof(...) | PostDominance.cs:20:45:20:53 | nameof(...) | | PostDominance.cs:21:9:21:29 | ...; | PostDominance.cs:21:9:21:29 | ...; | | Qualifiers.cs:7:16:7:21 | enter Method | Qualifiers.cs:7:16:7:21 | enter Method | @@ -11706,8 +12327,13 @@ blockDominance | Switch.cs:158:13:158:49 | ...; | Switch.cs:158:13:158:49 | ...; | | Switch.cs:160:13:160:49 | ...; | Switch.cs:160:13:160:49 | ...; | | TypeAccesses.cs:3:10:3:10 | enter M | TypeAccesses.cs:3:10:3:10 | enter M | +| TypeAccesses.cs:3:10:3:10 | enter M | TypeAccesses.cs:7:13:7:22 | [false] ... is ... | +| TypeAccesses.cs:3:10:3:10 | enter M | TypeAccesses.cs:7:13:7:22 | [true] ... is ... | | TypeAccesses.cs:3:10:3:10 | enter M | TypeAccesses.cs:7:25:7:25 | ; | | TypeAccesses.cs:3:10:3:10 | enter M | TypeAccesses.cs:8:9:8:28 | ... ...; | +| TypeAccesses.cs:7:13:7:22 | [false] ... is ... | TypeAccesses.cs:7:13:7:22 | [false] ... is ... | +| TypeAccesses.cs:7:13:7:22 | [true] ... is ... | TypeAccesses.cs:7:13:7:22 | [true] ... is ... | +| TypeAccesses.cs:7:13:7:22 | [true] ... is ... | TypeAccesses.cs:7:25:7:25 | ; | | TypeAccesses.cs:7:25:7:25 | ; | TypeAccesses.cs:7:25:7:25 | ; | | TypeAccesses.cs:8:9:8:28 | ... ...; | TypeAccesses.cs:8:9:8:28 | ... ...; | | VarDecls.cs:5:18:5:19 | enter M1 | VarDecls.cs:5:18:5:19 | enter M1 | @@ -13702,156 +14328,126 @@ postBlockDominance | Conditions.cs:147:13:147:49 | ...; | Conditions.cs:147:13:147:49 | ...; | | Conditions.cs:149:13:149:49 | ...; | Conditions.cs:145:27:145:29 | [b (line 143): false] "b" | | Conditions.cs:149:13:149:49 | ...; | Conditions.cs:149:13:149:49 | ...; | -| ExitMethods.cs:7:10:7:11 | enter M1 | ExitMethods.cs:7:10:7:11 | enter M1 | -| ExitMethods.cs:13:10:13:11 | enter M2 | ExitMethods.cs:13:10:13:11 | enter M2 | -| ExitMethods.cs:19:10:19:11 | enter M3 | ExitMethods.cs:19:10:19:11 | enter M3 | -| ExitMethods.cs:25:10:25:11 | enter M4 | ExitMethods.cs:25:10:25:11 | enter M4 | -| ExitMethods.cs:31:10:31:11 | enter M5 | ExitMethods.cs:31:10:31:11 | enter M5 | -| ExitMethods.cs:37:10:37:11 | enter M6 | ExitMethods.cs:37:10:37:11 | enter M6 | -| ExitMethods.cs:37:10:37:11 | exit M6 (normal) | ExitMethods.cs:37:10:37:11 | enter M6 | -| ExitMethods.cs:37:10:37:11 | exit M6 (normal) | ExitMethods.cs:37:10:37:11 | exit M6 (normal) | -| ExitMethods.cs:37:10:37:11 | exit M6 (normal) | ExitMethods.cs:43:9:46:9 | [exception: ArgumentException] catch (...) {...} | -| ExitMethods.cs:37:10:37:11 | exit M6 (normal) | ExitMethods.cs:43:9:46:9 | [exception: Exception] catch (...) {...} | -| ExitMethods.cs:37:10:37:11 | exit M6 (normal) | ExitMethods.cs:44:9:46:9 | {...} | -| ExitMethods.cs:37:10:37:11 | exit M6 (normal) | ExitMethods.cs:47:9:50:9 | [exception: Exception] catch (...) {...} | -| ExitMethods.cs:37:10:37:11 | exit M6 (normal) | ExitMethods.cs:48:9:50:9 | {...} | -| ExitMethods.cs:43:9:46:9 | [exception: ArgumentException] catch (...) {...} | ExitMethods.cs:43:9:46:9 | [exception: ArgumentException] catch (...) {...} | -| ExitMethods.cs:43:9:46:9 | [exception: Exception] catch (...) {...} | ExitMethods.cs:43:9:46:9 | [exception: Exception] catch (...) {...} | -| ExitMethods.cs:44:9:46:9 | {...} | ExitMethods.cs:43:9:46:9 | [exception: ArgumentException] catch (...) {...} | -| ExitMethods.cs:44:9:46:9 | {...} | ExitMethods.cs:44:9:46:9 | {...} | -| ExitMethods.cs:47:9:50:9 | [exception: Exception] catch (...) {...} | ExitMethods.cs:47:9:50:9 | [exception: Exception] catch (...) {...} | -| ExitMethods.cs:48:9:50:9 | {...} | ExitMethods.cs:47:9:50:9 | [exception: Exception] catch (...) {...} | -| ExitMethods.cs:48:9:50:9 | {...} | ExitMethods.cs:48:9:50:9 | {...} | -| ExitMethods.cs:53:10:53:11 | enter M7 | ExitMethods.cs:53:10:53:11 | enter M7 | -| ExitMethods.cs:59:10:59:11 | enter M8 | ExitMethods.cs:59:10:59:11 | enter M8 | -| ExitMethods.cs:65:17:65:26 | enter ErrorMaybe | ExitMethods.cs:65:17:65:26 | enter ErrorMaybe | -| ExitMethods.cs:65:17:65:26 | exit ErrorMaybe | ExitMethods.cs:65:17:65:26 | exit ErrorMaybe | -| ExitMethods.cs:65:17:65:26 | exit ErrorMaybe (normal) | ExitMethods.cs:65:17:65:26 | enter ErrorMaybe | -| ExitMethods.cs:65:17:65:26 | exit ErrorMaybe (normal) | ExitMethods.cs:65:17:65:26 | exit ErrorMaybe (normal) | -| ExitMethods.cs:68:19:68:33 | object creation of type Exception | ExitMethods.cs:68:19:68:33 | object creation of type Exception | -| ExitMethods.cs:71:17:71:27 | enter ErrorAlways | ExitMethods.cs:71:17:71:27 | enter ErrorAlways | -| ExitMethods.cs:71:17:71:27 | exit ErrorAlways (abnormal) | ExitMethods.cs:71:17:71:27 | exit ErrorAlways (abnormal) | -| ExitMethods.cs:74:19:74:33 | object creation of type Exception | ExitMethods.cs:74:19:74:33 | object creation of type Exception | -| ExitMethods.cs:76:41:76:43 | "b" | ExitMethods.cs:76:41:76:43 | "b" | -| ExitMethods.cs:79:17:79:28 | enter ErrorAlways2 | ExitMethods.cs:79:17:79:28 | enter ErrorAlways2 | -| ExitMethods.cs:84:17:84:28 | enter ErrorAlways3 | ExitMethods.cs:84:17:84:28 | enter ErrorAlways3 | -| ExitMethods.cs:86:10:86:13 | enter Exit | ExitMethods.cs:86:10:86:13 | enter Exit | -| ExitMethods.cs:91:10:91:18 | enter ExitInTry | ExitMethods.cs:91:10:91:18 | enter ExitInTry | -| ExitMethods.cs:104:10:104:24 | enter ApplicationExit | ExitMethods.cs:104:10:104:24 | enter ApplicationExit | -| ExitMethods.cs:109:13:109:21 | enter ThrowExpr | ExitMethods.cs:109:13:109:21 | enter ThrowExpr | -| ExitMethods.cs:109:13:109:21 | exit ThrowExpr | ExitMethods.cs:109:13:109:21 | exit ThrowExpr | -| ExitMethods.cs:111:29:111:29 | 1 | ExitMethods.cs:109:13:109:21 | enter ThrowExpr | -| ExitMethods.cs:111:29:111:29 | 1 | ExitMethods.cs:111:29:111:29 | 1 | -| ExitMethods.cs:111:69:111:75 | "input" | ExitMethods.cs:111:69:111:75 | "input" | -| ExitMethods.cs:114:16:114:34 | enter ExtensionMethodCall | ExitMethods.cs:114:16:114:34 | enter ExtensionMethodCall | -| ExitMethods.cs:116:16:116:38 | ... ? ... : ... | ExitMethods.cs:114:16:114:34 | enter ExtensionMethodCall | -| ExitMethods.cs:116:16:116:38 | ... ? ... : ... | ExitMethods.cs:116:16:116:38 | ... ? ... : ... | -| ExitMethods.cs:116:16:116:38 | ... ? ... : ... | ExitMethods.cs:116:34:116:34 | 0 | -| ExitMethods.cs:116:16:116:38 | ... ? ... : ... | ExitMethods.cs:116:38:116:38 | 1 | -| ExitMethods.cs:116:34:116:34 | 0 | ExitMethods.cs:116:34:116:34 | 0 | -| ExitMethods.cs:116:38:116:38 | 1 | ExitMethods.cs:116:38:116:38 | 1 | -| ExitMethods.cs:119:17:119:32 | enter FailingAssertion | ExitMethods.cs:119:17:119:32 | enter FailingAssertion | -| ExitMethods.cs:121:9:121:28 | [assertion failure] call to method IsTrue | ExitMethods.cs:121:9:121:28 | [assertion failure] call to method IsTrue | -| ExitMethods.cs:125:17:125:33 | enter FailingAssertion2 | ExitMethods.cs:125:17:125:33 | enter FailingAssertion2 | -| ExitMethods.cs:131:10:131:20 | enter AssertFalse | ExitMethods.cs:131:10:131:20 | enter AssertFalse | -| ExitMethods.cs:131:10:131:20 | exit AssertFalse | ExitMethods.cs:131:10:131:20 | exit AssertFalse | -| ExitMethods.cs:131:33:131:49 | [assertion failure] call to method IsFalse | ExitMethods.cs:131:33:131:49 | [assertion failure] call to method IsFalse | -| ExitMethods.cs:131:33:131:49 | [assertion success] call to method IsFalse | ExitMethods.cs:131:10:131:20 | enter AssertFalse | -| ExitMethods.cs:131:33:131:49 | [assertion success] call to method IsFalse | ExitMethods.cs:131:33:131:49 | [assertion success] call to method IsFalse | -| ExitMethods.cs:133:17:133:33 | enter FailingAssertion3 | ExitMethods.cs:133:17:133:33 | enter FailingAssertion3 | -| ExitMethods.cs:135:9:135:25 | [assertion failure] call to method AssertFalse | ExitMethods.cs:135:9:135:25 | [assertion failure] call to method AssertFalse | +| ExitMethods.cs:8:10:8:11 | enter M1 | ExitMethods.cs:8:10:8:11 | enter M1 | +| ExitMethods.cs:14:10:14:11 | enter M2 | ExitMethods.cs:14:10:14:11 | enter M2 | +| ExitMethods.cs:20:10:20:11 | enter M3 | ExitMethods.cs:20:10:20:11 | enter M3 | +| ExitMethods.cs:26:10:26:11 | enter M4 | ExitMethods.cs:26:10:26:11 | enter M4 | +| ExitMethods.cs:32:10:32:11 | enter M5 | ExitMethods.cs:32:10:32:11 | enter M5 | +| ExitMethods.cs:38:10:38:11 | enter M6 | ExitMethods.cs:38:10:38:11 | enter M6 | +| ExitMethods.cs:38:10:38:11 | exit M6 (normal) | ExitMethods.cs:38:10:38:11 | enter M6 | +| ExitMethods.cs:38:10:38:11 | exit M6 (normal) | ExitMethods.cs:38:10:38:11 | exit M6 (normal) | +| ExitMethods.cs:38:10:38:11 | exit M6 (normal) | ExitMethods.cs:44:9:47:9 | [exception: ArgumentException] catch (...) {...} | +| ExitMethods.cs:38:10:38:11 | exit M6 (normal) | ExitMethods.cs:44:9:47:9 | [exception: Exception] catch (...) {...} | +| ExitMethods.cs:38:10:38:11 | exit M6 (normal) | ExitMethods.cs:45:9:47:9 | {...} | +| ExitMethods.cs:38:10:38:11 | exit M6 (normal) | ExitMethods.cs:48:9:51:9 | [exception: Exception] catch (...) {...} | +| ExitMethods.cs:38:10:38:11 | exit M6 (normal) | ExitMethods.cs:49:9:51:9 | {...} | +| ExitMethods.cs:44:9:47:9 | [exception: ArgumentException] catch (...) {...} | ExitMethods.cs:44:9:47:9 | [exception: ArgumentException] catch (...) {...} | +| ExitMethods.cs:44:9:47:9 | [exception: Exception] catch (...) {...} | ExitMethods.cs:44:9:47:9 | [exception: Exception] catch (...) {...} | +| ExitMethods.cs:45:9:47:9 | {...} | ExitMethods.cs:44:9:47:9 | [exception: ArgumentException] catch (...) {...} | +| ExitMethods.cs:45:9:47:9 | {...} | ExitMethods.cs:45:9:47:9 | {...} | +| ExitMethods.cs:48:9:51:9 | [exception: Exception] catch (...) {...} | ExitMethods.cs:48:9:51:9 | [exception: Exception] catch (...) {...} | +| ExitMethods.cs:49:9:51:9 | {...} | ExitMethods.cs:48:9:51:9 | [exception: Exception] catch (...) {...} | +| ExitMethods.cs:49:9:51:9 | {...} | ExitMethods.cs:49:9:51:9 | {...} | +| ExitMethods.cs:54:10:54:11 | enter M7 | ExitMethods.cs:54:10:54:11 | enter M7 | +| ExitMethods.cs:60:10:60:11 | enter M8 | ExitMethods.cs:60:10:60:11 | enter M8 | +| ExitMethods.cs:66:17:66:26 | enter ErrorMaybe | ExitMethods.cs:66:17:66:26 | enter ErrorMaybe | +| ExitMethods.cs:66:17:66:26 | exit ErrorMaybe | ExitMethods.cs:66:17:66:26 | exit ErrorMaybe | +| ExitMethods.cs:66:17:66:26 | exit ErrorMaybe (normal) | ExitMethods.cs:66:17:66:26 | enter ErrorMaybe | +| ExitMethods.cs:66:17:66:26 | exit ErrorMaybe (normal) | ExitMethods.cs:66:17:66:26 | exit ErrorMaybe (normal) | +| ExitMethods.cs:69:19:69:33 | object creation of type Exception | ExitMethods.cs:69:19:69:33 | object creation of type Exception | +| ExitMethods.cs:72:17:72:27 | enter ErrorAlways | ExitMethods.cs:72:17:72:27 | enter ErrorAlways | +| ExitMethods.cs:72:17:72:27 | exit ErrorAlways (abnormal) | ExitMethods.cs:72:17:72:27 | exit ErrorAlways (abnormal) | +| ExitMethods.cs:75:19:75:33 | object creation of type Exception | ExitMethods.cs:75:19:75:33 | object creation of type Exception | +| ExitMethods.cs:77:41:77:43 | "b" | ExitMethods.cs:77:41:77:43 | "b" | +| ExitMethods.cs:80:17:80:28 | enter ErrorAlways2 | ExitMethods.cs:80:17:80:28 | enter ErrorAlways2 | +| ExitMethods.cs:85:17:85:28 | enter ErrorAlways3 | ExitMethods.cs:85:17:85:28 | enter ErrorAlways3 | +| ExitMethods.cs:87:10:87:13 | enter Exit | ExitMethods.cs:87:10:87:13 | enter Exit | +| ExitMethods.cs:92:10:92:18 | enter ExitInTry | ExitMethods.cs:92:10:92:18 | enter ExitInTry | +| ExitMethods.cs:105:10:105:24 | enter ApplicationExit | ExitMethods.cs:105:10:105:24 | enter ApplicationExit | +| ExitMethods.cs:110:13:110:21 | enter ThrowExpr | ExitMethods.cs:110:13:110:21 | enter ThrowExpr | +| ExitMethods.cs:110:13:110:21 | exit ThrowExpr | ExitMethods.cs:110:13:110:21 | exit ThrowExpr | +| ExitMethods.cs:112:29:112:29 | 1 | ExitMethods.cs:110:13:110:21 | enter ThrowExpr | +| ExitMethods.cs:112:29:112:29 | 1 | ExitMethods.cs:112:29:112:29 | 1 | +| ExitMethods.cs:112:69:112:75 | "input" | ExitMethods.cs:112:69:112:75 | "input" | +| ExitMethods.cs:115:16:115:34 | enter ExtensionMethodCall | ExitMethods.cs:115:16:115:34 | enter ExtensionMethodCall | +| ExitMethods.cs:117:16:117:38 | ... ? ... : ... | ExitMethods.cs:115:16:115:34 | enter ExtensionMethodCall | +| ExitMethods.cs:117:16:117:38 | ... ? ... : ... | ExitMethods.cs:117:16:117:38 | ... ? ... : ... | +| ExitMethods.cs:117:16:117:38 | ... ? ... : ... | ExitMethods.cs:117:34:117:34 | 0 | +| ExitMethods.cs:117:16:117:38 | ... ? ... : ... | ExitMethods.cs:117:38:117:38 | 1 | +| ExitMethods.cs:117:34:117:34 | 0 | ExitMethods.cs:117:34:117:34 | 0 | +| ExitMethods.cs:117:38:117:38 | 1 | ExitMethods.cs:117:38:117:38 | 1 | +| ExitMethods.cs:120:17:120:32 | enter FailingAssertion | ExitMethods.cs:120:17:120:32 | enter FailingAssertion | +| ExitMethods.cs:122:9:122:28 | [assertion failure] call to method IsTrue | ExitMethods.cs:122:9:122:28 | [assertion failure] call to method IsTrue | +| ExitMethods.cs:126:17:126:33 | enter FailingAssertion2 | ExitMethods.cs:126:17:126:33 | enter FailingAssertion2 | +| ExitMethods.cs:132:10:132:20 | enter AssertFalse | ExitMethods.cs:132:10:132:20 | enter AssertFalse | +| ExitMethods.cs:132:10:132:20 | exit AssertFalse | ExitMethods.cs:132:10:132:20 | exit AssertFalse | +| ExitMethods.cs:132:33:132:49 | [assertion failure] call to method IsFalse | ExitMethods.cs:132:33:132:49 | [assertion failure] call to method IsFalse | +| ExitMethods.cs:132:33:132:49 | [assertion success] call to method IsFalse | ExitMethods.cs:132:10:132:20 | enter AssertFalse | +| ExitMethods.cs:132:33:132:49 | [assertion success] call to method IsFalse | ExitMethods.cs:132:33:132:49 | [assertion success] call to method IsFalse | +| ExitMethods.cs:134:17:134:33 | enter FailingAssertion3 | ExitMethods.cs:134:17:134:33 | enter FailingAssertion3 | +| ExitMethods.cs:136:9:136:25 | [assertion failure] call to method AssertFalse | ExitMethods.cs:136:9:136:25 | [assertion failure] call to method AssertFalse | +| ExitMethods.cs:140:17:140:42 | enter ExceptionDispatchInfoThrow | ExitMethods.cs:140:17:140:42 | enter ExceptionDispatchInfoThrow | +| ExitMethods.cs:140:17:140:42 | exit ExceptionDispatchInfoThrow (abnormal) | ExitMethods.cs:140:17:140:42 | exit ExceptionDispatchInfoThrow (abnormal) | +| ExitMethods.cs:143:13:143:43 | ...; | ExitMethods.cs:143:13:143:43 | ...; | +| ExitMethods.cs:145:13:145:53 | ...; | ExitMethods.cs:145:13:145:53 | ...; | | Extensions.cs:5:23:5:29 | enter ToInt32 | Extensions.cs:5:23:5:29 | enter ToInt32 | | Extensions.cs:10:24:10:29 | enter ToBool | Extensions.cs:10:24:10:29 | enter ToBool | | Extensions.cs:15:23:15:33 | enter CallToInt32 | Extensions.cs:15:23:15:33 | enter CallToInt32 | | Extensions.cs:20:17:20:20 | enter Main | Extensions.cs:20:17:20:20 | enter Main | | Finally.cs:7:10:7:11 | enter M1 | Finally.cs:7:10:7:11 | enter M1 | | Finally.cs:7:10:7:11 | exit M1 | Finally.cs:7:10:7:11 | exit M1 | -| Finally.cs:7:10:7:11 | exit M1 (abnormal) | Finally.cs:7:10:7:11 | exit M1 (abnormal) | -| Finally.cs:11:13:11:37 | call to method WriteLine | Finally.cs:7:10:7:11 | enter M1 | -| Finally.cs:11:13:11:37 | call to method WriteLine | Finally.cs:11:13:11:37 | call to method WriteLine | | Finally.cs:14:9:16:9 | [finally: exception(Exception)] {...} | Finally.cs:14:9:16:9 | [finally: exception(Exception)] {...} | -| Finally.cs:14:9:16:9 | [finally: exception(OutOfMemoryException)] {...} | Finally.cs:14:9:16:9 | [finally: exception(OutOfMemoryException)] {...} | | Finally.cs:14:9:16:9 | {...} | Finally.cs:7:10:7:11 | enter M1 | -| Finally.cs:14:9:16:9 | {...} | Finally.cs:11:13:11:37 | call to method WriteLine | | Finally.cs:14:9:16:9 | {...} | Finally.cs:14:9:16:9 | {...} | | Finally.cs:19:10:19:11 | enter M2 | Finally.cs:19:10:19:11 | enter M2 | | Finally.cs:19:10:19:11 | exit M2 | Finally.cs:19:10:19:11 | exit M2 | | Finally.cs:19:10:19:11 | exit M2 (abnormal) | Finally.cs:19:10:19:11 | exit M2 (abnormal) | | Finally.cs:19:10:19:11 | exit M2 (normal) | Finally.cs:19:10:19:11 | enter M2 | | Finally.cs:19:10:19:11 | exit M2 (normal) | Finally.cs:19:10:19:11 | exit M2 (normal) | -| Finally.cs:19:10:19:11 | exit M2 (normal) | Finally.cs:23:13:23:37 | call to method WriteLine | | Finally.cs:19:10:19:11 | exit M2 (normal) | Finally.cs:24:13:24:19 | return ...; | | Finally.cs:19:10:19:11 | exit M2 (normal) | Finally.cs:26:9:29:9 | [exception: Exception] catch (...) {...} | -| Finally.cs:19:10:19:11 | exit M2 (normal) | Finally.cs:26:9:29:9 | [exception: OutOfMemoryException] catch (...) {...} | | Finally.cs:19:10:19:11 | exit M2 (normal) | Finally.cs:30:9:40:9 | [exception: Exception] catch (...) {...} | -| Finally.cs:19:10:19:11 | exit M2 (normal) | Finally.cs:30:9:40:9 | [exception: OutOfMemoryException] catch (...) {...} | | Finally.cs:19:10:19:11 | exit M2 (normal) | Finally.cs:41:9:43:9 | [exception: Exception] catch (...) {...} | -| Finally.cs:19:10:19:11 | exit M2 (normal) | Finally.cs:41:9:43:9 | [exception: OutOfMemoryException] catch (...) {...} | | Finally.cs:19:10:19:11 | exit M2 (normal) | Finally.cs:42:9:43:9 | {...} | -| Finally.cs:23:13:23:37 | call to method WriteLine | Finally.cs:23:13:23:37 | call to method WriteLine | | Finally.cs:24:13:24:19 | return ...; | Finally.cs:24:13:24:19 | return ...; | | Finally.cs:26:9:29:9 | [exception: Exception] catch (...) {...} | Finally.cs:26:9:29:9 | [exception: Exception] catch (...) {...} | -| Finally.cs:26:9:29:9 | [exception: OutOfMemoryException] catch (...) {...} | Finally.cs:26:9:29:9 | [exception: OutOfMemoryException] catch (...) {...} | | Finally.cs:26:38:26:39 | [exception: Exception] IOException ex | Finally.cs:26:38:26:39 | [exception: Exception] IOException ex | | Finally.cs:27:9:29:9 | {...} | Finally.cs:27:9:29:9 | {...} | | Finally.cs:30:9:40:9 | [exception: Exception] catch (...) {...} | Finally.cs:26:9:29:9 | [exception: Exception] catch (...) {...} | | Finally.cs:30:9:40:9 | [exception: Exception] catch (...) {...} | Finally.cs:30:9:40:9 | [exception: Exception] catch (...) {...} | -| Finally.cs:30:9:40:9 | [exception: OutOfMemoryException] catch (...) {...} | Finally.cs:26:9:29:9 | [exception: OutOfMemoryException] catch (...) {...} | -| Finally.cs:30:9:40:9 | [exception: OutOfMemoryException] catch (...) {...} | Finally.cs:30:9:40:9 | [exception: OutOfMemoryException] catch (...) {...} | | Finally.cs:30:41:30:42 | [exception: Exception] ArgumentException ex | Finally.cs:30:41:30:42 | [exception: Exception] ArgumentException ex | | Finally.cs:34:27:34:32 | throw ...; | Finally.cs:34:27:34:32 | throw ...; | | Finally.cs:41:9:43:9 | [exception: Exception] catch (...) {...} | Finally.cs:26:9:29:9 | [exception: Exception] catch (...) {...} | | Finally.cs:41:9:43:9 | [exception: Exception] catch (...) {...} | Finally.cs:30:9:40:9 | [exception: Exception] catch (...) {...} | | Finally.cs:41:9:43:9 | [exception: Exception] catch (...) {...} | Finally.cs:41:9:43:9 | [exception: Exception] catch (...) {...} | -| Finally.cs:41:9:43:9 | [exception: OutOfMemoryException] catch (...) {...} | Finally.cs:26:9:29:9 | [exception: OutOfMemoryException] catch (...) {...} | -| Finally.cs:41:9:43:9 | [exception: OutOfMemoryException] catch (...) {...} | Finally.cs:30:9:40:9 | [exception: OutOfMemoryException] catch (...) {...} | -| Finally.cs:41:9:43:9 | [exception: OutOfMemoryException] catch (...) {...} | Finally.cs:41:9:43:9 | [exception: OutOfMemoryException] catch (...) {...} | | Finally.cs:42:9:43:9 | {...} | Finally.cs:26:9:29:9 | [exception: Exception] catch (...) {...} | -| Finally.cs:42:9:43:9 | {...} | Finally.cs:26:9:29:9 | [exception: OutOfMemoryException] catch (...) {...} | | Finally.cs:42:9:43:9 | {...} | Finally.cs:30:9:40:9 | [exception: Exception] catch (...) {...} | -| Finally.cs:42:9:43:9 | {...} | Finally.cs:30:9:40:9 | [exception: OutOfMemoryException] catch (...) {...} | | Finally.cs:42:9:43:9 | {...} | Finally.cs:41:9:43:9 | [exception: Exception] catch (...) {...} | -| Finally.cs:42:9:43:9 | {...} | Finally.cs:41:9:43:9 | [exception: OutOfMemoryException] catch (...) {...} | | Finally.cs:42:9:43:9 | {...} | Finally.cs:42:9:43:9 | {...} | | Finally.cs:54:10:54:11 | enter M3 | Finally.cs:54:10:54:11 | enter M3 | | Finally.cs:54:10:54:11 | exit M3 | Finally.cs:54:10:54:11 | exit M3 | | Finally.cs:54:10:54:11 | exit M3 (abnormal) | Finally.cs:54:10:54:11 | exit M3 (abnormal) | | Finally.cs:54:10:54:11 | exit M3 (normal) | Finally.cs:54:10:54:11 | enter M3 | | Finally.cs:54:10:54:11 | exit M3 (normal) | Finally.cs:54:10:54:11 | exit M3 (normal) | -| Finally.cs:54:10:54:11 | exit M3 (normal) | Finally.cs:58:13:58:37 | call to method WriteLine | | Finally.cs:54:10:54:11 | exit M3 (normal) | Finally.cs:59:13:59:19 | return ...; | | Finally.cs:54:10:54:11 | exit M3 (normal) | Finally.cs:61:9:64:9 | [exception: Exception] catch (...) {...} | -| Finally.cs:54:10:54:11 | exit M3 (normal) | Finally.cs:61:9:64:9 | [exception: OutOfMemoryException] catch (...) {...} | | Finally.cs:54:10:54:11 | exit M3 (normal) | Finally.cs:65:9:67:9 | [exception: Exception] catch (...) {...} | -| Finally.cs:54:10:54:11 | exit M3 (normal) | Finally.cs:65:9:67:9 | [exception: OutOfMemoryException] catch (...) {...} | | Finally.cs:54:10:54:11 | exit M3 (normal) | Finally.cs:65:26:65:26 | [exception: Exception] Exception e | -| Finally.cs:54:10:54:11 | exit M3 (normal) | Finally.cs:65:26:65:26 | [exception: OutOfMemoryException] Exception e | | Finally.cs:54:10:54:11 | exit M3 (normal) | Finally.cs:66:9:67:9 | {...} | -| Finally.cs:58:13:58:37 | call to method WriteLine | Finally.cs:58:13:58:37 | call to method WriteLine | | Finally.cs:59:13:59:19 | return ...; | Finally.cs:59:13:59:19 | return ...; | | Finally.cs:61:9:64:9 | [exception: Exception] catch (...) {...} | Finally.cs:61:9:64:9 | [exception: Exception] catch (...) {...} | -| Finally.cs:61:9:64:9 | [exception: OutOfMemoryException] catch (...) {...} | Finally.cs:61:9:64:9 | [exception: OutOfMemoryException] catch (...) {...} | | Finally.cs:61:38:61:39 | [exception: Exception] IOException ex | Finally.cs:61:38:61:39 | [exception: Exception] IOException ex | | Finally.cs:62:9:64:9 | {...} | Finally.cs:62:9:64:9 | {...} | | Finally.cs:65:9:67:9 | [exception: Exception] catch (...) {...} | Finally.cs:61:9:64:9 | [exception: Exception] catch (...) {...} | | Finally.cs:65:9:67:9 | [exception: Exception] catch (...) {...} | Finally.cs:65:9:67:9 | [exception: Exception] catch (...) {...} | -| Finally.cs:65:9:67:9 | [exception: OutOfMemoryException] catch (...) {...} | Finally.cs:61:9:64:9 | [exception: OutOfMemoryException] catch (...) {...} | -| Finally.cs:65:9:67:9 | [exception: OutOfMemoryException] catch (...) {...} | Finally.cs:65:9:67:9 | [exception: OutOfMemoryException] catch (...) {...} | | Finally.cs:65:26:65:26 | [exception: Exception] Exception e | Finally.cs:61:9:64:9 | [exception: Exception] catch (...) {...} | | Finally.cs:65:26:65:26 | [exception: Exception] Exception e | Finally.cs:65:9:67:9 | [exception: Exception] catch (...) {...} | | Finally.cs:65:26:65:26 | [exception: Exception] Exception e | Finally.cs:65:26:65:26 | [exception: Exception] Exception e | -| Finally.cs:65:26:65:26 | [exception: OutOfMemoryException] Exception e | Finally.cs:61:9:64:9 | [exception: OutOfMemoryException] catch (...) {...} | -| Finally.cs:65:26:65:26 | [exception: OutOfMemoryException] Exception e | Finally.cs:65:9:67:9 | [exception: OutOfMemoryException] catch (...) {...} | -| Finally.cs:65:26:65:26 | [exception: OutOfMemoryException] Exception e | Finally.cs:65:26:65:26 | [exception: OutOfMemoryException] Exception e | | Finally.cs:66:9:67:9 | {...} | Finally.cs:61:9:64:9 | [exception: Exception] catch (...) {...} | -| Finally.cs:66:9:67:9 | {...} | Finally.cs:61:9:64:9 | [exception: OutOfMemoryException] catch (...) {...} | | Finally.cs:66:9:67:9 | {...} | Finally.cs:65:9:67:9 | [exception: Exception] catch (...) {...} | -| Finally.cs:66:9:67:9 | {...} | Finally.cs:65:9:67:9 | [exception: OutOfMemoryException] catch (...) {...} | | Finally.cs:66:9:67:9 | {...} | Finally.cs:65:26:65:26 | [exception: Exception] Exception e | -| Finally.cs:66:9:67:9 | {...} | Finally.cs:65:26:65:26 | [exception: OutOfMemoryException] Exception e | | Finally.cs:66:9:67:9 | {...} | Finally.cs:66:9:67:9 | {...} | | Finally.cs:69:9:71:9 | [finally: exception(Exception)] {...} | Finally.cs:69:9:71:9 | [finally: exception(Exception)] {...} | -| Finally.cs:69:9:71:9 | [finally: exception(OutOfMemoryException)] {...} | Finally.cs:69:9:71:9 | [finally: exception(OutOfMemoryException)] {...} | | Finally.cs:74:10:74:11 | enter M4 | Finally.cs:74:10:74:11 | enter M4 | | Finally.cs:74:10:74:11 | exit M4 | Finally.cs:74:10:74:11 | exit M4 | | Finally.cs:74:10:74:11 | exit M4 (abnormal) | Finally.cs:74:10:74:11 | exit M4 (abnormal) | @@ -13890,14 +14486,14 @@ postBlockDominance | Finally.cs:93:31:93:45 | [finally: continue] object creation of type Exception | Finally.cs:93:31:93:45 | [finally: continue] object creation of type Exception | | Finally.cs:93:31:93:45 | [finally: return] object creation of type Exception | Finally.cs:93:31:93:45 | [finally: return] object creation of type Exception | | Finally.cs:93:31:93:45 | object creation of type Exception | Finally.cs:93:31:93:45 | object creation of type Exception | -| Finally.cs:96:17:98:17 | [finally(2): exception(Exception)] {...} | Finally.cs:96:17:98:17 | [finally(2): exception(Exception)] {...} | -| Finally.cs:96:17:98:17 | [finally: break, finally(2): exception(Exception)] {...} | Finally.cs:96:17:98:17 | [finally: break, finally(2): exception(Exception)] {...} | +| Finally.cs:96:17:98:17 | [finally(1): exception(Exception)] {...} | Finally.cs:96:17:98:17 | [finally(1): exception(Exception)] {...} | +| Finally.cs:96:17:98:17 | [finally: break, finally(1): exception(Exception)] {...} | Finally.cs:96:17:98:17 | [finally: break, finally(1): exception(Exception)] {...} | | Finally.cs:96:17:98:17 | [finally: break] {...} | Finally.cs:86:21:86:26 | break; | | Finally.cs:96:17:98:17 | [finally: break] {...} | Finally.cs:96:17:98:17 | [finally: break] {...} | -| Finally.cs:96:17:98:17 | [finally: continue, finally(2): exception(Exception)] {...} | Finally.cs:96:17:98:17 | [finally: continue, finally(2): exception(Exception)] {...} | +| Finally.cs:96:17:98:17 | [finally: continue, finally(1): exception(Exception)] {...} | Finally.cs:96:17:98:17 | [finally: continue, finally(1): exception(Exception)] {...} | | Finally.cs:96:17:98:17 | [finally: continue] {...} | Finally.cs:84:21:84:29 | continue; | | Finally.cs:96:17:98:17 | [finally: continue] {...} | Finally.cs:96:17:98:17 | [finally: continue] {...} | -| Finally.cs:96:17:98:17 | [finally: return, finally(2): exception(Exception)] {...} | Finally.cs:96:17:98:17 | [finally: return, finally(2): exception(Exception)] {...} | +| Finally.cs:96:17:98:17 | [finally: return, finally(1): exception(Exception)] {...} | Finally.cs:96:17:98:17 | [finally: return, finally(1): exception(Exception)] {...} | | Finally.cs:96:17:98:17 | [finally: return] {...} | Finally.cs:82:21:82:27 | return ...; | | Finally.cs:96:17:98:17 | [finally: return] {...} | Finally.cs:96:17:98:17 | [finally: return] {...} | | Finally.cs:96:17:98:17 | {...} | Finally.cs:89:13:99:13 | {...} | @@ -13985,9 +14581,7 @@ postBlockDominance | Finally.cs:121:10:121:11 | enter M6 | Finally.cs:121:10:121:11 | enter M6 | | Finally.cs:133:10:133:11 | enter M7 | Finally.cs:133:10:133:11 | enter M7 | | Finally.cs:133:10:133:11 | exit M7 (abnormal) | Finally.cs:133:10:133:11 | exit M7 (abnormal) | -| Finally.cs:137:13:137:36 | call to method WriteLine | Finally.cs:137:13:137:36 | call to method WriteLine | | Finally.cs:140:9:143:9 | [finally: exception(Exception)] {...} | Finally.cs:140:9:143:9 | [finally: exception(Exception)] {...} | -| Finally.cs:140:9:143:9 | [finally: exception(OutOfMemoryException)] {...} | Finally.cs:140:9:143:9 | [finally: exception(OutOfMemoryException)] {...} | | Finally.cs:140:9:143:9 | {...} | Finally.cs:140:9:143:9 | {...} | | Finally.cs:147:10:147:11 | enter M8 | Finally.cs:147:10:147:11 | enter M8 | | Finally.cs:147:10:147:11 | exit M8 | Finally.cs:147:10:147:11 | exit M8 | @@ -13997,14 +14591,11 @@ postBlockDominance | Finally.cs:147:10:147:11 | exit M8 (normal) | Finally.cs:155:9:169:9 | {...} | | Finally.cs:147:10:147:11 | exit M8 (normal) | Finally.cs:158:36:158:36 | 1 | | Finally.cs:147:10:147:11 | exit M8 (normal) | Finally.cs:159:21:159:45 | throw ...; | -| Finally.cs:147:10:147:11 | exit M8 (normal) | Finally.cs:159:27:159:44 | object creation of type Exception | | Finally.cs:147:10:147:11 | exit M8 (normal) | Finally.cs:159:41:159:43 | "1" | | Finally.cs:147:10:147:11 | exit M8 (normal) | Finally.cs:161:13:164:13 | [exception: Exception] catch (...) {...} | | Finally.cs:147:10:147:11 | exit M8 (normal) | Finally.cs:161:13:164:13 | [exception: NullReferenceException] catch (...) {...} | -| Finally.cs:147:10:147:11 | exit M8 (normal) | Finally.cs:161:13:164:13 | [exception: OutOfMemoryException] catch (...) {...} | | Finally.cs:147:10:147:11 | exit M8 (normal) | Finally.cs:161:30:161:30 | [exception: Exception] Exception e | | Finally.cs:147:10:147:11 | exit M8 (normal) | Finally.cs:161:30:161:30 | [exception: NullReferenceException] Exception e | -| Finally.cs:147:10:147:11 | exit M8 (normal) | Finally.cs:161:30:161:30 | [exception: OutOfMemoryException] Exception e | | Finally.cs:147:10:147:11 | exit M8 (normal) | Finally.cs:162:13:164:13 | {...} | | Finally.cs:147:10:147:11 | exit M8 (normal) | Finally.cs:165:13:168:13 | catch {...} | | Finally.cs:152:17:152:50 | throw ...; | Finally.cs:152:17:152:50 | throw ...; | @@ -14018,37 +14609,27 @@ postBlockDominance | Finally.cs:159:21:159:45 | [finally: exception(ArgumentNullException)] throw ...; | Finally.cs:159:21:159:45 | [finally: exception(ArgumentNullException)] throw ...; | | Finally.cs:159:21:159:45 | [finally: exception(Exception)] throw ...; | Finally.cs:159:21:159:45 | [finally: exception(Exception)] throw ...; | | Finally.cs:159:21:159:45 | throw ...; | Finally.cs:159:21:159:45 | throw ...; | -| Finally.cs:159:27:159:44 | [finally: exception(ArgumentNullException)] object creation of type Exception | Finally.cs:159:27:159:44 | [finally: exception(ArgumentNullException)] object creation of type Exception | -| Finally.cs:159:27:159:44 | [finally: exception(Exception)] object creation of type Exception | Finally.cs:159:27:159:44 | [finally: exception(Exception)] object creation of type Exception | -| Finally.cs:159:27:159:44 | object creation of type Exception | Finally.cs:159:27:159:44 | object creation of type Exception | | Finally.cs:159:41:159:43 | "1" | Finally.cs:159:41:159:43 | "1" | | Finally.cs:159:41:159:43 | [finally: exception(ArgumentNullException)] "1" | Finally.cs:159:41:159:43 | [finally: exception(ArgumentNullException)] "1" | | Finally.cs:159:41:159:43 | [finally: exception(Exception)] "1" | Finally.cs:159:41:159:43 | [finally: exception(Exception)] "1" | | Finally.cs:161:13:164:13 | [exception: Exception] catch (...) {...} | Finally.cs:159:21:159:45 | throw ...; | -| Finally.cs:161:13:164:13 | [exception: Exception] catch (...) {...} | Finally.cs:159:27:159:44 | object creation of type Exception | +| Finally.cs:161:13:164:13 | [exception: Exception] catch (...) {...} | Finally.cs:159:41:159:43 | "1" | | Finally.cs:161:13:164:13 | [exception: Exception] catch (...) {...} | Finally.cs:161:13:164:13 | [exception: Exception] catch (...) {...} | | Finally.cs:161:13:164:13 | [exception: NullReferenceException] catch (...) {...} | Finally.cs:161:13:164:13 | [exception: NullReferenceException] catch (...) {...} | -| Finally.cs:161:13:164:13 | [exception: OutOfMemoryException] catch (...) {...} | Finally.cs:161:13:164:13 | [exception: OutOfMemoryException] catch (...) {...} | | Finally.cs:161:13:164:13 | [finally: exception(ArgumentNullException), exception: Exception] catch (...) {...} | Finally.cs:161:13:164:13 | [finally: exception(ArgumentNullException), exception: Exception] catch (...) {...} | | Finally.cs:161:13:164:13 | [finally: exception(ArgumentNullException), exception: NullReferenceException] catch (...) {...} | Finally.cs:161:13:164:13 | [finally: exception(ArgumentNullException), exception: NullReferenceException] catch (...) {...} | -| Finally.cs:161:13:164:13 | [finally: exception(ArgumentNullException), exception: OutOfMemoryException] catch (...) {...} | Finally.cs:161:13:164:13 | [finally: exception(ArgumentNullException), exception: OutOfMemoryException] catch (...) {...} | | Finally.cs:161:13:164:13 | [finally: exception(Exception), exception: Exception] catch (...) {...} | Finally.cs:161:13:164:13 | [finally: exception(Exception), exception: Exception] catch (...) {...} | | Finally.cs:161:13:164:13 | [finally: exception(Exception), exception: NullReferenceException] catch (...) {...} | Finally.cs:161:13:164:13 | [finally: exception(Exception), exception: NullReferenceException] catch (...) {...} | -| Finally.cs:161:13:164:13 | [finally: exception(Exception), exception: OutOfMemoryException] catch (...) {...} | Finally.cs:161:13:164:13 | [finally: exception(Exception), exception: OutOfMemoryException] catch (...) {...} | | Finally.cs:161:30:161:30 | [exception: Exception] Exception e | Finally.cs:159:21:159:45 | throw ...; | -| Finally.cs:161:30:161:30 | [exception: Exception] Exception e | Finally.cs:159:27:159:44 | object creation of type Exception | +| Finally.cs:161:30:161:30 | [exception: Exception] Exception e | Finally.cs:159:41:159:43 | "1" | | Finally.cs:161:30:161:30 | [exception: Exception] Exception e | Finally.cs:161:13:164:13 | [exception: Exception] catch (...) {...} | | Finally.cs:161:30:161:30 | [exception: Exception] Exception e | Finally.cs:161:30:161:30 | [exception: Exception] Exception e | | Finally.cs:161:30:161:30 | [exception: NullReferenceException] Exception e | Finally.cs:161:13:164:13 | [exception: NullReferenceException] catch (...) {...} | | Finally.cs:161:30:161:30 | [exception: NullReferenceException] Exception e | Finally.cs:161:30:161:30 | [exception: NullReferenceException] Exception e | -| Finally.cs:161:30:161:30 | [exception: OutOfMemoryException] Exception e | Finally.cs:161:13:164:13 | [exception: OutOfMemoryException] catch (...) {...} | -| Finally.cs:161:30:161:30 | [exception: OutOfMemoryException] Exception e | Finally.cs:161:30:161:30 | [exception: OutOfMemoryException] Exception e | | Finally.cs:161:30:161:30 | [finally: exception(ArgumentNullException), exception: Exception] Exception e | Finally.cs:161:30:161:30 | [finally: exception(ArgumentNullException), exception: Exception] Exception e | | Finally.cs:161:30:161:30 | [finally: exception(ArgumentNullException), exception: NullReferenceException] Exception e | Finally.cs:161:30:161:30 | [finally: exception(ArgumentNullException), exception: NullReferenceException] Exception e | -| Finally.cs:161:30:161:30 | [finally: exception(ArgumentNullException), exception: OutOfMemoryException] Exception e | Finally.cs:161:30:161:30 | [finally: exception(ArgumentNullException), exception: OutOfMemoryException] Exception e | | Finally.cs:161:30:161:30 | [finally: exception(Exception), exception: Exception] Exception e | Finally.cs:161:30:161:30 | [finally: exception(Exception), exception: Exception] Exception e | | Finally.cs:161:30:161:30 | [finally: exception(Exception), exception: NullReferenceException] Exception e | Finally.cs:161:30:161:30 | [finally: exception(Exception), exception: NullReferenceException] Exception e | -| Finally.cs:161:30:161:30 | [finally: exception(Exception), exception: OutOfMemoryException] Exception e | Finally.cs:161:30:161:30 | [finally: exception(Exception), exception: OutOfMemoryException] Exception e | | Finally.cs:162:13:164:13 | [finally: exception(ArgumentNullException)] {...} | Finally.cs:162:13:164:13 | [finally: exception(ArgumentNullException)] {...} | | Finally.cs:162:13:164:13 | [finally: exception(Exception)] {...} | Finally.cs:162:13:164:13 | [finally: exception(Exception)] {...} | | Finally.cs:162:13:164:13 | {...} | Finally.cs:162:13:164:13 | {...} | @@ -14113,21 +14694,21 @@ postBlockDominance | Finally.cs:205:31:205:46 | [finally: exception(Exception)] object creation of type ExceptionB | Finally.cs:205:31:205:46 | [finally: exception(Exception)] object creation of type ExceptionB | | Finally.cs:205:31:205:46 | [finally: exception(ExceptionA)] object creation of type ExceptionB | Finally.cs:205:31:205:46 | [finally: exception(ExceptionA)] object creation of type ExceptionB | | Finally.cs:205:31:205:46 | object creation of type ExceptionB | Finally.cs:205:31:205:46 | object creation of type ExceptionB | -| Finally.cs:208:13:210:13 | [finally(2): exception(Exception)] {...} | Finally.cs:208:13:210:13 | [finally(2): exception(Exception)] {...} | -| Finally.cs:208:13:210:13 | [finally: exception(Exception), finally(2): exception(Exception)] {...} | Finally.cs:208:13:210:13 | [finally: exception(Exception), finally(2): exception(Exception)] {...} | +| Finally.cs:208:13:210:13 | [finally(1): exception(Exception)] {...} | Finally.cs:208:13:210:13 | [finally(1): exception(Exception)] {...} | +| Finally.cs:208:13:210:13 | [finally: exception(Exception), finally(1): exception(Exception)] {...} | Finally.cs:208:13:210:13 | [finally: exception(Exception), finally(1): exception(Exception)] {...} | | Finally.cs:208:13:210:13 | [finally: exception(Exception)] {...} | Finally.cs:208:13:210:13 | [finally: exception(Exception)] {...} | -| Finally.cs:208:13:210:13 | [finally: exception(ExceptionA), finally(2): exception(Exception)] {...} | Finally.cs:208:13:210:13 | [finally: exception(ExceptionA), finally(2): exception(Exception)] {...} | +| Finally.cs:208:13:210:13 | [finally: exception(ExceptionA), finally(1): exception(Exception)] {...} | Finally.cs:208:13:210:13 | [finally: exception(ExceptionA), finally(1): exception(Exception)] {...} | | Finally.cs:208:13:210:13 | [finally: exception(ExceptionA)] {...} | Finally.cs:208:13:210:13 | [finally: exception(ExceptionA)] {...} | | Finally.cs:208:13:210:13 | {...} | Finally.cs:195:10:195:12 | enter M10 | | Finally.cs:208:13:210:13 | {...} | Finally.cs:202:9:212:9 | {...} | | Finally.cs:208:13:210:13 | {...} | Finally.cs:208:13:210:13 | {...} | -| Finally.cs:209:31:209:46 | [finally(2): exception(Exception)] object creation of type ExceptionC | Finally.cs:209:31:209:46 | [finally(2): exception(Exception)] object creation of type ExceptionC | -| Finally.cs:209:31:209:46 | [finally(2): exception(ExceptionB)] object creation of type ExceptionC | Finally.cs:209:31:209:46 | [finally(2): exception(ExceptionB)] object creation of type ExceptionC | -| Finally.cs:209:31:209:46 | [finally: exception(Exception), finally(2): exception(Exception)] object creation of type ExceptionC | Finally.cs:209:31:209:46 | [finally: exception(Exception), finally(2): exception(Exception)] object creation of type ExceptionC | -| Finally.cs:209:31:209:46 | [finally: exception(Exception), finally(2): exception(ExceptionB)] object creation of type ExceptionC | Finally.cs:209:31:209:46 | [finally: exception(Exception), finally(2): exception(ExceptionB)] object creation of type ExceptionC | +| Finally.cs:209:31:209:46 | [finally(1): exception(Exception)] object creation of type ExceptionC | Finally.cs:209:31:209:46 | [finally(1): exception(Exception)] object creation of type ExceptionC | +| Finally.cs:209:31:209:46 | [finally(1): exception(ExceptionB)] object creation of type ExceptionC | Finally.cs:209:31:209:46 | [finally(1): exception(ExceptionB)] object creation of type ExceptionC | +| Finally.cs:209:31:209:46 | [finally: exception(Exception), finally(1): exception(Exception)] object creation of type ExceptionC | Finally.cs:209:31:209:46 | [finally: exception(Exception), finally(1): exception(Exception)] object creation of type ExceptionC | +| Finally.cs:209:31:209:46 | [finally: exception(Exception), finally(1): exception(ExceptionB)] object creation of type ExceptionC | Finally.cs:209:31:209:46 | [finally: exception(Exception), finally(1): exception(ExceptionB)] object creation of type ExceptionC | | Finally.cs:209:31:209:46 | [finally: exception(Exception)] object creation of type ExceptionC | Finally.cs:209:31:209:46 | [finally: exception(Exception)] object creation of type ExceptionC | -| Finally.cs:209:31:209:46 | [finally: exception(ExceptionA), finally(2): exception(Exception)] object creation of type ExceptionC | Finally.cs:209:31:209:46 | [finally: exception(ExceptionA), finally(2): exception(Exception)] object creation of type ExceptionC | -| Finally.cs:209:31:209:46 | [finally: exception(ExceptionA), finally(2): exception(ExceptionB)] object creation of type ExceptionC | Finally.cs:209:31:209:46 | [finally: exception(ExceptionA), finally(2): exception(ExceptionB)] object creation of type ExceptionC | +| Finally.cs:209:31:209:46 | [finally: exception(ExceptionA), finally(1): exception(Exception)] object creation of type ExceptionC | Finally.cs:209:31:209:46 | [finally: exception(ExceptionA), finally(1): exception(Exception)] object creation of type ExceptionC | +| Finally.cs:209:31:209:46 | [finally: exception(ExceptionA), finally(1): exception(ExceptionB)] object creation of type ExceptionC | Finally.cs:209:31:209:46 | [finally: exception(ExceptionA), finally(1): exception(ExceptionB)] object creation of type ExceptionC | | Finally.cs:209:31:209:46 | [finally: exception(ExceptionA)] object creation of type ExceptionC | Finally.cs:209:31:209:46 | [finally: exception(ExceptionA)] object creation of type ExceptionC | | Finally.cs:209:31:209:46 | object creation of type ExceptionC | Finally.cs:209:31:209:46 | object creation of type ExceptionC | | Finally.cs:211:13:211:29 | ...; | Finally.cs:195:10:195:12 | enter M10 | @@ -14137,12 +14718,43 @@ postBlockDominance | Finally.cs:211:13:211:29 | [finally: exception(Exception)] ...; | Finally.cs:211:13:211:29 | [finally: exception(Exception)] ...; | | Finally.cs:211:13:211:29 | [finally: exception(ExceptionA)] ...; | Finally.cs:211:13:211:29 | [finally: exception(ExceptionA)] ...; | | Finally.cs:216:10:216:12 | enter M11 | Finally.cs:216:10:216:12 | enter M11 | -| Finally.cs:220:13:220:36 | call to method WriteLine | Finally.cs:220:13:220:36 | call to method WriteLine | | Finally.cs:222:9:225:9 | catch {...} | Finally.cs:222:9:225:9 | catch {...} | | Finally.cs:227:9:229:9 | {...} | Finally.cs:216:10:216:12 | enter M11 | -| Finally.cs:227:9:229:9 | {...} | Finally.cs:220:13:220:36 | call to method WriteLine | | Finally.cs:227:9:229:9 | {...} | Finally.cs:222:9:225:9 | catch {...} | | Finally.cs:227:9:229:9 | {...} | Finally.cs:227:9:229:9 | {...} | +| Finally.cs:233:10:233:12 | enter M12 | Finally.cs:233:10:233:12 | enter M12 | +| Finally.cs:233:10:233:12 | exit M12 | Finally.cs:233:10:233:12 | exit M12 | +| Finally.cs:233:10:233:12 | exit M12 (abnormal) | Finally.cs:233:10:233:12 | exit M12 (abnormal) | +| Finally.cs:240:21:240:43 | throw ...; | Finally.cs:240:21:240:43 | throw ...; | +| Finally.cs:240:27:240:42 | object creation of type ExceptionA | Finally.cs:240:27:240:42 | object creation of type ExceptionA | +| Finally.cs:243:13:253:13 | [finally: exception(Exception)] {...} | Finally.cs:243:13:253:13 | [finally: exception(Exception)] {...} | +| Finally.cs:243:13:253:13 | {...} | Finally.cs:233:10:233:12 | enter M12 | +| Finally.cs:243:13:253:13 | {...} | Finally.cs:243:13:253:13 | {...} | +| Finally.cs:247:25:247:47 | [finally: exception(Exception)] throw ...; | Finally.cs:247:25:247:47 | [finally: exception(Exception)] throw ...; | +| Finally.cs:247:25:247:47 | [finally: exception(ExceptionA)] throw ...; | Finally.cs:247:25:247:47 | [finally: exception(ExceptionA)] throw ...; | +| Finally.cs:247:25:247:47 | throw ...; | Finally.cs:247:25:247:47 | throw ...; | +| Finally.cs:247:31:247:46 | [finally: exception(Exception)] object creation of type ExceptionA | Finally.cs:247:31:247:46 | [finally: exception(Exception)] object creation of type ExceptionA | +| Finally.cs:247:31:247:46 | [finally: exception(ExceptionA)] object creation of type ExceptionA | Finally.cs:247:31:247:46 | [finally: exception(ExceptionA)] object creation of type ExceptionA | +| Finally.cs:247:31:247:46 | object creation of type ExceptionA | Finally.cs:247:31:247:46 | object creation of type ExceptionA | +| Finally.cs:250:17:252:17 | [finally(1): exception(Exception)] {...} | Finally.cs:250:17:252:17 | [finally(1): exception(Exception)] {...} | +| Finally.cs:250:17:252:17 | [finally: exception(Exception), finally(1): exception(Exception)] {...} | Finally.cs:250:17:252:17 | [finally: exception(Exception), finally(1): exception(Exception)] {...} | +| Finally.cs:250:17:252:17 | [finally: exception(Exception)] {...} | Finally.cs:250:17:252:17 | [finally: exception(Exception)] {...} | +| Finally.cs:250:17:252:17 | [finally: exception(ExceptionA), finally(1): exception(Exception)] {...} | Finally.cs:250:17:252:17 | [finally: exception(ExceptionA), finally(1): exception(Exception)] {...} | +| Finally.cs:250:17:252:17 | [finally: exception(ExceptionA)] {...} | Finally.cs:250:17:252:17 | [finally: exception(ExceptionA)] {...} | +| Finally.cs:250:17:252:17 | {...} | Finally.cs:233:10:233:12 | enter M12 | +| Finally.cs:250:17:252:17 | {...} | Finally.cs:243:13:253:13 | {...} | +| Finally.cs:250:17:252:17 | {...} | Finally.cs:250:17:252:17 | {...} | +| Finally.cs:257:9:259:9 | [finally: exception(Exception)] {...} | Finally.cs:257:9:259:9 | [finally: exception(Exception)] {...} | +| Finally.cs:257:9:259:9 | [finally: exception(ExceptionA)] {...} | Finally.cs:257:9:259:9 | [finally: exception(ExceptionA)] {...} | +| Finally.cs:257:9:259:9 | {...} | Finally.cs:233:10:233:12 | enter M12 | +| Finally.cs:257:9:259:9 | {...} | Finally.cs:243:13:253:13 | {...} | +| Finally.cs:257:9:259:9 | {...} | Finally.cs:250:17:252:17 | {...} | +| Finally.cs:257:9:259:9 | {...} | Finally.cs:257:9:259:9 | {...} | +| Finally.cs:263:10:263:12 | enter M13 | Finally.cs:263:10:263:12 | enter M13 | +| Finally.cs:263:10:263:12 | exit M13 | Finally.cs:263:10:263:12 | exit M13 | +| Finally.cs:270:9:273:9 | [finally: exception(Exception)] {...} | Finally.cs:270:9:273:9 | [finally: exception(Exception)] {...} | +| Finally.cs:270:9:273:9 | {...} | Finally.cs:263:10:263:12 | enter M13 | +| Finally.cs:270:9:273:9 | {...} | Finally.cs:270:9:273:9 | {...} | | Foreach.cs:6:10:6:11 | enter M1 | Foreach.cs:6:10:6:11 | enter M1 | | Foreach.cs:6:10:6:11 | exit M1 (normal) | Foreach.cs:6:10:6:11 | enter M1 | | Foreach.cs:6:10:6:11 | exit M1 (normal) | Foreach.cs:6:10:6:11 | exit M1 (normal) | @@ -14598,17 +15210,34 @@ postBlockDominance | NullCoalescing.cs:17:13:17:24 | ... ?? ... | NullCoalescing.cs:15:31:15:31 | 0 | | NullCoalescing.cs:17:13:17:24 | ... ?? ... | NullCoalescing.cs:16:17:16:25 | ... ?? ... | | NullCoalescing.cs:17:13:17:24 | ... ?? ... | NullCoalescing.cs:17:13:17:24 | ... ?? ... | -| Patterns.cs:5:10:5:13 | enter Test | Patterns.cs:5:10:5:13 | enter Test | +| Patterns.cs:5:10:5:11 | enter M1 | Patterns.cs:5:10:5:11 | enter M1 | +| Patterns.cs:8:13:8:23 | [false] ... is ... | Patterns.cs:8:13:8:23 | [false] ... is ... | +| Patterns.cs:8:13:8:23 | [true] ... is ... | Patterns.cs:8:13:8:23 | [true] ... is ... | +| Patterns.cs:9:9:11:9 | {...} | Patterns.cs:8:13:8:23 | [true] ... is ... | | Patterns.cs:9:9:11:9 | {...} | Patterns.cs:9:9:11:9 | {...} | +| Patterns.cs:12:14:18:9 | if (...) ... | Patterns.cs:8:13:8:23 | [false] ... is ... | | Patterns.cs:12:14:18:9 | if (...) ... | Patterns.cs:12:14:18:9 | if (...) ... | +| Patterns.cs:12:18:12:31 | [false] ... is ... | Patterns.cs:12:18:12:31 | [false] ... is ... | +| Patterns.cs:12:18:12:31 | [true] ... is ... | Patterns.cs:12:18:12:31 | [true] ... is ... | +| Patterns.cs:13:9:15:9 | {...} | Patterns.cs:12:18:12:31 | [true] ... is ... | | Patterns.cs:13:9:15:9 | {...} | Patterns.cs:13:9:15:9 | {...} | +| Patterns.cs:16:14:18:9 | if (...) ... | Patterns.cs:12:18:12:31 | [false] ... is ... | | Patterns.cs:16:14:18:9 | if (...) ... | Patterns.cs:16:14:18:9 | if (...) ... | +| Patterns.cs:16:18:16:28 | [false] ... is ... | Patterns.cs:16:18:16:28 | [false] ... is ... | +| Patterns.cs:16:18:16:28 | [true] ... is ... | Patterns.cs:16:18:16:28 | [true] ... is ... | +| Patterns.cs:17:9:18:9 | {...} | Patterns.cs:16:18:16:28 | [true] ... is ... | | Patterns.cs:17:9:18:9 | {...} | Patterns.cs:17:9:18:9 | {...} | -| Patterns.cs:20:9:38:9 | switch (...) {...} | Patterns.cs:5:10:5:13 | enter Test | +| Patterns.cs:20:9:38:9 | switch (...) {...} | Patterns.cs:5:10:5:11 | enter M1 | +| Patterns.cs:20:9:38:9 | switch (...) {...} | Patterns.cs:8:13:8:23 | [false] ... is ... | +| Patterns.cs:20:9:38:9 | switch (...) {...} | Patterns.cs:8:13:8:23 | [true] ... is ... | | Patterns.cs:20:9:38:9 | switch (...) {...} | Patterns.cs:9:9:11:9 | {...} | | Patterns.cs:20:9:38:9 | switch (...) {...} | Patterns.cs:12:14:18:9 | if (...) ... | +| Patterns.cs:20:9:38:9 | switch (...) {...} | Patterns.cs:12:18:12:31 | [false] ... is ... | +| Patterns.cs:20:9:38:9 | switch (...) {...} | Patterns.cs:12:18:12:31 | [true] ... is ... | | Patterns.cs:20:9:38:9 | switch (...) {...} | Patterns.cs:13:9:15:9 | {...} | | Patterns.cs:20:9:38:9 | switch (...) {...} | Patterns.cs:16:14:18:9 | if (...) ... | +| Patterns.cs:20:9:38:9 | switch (...) {...} | Patterns.cs:16:18:16:28 | [false] ... is ... | +| Patterns.cs:20:9:38:9 | switch (...) {...} | Patterns.cs:16:18:16:28 | [true] ... is ... | | Patterns.cs:20:9:38:9 | switch (...) {...} | Patterns.cs:17:9:18:9 | {...} | | Patterns.cs:20:9:38:9 | switch (...) {...} | Patterns.cs:20:9:38:9 | switch (...) {...} | | Patterns.cs:23:17:23:22 | break; | Patterns.cs:23:17:23:22 | break; | @@ -14622,11 +15251,17 @@ postBlockDominance | Patterns.cs:33:13:33:24 | case ...: | Patterns.cs:33:13:33:24 | case ...: | | Patterns.cs:34:17:34:22 | break; | Patterns.cs:34:17:34:22 | break; | | Patterns.cs:35:13:35:20 | default: | Patterns.cs:35:13:35:20 | default: | -| Patterns.cs:40:9:42:9 | switch (...) {...} | Patterns.cs:5:10:5:13 | enter Test | +| Patterns.cs:40:9:42:9 | switch (...) {...} | Patterns.cs:5:10:5:11 | enter M1 | +| Patterns.cs:40:9:42:9 | switch (...) {...} | Patterns.cs:8:13:8:23 | [false] ... is ... | +| Patterns.cs:40:9:42:9 | switch (...) {...} | Patterns.cs:8:13:8:23 | [true] ... is ... | | Patterns.cs:40:9:42:9 | switch (...) {...} | Patterns.cs:9:9:11:9 | {...} | | Patterns.cs:40:9:42:9 | switch (...) {...} | Patterns.cs:12:14:18:9 | if (...) ... | +| Patterns.cs:40:9:42:9 | switch (...) {...} | Patterns.cs:12:18:12:31 | [false] ... is ... | +| Patterns.cs:40:9:42:9 | switch (...) {...} | Patterns.cs:12:18:12:31 | [true] ... is ... | | Patterns.cs:40:9:42:9 | switch (...) {...} | Patterns.cs:13:9:15:9 | {...} | | Patterns.cs:40:9:42:9 | switch (...) {...} | Patterns.cs:16:14:18:9 | if (...) ... | +| Patterns.cs:40:9:42:9 | switch (...) {...} | Patterns.cs:16:18:16:28 | [false] ... is ... | +| Patterns.cs:40:9:42:9 | switch (...) {...} | Patterns.cs:16:18:16:28 | [true] ... is ... | | Patterns.cs:40:9:42:9 | switch (...) {...} | Patterns.cs:17:9:18:9 | {...} | | Patterns.cs:40:9:42:9 | switch (...) {...} | Patterns.cs:20:9:38:9 | switch (...) {...} | | Patterns.cs:40:9:42:9 | switch (...) {...} | Patterns.cs:23:17:23:22 | break; | @@ -14641,18 +15276,209 @@ postBlockDominance | Patterns.cs:40:9:42:9 | switch (...) {...} | Patterns.cs:34:17:34:22 | break; | | Patterns.cs:40:9:42:9 | switch (...) {...} | Patterns.cs:35:13:35:20 | default: | | Patterns.cs:40:9:42:9 | switch (...) {...} | Patterns.cs:40:9:42:9 | switch (...) {...} | +| Patterns.cs:47:24:47:25 | enter M2 | Patterns.cs:47:24:47:25 | enter M2 | +| Patterns.cs:50:24:50:25 | enter M3 | Patterns.cs:50:24:50:25 | enter M3 | +| Patterns.cs:51:9:51:21 | [false] ... is ... | Patterns.cs:51:9:51:21 | [false] ... is ... | +| Patterns.cs:51:9:51:21 | [false] ... is ... | Patterns.cs:51:14:51:21 | [no-match] not ... | +| Patterns.cs:51:9:51:21 | [true] ... is ... | Patterns.cs:51:9:51:21 | [true] ... is ... | +| Patterns.cs:51:9:51:21 | [true] ... is ... | Patterns.cs:51:14:51:21 | [match] not ... | +| Patterns.cs:51:9:51:39 | ... ? ... : ... | Patterns.cs:50:24:50:25 | enter M3 | +| Patterns.cs:51:9:51:39 | ... ? ... : ... | Patterns.cs:51:9:51:21 | [false] ... is ... | +| Patterns.cs:51:9:51:39 | ... ? ... : ... | Patterns.cs:51:9:51:21 | [true] ... is ... | +| Patterns.cs:51:9:51:39 | ... ? ... : ... | Patterns.cs:51:9:51:39 | ... ? ... : ... | +| Patterns.cs:51:9:51:39 | ... ? ... : ... | Patterns.cs:51:14:51:21 | [match] not ... | +| Patterns.cs:51:9:51:39 | ... ? ... : ... | Patterns.cs:51:14:51:21 | [no-match] not ... | +| Patterns.cs:51:9:51:39 | ... ? ... : ... | Patterns.cs:51:25:51:25 | access to parameter c | +| Patterns.cs:51:9:51:39 | ... ? ... : ... | Patterns.cs:51:34:51:34 | access to parameter c | +| Patterns.cs:51:14:51:21 | [match] not ... | Patterns.cs:51:14:51:21 | [match] not ... | +| Patterns.cs:51:14:51:21 | [no-match] not ... | Patterns.cs:51:14:51:21 | [no-match] not ... | +| Patterns.cs:51:25:51:25 | access to parameter c | Patterns.cs:51:9:51:21 | [true] ... is ... | +| Patterns.cs:51:25:51:25 | access to parameter c | Patterns.cs:51:14:51:21 | [match] not ... | +| Patterns.cs:51:25:51:25 | access to parameter c | Patterns.cs:51:25:51:25 | access to parameter c | +| Patterns.cs:51:34:51:34 | access to parameter c | Patterns.cs:51:9:51:21 | [false] ... is ... | +| Patterns.cs:51:34:51:34 | access to parameter c | Patterns.cs:51:14:51:21 | [no-match] not ... | +| Patterns.cs:51:34:51:34 | access to parameter c | Patterns.cs:51:34:51:34 | access to parameter c | +| Patterns.cs:53:24:53:25 | enter M4 | Patterns.cs:53:24:53:25 | enter M4 | +| Patterns.cs:54:18:54:37 | { ... } | Patterns.cs:53:24:53:25 | enter M4 | +| Patterns.cs:54:18:54:37 | { ... } | Patterns.cs:54:18:54:37 | { ... } | +| Patterns.cs:54:18:54:37 | { ... } | Patterns.cs:54:27:54:35 | [match] { ... } | +| Patterns.cs:54:18:54:37 | { ... } | Patterns.cs:54:27:54:35 | [no-match] { ... } | +| Patterns.cs:54:18:54:37 | { ... } | Patterns.cs:54:33:54:33 | 1 | +| Patterns.cs:54:27:54:35 | [match] { ... } | Patterns.cs:54:27:54:35 | [match] { ... } | +| Patterns.cs:54:27:54:35 | [no-match] { ... } | Patterns.cs:54:27:54:35 | [no-match] { ... } | +| Patterns.cs:54:33:54:33 | 1 | Patterns.cs:54:33:54:33 | 1 | +| Patterns.cs:56:26:56:27 | enter M5 | Patterns.cs:56:26:56:27 | enter M5 | +| Patterns.cs:58:16:62:9 | ... switch { ... } | Patterns.cs:56:26:56:27 | enter M5 | +| Patterns.cs:58:16:62:9 | ... switch { ... } | Patterns.cs:58:16:62:9 | ... switch { ... } | +| Patterns.cs:58:16:62:9 | ... switch { ... } | Patterns.cs:60:13:60:17 | [match] not ... | +| Patterns.cs:58:16:62:9 | ... switch { ... } | Patterns.cs:60:13:60:17 | [no-match] not ... | +| Patterns.cs:58:16:62:9 | ... switch { ... } | Patterns.cs:60:22:60:28 | "not 1" | +| Patterns.cs:58:16:62:9 | ... switch { ... } | Patterns.cs:61:13:61:13 | _ | +| Patterns.cs:58:16:62:9 | ... switch { ... } | Patterns.cs:61:18:61:24 | "other" | +| Patterns.cs:60:13:60:17 | [match] not ... | Patterns.cs:60:13:60:17 | [match] not ... | +| Patterns.cs:60:13:60:17 | [no-match] not ... | Patterns.cs:60:13:60:17 | [no-match] not ... | +| Patterns.cs:60:22:60:28 | "not 1" | Patterns.cs:60:13:60:17 | [match] not ... | +| Patterns.cs:60:22:60:28 | "not 1" | Patterns.cs:60:22:60:28 | "not 1" | +| Patterns.cs:61:13:61:13 | _ | Patterns.cs:60:13:60:17 | [no-match] not ... | +| Patterns.cs:61:13:61:13 | _ | Patterns.cs:61:13:61:13 | _ | +| Patterns.cs:61:18:61:24 | "other" | Patterns.cs:60:13:60:17 | [no-match] not ... | +| Patterns.cs:61:18:61:24 | "other" | Patterns.cs:61:13:61:13 | _ | +| Patterns.cs:61:18:61:24 | "other" | Patterns.cs:61:18:61:24 | "other" | +| Patterns.cs:65:26:65:27 | enter M6 | Patterns.cs:65:26:65:27 | enter M6 | +| Patterns.cs:69:13:69:17 | [no-match] not ... | Patterns.cs:65:26:65:27 | enter M6 | +| Patterns.cs:69:13:69:17 | [no-match] not ... | Patterns.cs:69:13:69:17 | [no-match] not ... | +| Patterns.cs:70:13:70:13 | 2 | Patterns.cs:65:26:65:27 | enter M6 | +| Patterns.cs:70:13:70:13 | 2 | Patterns.cs:69:13:69:17 | [no-match] not ... | +| Patterns.cs:70:13:70:13 | 2 | Patterns.cs:70:13:70:13 | 2 | +| Patterns.cs:70:18:70:27 | "possible" | Patterns.cs:65:26:65:27 | enter M6 | +| Patterns.cs:70:18:70:27 | "possible" | Patterns.cs:69:13:69:17 | [no-match] not ... | +| Patterns.cs:70:18:70:27 | "possible" | Patterns.cs:70:13:70:13 | 2 | +| Patterns.cs:70:18:70:27 | "possible" | Patterns.cs:70:18:70:27 | "possible" | +| Patterns.cs:74:26:74:27 | enter M7 | Patterns.cs:74:26:74:27 | enter M7 | +| Patterns.cs:76:16:82:9 | ... switch { ... } | Patterns.cs:74:26:74:27 | enter M7 | +| Patterns.cs:76:16:82:9 | ... switch { ... } | Patterns.cs:76:16:82:9 | ... switch { ... } | +| Patterns.cs:76:16:82:9 | ... switch { ... } | Patterns.cs:78:20:78:24 | "> 1" | +| Patterns.cs:76:16:82:9 | ... switch { ... } | Patterns.cs:79:15:79:15 | 0 | +| Patterns.cs:76:16:82:9 | ... switch { ... } | Patterns.cs:79:20:79:24 | "< 0" | +| Patterns.cs:76:16:82:9 | ... switch { ... } | Patterns.cs:80:13:80:13 | 1 | +| Patterns.cs:76:16:82:9 | ... switch { ... } | Patterns.cs:80:18:80:20 | "1" | +| Patterns.cs:76:16:82:9 | ... switch { ... } | Patterns.cs:81:13:81:13 | _ | +| Patterns.cs:76:16:82:9 | ... switch { ... } | Patterns.cs:81:18:81:20 | "0" | +| Patterns.cs:78:20:78:24 | "> 1" | Patterns.cs:78:20:78:24 | "> 1" | +| Patterns.cs:79:15:79:15 | 0 | Patterns.cs:79:15:79:15 | 0 | +| Patterns.cs:79:20:79:24 | "< 0" | Patterns.cs:79:20:79:24 | "< 0" | +| Patterns.cs:80:13:80:13 | 1 | Patterns.cs:80:13:80:13 | 1 | +| Patterns.cs:80:18:80:20 | "1" | Patterns.cs:80:18:80:20 | "1" | +| Patterns.cs:81:13:81:13 | _ | Patterns.cs:81:13:81:13 | _ | +| Patterns.cs:81:18:81:20 | "0" | Patterns.cs:81:13:81:13 | _ | +| Patterns.cs:81:18:81:20 | "0" | Patterns.cs:81:18:81:20 | "0" | +| Patterns.cs:85:26:85:27 | enter M8 | Patterns.cs:85:26:85:27 | enter M8 | +| Patterns.cs:85:39:85:53 | [false] ... is ... | Patterns.cs:85:39:85:53 | [false] ... is ... | +| Patterns.cs:85:39:85:53 | [false] ... is ... | Patterns.cs:85:44:85:53 | [no-match] ... or ... | +| Patterns.cs:85:39:85:53 | [false] ... is ... | Patterns.cs:85:49:85:53 | [no-match] not ... | +| Patterns.cs:85:39:85:53 | [true] ... is ... | Patterns.cs:85:39:85:53 | [true] ... is ... | +| Patterns.cs:85:39:85:53 | [true] ... is ... | Patterns.cs:85:44:85:53 | [match] ... or ... | +| Patterns.cs:85:39:85:53 | [true] ... is ... | Patterns.cs:85:49:85:53 | [match] not ... | +| Patterns.cs:85:39:85:69 | ... ? ... : ... | Patterns.cs:85:26:85:27 | enter M8 | +| Patterns.cs:85:39:85:69 | ... ? ... : ... | Patterns.cs:85:39:85:53 | [false] ... is ... | +| Patterns.cs:85:39:85:69 | ... ? ... : ... | Patterns.cs:85:39:85:53 | [true] ... is ... | +| Patterns.cs:85:39:85:69 | ... ? ... : ... | Patterns.cs:85:39:85:69 | ... ? ... : ... | +| Patterns.cs:85:39:85:69 | ... ? ... : ... | Patterns.cs:85:44:85:53 | [match] ... or ... | +| Patterns.cs:85:39:85:69 | ... ? ... : ... | Patterns.cs:85:44:85:53 | [no-match] ... or ... | +| Patterns.cs:85:39:85:69 | ... ? ... : ... | Patterns.cs:85:49:85:53 | [match] not ... | +| Patterns.cs:85:39:85:69 | ... ? ... : ... | Patterns.cs:85:49:85:53 | [no-match] not ... | +| Patterns.cs:85:39:85:69 | ... ? ... : ... | Patterns.cs:85:53:85:53 | 2 | +| Patterns.cs:85:39:85:69 | ... ? ... : ... | Patterns.cs:85:57:85:63 | "not 2" | +| Patterns.cs:85:39:85:69 | ... ? ... : ... | Patterns.cs:85:67:85:69 | "2" | +| Patterns.cs:85:44:85:53 | [match] ... or ... | Patterns.cs:85:44:85:53 | [match] ... or ... | +| Patterns.cs:85:44:85:53 | [match] ... or ... | Patterns.cs:85:49:85:53 | [match] not ... | +| Patterns.cs:85:44:85:53 | [no-match] ... or ... | Patterns.cs:85:44:85:53 | [no-match] ... or ... | +| Patterns.cs:85:44:85:53 | [no-match] ... or ... | Patterns.cs:85:49:85:53 | [no-match] not ... | +| Patterns.cs:85:49:85:53 | [match] not ... | Patterns.cs:85:49:85:53 | [match] not ... | +| Patterns.cs:85:49:85:53 | [no-match] not ... | Patterns.cs:85:49:85:53 | [no-match] not ... | +| Patterns.cs:85:53:85:53 | 2 | Patterns.cs:85:53:85:53 | 2 | +| Patterns.cs:85:57:85:63 | "not 2" | Patterns.cs:85:39:85:53 | [true] ... is ... | +| Patterns.cs:85:57:85:63 | "not 2" | Patterns.cs:85:44:85:53 | [match] ... or ... | +| Patterns.cs:85:57:85:63 | "not 2" | Patterns.cs:85:49:85:53 | [match] not ... | +| Patterns.cs:85:57:85:63 | "not 2" | Patterns.cs:85:57:85:63 | "not 2" | +| Patterns.cs:85:67:85:69 | "2" | Patterns.cs:85:39:85:53 | [false] ... is ... | +| Patterns.cs:85:67:85:69 | "2" | Patterns.cs:85:44:85:53 | [no-match] ... or ... | +| Patterns.cs:85:67:85:69 | "2" | Patterns.cs:85:49:85:53 | [no-match] not ... | +| Patterns.cs:85:67:85:69 | "2" | Patterns.cs:85:67:85:69 | "2" | +| Patterns.cs:87:26:87:27 | enter M9 | Patterns.cs:87:26:87:27 | enter M9 | +| Patterns.cs:87:39:87:54 | [false] ... is ... | Patterns.cs:87:39:87:54 | [false] ... is ... | +| Patterns.cs:87:39:87:54 | [false] ... is ... | Patterns.cs:87:44:87:54 | [no-match] ... and ... | +| Patterns.cs:87:39:87:54 | [false] ... is ... | Patterns.cs:87:50:87:54 | [no-match] not ... | +| Patterns.cs:87:39:87:54 | [true] ... is ... | Patterns.cs:87:39:87:54 | [true] ... is ... | +| Patterns.cs:87:39:87:54 | [true] ... is ... | Patterns.cs:87:44:87:54 | [match] ... and ... | +| Patterns.cs:87:39:87:54 | [true] ... is ... | Patterns.cs:87:50:87:54 | [match] not ... | +| Patterns.cs:87:39:87:70 | ... ? ... : ... | Patterns.cs:87:26:87:27 | enter M9 | +| Patterns.cs:87:39:87:70 | ... ? ... : ... | Patterns.cs:87:39:87:54 | [false] ... is ... | +| Patterns.cs:87:39:87:70 | ... ? ... : ... | Patterns.cs:87:39:87:54 | [true] ... is ... | +| Patterns.cs:87:39:87:70 | ... ? ... : ... | Patterns.cs:87:39:87:70 | ... ? ... : ... | +| Patterns.cs:87:39:87:70 | ... ? ... : ... | Patterns.cs:87:44:87:54 | [match] ... and ... | +| Patterns.cs:87:39:87:70 | ... ? ... : ... | Patterns.cs:87:44:87:54 | [no-match] ... and ... | +| Patterns.cs:87:39:87:70 | ... ? ... : ... | Patterns.cs:87:50:87:54 | [match] not ... | +| Patterns.cs:87:39:87:70 | ... ? ... : ... | Patterns.cs:87:50:87:54 | [no-match] not ... | +| Patterns.cs:87:39:87:70 | ... ? ... : ... | Patterns.cs:87:54:87:54 | 2 | +| Patterns.cs:87:39:87:70 | ... ? ... : ... | Patterns.cs:87:58:87:60 | "1" | +| Patterns.cs:87:39:87:70 | ... ? ... : ... | Patterns.cs:87:64:87:70 | "not 1" | +| Patterns.cs:87:44:87:54 | [match] ... and ... | Patterns.cs:87:44:87:54 | [match] ... and ... | +| Patterns.cs:87:44:87:54 | [match] ... and ... | Patterns.cs:87:50:87:54 | [match] not ... | +| Patterns.cs:87:44:87:54 | [no-match] ... and ... | Patterns.cs:87:44:87:54 | [no-match] ... and ... | +| Patterns.cs:87:44:87:54 | [no-match] ... and ... | Patterns.cs:87:50:87:54 | [no-match] not ... | +| Patterns.cs:87:50:87:54 | [match] not ... | Patterns.cs:87:50:87:54 | [match] not ... | +| Patterns.cs:87:50:87:54 | [no-match] not ... | Patterns.cs:87:50:87:54 | [no-match] not ... | +| Patterns.cs:87:54:87:54 | 2 | Patterns.cs:87:54:87:54 | 2 | +| Patterns.cs:87:58:87:60 | "1" | Patterns.cs:87:39:87:54 | [true] ... is ... | +| Patterns.cs:87:58:87:60 | "1" | Patterns.cs:87:44:87:54 | [match] ... and ... | +| Patterns.cs:87:58:87:60 | "1" | Patterns.cs:87:50:87:54 | [match] not ... | +| Patterns.cs:87:58:87:60 | "1" | Patterns.cs:87:58:87:60 | "1" | +| Patterns.cs:87:64:87:70 | "not 1" | Patterns.cs:87:39:87:54 | [false] ... is ... | +| Patterns.cs:87:64:87:70 | "not 1" | Patterns.cs:87:44:87:54 | [no-match] ... and ... | +| Patterns.cs:87:64:87:70 | "not 1" | Patterns.cs:87:50:87:54 | [no-match] not ... | +| Patterns.cs:87:64:87:70 | "not 1" | Patterns.cs:87:64:87:70 | "not 1" | +| Patterns.cs:93:17:93:19 | enter M10 | Patterns.cs:93:17:93:19 | enter M10 | +| Patterns.cs:93:17:93:19 | exit M10 (normal) | Patterns.cs:93:17:93:19 | enter M10 | +| Patterns.cs:93:17:93:19 | exit M10 (normal) | Patterns.cs:93:17:93:19 | exit M10 (normal) | +| Patterns.cs:93:17:93:19 | exit M10 (normal) | Patterns.cs:95:13:95:40 | [false] ... is ... | +| Patterns.cs:93:17:93:19 | exit M10 (normal) | Patterns.cs:95:13:95:40 | [true] ... is ... | +| Patterns.cs:93:17:93:19 | exit M10 (normal) | Patterns.cs:95:21:95:40 | [match] { ... } | +| Patterns.cs:93:17:93:19 | exit M10 (normal) | Patterns.cs:95:21:95:40 | [match] { ... } | +| Patterns.cs:93:17:93:19 | exit M10 (normal) | Patterns.cs:95:21:95:40 | [no-match] { ... } | +| Patterns.cs:93:17:93:19 | exit M10 (normal) | Patterns.cs:95:21:95:40 | [no-match] { ... } | +| Patterns.cs:93:17:93:19 | exit M10 (normal) | Patterns.cs:95:29:95:38 | [match] ... or ... | +| Patterns.cs:93:17:93:19 | exit M10 (normal) | Patterns.cs:95:29:95:38 | [no-match] ... or ... | +| Patterns.cs:93:17:93:19 | exit M10 (normal) | Patterns.cs:95:36:95:38 | access to constant B | +| Patterns.cs:93:17:93:19 | exit M10 (normal) | Patterns.cs:96:9:98:9 | {...} | +| Patterns.cs:95:13:95:40 | [false] ... is ... | Patterns.cs:95:13:95:40 | [false] ... is ... | +| Patterns.cs:95:13:95:40 | [false] ... is ... | Patterns.cs:95:21:95:40 | [no-match] { ... } | +| Patterns.cs:95:13:95:40 | [false] ... is ... | Patterns.cs:95:21:95:40 | [no-match] { ... } | +| Patterns.cs:95:13:95:40 | [false] ... is ... | Patterns.cs:95:29:95:38 | [no-match] ... or ... | +| Patterns.cs:95:13:95:40 | [true] ... is ... | Patterns.cs:95:13:95:40 | [true] ... is ... | +| Patterns.cs:95:13:95:40 | [true] ... is ... | Patterns.cs:95:21:95:40 | [match] { ... } | +| Patterns.cs:95:13:95:40 | [true] ... is ... | Patterns.cs:95:21:95:40 | [match] { ... } | +| Patterns.cs:95:13:95:40 | [true] ... is ... | Patterns.cs:95:29:95:38 | [match] ... or ... | +| Patterns.cs:95:21:95:40 | [match] { ... } | Patterns.cs:95:21:95:40 | [match] { ... } | +| Patterns.cs:95:21:95:40 | [match] { ... } | Patterns.cs:95:21:95:40 | [match] { ... } | +| Patterns.cs:95:21:95:40 | [match] { ... } | Patterns.cs:95:21:95:40 | [match] { ... } | +| Patterns.cs:95:21:95:40 | [match] { ... } | Patterns.cs:95:29:95:38 | [match] ... or ... | +| Patterns.cs:95:21:95:40 | [match] { ... } | Patterns.cs:95:29:95:38 | [match] ... or ... | +| Patterns.cs:95:21:95:40 | [no-match] { ... } | Patterns.cs:95:21:95:40 | [no-match] { ... } | +| Patterns.cs:95:21:95:40 | [no-match] { ... } | Patterns.cs:95:21:95:40 | [no-match] { ... } | +| Patterns.cs:95:21:95:40 | [no-match] { ... } | Patterns.cs:95:21:95:40 | [no-match] { ... } | +| Patterns.cs:95:21:95:40 | [no-match] { ... } | Patterns.cs:95:29:95:38 | [no-match] ... or ... | +| Patterns.cs:95:21:95:40 | [no-match] { ... } | Patterns.cs:95:29:95:38 | [no-match] ... or ... | +| Patterns.cs:95:29:95:38 | [match] ... or ... | Patterns.cs:95:29:95:38 | [match] ... or ... | +| Patterns.cs:95:29:95:38 | [no-match] ... or ... | Patterns.cs:95:29:95:38 | [no-match] ... or ... | +| Patterns.cs:95:36:95:38 | access to constant B | Patterns.cs:95:36:95:38 | access to constant B | +| Patterns.cs:96:9:98:9 | {...} | Patterns.cs:95:13:95:40 | [true] ... is ... | +| Patterns.cs:96:9:98:9 | {...} | Patterns.cs:95:21:95:40 | [match] { ... } | +| Patterns.cs:96:9:98:9 | {...} | Patterns.cs:95:21:95:40 | [match] { ... } | +| Patterns.cs:96:9:98:9 | {...} | Patterns.cs:95:29:95:38 | [match] ... or ... | +| Patterns.cs:96:9:98:9 | {...} | Patterns.cs:96:9:98:9 | {...} | | PostDominance.cs:5:10:5:11 | enter M1 | PostDominance.cs:5:10:5:11 | enter M1 | | PostDominance.cs:10:10:10:11 | enter M2 | PostDominance.cs:10:10:10:11 | enter M2 | | PostDominance.cs:10:10:10:11 | exit M2 (normal) | PostDominance.cs:10:10:10:11 | enter M2 | | PostDominance.cs:10:10:10:11 | exit M2 (normal) | PostDominance.cs:10:10:10:11 | exit M2 (normal) | +| PostDominance.cs:10:10:10:11 | exit M2 (normal) | PostDominance.cs:12:13:12:21 | [false] ... is ... | +| PostDominance.cs:10:10:10:11 | exit M2 (normal) | PostDominance.cs:12:13:12:21 | [true] ... is ... | | PostDominance.cs:10:10:10:11 | exit M2 (normal) | PostDominance.cs:13:13:13:19 | return ...; | | PostDominance.cs:10:10:10:11 | exit M2 (normal) | PostDominance.cs:14:9:14:29 | ...; | +| PostDominance.cs:12:13:12:21 | [false] ... is ... | PostDominance.cs:12:13:12:21 | [false] ... is ... | +| PostDominance.cs:12:13:12:21 | [true] ... is ... | PostDominance.cs:12:13:12:21 | [true] ... is ... | +| PostDominance.cs:13:13:13:19 | return ...; | PostDominance.cs:12:13:12:21 | [true] ... is ... | | PostDominance.cs:13:13:13:19 | return ...; | PostDominance.cs:13:13:13:19 | return ...; | +| PostDominance.cs:14:9:14:29 | ...; | PostDominance.cs:12:13:12:21 | [false] ... is ... | | PostDominance.cs:14:9:14:29 | ...; | PostDominance.cs:14:9:14:29 | ...; | | PostDominance.cs:17:10:17:11 | enter M3 | PostDominance.cs:17:10:17:11 | enter M3 | | PostDominance.cs:17:10:17:11 | exit M3 | PostDominance.cs:17:10:17:11 | exit M3 | +| PostDominance.cs:19:13:19:21 | [false] ... is ... | PostDominance.cs:17:10:17:11 | enter M3 | +| PostDominance.cs:19:13:19:21 | [false] ... is ... | PostDominance.cs:19:13:19:21 | [false] ... is ... | +| PostDominance.cs:19:13:19:21 | [true] ... is ... | PostDominance.cs:19:13:19:21 | [true] ... is ... | | PostDominance.cs:20:45:20:53 | nameof(...) | PostDominance.cs:20:45:20:53 | nameof(...) | | PostDominance.cs:21:9:21:29 | ...; | PostDominance.cs:17:10:17:11 | enter M3 | +| PostDominance.cs:21:9:21:29 | ...; | PostDominance.cs:19:13:19:21 | [false] ... is ... | | PostDominance.cs:21:9:21:29 | ...; | PostDominance.cs:21:9:21:29 | ...; | | Qualifiers.cs:7:16:7:21 | enter Method | Qualifiers.cs:7:16:7:21 | enter Method | | Qualifiers.cs:8:23:8:34 | enter StaticMethod | Qualifiers.cs:8:23:8:34 | enter StaticMethod | @@ -14894,8 +15720,13 @@ postBlockDominance | Switch.cs:158:13:158:49 | ...; | Switch.cs:158:13:158:49 | ...; | | Switch.cs:160:13:160:49 | ...; | Switch.cs:160:13:160:49 | ...; | | TypeAccesses.cs:3:10:3:10 | enter M | TypeAccesses.cs:3:10:3:10 | enter M | +| TypeAccesses.cs:7:13:7:22 | [false] ... is ... | TypeAccesses.cs:7:13:7:22 | [false] ... is ... | +| TypeAccesses.cs:7:13:7:22 | [true] ... is ... | TypeAccesses.cs:7:13:7:22 | [true] ... is ... | +| TypeAccesses.cs:7:25:7:25 | ; | TypeAccesses.cs:7:13:7:22 | [true] ... is ... | | TypeAccesses.cs:7:25:7:25 | ; | TypeAccesses.cs:7:25:7:25 | ; | | TypeAccesses.cs:8:9:8:28 | ... ...; | TypeAccesses.cs:3:10:3:10 | enter M | +| TypeAccesses.cs:8:9:8:28 | ... ...; | TypeAccesses.cs:7:13:7:22 | [false] ... is ... | +| TypeAccesses.cs:8:9:8:28 | ... ...; | TypeAccesses.cs:7:13:7:22 | [true] ... is ... | | TypeAccesses.cs:8:9:8:28 | ... ...; | TypeAccesses.cs:7:25:7:25 | ; | | TypeAccesses.cs:8:9:8:28 | ... ...; | TypeAccesses.cs:8:9:8:28 | ... ...; | | VarDecls.cs:5:18:5:19 | enter M1 | VarDecls.cs:5:18:5:19 | enter M1 | diff --git a/csharp/ql/test/library-tests/controlflow/graph/EnclosingCallable.expected b/csharp/ql/test/library-tests/controlflow/graph/EnclosingCallable.expected index ffc531ca8bc..6df7f49dc63 100644 --- a/csharp/ql/test/library-tests/controlflow/graph/EnclosingCallable.expected +++ b/csharp/ql/test/library-tests/controlflow/graph/EnclosingCallable.expected @@ -1603,182 +1603,195 @@ nodeEnclosing | Conditions.cs:149:38:149:47 | $"..." | Conditions.cs:143:10:143:12 | M11 | | Conditions.cs:149:40:149:43 | "b = " | Conditions.cs:143:10:143:12 | M11 | | Conditions.cs:149:45:149:45 | access to local variable s | Conditions.cs:143:10:143:12 | M11 | -| ExitMethods.cs:7:10:7:11 | enter M1 | ExitMethods.cs:7:10:7:11 | M1 | -| ExitMethods.cs:7:10:7:11 | exit M1 | ExitMethods.cs:7:10:7:11 | M1 | -| ExitMethods.cs:7:10:7:11 | exit M1 (normal) | ExitMethods.cs:7:10:7:11 | M1 | -| ExitMethods.cs:8:5:11:5 | {...} | ExitMethods.cs:7:10:7:11 | M1 | -| ExitMethods.cs:9:9:9:24 | call to method ErrorMaybe | ExitMethods.cs:7:10:7:11 | M1 | -| ExitMethods.cs:9:9:9:25 | ...; | ExitMethods.cs:7:10:7:11 | M1 | -| ExitMethods.cs:9:20:9:23 | true | ExitMethods.cs:7:10:7:11 | M1 | -| ExitMethods.cs:10:9:10:15 | return ...; | ExitMethods.cs:7:10:7:11 | M1 | -| ExitMethods.cs:13:10:13:11 | enter M2 | ExitMethods.cs:13:10:13:11 | M2 | -| ExitMethods.cs:13:10:13:11 | exit M2 | ExitMethods.cs:13:10:13:11 | M2 | -| ExitMethods.cs:13:10:13:11 | exit M2 (normal) | ExitMethods.cs:13:10:13:11 | M2 | -| ExitMethods.cs:14:5:17:5 | {...} | ExitMethods.cs:13:10:13:11 | M2 | -| ExitMethods.cs:15:9:15:25 | call to method ErrorMaybe | ExitMethods.cs:13:10:13:11 | M2 | -| ExitMethods.cs:15:9:15:26 | ...; | ExitMethods.cs:13:10:13:11 | M2 | -| ExitMethods.cs:15:20:15:24 | false | ExitMethods.cs:13:10:13:11 | M2 | -| ExitMethods.cs:16:9:16:15 | return ...; | ExitMethods.cs:13:10:13:11 | M2 | -| ExitMethods.cs:19:10:19:11 | enter M3 | ExitMethods.cs:19:10:19:11 | M3 | -| ExitMethods.cs:19:10:19:11 | exit M3 | ExitMethods.cs:19:10:19:11 | M3 | -| ExitMethods.cs:19:10:19:11 | exit M3 (abnormal) | ExitMethods.cs:19:10:19:11 | M3 | -| ExitMethods.cs:20:5:23:5 | {...} | ExitMethods.cs:19:10:19:11 | M3 | -| ExitMethods.cs:21:9:21:25 | call to method ErrorAlways | ExitMethods.cs:19:10:19:11 | M3 | -| ExitMethods.cs:21:9:21:26 | ...; | ExitMethods.cs:19:10:19:11 | M3 | -| ExitMethods.cs:21:21:21:24 | true | ExitMethods.cs:19:10:19:11 | M3 | -| ExitMethods.cs:25:10:25:11 | enter M4 | ExitMethods.cs:25:10:25:11 | M4 | -| ExitMethods.cs:25:10:25:11 | exit M4 | ExitMethods.cs:25:10:25:11 | M4 | -| ExitMethods.cs:25:10:25:11 | exit M4 (abnormal) | ExitMethods.cs:25:10:25:11 | M4 | -| ExitMethods.cs:26:5:29:5 | {...} | ExitMethods.cs:25:10:25:11 | M4 | -| ExitMethods.cs:27:9:27:14 | call to method Exit | ExitMethods.cs:25:10:25:11 | M4 | -| ExitMethods.cs:27:9:27:14 | this access | ExitMethods.cs:25:10:25:11 | M4 | -| ExitMethods.cs:27:9:27:15 | ...; | ExitMethods.cs:25:10:25:11 | M4 | -| ExitMethods.cs:31:10:31:11 | enter M5 | ExitMethods.cs:31:10:31:11 | M5 | -| ExitMethods.cs:31:10:31:11 | exit M5 | ExitMethods.cs:31:10:31:11 | M5 | -| ExitMethods.cs:31:10:31:11 | exit M5 (abnormal) | ExitMethods.cs:31:10:31:11 | M5 | -| ExitMethods.cs:32:5:35:5 | {...} | ExitMethods.cs:31:10:31:11 | M5 | -| ExitMethods.cs:33:9:33:25 | call to method ApplicationExit | ExitMethods.cs:31:10:31:11 | M5 | -| ExitMethods.cs:33:9:33:25 | this access | ExitMethods.cs:31:10:31:11 | M5 | -| ExitMethods.cs:33:9:33:26 | ...; | ExitMethods.cs:31:10:31:11 | M5 | -| ExitMethods.cs:37:10:37:11 | enter M6 | ExitMethods.cs:37:10:37:11 | M6 | -| ExitMethods.cs:37:10:37:11 | exit M6 | ExitMethods.cs:37:10:37:11 | M6 | -| ExitMethods.cs:37:10:37:11 | exit M6 (normal) | ExitMethods.cs:37:10:37:11 | M6 | -| ExitMethods.cs:38:5:51:5 | {...} | ExitMethods.cs:37:10:37:11 | M6 | -| ExitMethods.cs:39:9:50:9 | try {...} ... | ExitMethods.cs:37:10:37:11 | M6 | -| ExitMethods.cs:40:9:42:9 | {...} | ExitMethods.cs:37:10:37:11 | M6 | -| ExitMethods.cs:41:13:41:30 | call to method ErrorAlways | ExitMethods.cs:37:10:37:11 | M6 | -| ExitMethods.cs:41:13:41:31 | ...; | ExitMethods.cs:37:10:37:11 | M6 | -| ExitMethods.cs:41:25:41:29 | false | ExitMethods.cs:37:10:37:11 | M6 | -| ExitMethods.cs:43:9:46:9 | [exception: ArgumentException] catch (...) {...} | ExitMethods.cs:37:10:37:11 | M6 | -| ExitMethods.cs:43:9:46:9 | [exception: Exception] catch (...) {...} | ExitMethods.cs:37:10:37:11 | M6 | -| ExitMethods.cs:44:9:46:9 | {...} | ExitMethods.cs:37:10:37:11 | M6 | -| ExitMethods.cs:45:13:45:19 | return ...; | ExitMethods.cs:37:10:37:11 | M6 | -| ExitMethods.cs:47:9:50:9 | [exception: Exception] catch (...) {...} | ExitMethods.cs:37:10:37:11 | M6 | -| ExitMethods.cs:48:9:50:9 | {...} | ExitMethods.cs:37:10:37:11 | M6 | -| ExitMethods.cs:49:13:49:19 | return ...; | ExitMethods.cs:37:10:37:11 | M6 | -| ExitMethods.cs:53:10:53:11 | enter M7 | ExitMethods.cs:53:10:53:11 | M7 | -| ExitMethods.cs:53:10:53:11 | exit M7 | ExitMethods.cs:53:10:53:11 | M7 | -| ExitMethods.cs:53:10:53:11 | exit M7 (abnormal) | ExitMethods.cs:53:10:53:11 | M7 | -| ExitMethods.cs:54:5:57:5 | {...} | ExitMethods.cs:53:10:53:11 | M7 | -| ExitMethods.cs:55:9:55:22 | call to method ErrorAlways2 | ExitMethods.cs:53:10:53:11 | M7 | -| ExitMethods.cs:55:9:55:23 | ...; | ExitMethods.cs:53:10:53:11 | M7 | -| ExitMethods.cs:59:10:59:11 | enter M8 | ExitMethods.cs:59:10:59:11 | M8 | -| ExitMethods.cs:59:10:59:11 | exit M8 | ExitMethods.cs:59:10:59:11 | M8 | -| ExitMethods.cs:59:10:59:11 | exit M8 (abnormal) | ExitMethods.cs:59:10:59:11 | M8 | -| ExitMethods.cs:60:5:63:5 | {...} | ExitMethods.cs:59:10:59:11 | M8 | -| ExitMethods.cs:61:9:61:22 | call to method ErrorAlways3 | ExitMethods.cs:59:10:59:11 | M8 | -| ExitMethods.cs:61:9:61:23 | ...; | ExitMethods.cs:59:10:59:11 | M8 | -| ExitMethods.cs:65:17:65:26 | enter ErrorMaybe | ExitMethods.cs:65:17:65:26 | ErrorMaybe | -| ExitMethods.cs:65:17:65:26 | exit ErrorMaybe | ExitMethods.cs:65:17:65:26 | ErrorMaybe | -| ExitMethods.cs:65:17:65:26 | exit ErrorMaybe (abnormal) | ExitMethods.cs:65:17:65:26 | ErrorMaybe | -| ExitMethods.cs:65:17:65:26 | exit ErrorMaybe (normal) | ExitMethods.cs:65:17:65:26 | ErrorMaybe | -| ExitMethods.cs:66:5:69:5 | {...} | ExitMethods.cs:65:17:65:26 | ErrorMaybe | -| ExitMethods.cs:67:9:68:34 | if (...) ... | ExitMethods.cs:65:17:65:26 | ErrorMaybe | -| ExitMethods.cs:67:13:67:13 | access to parameter b | ExitMethods.cs:65:17:65:26 | ErrorMaybe | -| ExitMethods.cs:68:13:68:34 | throw ...; | ExitMethods.cs:65:17:65:26 | ErrorMaybe | -| ExitMethods.cs:68:19:68:33 | object creation of type Exception | ExitMethods.cs:65:17:65:26 | ErrorMaybe | -| ExitMethods.cs:71:17:71:27 | enter ErrorAlways | ExitMethods.cs:71:17:71:27 | ErrorAlways | -| ExitMethods.cs:71:17:71:27 | exit ErrorAlways | ExitMethods.cs:71:17:71:27 | ErrorAlways | -| ExitMethods.cs:71:17:71:27 | exit ErrorAlways (abnormal) | ExitMethods.cs:71:17:71:27 | ErrorAlways | -| ExitMethods.cs:72:5:77:5 | {...} | ExitMethods.cs:71:17:71:27 | ErrorAlways | -| ExitMethods.cs:73:9:76:45 | if (...) ... | ExitMethods.cs:71:17:71:27 | ErrorAlways | -| ExitMethods.cs:73:13:73:13 | access to parameter b | ExitMethods.cs:71:17:71:27 | ErrorAlways | -| ExitMethods.cs:74:13:74:34 | throw ...; | ExitMethods.cs:71:17:71:27 | ErrorAlways | -| ExitMethods.cs:74:19:74:33 | object creation of type Exception | ExitMethods.cs:71:17:71:27 | ErrorAlways | -| ExitMethods.cs:76:13:76:45 | throw ...; | ExitMethods.cs:71:17:71:27 | ErrorAlways | -| ExitMethods.cs:76:19:76:44 | object creation of type ArgumentException | ExitMethods.cs:71:17:71:27 | ErrorAlways | -| ExitMethods.cs:76:41:76:43 | "b" | ExitMethods.cs:71:17:71:27 | ErrorAlways | -| ExitMethods.cs:79:17:79:28 | enter ErrorAlways2 | ExitMethods.cs:79:17:79:28 | ErrorAlways2 | -| ExitMethods.cs:79:17:79:28 | exit ErrorAlways2 | ExitMethods.cs:79:17:79:28 | ErrorAlways2 | -| ExitMethods.cs:79:17:79:28 | exit ErrorAlways2 (abnormal) | ExitMethods.cs:79:17:79:28 | ErrorAlways2 | -| ExitMethods.cs:80:5:82:5 | {...} | ExitMethods.cs:79:17:79:28 | ErrorAlways2 | -| ExitMethods.cs:81:9:81:30 | throw ...; | ExitMethods.cs:79:17:79:28 | ErrorAlways2 | -| ExitMethods.cs:81:15:81:29 | object creation of type Exception | ExitMethods.cs:79:17:79:28 | ErrorAlways2 | -| ExitMethods.cs:84:17:84:28 | enter ErrorAlways3 | ExitMethods.cs:84:17:84:28 | ErrorAlways3 | -| ExitMethods.cs:84:17:84:28 | exit ErrorAlways3 | ExitMethods.cs:84:17:84:28 | ErrorAlways3 | -| ExitMethods.cs:84:17:84:28 | exit ErrorAlways3 (abnormal) | ExitMethods.cs:84:17:84:28 | ErrorAlways3 | -| ExitMethods.cs:84:35:84:55 | throw ... | ExitMethods.cs:84:17:84:28 | ErrorAlways3 | -| ExitMethods.cs:84:41:84:55 | object creation of type Exception | ExitMethods.cs:84:17:84:28 | ErrorAlways3 | -| ExitMethods.cs:86:10:86:13 | enter Exit | ExitMethods.cs:86:10:86:13 | Exit | -| ExitMethods.cs:86:10:86:13 | exit Exit | ExitMethods.cs:86:10:86:13 | Exit | -| ExitMethods.cs:86:10:86:13 | exit Exit (abnormal) | ExitMethods.cs:86:10:86:13 | Exit | -| ExitMethods.cs:87:5:89:5 | {...} | ExitMethods.cs:86:10:86:13 | Exit | -| ExitMethods.cs:88:9:88:27 | call to method Exit | ExitMethods.cs:86:10:86:13 | Exit | -| ExitMethods.cs:88:9:88:28 | ...; | ExitMethods.cs:86:10:86:13 | Exit | -| ExitMethods.cs:88:26:88:26 | 0 | ExitMethods.cs:86:10:86:13 | Exit | -| ExitMethods.cs:91:10:91:18 | enter ExitInTry | ExitMethods.cs:91:10:91:18 | ExitInTry | -| ExitMethods.cs:91:10:91:18 | exit ExitInTry | ExitMethods.cs:91:10:91:18 | ExitInTry | -| ExitMethods.cs:91:10:91:18 | exit ExitInTry (abnormal) | ExitMethods.cs:91:10:91:18 | ExitInTry | -| ExitMethods.cs:92:5:102:5 | {...} | ExitMethods.cs:91:10:91:18 | ExitInTry | -| ExitMethods.cs:93:9:101:9 | try {...} ... | ExitMethods.cs:91:10:91:18 | ExitInTry | -| ExitMethods.cs:94:9:96:9 | {...} | ExitMethods.cs:91:10:91:18 | ExitInTry | -| ExitMethods.cs:95:13:95:18 | call to method Exit | ExitMethods.cs:91:10:91:18 | ExitInTry | -| ExitMethods.cs:95:13:95:18 | this access | ExitMethods.cs:91:10:91:18 | ExitInTry | -| ExitMethods.cs:95:13:95:19 | ...; | ExitMethods.cs:91:10:91:18 | ExitInTry | -| ExitMethods.cs:104:10:104:24 | enter ApplicationExit | ExitMethods.cs:104:10:104:24 | ApplicationExit | -| ExitMethods.cs:104:10:104:24 | exit ApplicationExit | ExitMethods.cs:104:10:104:24 | ApplicationExit | -| ExitMethods.cs:104:10:104:24 | exit ApplicationExit (abnormal) | ExitMethods.cs:104:10:104:24 | ApplicationExit | -| ExitMethods.cs:105:5:107:5 | {...} | ExitMethods.cs:104:10:104:24 | ApplicationExit | -| ExitMethods.cs:106:9:106:47 | call to method Exit | ExitMethods.cs:104:10:104:24 | ApplicationExit | -| ExitMethods.cs:106:9:106:48 | ...; | ExitMethods.cs:104:10:104:24 | ApplicationExit | -| ExitMethods.cs:109:13:109:21 | enter ThrowExpr | ExitMethods.cs:109:13:109:21 | ThrowExpr | -| ExitMethods.cs:109:13:109:21 | exit ThrowExpr | ExitMethods.cs:109:13:109:21 | ThrowExpr | -| ExitMethods.cs:109:13:109:21 | exit ThrowExpr (abnormal) | ExitMethods.cs:109:13:109:21 | ThrowExpr | -| ExitMethods.cs:109:13:109:21 | exit ThrowExpr (normal) | ExitMethods.cs:109:13:109:21 | ThrowExpr | -| ExitMethods.cs:110:5:112:5 | {...} | ExitMethods.cs:109:13:109:21 | ThrowExpr | -| ExitMethods.cs:111:9:111:77 | return ...; | ExitMethods.cs:109:13:109:21 | ThrowExpr | -| ExitMethods.cs:111:16:111:20 | access to parameter input | ExitMethods.cs:109:13:109:21 | ThrowExpr | -| ExitMethods.cs:111:16:111:25 | ... != ... | ExitMethods.cs:109:13:109:21 | ThrowExpr | -| ExitMethods.cs:111:16:111:76 | ... ? ... : ... | ExitMethods.cs:109:13:109:21 | ThrowExpr | -| ExitMethods.cs:111:25:111:25 | 0 | ExitMethods.cs:109:13:109:21 | ThrowExpr | -| ExitMethods.cs:111:25:111:25 | (...) ... | ExitMethods.cs:109:13:109:21 | ThrowExpr | -| ExitMethods.cs:111:29:111:29 | 1 | ExitMethods.cs:109:13:109:21 | ThrowExpr | -| ExitMethods.cs:111:29:111:29 | (...) ... | ExitMethods.cs:109:13:109:21 | ThrowExpr | -| ExitMethods.cs:111:29:111:37 | ... / ... | ExitMethods.cs:109:13:109:21 | ThrowExpr | -| ExitMethods.cs:111:33:111:37 | access to parameter input | ExitMethods.cs:109:13:109:21 | ThrowExpr | -| ExitMethods.cs:111:41:111:76 | throw ... | ExitMethods.cs:109:13:109:21 | ThrowExpr | -| ExitMethods.cs:111:47:111:76 | object creation of type ArgumentException | ExitMethods.cs:109:13:109:21 | ThrowExpr | -| ExitMethods.cs:111:69:111:75 | "input" | ExitMethods.cs:109:13:109:21 | ThrowExpr | -| ExitMethods.cs:114:16:114:34 | enter ExtensionMethodCall | ExitMethods.cs:114:16:114:34 | ExtensionMethodCall | -| ExitMethods.cs:114:16:114:34 | exit ExtensionMethodCall | ExitMethods.cs:114:16:114:34 | ExtensionMethodCall | -| ExitMethods.cs:114:16:114:34 | exit ExtensionMethodCall (normal) | ExitMethods.cs:114:16:114:34 | ExtensionMethodCall | -| ExitMethods.cs:115:5:117:5 | {...} | ExitMethods.cs:114:16:114:34 | ExtensionMethodCall | -| ExitMethods.cs:116:9:116:39 | return ...; | ExitMethods.cs:114:16:114:34 | ExtensionMethodCall | -| ExitMethods.cs:116:16:116:16 | access to parameter s | ExitMethods.cs:114:16:114:34 | ExtensionMethodCall | -| ExitMethods.cs:116:16:116:30 | call to method Contains | ExitMethods.cs:114:16:114:34 | ExtensionMethodCall | -| ExitMethods.cs:116:16:116:38 | ... ? ... : ... | ExitMethods.cs:114:16:114:34 | ExtensionMethodCall | -| ExitMethods.cs:116:27:116:29 | - | ExitMethods.cs:114:16:114:34 | ExtensionMethodCall | -| ExitMethods.cs:116:34:116:34 | 0 | ExitMethods.cs:114:16:114:34 | ExtensionMethodCall | -| ExitMethods.cs:116:38:116:38 | 1 | ExitMethods.cs:114:16:114:34 | ExtensionMethodCall | -| ExitMethods.cs:119:17:119:32 | enter FailingAssertion | ExitMethods.cs:119:17:119:32 | FailingAssertion | -| ExitMethods.cs:119:17:119:32 | exit FailingAssertion | ExitMethods.cs:119:17:119:32 | FailingAssertion | -| ExitMethods.cs:119:17:119:32 | exit FailingAssertion (abnormal) | ExitMethods.cs:119:17:119:32 | FailingAssertion | -| ExitMethods.cs:120:5:123:5 | {...} | ExitMethods.cs:119:17:119:32 | FailingAssertion | -| ExitMethods.cs:121:9:121:28 | [assertion failure] call to method IsTrue | ExitMethods.cs:119:17:119:32 | FailingAssertion | -| ExitMethods.cs:121:9:121:29 | ...; | ExitMethods.cs:119:17:119:32 | FailingAssertion | -| ExitMethods.cs:121:23:121:27 | false | ExitMethods.cs:119:17:119:32 | FailingAssertion | -| ExitMethods.cs:125:17:125:33 | enter FailingAssertion2 | ExitMethods.cs:125:17:125:33 | FailingAssertion2 | -| ExitMethods.cs:125:17:125:33 | exit FailingAssertion2 | ExitMethods.cs:125:17:125:33 | FailingAssertion2 | -| ExitMethods.cs:125:17:125:33 | exit FailingAssertion2 (abnormal) | ExitMethods.cs:125:17:125:33 | FailingAssertion2 | -| ExitMethods.cs:126:5:129:5 | {...} | ExitMethods.cs:125:17:125:33 | FailingAssertion2 | -| ExitMethods.cs:127:9:127:26 | call to method FailingAssertion | ExitMethods.cs:125:17:125:33 | FailingAssertion2 | -| ExitMethods.cs:127:9:127:26 | this access | ExitMethods.cs:125:17:125:33 | FailingAssertion2 | -| ExitMethods.cs:127:9:127:27 | ...; | ExitMethods.cs:125:17:125:33 | FailingAssertion2 | -| ExitMethods.cs:131:10:131:20 | enter AssertFalse | ExitMethods.cs:131:10:131:20 | AssertFalse | -| ExitMethods.cs:131:10:131:20 | exit AssertFalse | ExitMethods.cs:131:10:131:20 | AssertFalse | -| ExitMethods.cs:131:10:131:20 | exit AssertFalse (abnormal) | ExitMethods.cs:131:10:131:20 | AssertFalse | -| ExitMethods.cs:131:10:131:20 | exit AssertFalse (normal) | ExitMethods.cs:131:10:131:20 | AssertFalse | -| ExitMethods.cs:131:33:131:49 | [assertion failure] call to method IsFalse | ExitMethods.cs:131:10:131:20 | AssertFalse | -| ExitMethods.cs:131:33:131:49 | [assertion success] call to method IsFalse | ExitMethods.cs:131:10:131:20 | AssertFalse | -| ExitMethods.cs:131:48:131:48 | access to parameter b | ExitMethods.cs:131:10:131:20 | AssertFalse | -| ExitMethods.cs:133:17:133:33 | enter FailingAssertion3 | ExitMethods.cs:133:17:133:33 | FailingAssertion3 | -| ExitMethods.cs:133:17:133:33 | exit FailingAssertion3 | ExitMethods.cs:133:17:133:33 | FailingAssertion3 | -| ExitMethods.cs:133:17:133:33 | exit FailingAssertion3 (abnormal) | ExitMethods.cs:133:17:133:33 | FailingAssertion3 | -| ExitMethods.cs:134:5:137:5 | {...} | ExitMethods.cs:133:17:133:33 | FailingAssertion3 | -| ExitMethods.cs:135:9:135:25 | [assertion failure] call to method AssertFalse | ExitMethods.cs:133:17:133:33 | FailingAssertion3 | -| ExitMethods.cs:135:9:135:25 | this access | ExitMethods.cs:133:17:133:33 | FailingAssertion3 | -| ExitMethods.cs:135:9:135:26 | ...; | ExitMethods.cs:133:17:133:33 | FailingAssertion3 | -| ExitMethods.cs:135:21:135:24 | true | ExitMethods.cs:133:17:133:33 | FailingAssertion3 | +| ExitMethods.cs:8:10:8:11 | enter M1 | ExitMethods.cs:8:10:8:11 | M1 | +| ExitMethods.cs:8:10:8:11 | exit M1 | ExitMethods.cs:8:10:8:11 | M1 | +| ExitMethods.cs:8:10:8:11 | exit M1 (normal) | ExitMethods.cs:8:10:8:11 | M1 | +| ExitMethods.cs:9:5:12:5 | {...} | ExitMethods.cs:8:10:8:11 | M1 | +| ExitMethods.cs:10:9:10:24 | call to method ErrorMaybe | ExitMethods.cs:8:10:8:11 | M1 | +| ExitMethods.cs:10:9:10:25 | ...; | ExitMethods.cs:8:10:8:11 | M1 | +| ExitMethods.cs:10:20:10:23 | true | ExitMethods.cs:8:10:8:11 | M1 | +| ExitMethods.cs:11:9:11:15 | return ...; | ExitMethods.cs:8:10:8:11 | M1 | +| ExitMethods.cs:14:10:14:11 | enter M2 | ExitMethods.cs:14:10:14:11 | M2 | +| ExitMethods.cs:14:10:14:11 | exit M2 | ExitMethods.cs:14:10:14:11 | M2 | +| ExitMethods.cs:14:10:14:11 | exit M2 (normal) | ExitMethods.cs:14:10:14:11 | M2 | +| ExitMethods.cs:15:5:18:5 | {...} | ExitMethods.cs:14:10:14:11 | M2 | +| ExitMethods.cs:16:9:16:25 | call to method ErrorMaybe | ExitMethods.cs:14:10:14:11 | M2 | +| ExitMethods.cs:16:9:16:26 | ...; | ExitMethods.cs:14:10:14:11 | M2 | +| ExitMethods.cs:16:20:16:24 | false | ExitMethods.cs:14:10:14:11 | M2 | +| ExitMethods.cs:17:9:17:15 | return ...; | ExitMethods.cs:14:10:14:11 | M2 | +| ExitMethods.cs:20:10:20:11 | enter M3 | ExitMethods.cs:20:10:20:11 | M3 | +| ExitMethods.cs:20:10:20:11 | exit M3 | ExitMethods.cs:20:10:20:11 | M3 | +| ExitMethods.cs:20:10:20:11 | exit M3 (abnormal) | ExitMethods.cs:20:10:20:11 | M3 | +| ExitMethods.cs:21:5:24:5 | {...} | ExitMethods.cs:20:10:20:11 | M3 | +| ExitMethods.cs:22:9:22:25 | call to method ErrorAlways | ExitMethods.cs:20:10:20:11 | M3 | +| ExitMethods.cs:22:9:22:26 | ...; | ExitMethods.cs:20:10:20:11 | M3 | +| ExitMethods.cs:22:21:22:24 | true | ExitMethods.cs:20:10:20:11 | M3 | +| ExitMethods.cs:26:10:26:11 | enter M4 | ExitMethods.cs:26:10:26:11 | M4 | +| ExitMethods.cs:26:10:26:11 | exit M4 | ExitMethods.cs:26:10:26:11 | M4 | +| ExitMethods.cs:26:10:26:11 | exit M4 (abnormal) | ExitMethods.cs:26:10:26:11 | M4 | +| ExitMethods.cs:27:5:30:5 | {...} | ExitMethods.cs:26:10:26:11 | M4 | +| ExitMethods.cs:28:9:28:14 | call to method Exit | ExitMethods.cs:26:10:26:11 | M4 | +| ExitMethods.cs:28:9:28:14 | this access | ExitMethods.cs:26:10:26:11 | M4 | +| ExitMethods.cs:28:9:28:15 | ...; | ExitMethods.cs:26:10:26:11 | M4 | +| ExitMethods.cs:32:10:32:11 | enter M5 | ExitMethods.cs:32:10:32:11 | M5 | +| ExitMethods.cs:32:10:32:11 | exit M5 | ExitMethods.cs:32:10:32:11 | M5 | +| ExitMethods.cs:32:10:32:11 | exit M5 (abnormal) | ExitMethods.cs:32:10:32:11 | M5 | +| ExitMethods.cs:33:5:36:5 | {...} | ExitMethods.cs:32:10:32:11 | M5 | +| ExitMethods.cs:34:9:34:25 | call to method ApplicationExit | ExitMethods.cs:32:10:32:11 | M5 | +| ExitMethods.cs:34:9:34:25 | this access | ExitMethods.cs:32:10:32:11 | M5 | +| ExitMethods.cs:34:9:34:26 | ...; | ExitMethods.cs:32:10:32:11 | M5 | +| ExitMethods.cs:38:10:38:11 | enter M6 | ExitMethods.cs:38:10:38:11 | M6 | +| ExitMethods.cs:38:10:38:11 | exit M6 | ExitMethods.cs:38:10:38:11 | M6 | +| ExitMethods.cs:38:10:38:11 | exit M6 (normal) | ExitMethods.cs:38:10:38:11 | M6 | +| ExitMethods.cs:39:5:52:5 | {...} | ExitMethods.cs:38:10:38:11 | M6 | +| ExitMethods.cs:40:9:51:9 | try {...} ... | ExitMethods.cs:38:10:38:11 | M6 | +| ExitMethods.cs:41:9:43:9 | {...} | ExitMethods.cs:38:10:38:11 | M6 | +| ExitMethods.cs:42:13:42:30 | call to method ErrorAlways | ExitMethods.cs:38:10:38:11 | M6 | +| ExitMethods.cs:42:13:42:31 | ...; | ExitMethods.cs:38:10:38:11 | M6 | +| ExitMethods.cs:42:25:42:29 | false | ExitMethods.cs:38:10:38:11 | M6 | +| ExitMethods.cs:44:9:47:9 | [exception: ArgumentException] catch (...) {...} | ExitMethods.cs:38:10:38:11 | M6 | +| ExitMethods.cs:44:9:47:9 | [exception: Exception] catch (...) {...} | ExitMethods.cs:38:10:38:11 | M6 | +| ExitMethods.cs:45:9:47:9 | {...} | ExitMethods.cs:38:10:38:11 | M6 | +| ExitMethods.cs:46:13:46:19 | return ...; | ExitMethods.cs:38:10:38:11 | M6 | +| ExitMethods.cs:48:9:51:9 | [exception: Exception] catch (...) {...} | ExitMethods.cs:38:10:38:11 | M6 | +| ExitMethods.cs:49:9:51:9 | {...} | ExitMethods.cs:38:10:38:11 | M6 | +| ExitMethods.cs:50:13:50:19 | return ...; | ExitMethods.cs:38:10:38:11 | M6 | +| ExitMethods.cs:54:10:54:11 | enter M7 | ExitMethods.cs:54:10:54:11 | M7 | +| ExitMethods.cs:54:10:54:11 | exit M7 | ExitMethods.cs:54:10:54:11 | M7 | +| ExitMethods.cs:54:10:54:11 | exit M7 (abnormal) | ExitMethods.cs:54:10:54:11 | M7 | +| ExitMethods.cs:55:5:58:5 | {...} | ExitMethods.cs:54:10:54:11 | M7 | +| ExitMethods.cs:56:9:56:22 | call to method ErrorAlways2 | ExitMethods.cs:54:10:54:11 | M7 | +| ExitMethods.cs:56:9:56:23 | ...; | ExitMethods.cs:54:10:54:11 | M7 | +| ExitMethods.cs:60:10:60:11 | enter M8 | ExitMethods.cs:60:10:60:11 | M8 | +| ExitMethods.cs:60:10:60:11 | exit M8 | ExitMethods.cs:60:10:60:11 | M8 | +| ExitMethods.cs:60:10:60:11 | exit M8 (abnormal) | ExitMethods.cs:60:10:60:11 | M8 | +| ExitMethods.cs:61:5:64:5 | {...} | ExitMethods.cs:60:10:60:11 | M8 | +| ExitMethods.cs:62:9:62:22 | call to method ErrorAlways3 | ExitMethods.cs:60:10:60:11 | M8 | +| ExitMethods.cs:62:9:62:23 | ...; | ExitMethods.cs:60:10:60:11 | M8 | +| ExitMethods.cs:66:17:66:26 | enter ErrorMaybe | ExitMethods.cs:66:17:66:26 | ErrorMaybe | +| ExitMethods.cs:66:17:66:26 | exit ErrorMaybe | ExitMethods.cs:66:17:66:26 | ErrorMaybe | +| ExitMethods.cs:66:17:66:26 | exit ErrorMaybe (abnormal) | ExitMethods.cs:66:17:66:26 | ErrorMaybe | +| ExitMethods.cs:66:17:66:26 | exit ErrorMaybe (normal) | ExitMethods.cs:66:17:66:26 | ErrorMaybe | +| ExitMethods.cs:67:5:70:5 | {...} | ExitMethods.cs:66:17:66:26 | ErrorMaybe | +| ExitMethods.cs:68:9:69:34 | if (...) ... | ExitMethods.cs:66:17:66:26 | ErrorMaybe | +| ExitMethods.cs:68:13:68:13 | access to parameter b | ExitMethods.cs:66:17:66:26 | ErrorMaybe | +| ExitMethods.cs:69:13:69:34 | throw ...; | ExitMethods.cs:66:17:66:26 | ErrorMaybe | +| ExitMethods.cs:69:19:69:33 | object creation of type Exception | ExitMethods.cs:66:17:66:26 | ErrorMaybe | +| ExitMethods.cs:72:17:72:27 | enter ErrorAlways | ExitMethods.cs:72:17:72:27 | ErrorAlways | +| ExitMethods.cs:72:17:72:27 | exit ErrorAlways | ExitMethods.cs:72:17:72:27 | ErrorAlways | +| ExitMethods.cs:72:17:72:27 | exit ErrorAlways (abnormal) | ExitMethods.cs:72:17:72:27 | ErrorAlways | +| ExitMethods.cs:73:5:78:5 | {...} | ExitMethods.cs:72:17:72:27 | ErrorAlways | +| ExitMethods.cs:74:9:77:45 | if (...) ... | ExitMethods.cs:72:17:72:27 | ErrorAlways | +| ExitMethods.cs:74:13:74:13 | access to parameter b | ExitMethods.cs:72:17:72:27 | ErrorAlways | +| ExitMethods.cs:75:13:75:34 | throw ...; | ExitMethods.cs:72:17:72:27 | ErrorAlways | +| ExitMethods.cs:75:19:75:33 | object creation of type Exception | ExitMethods.cs:72:17:72:27 | ErrorAlways | +| ExitMethods.cs:77:13:77:45 | throw ...; | ExitMethods.cs:72:17:72:27 | ErrorAlways | +| ExitMethods.cs:77:19:77:44 | object creation of type ArgumentException | ExitMethods.cs:72:17:72:27 | ErrorAlways | +| ExitMethods.cs:77:41:77:43 | "b" | ExitMethods.cs:72:17:72:27 | ErrorAlways | +| ExitMethods.cs:80:17:80:28 | enter ErrorAlways2 | ExitMethods.cs:80:17:80:28 | ErrorAlways2 | +| ExitMethods.cs:80:17:80:28 | exit ErrorAlways2 | ExitMethods.cs:80:17:80:28 | ErrorAlways2 | +| ExitMethods.cs:80:17:80:28 | exit ErrorAlways2 (abnormal) | ExitMethods.cs:80:17:80:28 | ErrorAlways2 | +| ExitMethods.cs:81:5:83:5 | {...} | ExitMethods.cs:80:17:80:28 | ErrorAlways2 | +| ExitMethods.cs:82:9:82:30 | throw ...; | ExitMethods.cs:80:17:80:28 | ErrorAlways2 | +| ExitMethods.cs:82:15:82:29 | object creation of type Exception | ExitMethods.cs:80:17:80:28 | ErrorAlways2 | +| ExitMethods.cs:85:17:85:28 | enter ErrorAlways3 | ExitMethods.cs:85:17:85:28 | ErrorAlways3 | +| ExitMethods.cs:85:17:85:28 | exit ErrorAlways3 | ExitMethods.cs:85:17:85:28 | ErrorAlways3 | +| ExitMethods.cs:85:17:85:28 | exit ErrorAlways3 (abnormal) | ExitMethods.cs:85:17:85:28 | ErrorAlways3 | +| ExitMethods.cs:85:35:85:55 | throw ... | ExitMethods.cs:85:17:85:28 | ErrorAlways3 | +| ExitMethods.cs:85:41:85:55 | object creation of type Exception | ExitMethods.cs:85:17:85:28 | ErrorAlways3 | +| ExitMethods.cs:87:10:87:13 | enter Exit | ExitMethods.cs:87:10:87:13 | Exit | +| ExitMethods.cs:87:10:87:13 | exit Exit | ExitMethods.cs:87:10:87:13 | Exit | +| ExitMethods.cs:87:10:87:13 | exit Exit (abnormal) | ExitMethods.cs:87:10:87:13 | Exit | +| ExitMethods.cs:88:5:90:5 | {...} | ExitMethods.cs:87:10:87:13 | Exit | +| ExitMethods.cs:89:9:89:27 | call to method Exit | ExitMethods.cs:87:10:87:13 | Exit | +| ExitMethods.cs:89:9:89:28 | ...; | ExitMethods.cs:87:10:87:13 | Exit | +| ExitMethods.cs:89:26:89:26 | 0 | ExitMethods.cs:87:10:87:13 | Exit | +| ExitMethods.cs:92:10:92:18 | enter ExitInTry | ExitMethods.cs:92:10:92:18 | ExitInTry | +| ExitMethods.cs:92:10:92:18 | exit ExitInTry | ExitMethods.cs:92:10:92:18 | ExitInTry | +| ExitMethods.cs:92:10:92:18 | exit ExitInTry (abnormal) | ExitMethods.cs:92:10:92:18 | ExitInTry | +| ExitMethods.cs:93:5:103:5 | {...} | ExitMethods.cs:92:10:92:18 | ExitInTry | +| ExitMethods.cs:94:9:102:9 | try {...} ... | ExitMethods.cs:92:10:92:18 | ExitInTry | +| ExitMethods.cs:95:9:97:9 | {...} | ExitMethods.cs:92:10:92:18 | ExitInTry | +| ExitMethods.cs:96:13:96:18 | call to method Exit | ExitMethods.cs:92:10:92:18 | ExitInTry | +| ExitMethods.cs:96:13:96:18 | this access | ExitMethods.cs:92:10:92:18 | ExitInTry | +| ExitMethods.cs:96:13:96:19 | ...; | ExitMethods.cs:92:10:92:18 | ExitInTry | +| ExitMethods.cs:105:10:105:24 | enter ApplicationExit | ExitMethods.cs:105:10:105:24 | ApplicationExit | +| ExitMethods.cs:105:10:105:24 | exit ApplicationExit | ExitMethods.cs:105:10:105:24 | ApplicationExit | +| ExitMethods.cs:105:10:105:24 | exit ApplicationExit (abnormal) | ExitMethods.cs:105:10:105:24 | ApplicationExit | +| ExitMethods.cs:106:5:108:5 | {...} | ExitMethods.cs:105:10:105:24 | ApplicationExit | +| ExitMethods.cs:107:9:107:47 | call to method Exit | ExitMethods.cs:105:10:105:24 | ApplicationExit | +| ExitMethods.cs:107:9:107:48 | ...; | ExitMethods.cs:105:10:105:24 | ApplicationExit | +| ExitMethods.cs:110:13:110:21 | enter ThrowExpr | ExitMethods.cs:110:13:110:21 | ThrowExpr | +| ExitMethods.cs:110:13:110:21 | exit ThrowExpr | ExitMethods.cs:110:13:110:21 | ThrowExpr | +| ExitMethods.cs:110:13:110:21 | exit ThrowExpr (abnormal) | ExitMethods.cs:110:13:110:21 | ThrowExpr | +| ExitMethods.cs:110:13:110:21 | exit ThrowExpr (normal) | ExitMethods.cs:110:13:110:21 | ThrowExpr | +| ExitMethods.cs:111:5:113:5 | {...} | ExitMethods.cs:110:13:110:21 | ThrowExpr | +| ExitMethods.cs:112:9:112:77 | return ...; | ExitMethods.cs:110:13:110:21 | ThrowExpr | +| ExitMethods.cs:112:16:112:20 | access to parameter input | ExitMethods.cs:110:13:110:21 | ThrowExpr | +| ExitMethods.cs:112:16:112:25 | ... != ... | ExitMethods.cs:110:13:110:21 | ThrowExpr | +| ExitMethods.cs:112:16:112:76 | ... ? ... : ... | ExitMethods.cs:110:13:110:21 | ThrowExpr | +| ExitMethods.cs:112:25:112:25 | 0 | ExitMethods.cs:110:13:110:21 | ThrowExpr | +| ExitMethods.cs:112:25:112:25 | (...) ... | ExitMethods.cs:110:13:110:21 | ThrowExpr | +| ExitMethods.cs:112:29:112:29 | 1 | ExitMethods.cs:110:13:110:21 | ThrowExpr | +| ExitMethods.cs:112:29:112:29 | (...) ... | ExitMethods.cs:110:13:110:21 | ThrowExpr | +| ExitMethods.cs:112:29:112:37 | ... / ... | ExitMethods.cs:110:13:110:21 | ThrowExpr | +| ExitMethods.cs:112:33:112:37 | access to parameter input | ExitMethods.cs:110:13:110:21 | ThrowExpr | +| ExitMethods.cs:112:41:112:76 | throw ... | ExitMethods.cs:110:13:110:21 | ThrowExpr | +| ExitMethods.cs:112:47:112:76 | object creation of type ArgumentException | ExitMethods.cs:110:13:110:21 | ThrowExpr | +| ExitMethods.cs:112:69:112:75 | "input" | ExitMethods.cs:110:13:110:21 | ThrowExpr | +| ExitMethods.cs:115:16:115:34 | enter ExtensionMethodCall | ExitMethods.cs:115:16:115:34 | ExtensionMethodCall | +| ExitMethods.cs:115:16:115:34 | exit ExtensionMethodCall | ExitMethods.cs:115:16:115:34 | ExtensionMethodCall | +| ExitMethods.cs:115:16:115:34 | exit ExtensionMethodCall (normal) | ExitMethods.cs:115:16:115:34 | ExtensionMethodCall | +| ExitMethods.cs:116:5:118:5 | {...} | ExitMethods.cs:115:16:115:34 | ExtensionMethodCall | +| ExitMethods.cs:117:9:117:39 | return ...; | ExitMethods.cs:115:16:115:34 | ExtensionMethodCall | +| ExitMethods.cs:117:16:117:16 | access to parameter s | ExitMethods.cs:115:16:115:34 | ExtensionMethodCall | +| ExitMethods.cs:117:16:117:30 | call to method Contains | ExitMethods.cs:115:16:115:34 | ExtensionMethodCall | +| ExitMethods.cs:117:16:117:38 | ... ? ... : ... | ExitMethods.cs:115:16:115:34 | ExtensionMethodCall | +| ExitMethods.cs:117:27:117:29 | - | ExitMethods.cs:115:16:115:34 | ExtensionMethodCall | +| ExitMethods.cs:117:34:117:34 | 0 | ExitMethods.cs:115:16:115:34 | ExtensionMethodCall | +| ExitMethods.cs:117:38:117:38 | 1 | ExitMethods.cs:115:16:115:34 | ExtensionMethodCall | +| ExitMethods.cs:120:17:120:32 | enter FailingAssertion | ExitMethods.cs:120:17:120:32 | FailingAssertion | +| ExitMethods.cs:120:17:120:32 | exit FailingAssertion | ExitMethods.cs:120:17:120:32 | FailingAssertion | +| ExitMethods.cs:120:17:120:32 | exit FailingAssertion (abnormal) | ExitMethods.cs:120:17:120:32 | FailingAssertion | +| ExitMethods.cs:121:5:124:5 | {...} | ExitMethods.cs:120:17:120:32 | FailingAssertion | +| ExitMethods.cs:122:9:122:28 | [assertion failure] call to method IsTrue | ExitMethods.cs:120:17:120:32 | FailingAssertion | +| ExitMethods.cs:122:9:122:29 | ...; | ExitMethods.cs:120:17:120:32 | FailingAssertion | +| ExitMethods.cs:122:23:122:27 | false | ExitMethods.cs:120:17:120:32 | FailingAssertion | +| ExitMethods.cs:126:17:126:33 | enter FailingAssertion2 | ExitMethods.cs:126:17:126:33 | FailingAssertion2 | +| ExitMethods.cs:126:17:126:33 | exit FailingAssertion2 | ExitMethods.cs:126:17:126:33 | FailingAssertion2 | +| ExitMethods.cs:126:17:126:33 | exit FailingAssertion2 (abnormal) | ExitMethods.cs:126:17:126:33 | FailingAssertion2 | +| ExitMethods.cs:127:5:130:5 | {...} | ExitMethods.cs:126:17:126:33 | FailingAssertion2 | +| ExitMethods.cs:128:9:128:26 | call to method FailingAssertion | ExitMethods.cs:126:17:126:33 | FailingAssertion2 | +| ExitMethods.cs:128:9:128:26 | this access | ExitMethods.cs:126:17:126:33 | FailingAssertion2 | +| ExitMethods.cs:128:9:128:27 | ...; | ExitMethods.cs:126:17:126:33 | FailingAssertion2 | +| ExitMethods.cs:132:10:132:20 | enter AssertFalse | ExitMethods.cs:132:10:132:20 | AssertFalse | +| ExitMethods.cs:132:10:132:20 | exit AssertFalse | ExitMethods.cs:132:10:132:20 | AssertFalse | +| ExitMethods.cs:132:10:132:20 | exit AssertFalse (abnormal) | ExitMethods.cs:132:10:132:20 | AssertFalse | +| ExitMethods.cs:132:10:132:20 | exit AssertFalse (normal) | ExitMethods.cs:132:10:132:20 | AssertFalse | +| ExitMethods.cs:132:33:132:49 | [assertion failure] call to method IsFalse | ExitMethods.cs:132:10:132:20 | AssertFalse | +| ExitMethods.cs:132:33:132:49 | [assertion success] call to method IsFalse | ExitMethods.cs:132:10:132:20 | AssertFalse | +| ExitMethods.cs:132:48:132:48 | access to parameter b | ExitMethods.cs:132:10:132:20 | AssertFalse | +| ExitMethods.cs:134:17:134:33 | enter FailingAssertion3 | ExitMethods.cs:134:17:134:33 | FailingAssertion3 | +| ExitMethods.cs:134:17:134:33 | exit FailingAssertion3 | ExitMethods.cs:134:17:134:33 | FailingAssertion3 | +| ExitMethods.cs:134:17:134:33 | exit FailingAssertion3 (abnormal) | ExitMethods.cs:134:17:134:33 | FailingAssertion3 | +| ExitMethods.cs:135:5:138:5 | {...} | ExitMethods.cs:134:17:134:33 | FailingAssertion3 | +| ExitMethods.cs:136:9:136:25 | [assertion failure] call to method AssertFalse | ExitMethods.cs:134:17:134:33 | FailingAssertion3 | +| ExitMethods.cs:136:9:136:25 | this access | ExitMethods.cs:134:17:134:33 | FailingAssertion3 | +| ExitMethods.cs:136:9:136:26 | ...; | ExitMethods.cs:134:17:134:33 | FailingAssertion3 | +| ExitMethods.cs:136:21:136:24 | true | ExitMethods.cs:134:17:134:33 | FailingAssertion3 | +| ExitMethods.cs:140:17:140:42 | enter ExceptionDispatchInfoThrow | ExitMethods.cs:140:17:140:42 | ExceptionDispatchInfoThrow | +| ExitMethods.cs:140:17:140:42 | exit ExceptionDispatchInfoThrow | ExitMethods.cs:140:17:140:42 | ExceptionDispatchInfoThrow | +| ExitMethods.cs:140:17:140:42 | exit ExceptionDispatchInfoThrow (abnormal) | ExitMethods.cs:140:17:140:42 | ExceptionDispatchInfoThrow | +| ExitMethods.cs:141:5:147:5 | {...} | ExitMethods.cs:140:17:140:42 | ExceptionDispatchInfoThrow | +| ExitMethods.cs:142:9:145:53 | if (...) ... | ExitMethods.cs:140:17:140:42 | ExceptionDispatchInfoThrow | +| ExitMethods.cs:142:13:142:13 | access to parameter b | ExitMethods.cs:140:17:140:42 | ExceptionDispatchInfoThrow | +| ExitMethods.cs:143:13:143:42 | call to method Throw | ExitMethods.cs:140:17:140:42 | ExceptionDispatchInfoThrow | +| ExitMethods.cs:143:13:143:43 | ...; | ExitMethods.cs:140:17:140:42 | ExceptionDispatchInfoThrow | +| ExitMethods.cs:143:41:143:41 | access to parameter e | ExitMethods.cs:140:17:140:42 | ExceptionDispatchInfoThrow | +| ExitMethods.cs:145:13:145:44 | call to method Capture | ExitMethods.cs:140:17:140:42 | ExceptionDispatchInfoThrow | +| ExitMethods.cs:145:13:145:52 | call to method Throw | ExitMethods.cs:140:17:140:42 | ExceptionDispatchInfoThrow | +| ExitMethods.cs:145:13:145:53 | ...; | ExitMethods.cs:140:17:140:42 | ExceptionDispatchInfoThrow | +| ExitMethods.cs:145:43:145:43 | access to parameter e | ExitMethods.cs:140:17:140:42 | ExceptionDispatchInfoThrow | | Extensions.cs:5:23:5:29 | enter ToInt32 | Extensions.cs:5:23:5:29 | ToInt32 | | Extensions.cs:5:23:5:29 | exit ToInt32 | Extensions.cs:5:23:5:29 | ToInt32 | | Extensions.cs:5:23:5:29 | exit ToInt32 (normal) | Extensions.cs:5:23:5:29 | ToInt32 | @@ -1830,17 +1843,13 @@ nodeEnclosing | Finally.cs:11:13:11:38 | ...; | Finally.cs:7:10:7:11 | M1 | | Finally.cs:11:31:11:36 | "Try1" | Finally.cs:7:10:7:11 | M1 | | Finally.cs:14:9:16:9 | [finally: exception(Exception)] {...} | Finally.cs:7:10:7:11 | M1 | -| Finally.cs:14:9:16:9 | [finally: exception(OutOfMemoryException)] {...} | Finally.cs:7:10:7:11 | M1 | | Finally.cs:14:9:16:9 | {...} | Finally.cs:7:10:7:11 | M1 | | Finally.cs:15:13:15:40 | [finally: exception(Exception)] call to method WriteLine | Finally.cs:7:10:7:11 | M1 | -| Finally.cs:15:13:15:40 | [finally: exception(OutOfMemoryException)] call to method WriteLine | Finally.cs:7:10:7:11 | M1 | | Finally.cs:15:13:15:40 | call to method WriteLine | Finally.cs:7:10:7:11 | M1 | | Finally.cs:15:13:15:41 | ...; | Finally.cs:7:10:7:11 | M1 | | Finally.cs:15:13:15:41 | [finally: exception(Exception)] ...; | Finally.cs:7:10:7:11 | M1 | -| Finally.cs:15:13:15:41 | [finally: exception(OutOfMemoryException)] ...; | Finally.cs:7:10:7:11 | M1 | | Finally.cs:15:31:15:39 | "Finally" | Finally.cs:7:10:7:11 | M1 | | Finally.cs:15:31:15:39 | [finally: exception(Exception)] "Finally" | Finally.cs:7:10:7:11 | M1 | -| Finally.cs:15:31:15:39 | [finally: exception(OutOfMemoryException)] "Finally" | Finally.cs:7:10:7:11 | M1 | | Finally.cs:19:10:19:11 | enter M2 | Finally.cs:19:10:19:11 | M2 | | Finally.cs:19:10:19:11 | exit M2 | Finally.cs:19:10:19:11 | M2 | | Finally.cs:19:10:19:11 | exit M2 (abnormal) | Finally.cs:19:10:19:11 | M2 | @@ -1853,13 +1862,11 @@ nodeEnclosing | Finally.cs:23:31:23:36 | "Try2" | Finally.cs:19:10:19:11 | M2 | | Finally.cs:24:13:24:19 | return ...; | Finally.cs:19:10:19:11 | M2 | | Finally.cs:26:9:29:9 | [exception: Exception] catch (...) {...} | Finally.cs:19:10:19:11 | M2 | -| Finally.cs:26:9:29:9 | [exception: OutOfMemoryException] catch (...) {...} | Finally.cs:19:10:19:11 | M2 | | Finally.cs:26:38:26:39 | [exception: Exception] IOException ex | Finally.cs:19:10:19:11 | M2 | | Finally.cs:26:48:26:51 | [exception: Exception] true | Finally.cs:19:10:19:11 | M2 | | Finally.cs:27:9:29:9 | {...} | Finally.cs:19:10:19:11 | M2 | | Finally.cs:28:13:28:18 | throw ...; | Finally.cs:19:10:19:11 | M2 | | Finally.cs:30:9:40:9 | [exception: Exception] catch (...) {...} | Finally.cs:19:10:19:11 | M2 | -| Finally.cs:30:9:40:9 | [exception: OutOfMemoryException] catch (...) {...} | Finally.cs:19:10:19:11 | M2 | | Finally.cs:30:41:30:42 | [exception: Exception] ArgumentException ex | Finally.cs:19:10:19:11 | M2 | | Finally.cs:31:9:40:9 | {...} | Finally.cs:19:10:19:11 | M2 | | Finally.cs:32:13:39:13 | try {...} ... | Finally.cs:19:10:19:11 | M2 | @@ -1872,7 +1879,6 @@ nodeEnclosing | Finally.cs:38:23:38:43 | [finally: exception(ArgumentException)] object creation of type Exception | Finally.cs:19:10:19:11 | M2 | | Finally.cs:38:37:38:42 | [finally: exception(ArgumentException)] "Boo!" | Finally.cs:19:10:19:11 | M2 | | Finally.cs:41:9:43:9 | [exception: Exception] catch (...) {...} | Finally.cs:19:10:19:11 | M2 | -| Finally.cs:41:9:43:9 | [exception: OutOfMemoryException] catch (...) {...} | Finally.cs:19:10:19:11 | M2 | | Finally.cs:42:9:43:9 | {...} | Finally.cs:19:10:19:11 | M2 | | Finally.cs:49:9:51:9 | [finally: exception(Exception)] {...} | Finally.cs:19:10:19:11 | M2 | | Finally.cs:49:9:51:9 | [finally: exception(IOException)] {...} | Finally.cs:19:10:19:11 | M2 | @@ -1902,43 +1908,32 @@ nodeEnclosing | Finally.cs:58:31:58:36 | "Try3" | Finally.cs:54:10:54:11 | M3 | | Finally.cs:59:13:59:19 | return ...; | Finally.cs:54:10:54:11 | M3 | | Finally.cs:61:9:64:9 | [exception: Exception] catch (...) {...} | Finally.cs:54:10:54:11 | M3 | -| Finally.cs:61:9:64:9 | [exception: OutOfMemoryException] catch (...) {...} | Finally.cs:54:10:54:11 | M3 | | Finally.cs:61:38:61:39 | [exception: Exception] IOException ex | Finally.cs:54:10:54:11 | M3 | | Finally.cs:61:48:61:51 | [exception: Exception] true | Finally.cs:54:10:54:11 | M3 | | Finally.cs:62:9:64:9 | {...} | Finally.cs:54:10:54:11 | M3 | | Finally.cs:63:13:63:18 | throw ...; | Finally.cs:54:10:54:11 | M3 | | Finally.cs:65:9:67:9 | [exception: Exception] catch (...) {...} | Finally.cs:54:10:54:11 | M3 | -| Finally.cs:65:9:67:9 | [exception: OutOfMemoryException] catch (...) {...} | Finally.cs:54:10:54:11 | M3 | | Finally.cs:65:26:65:26 | [exception: Exception] Exception e | Finally.cs:54:10:54:11 | M3 | -| Finally.cs:65:26:65:26 | [exception: OutOfMemoryException] Exception e | Finally.cs:54:10:54:11 | M3 | | Finally.cs:65:35:65:35 | [exception: Exception] access to local variable e | Finally.cs:54:10:54:11 | M3 | -| Finally.cs:65:35:65:35 | [exception: OutOfMemoryException] access to local variable e | Finally.cs:54:10:54:11 | M3 | | Finally.cs:65:35:65:43 | [exception: Exception] access to property Message | Finally.cs:54:10:54:11 | M3 | -| Finally.cs:65:35:65:43 | [exception: OutOfMemoryException] access to property Message | Finally.cs:54:10:54:11 | M3 | | Finally.cs:65:35:65:51 | [exception: Exception] ... != ... | Finally.cs:54:10:54:11 | M3 | -| Finally.cs:65:35:65:51 | [exception: OutOfMemoryException] ... != ... | Finally.cs:54:10:54:11 | M3 | | Finally.cs:65:48:65:51 | [exception: Exception] null | Finally.cs:54:10:54:11 | M3 | -| Finally.cs:65:48:65:51 | [exception: OutOfMemoryException] null | Finally.cs:54:10:54:11 | M3 | | Finally.cs:66:9:67:9 | {...} | Finally.cs:54:10:54:11 | M3 | | Finally.cs:69:9:71:9 | [finally: exception(Exception)] {...} | Finally.cs:54:10:54:11 | M3 | | Finally.cs:69:9:71:9 | [finally: exception(IOException)] {...} | Finally.cs:54:10:54:11 | M3 | -| Finally.cs:69:9:71:9 | [finally: exception(OutOfMemoryException)] {...} | Finally.cs:54:10:54:11 | M3 | | Finally.cs:69:9:71:9 | [finally: return] {...} | Finally.cs:54:10:54:11 | M3 | | Finally.cs:69:9:71:9 | {...} | Finally.cs:54:10:54:11 | M3 | | Finally.cs:70:13:70:40 | [finally: exception(Exception)] call to method WriteLine | Finally.cs:54:10:54:11 | M3 | | Finally.cs:70:13:70:40 | [finally: exception(IOException)] call to method WriteLine | Finally.cs:54:10:54:11 | M3 | -| Finally.cs:70:13:70:40 | [finally: exception(OutOfMemoryException)] call to method WriteLine | Finally.cs:54:10:54:11 | M3 | | Finally.cs:70:13:70:40 | [finally: return] call to method WriteLine | Finally.cs:54:10:54:11 | M3 | | Finally.cs:70:13:70:40 | call to method WriteLine | Finally.cs:54:10:54:11 | M3 | | Finally.cs:70:13:70:41 | ...; | Finally.cs:54:10:54:11 | M3 | | Finally.cs:70:13:70:41 | [finally: exception(Exception)] ...; | Finally.cs:54:10:54:11 | M3 | | Finally.cs:70:13:70:41 | [finally: exception(IOException)] ...; | Finally.cs:54:10:54:11 | M3 | -| Finally.cs:70:13:70:41 | [finally: exception(OutOfMemoryException)] ...; | Finally.cs:54:10:54:11 | M3 | | Finally.cs:70:13:70:41 | [finally: return] ...; | Finally.cs:54:10:54:11 | M3 | | Finally.cs:70:31:70:39 | "Finally" | Finally.cs:54:10:54:11 | M3 | | Finally.cs:70:31:70:39 | [finally: exception(Exception)] "Finally" | Finally.cs:54:10:54:11 | M3 | | Finally.cs:70:31:70:39 | [finally: exception(IOException)] "Finally" | Finally.cs:54:10:54:11 | M3 | -| Finally.cs:70:31:70:39 | [finally: exception(OutOfMemoryException)] "Finally" | Finally.cs:54:10:54:11 | M3 | | Finally.cs:70:31:70:39 | [finally: return] "Finally" | Finally.cs:54:10:54:11 | M3 | | Finally.cs:74:10:74:11 | enter M4 | Finally.cs:74:10:74:11 | M4 | | Finally.cs:74:10:74:11 | exit M4 | Finally.cs:74:10:74:11 | M4 | @@ -2006,37 +2001,37 @@ nodeEnclosing | Finally.cs:93:31:93:45 | [finally: continue] object creation of type Exception | Finally.cs:74:10:74:11 | M4 | | Finally.cs:93:31:93:45 | [finally: return] object creation of type Exception | Finally.cs:74:10:74:11 | M4 | | Finally.cs:93:31:93:45 | object creation of type Exception | Finally.cs:74:10:74:11 | M4 | -| Finally.cs:96:17:98:17 | [finally(2): exception(Exception)] {...} | Finally.cs:74:10:74:11 | M4 | -| Finally.cs:96:17:98:17 | [finally: break, finally(2): exception(Exception)] {...} | Finally.cs:74:10:74:11 | M4 | +| Finally.cs:96:17:98:17 | [finally(1): exception(Exception)] {...} | Finally.cs:74:10:74:11 | M4 | +| Finally.cs:96:17:98:17 | [finally: break, finally(1): exception(Exception)] {...} | Finally.cs:74:10:74:11 | M4 | | Finally.cs:96:17:98:17 | [finally: break] {...} | Finally.cs:74:10:74:11 | M4 | -| Finally.cs:96:17:98:17 | [finally: continue, finally(2): exception(Exception)] {...} | Finally.cs:74:10:74:11 | M4 | +| Finally.cs:96:17:98:17 | [finally: continue, finally(1): exception(Exception)] {...} | Finally.cs:74:10:74:11 | M4 | | Finally.cs:96:17:98:17 | [finally: continue] {...} | Finally.cs:74:10:74:11 | M4 | -| Finally.cs:96:17:98:17 | [finally: return, finally(2): exception(Exception)] {...} | Finally.cs:74:10:74:11 | M4 | +| Finally.cs:96:17:98:17 | [finally: return, finally(1): exception(Exception)] {...} | Finally.cs:74:10:74:11 | M4 | | Finally.cs:96:17:98:17 | [finally: return] {...} | Finally.cs:74:10:74:11 | M4 | | Finally.cs:96:17:98:17 | {...} | Finally.cs:74:10:74:11 | M4 | -| Finally.cs:97:21:97:21 | [finally(2): exception(Exception)] access to local variable i | Finally.cs:74:10:74:11 | M4 | -| Finally.cs:97:21:97:21 | [finally: break, finally(2): exception(Exception)] access to local variable i | Finally.cs:74:10:74:11 | M4 | +| Finally.cs:97:21:97:21 | [finally(1): exception(Exception)] access to local variable i | Finally.cs:74:10:74:11 | M4 | +| Finally.cs:97:21:97:21 | [finally: break, finally(1): exception(Exception)] access to local variable i | Finally.cs:74:10:74:11 | M4 | | Finally.cs:97:21:97:21 | [finally: break] access to local variable i | Finally.cs:74:10:74:11 | M4 | -| Finally.cs:97:21:97:21 | [finally: continue, finally(2): exception(Exception)] access to local variable i | Finally.cs:74:10:74:11 | M4 | +| Finally.cs:97:21:97:21 | [finally: continue, finally(1): exception(Exception)] access to local variable i | Finally.cs:74:10:74:11 | M4 | | Finally.cs:97:21:97:21 | [finally: continue] access to local variable i | Finally.cs:74:10:74:11 | M4 | -| Finally.cs:97:21:97:21 | [finally: return, finally(2): exception(Exception)] access to local variable i | Finally.cs:74:10:74:11 | M4 | +| Finally.cs:97:21:97:21 | [finally: return, finally(1): exception(Exception)] access to local variable i | Finally.cs:74:10:74:11 | M4 | | Finally.cs:97:21:97:21 | [finally: return] access to local variable i | Finally.cs:74:10:74:11 | M4 | | Finally.cs:97:21:97:21 | access to local variable i | Finally.cs:74:10:74:11 | M4 | | Finally.cs:97:21:97:23 | ...-- | Finally.cs:74:10:74:11 | M4 | -| Finally.cs:97:21:97:23 | [finally(2): exception(Exception)] ...-- | Finally.cs:74:10:74:11 | M4 | -| Finally.cs:97:21:97:23 | [finally: break, finally(2): exception(Exception)] ...-- | Finally.cs:74:10:74:11 | M4 | +| Finally.cs:97:21:97:23 | [finally(1): exception(Exception)] ...-- | Finally.cs:74:10:74:11 | M4 | +| Finally.cs:97:21:97:23 | [finally: break, finally(1): exception(Exception)] ...-- | Finally.cs:74:10:74:11 | M4 | | Finally.cs:97:21:97:23 | [finally: break] ...-- | Finally.cs:74:10:74:11 | M4 | -| Finally.cs:97:21:97:23 | [finally: continue, finally(2): exception(Exception)] ...-- | Finally.cs:74:10:74:11 | M4 | +| Finally.cs:97:21:97:23 | [finally: continue, finally(1): exception(Exception)] ...-- | Finally.cs:74:10:74:11 | M4 | | Finally.cs:97:21:97:23 | [finally: continue] ...-- | Finally.cs:74:10:74:11 | M4 | -| Finally.cs:97:21:97:23 | [finally: return, finally(2): exception(Exception)] ...-- | Finally.cs:74:10:74:11 | M4 | +| Finally.cs:97:21:97:23 | [finally: return, finally(1): exception(Exception)] ...-- | Finally.cs:74:10:74:11 | M4 | | Finally.cs:97:21:97:23 | [finally: return] ...-- | Finally.cs:74:10:74:11 | M4 | | Finally.cs:97:21:97:24 | ...; | Finally.cs:74:10:74:11 | M4 | -| Finally.cs:97:21:97:24 | [finally(2): exception(Exception)] ...; | Finally.cs:74:10:74:11 | M4 | -| Finally.cs:97:21:97:24 | [finally: break, finally(2): exception(Exception)] ...; | Finally.cs:74:10:74:11 | M4 | +| Finally.cs:97:21:97:24 | [finally(1): exception(Exception)] ...; | Finally.cs:74:10:74:11 | M4 | +| Finally.cs:97:21:97:24 | [finally: break, finally(1): exception(Exception)] ...; | Finally.cs:74:10:74:11 | M4 | | Finally.cs:97:21:97:24 | [finally: break] ...; | Finally.cs:74:10:74:11 | M4 | -| Finally.cs:97:21:97:24 | [finally: continue, finally(2): exception(Exception)] ...; | Finally.cs:74:10:74:11 | M4 | +| Finally.cs:97:21:97:24 | [finally: continue, finally(1): exception(Exception)] ...; | Finally.cs:74:10:74:11 | M4 | | Finally.cs:97:21:97:24 | [finally: continue] ...; | Finally.cs:74:10:74:11 | M4 | -| Finally.cs:97:21:97:24 | [finally: return, finally(2): exception(Exception)] ...; | Finally.cs:74:10:74:11 | M4 | +| Finally.cs:97:21:97:24 | [finally: return, finally(1): exception(Exception)] ...; | Finally.cs:74:10:74:11 | M4 | | Finally.cs:97:21:97:24 | [finally: return] ...; | Finally.cs:74:10:74:11 | M4 | | Finally.cs:103:10:103:11 | enter M5 | Finally.cs:103:10:103:11 | M5 | | Finally.cs:103:10:103:11 | exit M5 | Finally.cs:103:10:103:11 | M5 | @@ -2192,17 +2187,13 @@ nodeEnclosing | Finally.cs:137:13:137:37 | ...; | Finally.cs:133:10:133:11 | M7 | | Finally.cs:137:31:137:35 | "Try" | Finally.cs:133:10:133:11 | M7 | | Finally.cs:140:9:143:9 | [finally: exception(Exception)] {...} | Finally.cs:133:10:133:11 | M7 | -| Finally.cs:140:9:143:9 | [finally: exception(OutOfMemoryException)] {...} | Finally.cs:133:10:133:11 | M7 | | Finally.cs:140:9:143:9 | {...} | Finally.cs:133:10:133:11 | M7 | | Finally.cs:141:13:141:44 | [finally: exception(Exception)] throw ...; | Finally.cs:133:10:133:11 | M7 | -| Finally.cs:141:13:141:44 | [finally: exception(OutOfMemoryException)] throw ...; | Finally.cs:133:10:133:11 | M7 | | Finally.cs:141:13:141:44 | throw ...; | Finally.cs:133:10:133:11 | M7 | | Finally.cs:141:19:141:43 | [finally: exception(Exception)] object creation of type ArgumentException | Finally.cs:133:10:133:11 | M7 | -| Finally.cs:141:19:141:43 | [finally: exception(OutOfMemoryException)] object creation of type ArgumentException | Finally.cs:133:10:133:11 | M7 | | Finally.cs:141:19:141:43 | object creation of type ArgumentException | Finally.cs:133:10:133:11 | M7 | | Finally.cs:141:41:141:42 | "" | Finally.cs:133:10:133:11 | M7 | | Finally.cs:141:41:141:42 | [finally: exception(Exception)] "" | Finally.cs:133:10:133:11 | M7 | -| Finally.cs:141:41:141:42 | [finally: exception(OutOfMemoryException)] "" | Finally.cs:133:10:133:11 | M7 | | Finally.cs:147:10:147:11 | enter M8 | Finally.cs:147:10:147:11 | M8 | | Finally.cs:147:10:147:11 | exit M8 | Finally.cs:147:10:147:11 | M8 | | Finally.cs:147:10:147:11 | exit M8 (abnormal) | Finally.cs:147:10:147:11 | M8 | @@ -2251,58 +2242,40 @@ nodeEnclosing | Finally.cs:159:41:159:43 | [finally: exception(Exception)] "1" | Finally.cs:147:10:147:11 | M8 | | Finally.cs:161:13:164:13 | [exception: Exception] catch (...) {...} | Finally.cs:147:10:147:11 | M8 | | Finally.cs:161:13:164:13 | [exception: NullReferenceException] catch (...) {...} | Finally.cs:147:10:147:11 | M8 | -| Finally.cs:161:13:164:13 | [exception: OutOfMemoryException] catch (...) {...} | Finally.cs:147:10:147:11 | M8 | | Finally.cs:161:13:164:13 | [finally: exception(ArgumentNullException), exception: Exception] catch (...) {...} | Finally.cs:147:10:147:11 | M8 | | Finally.cs:161:13:164:13 | [finally: exception(ArgumentNullException), exception: NullReferenceException] catch (...) {...} | Finally.cs:147:10:147:11 | M8 | -| Finally.cs:161:13:164:13 | [finally: exception(ArgumentNullException), exception: OutOfMemoryException] catch (...) {...} | Finally.cs:147:10:147:11 | M8 | | Finally.cs:161:13:164:13 | [finally: exception(Exception), exception: Exception] catch (...) {...} | Finally.cs:147:10:147:11 | M8 | | Finally.cs:161:13:164:13 | [finally: exception(Exception), exception: NullReferenceException] catch (...) {...} | Finally.cs:147:10:147:11 | M8 | -| Finally.cs:161:13:164:13 | [finally: exception(Exception), exception: OutOfMemoryException] catch (...) {...} | Finally.cs:147:10:147:11 | M8 | | Finally.cs:161:30:161:30 | [exception: Exception] Exception e | Finally.cs:147:10:147:11 | M8 | | Finally.cs:161:30:161:30 | [exception: NullReferenceException] Exception e | Finally.cs:147:10:147:11 | M8 | -| Finally.cs:161:30:161:30 | [exception: OutOfMemoryException] Exception e | Finally.cs:147:10:147:11 | M8 | | Finally.cs:161:30:161:30 | [finally: exception(ArgumentNullException), exception: Exception] Exception e | Finally.cs:147:10:147:11 | M8 | | Finally.cs:161:30:161:30 | [finally: exception(ArgumentNullException), exception: NullReferenceException] Exception e | Finally.cs:147:10:147:11 | M8 | -| Finally.cs:161:30:161:30 | [finally: exception(ArgumentNullException), exception: OutOfMemoryException] Exception e | Finally.cs:147:10:147:11 | M8 | | Finally.cs:161:30:161:30 | [finally: exception(Exception), exception: Exception] Exception e | Finally.cs:147:10:147:11 | M8 | | Finally.cs:161:30:161:30 | [finally: exception(Exception), exception: NullReferenceException] Exception e | Finally.cs:147:10:147:11 | M8 | -| Finally.cs:161:30:161:30 | [finally: exception(Exception), exception: OutOfMemoryException] Exception e | Finally.cs:147:10:147:11 | M8 | | Finally.cs:161:39:161:39 | [exception: Exception] access to local variable e | Finally.cs:147:10:147:11 | M8 | | Finally.cs:161:39:161:39 | [exception: NullReferenceException] access to local variable e | Finally.cs:147:10:147:11 | M8 | -| Finally.cs:161:39:161:39 | [exception: OutOfMemoryException] access to local variable e | Finally.cs:147:10:147:11 | M8 | | Finally.cs:161:39:161:39 | [finally: exception(ArgumentNullException), exception: Exception] access to local variable e | Finally.cs:147:10:147:11 | M8 | | Finally.cs:161:39:161:39 | [finally: exception(ArgumentNullException), exception: NullReferenceException] access to local variable e | Finally.cs:147:10:147:11 | M8 | -| Finally.cs:161:39:161:39 | [finally: exception(ArgumentNullException), exception: OutOfMemoryException] access to local variable e | Finally.cs:147:10:147:11 | M8 | | Finally.cs:161:39:161:39 | [finally: exception(Exception), exception: Exception] access to local variable e | Finally.cs:147:10:147:11 | M8 | | Finally.cs:161:39:161:39 | [finally: exception(Exception), exception: NullReferenceException] access to local variable e | Finally.cs:147:10:147:11 | M8 | -| Finally.cs:161:39:161:39 | [finally: exception(Exception), exception: OutOfMemoryException] access to local variable e | Finally.cs:147:10:147:11 | M8 | | Finally.cs:161:39:161:47 | [exception: Exception] access to property Message | Finally.cs:147:10:147:11 | M8 | | Finally.cs:161:39:161:47 | [exception: NullReferenceException] access to property Message | Finally.cs:147:10:147:11 | M8 | -| Finally.cs:161:39:161:47 | [exception: OutOfMemoryException] access to property Message | Finally.cs:147:10:147:11 | M8 | | Finally.cs:161:39:161:47 | [finally: exception(ArgumentNullException), exception: Exception] access to property Message | Finally.cs:147:10:147:11 | M8 | | Finally.cs:161:39:161:47 | [finally: exception(ArgumentNullException), exception: NullReferenceException] access to property Message | Finally.cs:147:10:147:11 | M8 | -| Finally.cs:161:39:161:47 | [finally: exception(ArgumentNullException), exception: OutOfMemoryException] access to property Message | Finally.cs:147:10:147:11 | M8 | | Finally.cs:161:39:161:47 | [finally: exception(Exception), exception: Exception] access to property Message | Finally.cs:147:10:147:11 | M8 | | Finally.cs:161:39:161:47 | [finally: exception(Exception), exception: NullReferenceException] access to property Message | Finally.cs:147:10:147:11 | M8 | -| Finally.cs:161:39:161:47 | [finally: exception(Exception), exception: OutOfMemoryException] access to property Message | Finally.cs:147:10:147:11 | M8 | | Finally.cs:161:39:161:54 | [exception: Exception] ... == ... | Finally.cs:147:10:147:11 | M8 | | Finally.cs:161:39:161:54 | [exception: NullReferenceException] ... == ... | Finally.cs:147:10:147:11 | M8 | -| Finally.cs:161:39:161:54 | [exception: OutOfMemoryException] ... == ... | Finally.cs:147:10:147:11 | M8 | | Finally.cs:161:39:161:54 | [finally: exception(ArgumentNullException), exception: Exception] ... == ... | Finally.cs:147:10:147:11 | M8 | | Finally.cs:161:39:161:54 | [finally: exception(ArgumentNullException), exception: NullReferenceException] ... == ... | Finally.cs:147:10:147:11 | M8 | -| Finally.cs:161:39:161:54 | [finally: exception(ArgumentNullException), exception: OutOfMemoryException] ... == ... | Finally.cs:147:10:147:11 | M8 | | Finally.cs:161:39:161:54 | [finally: exception(Exception), exception: Exception] ... == ... | Finally.cs:147:10:147:11 | M8 | | Finally.cs:161:39:161:54 | [finally: exception(Exception), exception: NullReferenceException] ... == ... | Finally.cs:147:10:147:11 | M8 | -| Finally.cs:161:39:161:54 | [finally: exception(Exception), exception: OutOfMemoryException] ... == ... | Finally.cs:147:10:147:11 | M8 | | Finally.cs:161:52:161:54 | [exception: Exception] "1" | Finally.cs:147:10:147:11 | M8 | | Finally.cs:161:52:161:54 | [exception: NullReferenceException] "1" | Finally.cs:147:10:147:11 | M8 | -| Finally.cs:161:52:161:54 | [exception: OutOfMemoryException] "1" | Finally.cs:147:10:147:11 | M8 | | Finally.cs:161:52:161:54 | [finally: exception(ArgumentNullException), exception: Exception] "1" | Finally.cs:147:10:147:11 | M8 | | Finally.cs:161:52:161:54 | [finally: exception(ArgumentNullException), exception: NullReferenceException] "1" | Finally.cs:147:10:147:11 | M8 | -| Finally.cs:161:52:161:54 | [finally: exception(ArgumentNullException), exception: OutOfMemoryException] "1" | Finally.cs:147:10:147:11 | M8 | | Finally.cs:161:52:161:54 | [finally: exception(Exception), exception: Exception] "1" | Finally.cs:147:10:147:11 | M8 | | Finally.cs:161:52:161:54 | [finally: exception(Exception), exception: NullReferenceException] "1" | Finally.cs:147:10:147:11 | M8 | -| Finally.cs:161:52:161:54 | [finally: exception(Exception), exception: OutOfMemoryException] "1" | Finally.cs:147:10:147:11 | M8 | | Finally.cs:162:13:164:13 | [finally: exception(ArgumentNullException)] {...} | Finally.cs:147:10:147:11 | M8 | | Finally.cs:162:13:164:13 | [finally: exception(Exception)] {...} | Finally.cs:147:10:147:11 | M8 | | Finally.cs:162:13:164:13 | {...} | Finally.cs:147:10:147:11 | M8 | @@ -2425,49 +2398,49 @@ nodeEnclosing | Finally.cs:205:31:205:46 | [finally: exception(Exception)] object creation of type ExceptionB | Finally.cs:195:10:195:12 | M10 | | Finally.cs:205:31:205:46 | [finally: exception(ExceptionA)] object creation of type ExceptionB | Finally.cs:195:10:195:12 | M10 | | Finally.cs:205:31:205:46 | object creation of type ExceptionB | Finally.cs:195:10:195:12 | M10 | -| Finally.cs:208:13:210:13 | [finally(2): exception(Exception)] {...} | Finally.cs:195:10:195:12 | M10 | -| Finally.cs:208:13:210:13 | [finally(2): exception(ExceptionB)] {...} | Finally.cs:195:10:195:12 | M10 | -| Finally.cs:208:13:210:13 | [finally: exception(Exception), finally(2): exception(Exception)] {...} | Finally.cs:195:10:195:12 | M10 | -| Finally.cs:208:13:210:13 | [finally: exception(Exception), finally(2): exception(ExceptionB)] {...} | Finally.cs:195:10:195:12 | M10 | +| Finally.cs:208:13:210:13 | [finally(1): exception(Exception)] {...} | Finally.cs:195:10:195:12 | M10 | +| Finally.cs:208:13:210:13 | [finally(1): exception(ExceptionB)] {...} | Finally.cs:195:10:195:12 | M10 | +| Finally.cs:208:13:210:13 | [finally: exception(Exception), finally(1): exception(Exception)] {...} | Finally.cs:195:10:195:12 | M10 | +| Finally.cs:208:13:210:13 | [finally: exception(Exception), finally(1): exception(ExceptionB)] {...} | Finally.cs:195:10:195:12 | M10 | | Finally.cs:208:13:210:13 | [finally: exception(Exception)] {...} | Finally.cs:195:10:195:12 | M10 | -| Finally.cs:208:13:210:13 | [finally: exception(ExceptionA), finally(2): exception(Exception)] {...} | Finally.cs:195:10:195:12 | M10 | -| Finally.cs:208:13:210:13 | [finally: exception(ExceptionA), finally(2): exception(ExceptionB)] {...} | Finally.cs:195:10:195:12 | M10 | +| Finally.cs:208:13:210:13 | [finally: exception(ExceptionA), finally(1): exception(Exception)] {...} | Finally.cs:195:10:195:12 | M10 | +| Finally.cs:208:13:210:13 | [finally: exception(ExceptionA), finally(1): exception(ExceptionB)] {...} | Finally.cs:195:10:195:12 | M10 | | Finally.cs:208:13:210:13 | [finally: exception(ExceptionA)] {...} | Finally.cs:195:10:195:12 | M10 | | Finally.cs:208:13:210:13 | {...} | Finally.cs:195:10:195:12 | M10 | -| Finally.cs:209:17:209:47 | [finally(2): exception(Exception)] if (...) ... | Finally.cs:195:10:195:12 | M10 | -| Finally.cs:209:17:209:47 | [finally(2): exception(ExceptionB)] if (...) ... | Finally.cs:195:10:195:12 | M10 | -| Finally.cs:209:17:209:47 | [finally: exception(Exception), finally(2): exception(Exception)] if (...) ... | Finally.cs:195:10:195:12 | M10 | -| Finally.cs:209:17:209:47 | [finally: exception(Exception), finally(2): exception(ExceptionB)] if (...) ... | Finally.cs:195:10:195:12 | M10 | +| Finally.cs:209:17:209:47 | [finally(1): exception(Exception)] if (...) ... | Finally.cs:195:10:195:12 | M10 | +| Finally.cs:209:17:209:47 | [finally(1): exception(ExceptionB)] if (...) ... | Finally.cs:195:10:195:12 | M10 | +| Finally.cs:209:17:209:47 | [finally: exception(Exception), finally(1): exception(Exception)] if (...) ... | Finally.cs:195:10:195:12 | M10 | +| Finally.cs:209:17:209:47 | [finally: exception(Exception), finally(1): exception(ExceptionB)] if (...) ... | Finally.cs:195:10:195:12 | M10 | | Finally.cs:209:17:209:47 | [finally: exception(Exception)] if (...) ... | Finally.cs:195:10:195:12 | M10 | -| Finally.cs:209:17:209:47 | [finally: exception(ExceptionA), finally(2): exception(Exception)] if (...) ... | Finally.cs:195:10:195:12 | M10 | -| Finally.cs:209:17:209:47 | [finally: exception(ExceptionA), finally(2): exception(ExceptionB)] if (...) ... | Finally.cs:195:10:195:12 | M10 | +| Finally.cs:209:17:209:47 | [finally: exception(ExceptionA), finally(1): exception(Exception)] if (...) ... | Finally.cs:195:10:195:12 | M10 | +| Finally.cs:209:17:209:47 | [finally: exception(ExceptionA), finally(1): exception(ExceptionB)] if (...) ... | Finally.cs:195:10:195:12 | M10 | | Finally.cs:209:17:209:47 | [finally: exception(ExceptionA)] if (...) ... | Finally.cs:195:10:195:12 | M10 | | Finally.cs:209:17:209:47 | if (...) ... | Finally.cs:195:10:195:12 | M10 | -| Finally.cs:209:21:209:22 | [finally(2): exception(Exception)] access to parameter b3 | Finally.cs:195:10:195:12 | M10 | -| Finally.cs:209:21:209:22 | [finally(2): exception(ExceptionB)] access to parameter b3 | Finally.cs:195:10:195:12 | M10 | -| Finally.cs:209:21:209:22 | [finally: exception(Exception), finally(2): exception(Exception)] access to parameter b3 | Finally.cs:195:10:195:12 | M10 | -| Finally.cs:209:21:209:22 | [finally: exception(Exception), finally(2): exception(ExceptionB)] access to parameter b3 | Finally.cs:195:10:195:12 | M10 | +| Finally.cs:209:21:209:22 | [finally(1): exception(Exception)] access to parameter b3 | Finally.cs:195:10:195:12 | M10 | +| Finally.cs:209:21:209:22 | [finally(1): exception(ExceptionB)] access to parameter b3 | Finally.cs:195:10:195:12 | M10 | +| Finally.cs:209:21:209:22 | [finally: exception(Exception), finally(1): exception(Exception)] access to parameter b3 | Finally.cs:195:10:195:12 | M10 | +| Finally.cs:209:21:209:22 | [finally: exception(Exception), finally(1): exception(ExceptionB)] access to parameter b3 | Finally.cs:195:10:195:12 | M10 | | Finally.cs:209:21:209:22 | [finally: exception(Exception)] access to parameter b3 | Finally.cs:195:10:195:12 | M10 | -| Finally.cs:209:21:209:22 | [finally: exception(ExceptionA), finally(2): exception(Exception)] access to parameter b3 | Finally.cs:195:10:195:12 | M10 | -| Finally.cs:209:21:209:22 | [finally: exception(ExceptionA), finally(2): exception(ExceptionB)] access to parameter b3 | Finally.cs:195:10:195:12 | M10 | +| Finally.cs:209:21:209:22 | [finally: exception(ExceptionA), finally(1): exception(Exception)] access to parameter b3 | Finally.cs:195:10:195:12 | M10 | +| Finally.cs:209:21:209:22 | [finally: exception(ExceptionA), finally(1): exception(ExceptionB)] access to parameter b3 | Finally.cs:195:10:195:12 | M10 | | Finally.cs:209:21:209:22 | [finally: exception(ExceptionA)] access to parameter b3 | Finally.cs:195:10:195:12 | M10 | | Finally.cs:209:21:209:22 | access to parameter b3 | Finally.cs:195:10:195:12 | M10 | -| Finally.cs:209:25:209:47 | [finally(2): exception(Exception)] throw ...; | Finally.cs:195:10:195:12 | M10 | -| Finally.cs:209:25:209:47 | [finally(2): exception(ExceptionB)] throw ...; | Finally.cs:195:10:195:12 | M10 | -| Finally.cs:209:25:209:47 | [finally: exception(Exception), finally(2): exception(Exception)] throw ...; | Finally.cs:195:10:195:12 | M10 | -| Finally.cs:209:25:209:47 | [finally: exception(Exception), finally(2): exception(ExceptionB)] throw ...; | Finally.cs:195:10:195:12 | M10 | +| Finally.cs:209:25:209:47 | [finally(1): exception(Exception)] throw ...; | Finally.cs:195:10:195:12 | M10 | +| Finally.cs:209:25:209:47 | [finally(1): exception(ExceptionB)] throw ...; | Finally.cs:195:10:195:12 | M10 | +| Finally.cs:209:25:209:47 | [finally: exception(Exception), finally(1): exception(Exception)] throw ...; | Finally.cs:195:10:195:12 | M10 | +| Finally.cs:209:25:209:47 | [finally: exception(Exception), finally(1): exception(ExceptionB)] throw ...; | Finally.cs:195:10:195:12 | M10 | | Finally.cs:209:25:209:47 | [finally: exception(Exception)] throw ...; | Finally.cs:195:10:195:12 | M10 | -| Finally.cs:209:25:209:47 | [finally: exception(ExceptionA), finally(2): exception(Exception)] throw ...; | Finally.cs:195:10:195:12 | M10 | -| Finally.cs:209:25:209:47 | [finally: exception(ExceptionA), finally(2): exception(ExceptionB)] throw ...; | Finally.cs:195:10:195:12 | M10 | +| Finally.cs:209:25:209:47 | [finally: exception(ExceptionA), finally(1): exception(Exception)] throw ...; | Finally.cs:195:10:195:12 | M10 | +| Finally.cs:209:25:209:47 | [finally: exception(ExceptionA), finally(1): exception(ExceptionB)] throw ...; | Finally.cs:195:10:195:12 | M10 | | Finally.cs:209:25:209:47 | [finally: exception(ExceptionA)] throw ...; | Finally.cs:195:10:195:12 | M10 | | Finally.cs:209:25:209:47 | throw ...; | Finally.cs:195:10:195:12 | M10 | -| Finally.cs:209:31:209:46 | [finally(2): exception(Exception)] object creation of type ExceptionC | Finally.cs:195:10:195:12 | M10 | -| Finally.cs:209:31:209:46 | [finally(2): exception(ExceptionB)] object creation of type ExceptionC | Finally.cs:195:10:195:12 | M10 | -| Finally.cs:209:31:209:46 | [finally: exception(Exception), finally(2): exception(Exception)] object creation of type ExceptionC | Finally.cs:195:10:195:12 | M10 | -| Finally.cs:209:31:209:46 | [finally: exception(Exception), finally(2): exception(ExceptionB)] object creation of type ExceptionC | Finally.cs:195:10:195:12 | M10 | +| Finally.cs:209:31:209:46 | [finally(1): exception(Exception)] object creation of type ExceptionC | Finally.cs:195:10:195:12 | M10 | +| Finally.cs:209:31:209:46 | [finally(1): exception(ExceptionB)] object creation of type ExceptionC | Finally.cs:195:10:195:12 | M10 | +| Finally.cs:209:31:209:46 | [finally: exception(Exception), finally(1): exception(Exception)] object creation of type ExceptionC | Finally.cs:195:10:195:12 | M10 | +| Finally.cs:209:31:209:46 | [finally: exception(Exception), finally(1): exception(ExceptionB)] object creation of type ExceptionC | Finally.cs:195:10:195:12 | M10 | | Finally.cs:209:31:209:46 | [finally: exception(Exception)] object creation of type ExceptionC | Finally.cs:195:10:195:12 | M10 | -| Finally.cs:209:31:209:46 | [finally: exception(ExceptionA), finally(2): exception(Exception)] object creation of type ExceptionC | Finally.cs:195:10:195:12 | M10 | -| Finally.cs:209:31:209:46 | [finally: exception(ExceptionA), finally(2): exception(ExceptionB)] object creation of type ExceptionC | Finally.cs:195:10:195:12 | M10 | +| Finally.cs:209:31:209:46 | [finally: exception(ExceptionA), finally(1): exception(Exception)] object creation of type ExceptionC | Finally.cs:195:10:195:12 | M10 | +| Finally.cs:209:31:209:46 | [finally: exception(ExceptionA), finally(1): exception(ExceptionB)] object creation of type ExceptionC | Finally.cs:195:10:195:12 | M10 | | Finally.cs:209:31:209:46 | [finally: exception(ExceptionA)] object creation of type ExceptionC | Finally.cs:195:10:195:12 | M10 | | Finally.cs:209:31:209:46 | object creation of type ExceptionC | Finally.cs:195:10:195:12 | M10 | | Finally.cs:211:13:211:16 | [finally: exception(Exception)] this access | Finally.cs:195:10:195:12 | M10 | @@ -2507,6 +2480,122 @@ nodeEnclosing | Finally.cs:230:9:230:33 | call to method WriteLine | Finally.cs:216:10:216:12 | M11 | | Finally.cs:230:9:230:34 | ...; | Finally.cs:216:10:216:12 | M11 | | Finally.cs:230:27:230:32 | "Done" | Finally.cs:216:10:216:12 | M11 | +| Finally.cs:233:10:233:12 | enter M12 | Finally.cs:233:10:233:12 | M12 | +| Finally.cs:233:10:233:12 | exit M12 | Finally.cs:233:10:233:12 | M12 | +| Finally.cs:233:10:233:12 | exit M12 (abnormal) | Finally.cs:233:10:233:12 | M12 | +| Finally.cs:233:10:233:12 | exit M12 (normal) | Finally.cs:233:10:233:12 | M12 | +| Finally.cs:234:5:261:5 | {...} | Finally.cs:233:10:233:12 | M12 | +| Finally.cs:235:9:259:9 | try {...} ... | Finally.cs:233:10:233:12 | M12 | +| Finally.cs:236:9:255:9 | {...} | Finally.cs:233:10:233:12 | M12 | +| Finally.cs:237:13:253:13 | try {...} ... | Finally.cs:233:10:233:12 | M12 | +| Finally.cs:238:13:241:13 | {...} | Finally.cs:233:10:233:12 | M12 | +| Finally.cs:239:17:240:43 | if (...) ... | Finally.cs:233:10:233:12 | M12 | +| Finally.cs:239:21:239:22 | access to parameter b1 | Finally.cs:233:10:233:12 | M12 | +| Finally.cs:240:21:240:43 | throw ...; | Finally.cs:233:10:233:12 | M12 | +| Finally.cs:240:27:240:42 | object creation of type ExceptionA | Finally.cs:233:10:233:12 | M12 | +| Finally.cs:243:13:253:13 | [finally: exception(Exception)] {...} | Finally.cs:233:10:233:12 | M12 | +| Finally.cs:243:13:253:13 | [finally: exception(ExceptionA)] {...} | Finally.cs:233:10:233:12 | M12 | +| Finally.cs:243:13:253:13 | {...} | Finally.cs:233:10:233:12 | M12 | +| Finally.cs:244:17:252:17 | [finally: exception(Exception)] try {...} ... | Finally.cs:233:10:233:12 | M12 | +| Finally.cs:244:17:252:17 | [finally: exception(ExceptionA)] try {...} ... | Finally.cs:233:10:233:12 | M12 | +| Finally.cs:244:17:252:17 | try {...} ... | Finally.cs:233:10:233:12 | M12 | +| Finally.cs:245:17:248:17 | [finally: exception(Exception)] {...} | Finally.cs:233:10:233:12 | M12 | +| Finally.cs:245:17:248:17 | [finally: exception(ExceptionA)] {...} | Finally.cs:233:10:233:12 | M12 | +| Finally.cs:245:17:248:17 | {...} | Finally.cs:233:10:233:12 | M12 | +| Finally.cs:246:21:247:47 | [finally: exception(Exception)] if (...) ... | Finally.cs:233:10:233:12 | M12 | +| Finally.cs:246:21:247:47 | [finally: exception(ExceptionA)] if (...) ... | Finally.cs:233:10:233:12 | M12 | +| Finally.cs:246:21:247:47 | if (...) ... | Finally.cs:233:10:233:12 | M12 | +| Finally.cs:246:25:246:26 | [finally: exception(Exception)] access to parameter b2 | Finally.cs:233:10:233:12 | M12 | +| Finally.cs:246:25:246:26 | [finally: exception(ExceptionA)] access to parameter b2 | Finally.cs:233:10:233:12 | M12 | +| Finally.cs:246:25:246:26 | access to parameter b2 | Finally.cs:233:10:233:12 | M12 | +| Finally.cs:247:25:247:47 | [finally: exception(Exception)] throw ...; | Finally.cs:233:10:233:12 | M12 | +| Finally.cs:247:25:247:47 | [finally: exception(ExceptionA)] throw ...; | Finally.cs:233:10:233:12 | M12 | +| Finally.cs:247:25:247:47 | throw ...; | Finally.cs:233:10:233:12 | M12 | +| Finally.cs:247:31:247:46 | [finally: exception(Exception)] object creation of type ExceptionA | Finally.cs:233:10:233:12 | M12 | +| Finally.cs:247:31:247:46 | [finally: exception(ExceptionA)] object creation of type ExceptionA | Finally.cs:233:10:233:12 | M12 | +| Finally.cs:247:31:247:46 | object creation of type ExceptionA | Finally.cs:233:10:233:12 | M12 | +| Finally.cs:250:17:252:17 | [finally(1): exception(Exception)] {...} | Finally.cs:233:10:233:12 | M12 | +| Finally.cs:250:17:252:17 | [finally(1): exception(ExceptionA)] {...} | Finally.cs:233:10:233:12 | M12 | +| Finally.cs:250:17:252:17 | [finally: exception(Exception), finally(1): exception(Exception)] {...} | Finally.cs:233:10:233:12 | M12 | +| Finally.cs:250:17:252:17 | [finally: exception(Exception), finally(1): exception(ExceptionA)] {...} | Finally.cs:233:10:233:12 | M12 | +| Finally.cs:250:17:252:17 | [finally: exception(Exception)] {...} | Finally.cs:233:10:233:12 | M12 | +| Finally.cs:250:17:252:17 | [finally: exception(ExceptionA), finally(1): exception(Exception)] {...} | Finally.cs:233:10:233:12 | M12 | +| Finally.cs:250:17:252:17 | [finally: exception(ExceptionA), finally(1): exception(ExceptionA)] {...} | Finally.cs:233:10:233:12 | M12 | +| Finally.cs:250:17:252:17 | [finally: exception(ExceptionA)] {...} | Finally.cs:233:10:233:12 | M12 | +| Finally.cs:250:17:252:17 | {...} | Finally.cs:233:10:233:12 | M12 | +| Finally.cs:251:21:251:54 | [finally(1): exception(Exception)] call to method WriteLine | Finally.cs:233:10:233:12 | M12 | +| Finally.cs:251:21:251:54 | [finally(1): exception(ExceptionA)] call to method WriteLine | Finally.cs:233:10:233:12 | M12 | +| Finally.cs:251:21:251:54 | [finally: exception(Exception), finally(1): exception(Exception)] call to method WriteLine | Finally.cs:233:10:233:12 | M12 | +| Finally.cs:251:21:251:54 | [finally: exception(Exception), finally(1): exception(ExceptionA)] call to method WriteLine | Finally.cs:233:10:233:12 | M12 | +| Finally.cs:251:21:251:54 | [finally: exception(Exception)] call to method WriteLine | Finally.cs:233:10:233:12 | M12 | +| Finally.cs:251:21:251:54 | [finally: exception(ExceptionA), finally(1): exception(Exception)] call to method WriteLine | Finally.cs:233:10:233:12 | M12 | +| Finally.cs:251:21:251:54 | [finally: exception(ExceptionA), finally(1): exception(ExceptionA)] call to method WriteLine | Finally.cs:233:10:233:12 | M12 | +| Finally.cs:251:21:251:54 | [finally: exception(ExceptionA)] call to method WriteLine | Finally.cs:233:10:233:12 | M12 | +| Finally.cs:251:21:251:54 | call to method WriteLine | Finally.cs:233:10:233:12 | M12 | +| Finally.cs:251:21:251:55 | ...; | Finally.cs:233:10:233:12 | M12 | +| Finally.cs:251:21:251:55 | [finally(1): exception(Exception)] ...; | Finally.cs:233:10:233:12 | M12 | +| Finally.cs:251:21:251:55 | [finally(1): exception(ExceptionA)] ...; | Finally.cs:233:10:233:12 | M12 | +| Finally.cs:251:21:251:55 | [finally: exception(Exception), finally(1): exception(Exception)] ...; | Finally.cs:233:10:233:12 | M12 | +| Finally.cs:251:21:251:55 | [finally: exception(Exception), finally(1): exception(ExceptionA)] ...; | Finally.cs:233:10:233:12 | M12 | +| Finally.cs:251:21:251:55 | [finally: exception(Exception)] ...; | Finally.cs:233:10:233:12 | M12 | +| Finally.cs:251:21:251:55 | [finally: exception(ExceptionA), finally(1): exception(Exception)] ...; | Finally.cs:233:10:233:12 | M12 | +| Finally.cs:251:21:251:55 | [finally: exception(ExceptionA), finally(1): exception(ExceptionA)] ...; | Finally.cs:233:10:233:12 | M12 | +| Finally.cs:251:21:251:55 | [finally: exception(ExceptionA)] ...; | Finally.cs:233:10:233:12 | M12 | +| Finally.cs:251:39:251:53 | "Inner finally" | Finally.cs:233:10:233:12 | M12 | +| Finally.cs:251:39:251:53 | [finally(1): exception(Exception)] "Inner finally" | Finally.cs:233:10:233:12 | M12 | +| Finally.cs:251:39:251:53 | [finally(1): exception(ExceptionA)] "Inner finally" | Finally.cs:233:10:233:12 | M12 | +| Finally.cs:251:39:251:53 | [finally: exception(Exception), finally(1): exception(Exception)] "Inner finally" | Finally.cs:233:10:233:12 | M12 | +| Finally.cs:251:39:251:53 | [finally: exception(Exception), finally(1): exception(ExceptionA)] "Inner finally" | Finally.cs:233:10:233:12 | M12 | +| Finally.cs:251:39:251:53 | [finally: exception(Exception)] "Inner finally" | Finally.cs:233:10:233:12 | M12 | +| Finally.cs:251:39:251:53 | [finally: exception(ExceptionA), finally(1): exception(Exception)] "Inner finally" | Finally.cs:233:10:233:12 | M12 | +| Finally.cs:251:39:251:53 | [finally: exception(ExceptionA), finally(1): exception(ExceptionA)] "Inner finally" | Finally.cs:233:10:233:12 | M12 | +| Finally.cs:251:39:251:53 | [finally: exception(ExceptionA)] "Inner finally" | Finally.cs:233:10:233:12 | M12 | +| Finally.cs:254:13:254:44 | call to method WriteLine | Finally.cs:233:10:233:12 | M12 | +| Finally.cs:254:13:254:45 | ...; | Finally.cs:233:10:233:12 | M12 | +| Finally.cs:254:31:254:43 | "Mid finally" | Finally.cs:233:10:233:12 | M12 | +| Finally.cs:257:9:259:9 | [finally: exception(Exception)] {...} | Finally.cs:233:10:233:12 | M12 | +| Finally.cs:257:9:259:9 | [finally: exception(ExceptionA)] {...} | Finally.cs:233:10:233:12 | M12 | +| Finally.cs:257:9:259:9 | {...} | Finally.cs:233:10:233:12 | M12 | +| Finally.cs:258:13:258:46 | [finally: exception(Exception)] call to method WriteLine | Finally.cs:233:10:233:12 | M12 | +| Finally.cs:258:13:258:46 | [finally: exception(ExceptionA)] call to method WriteLine | Finally.cs:233:10:233:12 | M12 | +| Finally.cs:258:13:258:46 | call to method WriteLine | Finally.cs:233:10:233:12 | M12 | +| Finally.cs:258:13:258:47 | ...; | Finally.cs:233:10:233:12 | M12 | +| Finally.cs:258:13:258:47 | [finally: exception(Exception)] ...; | Finally.cs:233:10:233:12 | M12 | +| Finally.cs:258:13:258:47 | [finally: exception(ExceptionA)] ...; | Finally.cs:233:10:233:12 | M12 | +| Finally.cs:258:31:258:45 | "Outer finally" | Finally.cs:233:10:233:12 | M12 | +| Finally.cs:258:31:258:45 | [finally: exception(Exception)] "Outer finally" | Finally.cs:233:10:233:12 | M12 | +| Finally.cs:258:31:258:45 | [finally: exception(ExceptionA)] "Outer finally" | Finally.cs:233:10:233:12 | M12 | +| Finally.cs:260:9:260:33 | call to method WriteLine | Finally.cs:233:10:233:12 | M12 | +| Finally.cs:260:9:260:34 | ...; | Finally.cs:233:10:233:12 | M12 | +| Finally.cs:260:27:260:32 | "Done" | Finally.cs:233:10:233:12 | M12 | +| Finally.cs:263:10:263:12 | enter M13 | Finally.cs:263:10:263:12 | M13 | +| Finally.cs:263:10:263:12 | exit M13 | Finally.cs:263:10:263:12 | M13 | +| Finally.cs:263:10:263:12 | exit M13 (abnormal) | Finally.cs:263:10:263:12 | M13 | +| Finally.cs:263:10:263:12 | exit M13 (normal) | Finally.cs:263:10:263:12 | M13 | +| Finally.cs:264:5:274:5 | {...} | Finally.cs:263:10:263:12 | M13 | +| Finally.cs:265:9:273:9 | try {...} ... | Finally.cs:263:10:263:12 | M13 | +| Finally.cs:266:9:268:9 | {...} | Finally.cs:263:10:263:12 | M13 | +| Finally.cs:267:13:267:34 | call to method WriteLine | Finally.cs:263:10:263:12 | M13 | +| Finally.cs:267:13:267:35 | ...; | Finally.cs:263:10:263:12 | M13 | +| Finally.cs:267:31:267:33 | "1" | Finally.cs:263:10:263:12 | M13 | +| Finally.cs:270:9:273:9 | [finally: exception(Exception)] {...} | Finally.cs:263:10:263:12 | M13 | +| Finally.cs:270:9:273:9 | {...} | Finally.cs:263:10:263:12 | M13 | +| Finally.cs:271:13:271:34 | [finally: exception(Exception)] call to method WriteLine | Finally.cs:263:10:263:12 | M13 | +| Finally.cs:271:13:271:34 | call to method WriteLine | Finally.cs:263:10:263:12 | M13 | +| Finally.cs:271:13:271:35 | ...; | Finally.cs:263:10:263:12 | M13 | +| Finally.cs:271:13:271:35 | [finally: exception(Exception)] ...; | Finally.cs:263:10:263:12 | M13 | +| Finally.cs:271:31:271:33 | "3" | Finally.cs:263:10:263:12 | M13 | +| Finally.cs:271:31:271:33 | [finally: exception(Exception)] "3" | Finally.cs:263:10:263:12 | M13 | +| Finally.cs:272:13:272:13 | [finally: exception(Exception)] access to parameter i | Finally.cs:263:10:263:12 | M13 | +| Finally.cs:272:13:272:13 | access to parameter i | Finally.cs:263:10:263:12 | M13 | +| Finally.cs:272:13:272:18 | ... + ... | Finally.cs:263:10:263:12 | M13 | +| Finally.cs:272:13:272:18 | ... = ... | Finally.cs:263:10:263:12 | M13 | +| Finally.cs:272:13:272:18 | [finally: exception(Exception)] ... + ... | Finally.cs:263:10:263:12 | M13 | +| Finally.cs:272:13:272:18 | [finally: exception(Exception)] ... = ... | Finally.cs:263:10:263:12 | M13 | +| Finally.cs:272:13:272:19 | ...; | Finally.cs:263:10:263:12 | M13 | +| Finally.cs:272:13:272:19 | [finally: exception(Exception)] ...; | Finally.cs:263:10:263:12 | M13 | +| Finally.cs:272:18:272:18 | 3 | Finally.cs:263:10:263:12 | M13 | +| Finally.cs:272:18:272:18 | [finally: exception(Exception)] 3 | Finally.cs:263:10:263:12 | M13 | | Foreach.cs:6:10:6:11 | enter M1 | Foreach.cs:6:10:6:11 | M1 | | Foreach.cs:6:10:6:11 | exit M1 | Foreach.cs:6:10:6:11 | M1 | | Foreach.cs:6:10:6:11 | exit M1 (normal) | Foreach.cs:6:10:6:11 | M1 | @@ -3408,80 +3497,215 @@ nodeEnclosing | NullCoalescing.cs:17:13:17:19 | (...) ... | NullCoalescing.cs:13:10:13:11 | M6 | | NullCoalescing.cs:17:13:17:24 | ... ?? ... | NullCoalescing.cs:13:10:13:11 | M6 | | NullCoalescing.cs:17:19:17:19 | access to parameter i | NullCoalescing.cs:13:10:13:11 | M6 | -| Patterns.cs:5:10:5:13 | enter Test | Patterns.cs:5:10:5:13 | Test | -| Patterns.cs:5:10:5:13 | exit Test | Patterns.cs:5:10:5:13 | Test | -| Patterns.cs:5:10:5:13 | exit Test (normal) | Patterns.cs:5:10:5:13 | Test | -| Patterns.cs:6:5:43:5 | {...} | Patterns.cs:5:10:5:13 | Test | -| Patterns.cs:7:9:7:24 | ... ...; | Patterns.cs:5:10:5:13 | Test | -| Patterns.cs:7:16:7:23 | Object o = ... | Patterns.cs:5:10:5:13 | Test | -| Patterns.cs:7:20:7:23 | null | Patterns.cs:5:10:5:13 | Test | -| Patterns.cs:8:9:18:9 | if (...) ... | Patterns.cs:5:10:5:13 | Test | -| Patterns.cs:8:13:8:13 | access to local variable o | Patterns.cs:5:10:5:13 | Test | -| Patterns.cs:8:13:8:23 | ... is ... | Patterns.cs:5:10:5:13 | Test | -| Patterns.cs:8:18:8:23 | Int32 i1 | Patterns.cs:5:10:5:13 | Test | -| Patterns.cs:9:9:11:9 | {...} | Patterns.cs:5:10:5:13 | Test | -| Patterns.cs:10:13:10:42 | call to method WriteLine | Patterns.cs:5:10:5:13 | Test | -| Patterns.cs:10:13:10:43 | ...; | Patterns.cs:5:10:5:13 | Test | -| Patterns.cs:10:31:10:41 | $"..." | Patterns.cs:5:10:5:13 | Test | -| Patterns.cs:10:33:10:36 | "int " | Patterns.cs:5:10:5:13 | Test | -| Patterns.cs:10:38:10:39 | access to local variable i1 | Patterns.cs:5:10:5:13 | Test | -| Patterns.cs:12:14:18:9 | if (...) ... | Patterns.cs:5:10:5:13 | Test | -| Patterns.cs:12:18:12:18 | access to local variable o | Patterns.cs:5:10:5:13 | Test | -| Patterns.cs:12:18:12:31 | ... is ... | Patterns.cs:5:10:5:13 | Test | -| Patterns.cs:12:23:12:31 | String s1 | Patterns.cs:5:10:5:13 | Test | -| Patterns.cs:13:9:15:9 | {...} | Patterns.cs:5:10:5:13 | Test | -| Patterns.cs:14:13:14:45 | call to method WriteLine | Patterns.cs:5:10:5:13 | Test | -| Patterns.cs:14:13:14:46 | ...; | Patterns.cs:5:10:5:13 | Test | -| Patterns.cs:14:31:14:44 | $"..." | Patterns.cs:5:10:5:13 | Test | -| Patterns.cs:14:33:14:39 | "string " | Patterns.cs:5:10:5:13 | Test | -| Patterns.cs:14:41:14:42 | access to local variable s1 | Patterns.cs:5:10:5:13 | Test | -| Patterns.cs:16:14:18:9 | if (...) ... | Patterns.cs:5:10:5:13 | Test | -| Patterns.cs:16:18:16:18 | access to local variable o | Patterns.cs:5:10:5:13 | Test | -| Patterns.cs:16:18:16:28 | ... is ... | Patterns.cs:5:10:5:13 | Test | -| Patterns.cs:16:23:16:28 | Object v1 | Patterns.cs:5:10:5:13 | Test | -| Patterns.cs:17:9:18:9 | {...} | Patterns.cs:5:10:5:13 | Test | -| Patterns.cs:20:9:38:9 | switch (...) {...} | Patterns.cs:5:10:5:13 | Test | -| Patterns.cs:20:17:20:17 | access to local variable o | Patterns.cs:5:10:5:13 | Test | -| Patterns.cs:22:13:22:23 | case ...: | Patterns.cs:5:10:5:13 | Test | -| Patterns.cs:22:18:22:22 | "xyz" | Patterns.cs:5:10:5:13 | Test | -| Patterns.cs:23:17:23:22 | break; | Patterns.cs:5:10:5:13 | Test | -| Patterns.cs:24:13:24:36 | case ...: | Patterns.cs:5:10:5:13 | Test | -| Patterns.cs:24:18:24:23 | Int32 i2 | Patterns.cs:5:10:5:13 | Test | -| Patterns.cs:24:30:24:31 | access to local variable i2 | Patterns.cs:5:10:5:13 | Test | -| Patterns.cs:24:30:24:35 | ... > ... | Patterns.cs:5:10:5:13 | Test | -| Patterns.cs:24:35:24:35 | 0 | Patterns.cs:5:10:5:13 | Test | -| Patterns.cs:25:17:25:51 | call to method WriteLine | Patterns.cs:5:10:5:13 | Test | -| Patterns.cs:25:17:25:52 | ...; | Patterns.cs:5:10:5:13 | Test | -| Patterns.cs:25:35:25:50 | $"..." | Patterns.cs:5:10:5:13 | Test | -| Patterns.cs:25:37:25:45 | "positive " | Patterns.cs:5:10:5:13 | Test | -| Patterns.cs:25:47:25:48 | access to local variable i2 | Patterns.cs:5:10:5:13 | Test | -| Patterns.cs:26:17:26:22 | break; | Patterns.cs:5:10:5:13 | Test | -| Patterns.cs:27:13:27:24 | case ...: | Patterns.cs:5:10:5:13 | Test | -| Patterns.cs:27:18:27:23 | Int32 i3 | Patterns.cs:5:10:5:13 | Test | -| Patterns.cs:28:17:28:46 | call to method WriteLine | Patterns.cs:5:10:5:13 | Test | -| Patterns.cs:28:17:28:47 | ...; | Patterns.cs:5:10:5:13 | Test | -| Patterns.cs:28:35:28:45 | $"..." | Patterns.cs:5:10:5:13 | Test | -| Patterns.cs:28:37:28:40 | "int " | Patterns.cs:5:10:5:13 | Test | -| Patterns.cs:28:42:28:43 | access to local variable i3 | Patterns.cs:5:10:5:13 | Test | -| Patterns.cs:29:17:29:22 | break; | Patterns.cs:5:10:5:13 | Test | -| Patterns.cs:30:13:30:27 | case ...: | Patterns.cs:5:10:5:13 | Test | -| Patterns.cs:30:18:30:26 | String s2 | Patterns.cs:5:10:5:13 | Test | -| Patterns.cs:31:17:31:49 | call to method WriteLine | Patterns.cs:5:10:5:13 | Test | -| Patterns.cs:31:17:31:50 | ...; | Patterns.cs:5:10:5:13 | Test | -| Patterns.cs:31:35:31:48 | $"..." | Patterns.cs:5:10:5:13 | Test | -| Patterns.cs:31:37:31:43 | "string " | Patterns.cs:5:10:5:13 | Test | -| Patterns.cs:31:45:31:46 | access to local variable s2 | Patterns.cs:5:10:5:13 | Test | -| Patterns.cs:32:17:32:22 | break; | Patterns.cs:5:10:5:13 | Test | -| Patterns.cs:33:13:33:24 | case ...: | Patterns.cs:5:10:5:13 | Test | -| Patterns.cs:33:18:33:23 | Object v2 | Patterns.cs:5:10:5:13 | Test | -| Patterns.cs:34:17:34:22 | break; | Patterns.cs:5:10:5:13 | Test | -| Patterns.cs:35:13:35:20 | default: | Patterns.cs:5:10:5:13 | Test | -| Patterns.cs:36:17:36:51 | call to method WriteLine | Patterns.cs:5:10:5:13 | Test | -| Patterns.cs:36:17:36:52 | ...; | Patterns.cs:5:10:5:13 | Test | -| Patterns.cs:36:35:36:50 | "Something else" | Patterns.cs:5:10:5:13 | Test | -| Patterns.cs:37:17:37:22 | break; | Patterns.cs:5:10:5:13 | Test | -| Patterns.cs:40:9:42:9 | switch (...) {...} | Patterns.cs:5:10:5:13 | Test | -| Patterns.cs:40:17:40:17 | access to local variable o | Patterns.cs:5:10:5:13 | Test | +| Patterns.cs:5:10:5:11 | enter M1 | Patterns.cs:5:10:5:11 | M1 | +| Patterns.cs:5:10:5:11 | exit M1 | Patterns.cs:5:10:5:11 | M1 | +| Patterns.cs:5:10:5:11 | exit M1 (normal) | Patterns.cs:5:10:5:11 | M1 | +| Patterns.cs:6:5:43:5 | {...} | Patterns.cs:5:10:5:11 | M1 | +| Patterns.cs:7:9:7:24 | ... ...; | Patterns.cs:5:10:5:11 | M1 | +| Patterns.cs:7:16:7:23 | Object o = ... | Patterns.cs:5:10:5:11 | M1 | +| Patterns.cs:7:20:7:23 | null | Patterns.cs:5:10:5:11 | M1 | +| Patterns.cs:8:9:18:9 | if (...) ... | Patterns.cs:5:10:5:11 | M1 | +| Patterns.cs:8:13:8:13 | access to local variable o | Patterns.cs:5:10:5:11 | M1 | +| Patterns.cs:8:13:8:23 | [false] ... is ... | Patterns.cs:5:10:5:11 | M1 | +| Patterns.cs:8:13:8:23 | [true] ... is ... | Patterns.cs:5:10:5:11 | M1 | +| Patterns.cs:8:18:8:23 | Int32 i1 | Patterns.cs:5:10:5:11 | M1 | +| Patterns.cs:9:9:11:9 | {...} | Patterns.cs:5:10:5:11 | M1 | +| Patterns.cs:10:13:10:42 | call to method WriteLine | Patterns.cs:5:10:5:11 | M1 | +| Patterns.cs:10:13:10:43 | ...; | Patterns.cs:5:10:5:11 | M1 | +| Patterns.cs:10:31:10:41 | $"..." | Patterns.cs:5:10:5:11 | M1 | +| Patterns.cs:10:33:10:36 | "int " | Patterns.cs:5:10:5:11 | M1 | +| Patterns.cs:10:38:10:39 | access to local variable i1 | Patterns.cs:5:10:5:11 | M1 | +| Patterns.cs:12:14:18:9 | if (...) ... | Patterns.cs:5:10:5:11 | M1 | +| Patterns.cs:12:18:12:18 | access to local variable o | Patterns.cs:5:10:5:11 | M1 | +| Patterns.cs:12:18:12:31 | [false] ... is ... | Patterns.cs:5:10:5:11 | M1 | +| Patterns.cs:12:18:12:31 | [true] ... is ... | Patterns.cs:5:10:5:11 | M1 | +| Patterns.cs:12:23:12:31 | String s1 | Patterns.cs:5:10:5:11 | M1 | +| Patterns.cs:13:9:15:9 | {...} | Patterns.cs:5:10:5:11 | M1 | +| Patterns.cs:14:13:14:45 | call to method WriteLine | Patterns.cs:5:10:5:11 | M1 | +| Patterns.cs:14:13:14:46 | ...; | Patterns.cs:5:10:5:11 | M1 | +| Patterns.cs:14:31:14:44 | $"..." | Patterns.cs:5:10:5:11 | M1 | +| Patterns.cs:14:33:14:39 | "string " | Patterns.cs:5:10:5:11 | M1 | +| Patterns.cs:14:41:14:42 | access to local variable s1 | Patterns.cs:5:10:5:11 | M1 | +| Patterns.cs:16:14:18:9 | if (...) ... | Patterns.cs:5:10:5:11 | M1 | +| Patterns.cs:16:18:16:18 | access to local variable o | Patterns.cs:5:10:5:11 | M1 | +| Patterns.cs:16:18:16:28 | [false] ... is ... | Patterns.cs:5:10:5:11 | M1 | +| Patterns.cs:16:18:16:28 | [true] ... is ... | Patterns.cs:5:10:5:11 | M1 | +| Patterns.cs:16:23:16:28 | Object v1 | Patterns.cs:5:10:5:11 | M1 | +| Patterns.cs:17:9:18:9 | {...} | Patterns.cs:5:10:5:11 | M1 | +| Patterns.cs:20:9:38:9 | switch (...) {...} | Patterns.cs:5:10:5:11 | M1 | +| Patterns.cs:20:17:20:17 | access to local variable o | Patterns.cs:5:10:5:11 | M1 | +| Patterns.cs:22:13:22:23 | case ...: | Patterns.cs:5:10:5:11 | M1 | +| Patterns.cs:22:18:22:22 | "xyz" | Patterns.cs:5:10:5:11 | M1 | +| Patterns.cs:23:17:23:22 | break; | Patterns.cs:5:10:5:11 | M1 | +| Patterns.cs:24:13:24:36 | case ...: | Patterns.cs:5:10:5:11 | M1 | +| Patterns.cs:24:18:24:23 | Int32 i2 | Patterns.cs:5:10:5:11 | M1 | +| Patterns.cs:24:30:24:31 | access to local variable i2 | Patterns.cs:5:10:5:11 | M1 | +| Patterns.cs:24:30:24:35 | ... > ... | Patterns.cs:5:10:5:11 | M1 | +| Patterns.cs:24:35:24:35 | 0 | Patterns.cs:5:10:5:11 | M1 | +| Patterns.cs:25:17:25:51 | call to method WriteLine | Patterns.cs:5:10:5:11 | M1 | +| Patterns.cs:25:17:25:52 | ...; | Patterns.cs:5:10:5:11 | M1 | +| Patterns.cs:25:35:25:50 | $"..." | Patterns.cs:5:10:5:11 | M1 | +| Patterns.cs:25:37:25:45 | "positive " | Patterns.cs:5:10:5:11 | M1 | +| Patterns.cs:25:47:25:48 | access to local variable i2 | Patterns.cs:5:10:5:11 | M1 | +| Patterns.cs:26:17:26:22 | break; | Patterns.cs:5:10:5:11 | M1 | +| Patterns.cs:27:13:27:24 | case ...: | Patterns.cs:5:10:5:11 | M1 | +| Patterns.cs:27:18:27:23 | Int32 i3 | Patterns.cs:5:10:5:11 | M1 | +| Patterns.cs:28:17:28:46 | call to method WriteLine | Patterns.cs:5:10:5:11 | M1 | +| Patterns.cs:28:17:28:47 | ...; | Patterns.cs:5:10:5:11 | M1 | +| Patterns.cs:28:35:28:45 | $"..." | Patterns.cs:5:10:5:11 | M1 | +| Patterns.cs:28:37:28:40 | "int " | Patterns.cs:5:10:5:11 | M1 | +| Patterns.cs:28:42:28:43 | access to local variable i3 | Patterns.cs:5:10:5:11 | M1 | +| Patterns.cs:29:17:29:22 | break; | Patterns.cs:5:10:5:11 | M1 | +| Patterns.cs:30:13:30:27 | case ...: | Patterns.cs:5:10:5:11 | M1 | +| Patterns.cs:30:18:30:26 | String s2 | Patterns.cs:5:10:5:11 | M1 | +| Patterns.cs:31:17:31:49 | call to method WriteLine | Patterns.cs:5:10:5:11 | M1 | +| Patterns.cs:31:17:31:50 | ...; | Patterns.cs:5:10:5:11 | M1 | +| Patterns.cs:31:35:31:48 | $"..." | Patterns.cs:5:10:5:11 | M1 | +| Patterns.cs:31:37:31:43 | "string " | Patterns.cs:5:10:5:11 | M1 | +| Patterns.cs:31:45:31:46 | access to local variable s2 | Patterns.cs:5:10:5:11 | M1 | +| Patterns.cs:32:17:32:22 | break; | Patterns.cs:5:10:5:11 | M1 | +| Patterns.cs:33:13:33:24 | case ...: | Patterns.cs:5:10:5:11 | M1 | +| Patterns.cs:33:18:33:23 | Object v2 | Patterns.cs:5:10:5:11 | M1 | +| Patterns.cs:34:17:34:22 | break; | Patterns.cs:5:10:5:11 | M1 | +| Patterns.cs:35:13:35:20 | default: | Patterns.cs:5:10:5:11 | M1 | +| Patterns.cs:36:17:36:51 | call to method WriteLine | Patterns.cs:5:10:5:11 | M1 | +| Patterns.cs:36:17:36:52 | ...; | Patterns.cs:5:10:5:11 | M1 | +| Patterns.cs:36:35:36:50 | "Something else" | Patterns.cs:5:10:5:11 | M1 | +| Patterns.cs:37:17:37:22 | break; | Patterns.cs:5:10:5:11 | M1 | +| Patterns.cs:40:9:42:9 | switch (...) {...} | Patterns.cs:5:10:5:11 | M1 | +| Patterns.cs:40:17:40:17 | access to local variable o | Patterns.cs:5:10:5:11 | M1 | +| Patterns.cs:47:24:47:25 | enter M2 | Patterns.cs:47:24:47:25 | M2 | +| Patterns.cs:47:24:47:25 | exit M2 | Patterns.cs:47:24:47:25 | M2 | +| Patterns.cs:47:24:47:25 | exit M2 (normal) | Patterns.cs:47:24:47:25 | M2 | +| Patterns.cs:48:9:48:9 | access to parameter c | Patterns.cs:47:24:47:25 | M2 | +| Patterns.cs:48:9:48:20 | ... is ... | Patterns.cs:47:24:47:25 | M2 | +| Patterns.cs:48:14:48:20 | not ... | Patterns.cs:47:24:47:25 | M2 | +| Patterns.cs:48:18:48:20 | a | Patterns.cs:47:24:47:25 | M2 | +| Patterns.cs:50:24:50:25 | enter M3 | Patterns.cs:50:24:50:25 | M3 | +| Patterns.cs:50:24:50:25 | exit M3 | Patterns.cs:50:24:50:25 | M3 | +| Patterns.cs:50:24:50:25 | exit M3 (normal) | Patterns.cs:50:24:50:25 | M3 | +| Patterns.cs:51:9:51:9 | access to parameter c | Patterns.cs:50:24:50:25 | M3 | +| Patterns.cs:51:9:51:21 | [false] ... is ... | Patterns.cs:50:24:50:25 | M3 | +| Patterns.cs:51:9:51:21 | [true] ... is ... | Patterns.cs:50:24:50:25 | M3 | +| Patterns.cs:51:9:51:39 | ... ? ... : ... | Patterns.cs:50:24:50:25 | M3 | +| Patterns.cs:51:14:51:21 | [match] not ... | Patterns.cs:50:24:50:25 | M3 | +| Patterns.cs:51:14:51:21 | [no-match] not ... | Patterns.cs:50:24:50:25 | M3 | +| Patterns.cs:51:18:51:21 | null | Patterns.cs:50:24:50:25 | M3 | +| Patterns.cs:51:25:51:25 | access to parameter c | Patterns.cs:50:24:50:25 | M3 | +| Patterns.cs:51:25:51:30 | ... is ... | Patterns.cs:50:24:50:25 | M3 | +| Patterns.cs:51:30:51:30 | 1 | Patterns.cs:50:24:50:25 | M3 | +| Patterns.cs:51:34:51:34 | access to parameter c | Patterns.cs:50:24:50:25 | M3 | +| Patterns.cs:51:34:51:39 | ... is ... | Patterns.cs:50:24:50:25 | M3 | +| Patterns.cs:51:39:51:39 | 2 | Patterns.cs:50:24:50:25 | M3 | +| Patterns.cs:53:24:53:25 | enter M4 | Patterns.cs:53:24:53:25 | M4 | +| Patterns.cs:53:24:53:25 | exit M4 | Patterns.cs:53:24:53:25 | M4 | +| Patterns.cs:53:24:53:25 | exit M4 (normal) | Patterns.cs:53:24:53:25 | M4 | +| Patterns.cs:54:9:54:9 | access to parameter c | Patterns.cs:53:24:53:25 | M4 | +| Patterns.cs:54:9:54:37 | ... is ... | Patterns.cs:53:24:53:25 | M4 | +| Patterns.cs:54:14:54:37 | not ... | Patterns.cs:53:24:53:25 | M4 | +| Patterns.cs:54:18:54:37 | Patterns u | Patterns.cs:53:24:53:25 | M4 | +| Patterns.cs:54:18:54:37 | { ... } | Patterns.cs:53:24:53:25 | M4 | +| Patterns.cs:54:27:54:35 | [match] { ... } | Patterns.cs:53:24:53:25 | M4 | +| Patterns.cs:54:27:54:35 | [no-match] { ... } | Patterns.cs:53:24:53:25 | M4 | +| Patterns.cs:54:33:54:33 | 1 | Patterns.cs:53:24:53:25 | M4 | +| Patterns.cs:56:26:56:27 | enter M5 | Patterns.cs:56:26:56:27 | M5 | +| Patterns.cs:56:26:56:27 | exit M5 | Patterns.cs:56:26:56:27 | M5 | +| Patterns.cs:56:26:56:27 | exit M5 (normal) | Patterns.cs:56:26:56:27 | M5 | +| Patterns.cs:57:5:63:5 | {...} | Patterns.cs:56:26:56:27 | M5 | +| Patterns.cs:58:9:62:10 | return ...; | Patterns.cs:56:26:56:27 | M5 | +| Patterns.cs:58:16:58:16 | access to parameter i | Patterns.cs:56:26:56:27 | M5 | +| Patterns.cs:58:16:62:9 | ... switch { ... } | Patterns.cs:56:26:56:27 | M5 | +| Patterns.cs:60:13:60:17 | [match] not ... | Patterns.cs:56:26:56:27 | M5 | +| Patterns.cs:60:13:60:17 | [no-match] not ... | Patterns.cs:56:26:56:27 | M5 | +| Patterns.cs:60:13:60:28 | ... => ... | Patterns.cs:56:26:56:27 | M5 | +| Patterns.cs:60:17:60:17 | 1 | Patterns.cs:56:26:56:27 | M5 | +| Patterns.cs:60:22:60:28 | "not 1" | Patterns.cs:56:26:56:27 | M5 | +| Patterns.cs:61:13:61:13 | _ | Patterns.cs:56:26:56:27 | M5 | +| Patterns.cs:61:13:61:24 | ... => ... | Patterns.cs:56:26:56:27 | M5 | +| Patterns.cs:61:18:61:24 | "other" | Patterns.cs:56:26:56:27 | M5 | +| Patterns.cs:65:26:65:27 | enter M6 | Patterns.cs:65:26:65:27 | M6 | +| Patterns.cs:65:26:65:27 | exit M6 | Patterns.cs:65:26:65:27 | M6 | +| Patterns.cs:65:26:65:27 | exit M6 (normal) | Patterns.cs:65:26:65:27 | M6 | +| Patterns.cs:66:5:72:5 | {...} | Patterns.cs:65:26:65:27 | M6 | +| Patterns.cs:67:9:71:10 | return ...; | Patterns.cs:65:26:65:27 | M6 | +| Patterns.cs:67:16:67:16 | 2 | Patterns.cs:65:26:65:27 | M6 | +| Patterns.cs:67:16:71:9 | ... switch { ... } | Patterns.cs:65:26:65:27 | M6 | +| Patterns.cs:69:13:69:17 | [no-match] not ... | Patterns.cs:65:26:65:27 | M6 | +| Patterns.cs:69:17:69:17 | 2 | Patterns.cs:65:26:65:27 | M6 | +| Patterns.cs:70:13:70:13 | 2 | Patterns.cs:65:26:65:27 | M6 | +| Patterns.cs:70:13:70:27 | ... => ... | Patterns.cs:65:26:65:27 | M6 | +| Patterns.cs:70:18:70:27 | "possible" | Patterns.cs:65:26:65:27 | M6 | +| Patterns.cs:74:26:74:27 | enter M7 | Patterns.cs:74:26:74:27 | M7 | +| Patterns.cs:74:26:74:27 | exit M7 | Patterns.cs:74:26:74:27 | M7 | +| Patterns.cs:74:26:74:27 | exit M7 (normal) | Patterns.cs:74:26:74:27 | M7 | +| Patterns.cs:75:5:83:5 | {...} | Patterns.cs:74:26:74:27 | M7 | +| Patterns.cs:76:9:82:10 | return ...; | Patterns.cs:74:26:74:27 | M7 | +| Patterns.cs:76:16:76:16 | access to parameter i | Patterns.cs:74:26:74:27 | M7 | +| Patterns.cs:76:16:82:9 | ... switch { ... } | Patterns.cs:74:26:74:27 | M7 | +| Patterns.cs:78:13:78:15 | > ... | Patterns.cs:74:26:74:27 | M7 | +| Patterns.cs:78:13:78:24 | ... => ... | Patterns.cs:74:26:74:27 | M7 | +| Patterns.cs:78:15:78:15 | 1 | Patterns.cs:74:26:74:27 | M7 | +| Patterns.cs:78:20:78:24 | "> 1" | Patterns.cs:74:26:74:27 | M7 | +| Patterns.cs:79:13:79:15 | < ... | Patterns.cs:74:26:74:27 | M7 | +| Patterns.cs:79:13:79:24 | ... => ... | Patterns.cs:74:26:74:27 | M7 | +| Patterns.cs:79:15:79:15 | 0 | Patterns.cs:74:26:74:27 | M7 | +| Patterns.cs:79:20:79:24 | "< 0" | Patterns.cs:74:26:74:27 | M7 | +| Patterns.cs:80:13:80:13 | 1 | Patterns.cs:74:26:74:27 | M7 | +| Patterns.cs:80:13:80:20 | ... => ... | Patterns.cs:74:26:74:27 | M7 | +| Patterns.cs:80:18:80:20 | "1" | Patterns.cs:74:26:74:27 | M7 | +| Patterns.cs:81:13:81:13 | _ | Patterns.cs:74:26:74:27 | M7 | +| Patterns.cs:81:13:81:20 | ... => ... | Patterns.cs:74:26:74:27 | M7 | +| Patterns.cs:81:18:81:20 | "0" | Patterns.cs:74:26:74:27 | M7 | +| Patterns.cs:85:26:85:27 | enter M8 | Patterns.cs:85:26:85:27 | M8 | +| Patterns.cs:85:26:85:27 | exit M8 | Patterns.cs:85:26:85:27 | M8 | +| Patterns.cs:85:26:85:27 | exit M8 (normal) | Patterns.cs:85:26:85:27 | M8 | +| Patterns.cs:85:39:85:39 | access to parameter i | Patterns.cs:85:26:85:27 | M8 | +| Patterns.cs:85:39:85:53 | [false] ... is ... | Patterns.cs:85:26:85:27 | M8 | +| Patterns.cs:85:39:85:53 | [true] ... is ... | Patterns.cs:85:26:85:27 | M8 | +| Patterns.cs:85:39:85:69 | ... ? ... : ... | Patterns.cs:85:26:85:27 | M8 | +| Patterns.cs:85:44:85:44 | 1 | Patterns.cs:85:26:85:27 | M8 | +| Patterns.cs:85:44:85:53 | [match] ... or ... | Patterns.cs:85:26:85:27 | M8 | +| Patterns.cs:85:44:85:53 | [no-match] ... or ... | Patterns.cs:85:26:85:27 | M8 | +| Patterns.cs:85:49:85:53 | [match] not ... | Patterns.cs:85:26:85:27 | M8 | +| Patterns.cs:85:49:85:53 | [no-match] not ... | Patterns.cs:85:26:85:27 | M8 | +| Patterns.cs:85:53:85:53 | 2 | Patterns.cs:85:26:85:27 | M8 | +| Patterns.cs:85:57:85:63 | "not 2" | Patterns.cs:85:26:85:27 | M8 | +| Patterns.cs:85:67:85:69 | "2" | Patterns.cs:85:26:85:27 | M8 | +| Patterns.cs:87:26:87:27 | enter M9 | Patterns.cs:87:26:87:27 | M9 | +| Patterns.cs:87:26:87:27 | exit M9 | Patterns.cs:87:26:87:27 | M9 | +| Patterns.cs:87:26:87:27 | exit M9 (normal) | Patterns.cs:87:26:87:27 | M9 | +| Patterns.cs:87:39:87:39 | access to parameter i | Patterns.cs:87:26:87:27 | M9 | +| Patterns.cs:87:39:87:54 | [false] ... is ... | Patterns.cs:87:26:87:27 | M9 | +| Patterns.cs:87:39:87:54 | [true] ... is ... | Patterns.cs:87:26:87:27 | M9 | +| Patterns.cs:87:39:87:70 | ... ? ... : ... | Patterns.cs:87:26:87:27 | M9 | +| Patterns.cs:87:44:87:44 | 1 | Patterns.cs:87:26:87:27 | M9 | +| Patterns.cs:87:44:87:54 | [match] ... and ... | Patterns.cs:87:26:87:27 | M9 | +| Patterns.cs:87:44:87:54 | [no-match] ... and ... | Patterns.cs:87:26:87:27 | M9 | +| Patterns.cs:87:50:87:54 | [match] not ... | Patterns.cs:87:26:87:27 | M9 | +| Patterns.cs:87:50:87:54 | [no-match] not ... | Patterns.cs:87:26:87:27 | M9 | +| Patterns.cs:87:54:87:54 | 2 | Patterns.cs:87:26:87:27 | M9 | +| Patterns.cs:87:58:87:60 | "1" | Patterns.cs:87:26:87:27 | M9 | +| Patterns.cs:87:64:87:70 | "not 1" | Patterns.cs:87:26:87:27 | M9 | +| Patterns.cs:93:17:93:19 | enter M10 | Patterns.cs:93:17:93:19 | M10 | +| Patterns.cs:93:17:93:19 | exit M10 | Patterns.cs:93:17:93:19 | M10 | +| Patterns.cs:93:17:93:19 | exit M10 (normal) | Patterns.cs:93:17:93:19 | M10 | +| Patterns.cs:94:5:99:5 | {...} | Patterns.cs:93:17:93:19 | M10 | +| Patterns.cs:95:9:98:9 | if (...) ... | Patterns.cs:93:17:93:19 | M10 | +| Patterns.cs:95:13:95:16 | this access | Patterns.cs:93:17:93:19 | M10 | +| Patterns.cs:95:13:95:40 | [false] ... is ... | Patterns.cs:93:17:93:19 | M10 | +| Patterns.cs:95:13:95:40 | [true] ... is ... | Patterns.cs:93:17:93:19 | M10 | +| Patterns.cs:95:21:95:40 | [match] { ... } | Patterns.cs:93:17:93:19 | M10 | +| Patterns.cs:95:21:95:40 | [match] { ... } | Patterns.cs:93:17:93:19 | M10 | +| Patterns.cs:95:21:95:40 | [no-match] { ... } | Patterns.cs:93:17:93:19 | M10 | +| Patterns.cs:95:21:95:40 | [no-match] { ... } | Patterns.cs:93:17:93:19 | M10 | +| Patterns.cs:95:29:95:31 | access to constant A | Patterns.cs:93:17:93:19 | M10 | +| Patterns.cs:95:29:95:38 | [match] ... or ... | Patterns.cs:93:17:93:19 | M10 | +| Patterns.cs:95:29:95:38 | [no-match] ... or ... | Patterns.cs:93:17:93:19 | M10 | +| Patterns.cs:95:36:95:38 | access to constant B | Patterns.cs:93:17:93:19 | M10 | +| Patterns.cs:96:9:98:9 | {...} | Patterns.cs:93:17:93:19 | M10 | +| Patterns.cs:97:13:97:38 | call to method WriteLine | Patterns.cs:93:17:93:19 | M10 | +| Patterns.cs:97:13:97:39 | ...; | Patterns.cs:93:17:93:19 | M10 | +| Patterns.cs:97:31:97:37 | "not C" | Patterns.cs:93:17:93:19 | M10 | | PostDominance.cs:5:10:5:11 | enter M1 | PostDominance.cs:5:10:5:11 | M1 | | PostDominance.cs:5:10:5:11 | exit M1 | PostDominance.cs:5:10:5:11 | M1 | | PostDominance.cs:5:10:5:11 | exit M1 (normal) | PostDominance.cs:5:10:5:11 | M1 | @@ -3495,7 +3719,8 @@ nodeEnclosing | PostDominance.cs:11:5:15:5 | {...} | PostDominance.cs:10:10:10:11 | M2 | | PostDominance.cs:12:9:13:19 | if (...) ... | PostDominance.cs:10:10:10:11 | M2 | | PostDominance.cs:12:13:12:13 | access to parameter s | PostDominance.cs:10:10:10:11 | M2 | -| PostDominance.cs:12:13:12:21 | ... is ... | PostDominance.cs:10:10:10:11 | M2 | +| PostDominance.cs:12:13:12:21 | [false] ... is ... | PostDominance.cs:10:10:10:11 | M2 | +| PostDominance.cs:12:13:12:21 | [true] ... is ... | PostDominance.cs:10:10:10:11 | M2 | | PostDominance.cs:12:18:12:21 | null | PostDominance.cs:10:10:10:11 | M2 | | PostDominance.cs:13:13:13:19 | return ...; | PostDominance.cs:10:10:10:11 | M2 | | PostDominance.cs:14:9:14:28 | call to method WriteLine | PostDominance.cs:10:10:10:11 | M2 | @@ -3508,7 +3733,8 @@ nodeEnclosing | PostDominance.cs:18:5:22:5 | {...} | PostDominance.cs:17:10:17:11 | M3 | | PostDominance.cs:19:9:20:55 | if (...) ... | PostDominance.cs:17:10:17:11 | M3 | | PostDominance.cs:19:13:19:13 | access to parameter s | PostDominance.cs:17:10:17:11 | M3 | -| PostDominance.cs:19:13:19:21 | ... is ... | PostDominance.cs:17:10:17:11 | M3 | +| PostDominance.cs:19:13:19:21 | [false] ... is ... | PostDominance.cs:17:10:17:11 | M3 | +| PostDominance.cs:19:13:19:21 | [true] ... is ... | PostDominance.cs:17:10:17:11 | M3 | | PostDominance.cs:19:18:19:21 | null | PostDominance.cs:17:10:17:11 | M3 | | PostDominance.cs:20:13:20:55 | throw ...; | PostDominance.cs:17:10:17:11 | M3 | | PostDominance.cs:20:19:20:54 | object creation of type ArgumentNullException | PostDominance.cs:17:10:17:11 | M3 | @@ -3871,7 +4097,8 @@ nodeEnclosing | TypeAccesses.cs:6:13:6:23 | ... as ... | TypeAccesses.cs:3:10:3:10 | M | | TypeAccesses.cs:7:9:7:25 | if (...) ... | TypeAccesses.cs:3:10:3:10 | M | | TypeAccesses.cs:7:13:7:13 | access to parameter o | TypeAccesses.cs:3:10:3:10 | M | -| TypeAccesses.cs:7:13:7:22 | ... is ... | TypeAccesses.cs:3:10:3:10 | M | +| TypeAccesses.cs:7:13:7:22 | [false] ... is ... | TypeAccesses.cs:3:10:3:10 | M | +| TypeAccesses.cs:7:13:7:22 | [true] ... is ... | TypeAccesses.cs:3:10:3:10 | M | | TypeAccesses.cs:7:18:7:22 | Int32 j | TypeAccesses.cs:3:10:3:10 | M | | TypeAccesses.cs:7:25:7:25 | ; | TypeAccesses.cs:3:10:3:10 | M | | TypeAccesses.cs:8:9:8:28 | ... ...; | TypeAccesses.cs:3:10:3:10 | M | @@ -4993,95 +5220,87 @@ blockEnclosing | Conditions.cs:145:27:145:29 | [b (line 143): false] "b" | Conditions.cs:143:10:143:12 | M11 | | Conditions.cs:147:13:147:49 | ...; | Conditions.cs:143:10:143:12 | M11 | | Conditions.cs:149:13:149:49 | ...; | Conditions.cs:143:10:143:12 | M11 | -| ExitMethods.cs:7:10:7:11 | enter M1 | ExitMethods.cs:7:10:7:11 | M1 | -| ExitMethods.cs:13:10:13:11 | enter M2 | ExitMethods.cs:13:10:13:11 | M2 | -| ExitMethods.cs:19:10:19:11 | enter M3 | ExitMethods.cs:19:10:19:11 | M3 | -| ExitMethods.cs:25:10:25:11 | enter M4 | ExitMethods.cs:25:10:25:11 | M4 | -| ExitMethods.cs:31:10:31:11 | enter M5 | ExitMethods.cs:31:10:31:11 | M5 | -| ExitMethods.cs:37:10:37:11 | enter M6 | ExitMethods.cs:37:10:37:11 | M6 | -| ExitMethods.cs:37:10:37:11 | exit M6 (normal) | ExitMethods.cs:37:10:37:11 | M6 | -| ExitMethods.cs:43:9:46:9 | [exception: ArgumentException] catch (...) {...} | ExitMethods.cs:37:10:37:11 | M6 | -| ExitMethods.cs:43:9:46:9 | [exception: Exception] catch (...) {...} | ExitMethods.cs:37:10:37:11 | M6 | -| ExitMethods.cs:44:9:46:9 | {...} | ExitMethods.cs:37:10:37:11 | M6 | -| ExitMethods.cs:47:9:50:9 | [exception: Exception] catch (...) {...} | ExitMethods.cs:37:10:37:11 | M6 | -| ExitMethods.cs:48:9:50:9 | {...} | ExitMethods.cs:37:10:37:11 | M6 | -| ExitMethods.cs:53:10:53:11 | enter M7 | ExitMethods.cs:53:10:53:11 | M7 | -| ExitMethods.cs:59:10:59:11 | enter M8 | ExitMethods.cs:59:10:59:11 | M8 | -| ExitMethods.cs:65:17:65:26 | enter ErrorMaybe | ExitMethods.cs:65:17:65:26 | ErrorMaybe | -| ExitMethods.cs:65:17:65:26 | exit ErrorMaybe | ExitMethods.cs:65:17:65:26 | ErrorMaybe | -| ExitMethods.cs:65:17:65:26 | exit ErrorMaybe (normal) | ExitMethods.cs:65:17:65:26 | ErrorMaybe | -| ExitMethods.cs:68:19:68:33 | object creation of type Exception | ExitMethods.cs:65:17:65:26 | ErrorMaybe | -| ExitMethods.cs:71:17:71:27 | enter ErrorAlways | ExitMethods.cs:71:17:71:27 | ErrorAlways | -| ExitMethods.cs:71:17:71:27 | exit ErrorAlways (abnormal) | ExitMethods.cs:71:17:71:27 | ErrorAlways | -| ExitMethods.cs:74:19:74:33 | object creation of type Exception | ExitMethods.cs:71:17:71:27 | ErrorAlways | -| ExitMethods.cs:76:41:76:43 | "b" | ExitMethods.cs:71:17:71:27 | ErrorAlways | -| ExitMethods.cs:79:17:79:28 | enter ErrorAlways2 | ExitMethods.cs:79:17:79:28 | ErrorAlways2 | -| ExitMethods.cs:84:17:84:28 | enter ErrorAlways3 | ExitMethods.cs:84:17:84:28 | ErrorAlways3 | -| ExitMethods.cs:86:10:86:13 | enter Exit | ExitMethods.cs:86:10:86:13 | Exit | -| ExitMethods.cs:91:10:91:18 | enter ExitInTry | ExitMethods.cs:91:10:91:18 | ExitInTry | -| ExitMethods.cs:104:10:104:24 | enter ApplicationExit | ExitMethods.cs:104:10:104:24 | ApplicationExit | -| ExitMethods.cs:109:13:109:21 | enter ThrowExpr | ExitMethods.cs:109:13:109:21 | ThrowExpr | -| ExitMethods.cs:109:13:109:21 | exit ThrowExpr | ExitMethods.cs:109:13:109:21 | ThrowExpr | -| ExitMethods.cs:111:29:111:29 | 1 | ExitMethods.cs:109:13:109:21 | ThrowExpr | -| ExitMethods.cs:111:69:111:75 | "input" | ExitMethods.cs:109:13:109:21 | ThrowExpr | -| ExitMethods.cs:114:16:114:34 | enter ExtensionMethodCall | ExitMethods.cs:114:16:114:34 | ExtensionMethodCall | -| ExitMethods.cs:116:16:116:38 | ... ? ... : ... | ExitMethods.cs:114:16:114:34 | ExtensionMethodCall | -| ExitMethods.cs:116:34:116:34 | 0 | ExitMethods.cs:114:16:114:34 | ExtensionMethodCall | -| ExitMethods.cs:116:38:116:38 | 1 | ExitMethods.cs:114:16:114:34 | ExtensionMethodCall | -| ExitMethods.cs:119:17:119:32 | enter FailingAssertion | ExitMethods.cs:119:17:119:32 | FailingAssertion | -| ExitMethods.cs:121:9:121:28 | [assertion failure] call to method IsTrue | ExitMethods.cs:119:17:119:32 | FailingAssertion | -| ExitMethods.cs:125:17:125:33 | enter FailingAssertion2 | ExitMethods.cs:125:17:125:33 | FailingAssertion2 | -| ExitMethods.cs:131:10:131:20 | enter AssertFalse | ExitMethods.cs:131:10:131:20 | AssertFalse | -| ExitMethods.cs:131:10:131:20 | exit AssertFalse | ExitMethods.cs:131:10:131:20 | AssertFalse | -| ExitMethods.cs:131:33:131:49 | [assertion failure] call to method IsFalse | ExitMethods.cs:131:10:131:20 | AssertFalse | -| ExitMethods.cs:131:33:131:49 | [assertion success] call to method IsFalse | ExitMethods.cs:131:10:131:20 | AssertFalse | -| ExitMethods.cs:133:17:133:33 | enter FailingAssertion3 | ExitMethods.cs:133:17:133:33 | FailingAssertion3 | -| ExitMethods.cs:135:9:135:25 | [assertion failure] call to method AssertFalse | ExitMethods.cs:133:17:133:33 | FailingAssertion3 | +| ExitMethods.cs:8:10:8:11 | enter M1 | ExitMethods.cs:8:10:8:11 | M1 | +| ExitMethods.cs:14:10:14:11 | enter M2 | ExitMethods.cs:14:10:14:11 | M2 | +| ExitMethods.cs:20:10:20:11 | enter M3 | ExitMethods.cs:20:10:20:11 | M3 | +| ExitMethods.cs:26:10:26:11 | enter M4 | ExitMethods.cs:26:10:26:11 | M4 | +| ExitMethods.cs:32:10:32:11 | enter M5 | ExitMethods.cs:32:10:32:11 | M5 | +| ExitMethods.cs:38:10:38:11 | enter M6 | ExitMethods.cs:38:10:38:11 | M6 | +| ExitMethods.cs:38:10:38:11 | exit M6 (normal) | ExitMethods.cs:38:10:38:11 | M6 | +| ExitMethods.cs:44:9:47:9 | [exception: ArgumentException] catch (...) {...} | ExitMethods.cs:38:10:38:11 | M6 | +| ExitMethods.cs:44:9:47:9 | [exception: Exception] catch (...) {...} | ExitMethods.cs:38:10:38:11 | M6 | +| ExitMethods.cs:45:9:47:9 | {...} | ExitMethods.cs:38:10:38:11 | M6 | +| ExitMethods.cs:48:9:51:9 | [exception: Exception] catch (...) {...} | ExitMethods.cs:38:10:38:11 | M6 | +| ExitMethods.cs:49:9:51:9 | {...} | ExitMethods.cs:38:10:38:11 | M6 | +| ExitMethods.cs:54:10:54:11 | enter M7 | ExitMethods.cs:54:10:54:11 | M7 | +| ExitMethods.cs:60:10:60:11 | enter M8 | ExitMethods.cs:60:10:60:11 | M8 | +| ExitMethods.cs:66:17:66:26 | enter ErrorMaybe | ExitMethods.cs:66:17:66:26 | ErrorMaybe | +| ExitMethods.cs:66:17:66:26 | exit ErrorMaybe | ExitMethods.cs:66:17:66:26 | ErrorMaybe | +| ExitMethods.cs:66:17:66:26 | exit ErrorMaybe (normal) | ExitMethods.cs:66:17:66:26 | ErrorMaybe | +| ExitMethods.cs:69:19:69:33 | object creation of type Exception | ExitMethods.cs:66:17:66:26 | ErrorMaybe | +| ExitMethods.cs:72:17:72:27 | enter ErrorAlways | ExitMethods.cs:72:17:72:27 | ErrorAlways | +| ExitMethods.cs:72:17:72:27 | exit ErrorAlways (abnormal) | ExitMethods.cs:72:17:72:27 | ErrorAlways | +| ExitMethods.cs:75:19:75:33 | object creation of type Exception | ExitMethods.cs:72:17:72:27 | ErrorAlways | +| ExitMethods.cs:77:41:77:43 | "b" | ExitMethods.cs:72:17:72:27 | ErrorAlways | +| ExitMethods.cs:80:17:80:28 | enter ErrorAlways2 | ExitMethods.cs:80:17:80:28 | ErrorAlways2 | +| ExitMethods.cs:85:17:85:28 | enter ErrorAlways3 | ExitMethods.cs:85:17:85:28 | ErrorAlways3 | +| ExitMethods.cs:87:10:87:13 | enter Exit | ExitMethods.cs:87:10:87:13 | Exit | +| ExitMethods.cs:92:10:92:18 | enter ExitInTry | ExitMethods.cs:92:10:92:18 | ExitInTry | +| ExitMethods.cs:105:10:105:24 | enter ApplicationExit | ExitMethods.cs:105:10:105:24 | ApplicationExit | +| ExitMethods.cs:110:13:110:21 | enter ThrowExpr | ExitMethods.cs:110:13:110:21 | ThrowExpr | +| ExitMethods.cs:110:13:110:21 | exit ThrowExpr | ExitMethods.cs:110:13:110:21 | ThrowExpr | +| ExitMethods.cs:112:29:112:29 | 1 | ExitMethods.cs:110:13:110:21 | ThrowExpr | +| ExitMethods.cs:112:69:112:75 | "input" | ExitMethods.cs:110:13:110:21 | ThrowExpr | +| ExitMethods.cs:115:16:115:34 | enter ExtensionMethodCall | ExitMethods.cs:115:16:115:34 | ExtensionMethodCall | +| ExitMethods.cs:117:16:117:38 | ... ? ... : ... | ExitMethods.cs:115:16:115:34 | ExtensionMethodCall | +| ExitMethods.cs:117:34:117:34 | 0 | ExitMethods.cs:115:16:115:34 | ExtensionMethodCall | +| ExitMethods.cs:117:38:117:38 | 1 | ExitMethods.cs:115:16:115:34 | ExtensionMethodCall | +| ExitMethods.cs:120:17:120:32 | enter FailingAssertion | ExitMethods.cs:120:17:120:32 | FailingAssertion | +| ExitMethods.cs:122:9:122:28 | [assertion failure] call to method IsTrue | ExitMethods.cs:120:17:120:32 | FailingAssertion | +| ExitMethods.cs:126:17:126:33 | enter FailingAssertion2 | ExitMethods.cs:126:17:126:33 | FailingAssertion2 | +| ExitMethods.cs:132:10:132:20 | enter AssertFalse | ExitMethods.cs:132:10:132:20 | AssertFalse | +| ExitMethods.cs:132:10:132:20 | exit AssertFalse | ExitMethods.cs:132:10:132:20 | AssertFalse | +| ExitMethods.cs:132:33:132:49 | [assertion failure] call to method IsFalse | ExitMethods.cs:132:10:132:20 | AssertFalse | +| ExitMethods.cs:132:33:132:49 | [assertion success] call to method IsFalse | ExitMethods.cs:132:10:132:20 | AssertFalse | +| ExitMethods.cs:134:17:134:33 | enter FailingAssertion3 | ExitMethods.cs:134:17:134:33 | FailingAssertion3 | +| ExitMethods.cs:136:9:136:25 | [assertion failure] call to method AssertFalse | ExitMethods.cs:134:17:134:33 | FailingAssertion3 | +| ExitMethods.cs:140:17:140:42 | enter ExceptionDispatchInfoThrow | ExitMethods.cs:140:17:140:42 | ExceptionDispatchInfoThrow | +| ExitMethods.cs:140:17:140:42 | exit ExceptionDispatchInfoThrow (abnormal) | ExitMethods.cs:140:17:140:42 | ExceptionDispatchInfoThrow | +| ExitMethods.cs:143:13:143:43 | ...; | ExitMethods.cs:140:17:140:42 | ExceptionDispatchInfoThrow | +| ExitMethods.cs:145:13:145:53 | ...; | ExitMethods.cs:140:17:140:42 | ExceptionDispatchInfoThrow | | Extensions.cs:5:23:5:29 | enter ToInt32 | Extensions.cs:5:23:5:29 | ToInt32 | | Extensions.cs:10:24:10:29 | enter ToBool | Extensions.cs:10:24:10:29 | ToBool | | Extensions.cs:15:23:15:33 | enter CallToInt32 | Extensions.cs:15:23:15:33 | CallToInt32 | | Extensions.cs:20:17:20:20 | enter Main | Extensions.cs:20:17:20:20 | Main | | Finally.cs:7:10:7:11 | enter M1 | Finally.cs:7:10:7:11 | M1 | | Finally.cs:7:10:7:11 | exit M1 | Finally.cs:7:10:7:11 | M1 | -| Finally.cs:7:10:7:11 | exit M1 (abnormal) | Finally.cs:7:10:7:11 | M1 | -| Finally.cs:11:13:11:37 | call to method WriteLine | Finally.cs:7:10:7:11 | M1 | | Finally.cs:14:9:16:9 | [finally: exception(Exception)] {...} | Finally.cs:7:10:7:11 | M1 | -| Finally.cs:14:9:16:9 | [finally: exception(OutOfMemoryException)] {...} | Finally.cs:7:10:7:11 | M1 | | Finally.cs:14:9:16:9 | {...} | Finally.cs:7:10:7:11 | M1 | | Finally.cs:19:10:19:11 | enter M2 | Finally.cs:19:10:19:11 | M2 | | Finally.cs:19:10:19:11 | exit M2 | Finally.cs:19:10:19:11 | M2 | | Finally.cs:19:10:19:11 | exit M2 (abnormal) | Finally.cs:19:10:19:11 | M2 | | Finally.cs:19:10:19:11 | exit M2 (normal) | Finally.cs:19:10:19:11 | M2 | -| Finally.cs:23:13:23:37 | call to method WriteLine | Finally.cs:19:10:19:11 | M2 | | Finally.cs:24:13:24:19 | return ...; | Finally.cs:19:10:19:11 | M2 | | Finally.cs:26:9:29:9 | [exception: Exception] catch (...) {...} | Finally.cs:19:10:19:11 | M2 | -| Finally.cs:26:9:29:9 | [exception: OutOfMemoryException] catch (...) {...} | Finally.cs:19:10:19:11 | M2 | | Finally.cs:26:38:26:39 | [exception: Exception] IOException ex | Finally.cs:19:10:19:11 | M2 | | Finally.cs:27:9:29:9 | {...} | Finally.cs:19:10:19:11 | M2 | | Finally.cs:30:9:40:9 | [exception: Exception] catch (...) {...} | Finally.cs:19:10:19:11 | M2 | -| Finally.cs:30:9:40:9 | [exception: OutOfMemoryException] catch (...) {...} | Finally.cs:19:10:19:11 | M2 | | Finally.cs:30:41:30:42 | [exception: Exception] ArgumentException ex | Finally.cs:19:10:19:11 | M2 | | Finally.cs:34:27:34:32 | throw ...; | Finally.cs:19:10:19:11 | M2 | | Finally.cs:41:9:43:9 | [exception: Exception] catch (...) {...} | Finally.cs:19:10:19:11 | M2 | -| Finally.cs:41:9:43:9 | [exception: OutOfMemoryException] catch (...) {...} | Finally.cs:19:10:19:11 | M2 | | Finally.cs:42:9:43:9 | {...} | Finally.cs:19:10:19:11 | M2 | | Finally.cs:54:10:54:11 | enter M3 | Finally.cs:54:10:54:11 | M3 | | Finally.cs:54:10:54:11 | exit M3 | Finally.cs:54:10:54:11 | M3 | | Finally.cs:54:10:54:11 | exit M3 (abnormal) | Finally.cs:54:10:54:11 | M3 | | Finally.cs:54:10:54:11 | exit M3 (normal) | Finally.cs:54:10:54:11 | M3 | -| Finally.cs:58:13:58:37 | call to method WriteLine | Finally.cs:54:10:54:11 | M3 | | Finally.cs:59:13:59:19 | return ...; | Finally.cs:54:10:54:11 | M3 | | Finally.cs:61:9:64:9 | [exception: Exception] catch (...) {...} | Finally.cs:54:10:54:11 | M3 | -| Finally.cs:61:9:64:9 | [exception: OutOfMemoryException] catch (...) {...} | Finally.cs:54:10:54:11 | M3 | | Finally.cs:61:38:61:39 | [exception: Exception] IOException ex | Finally.cs:54:10:54:11 | M3 | | Finally.cs:62:9:64:9 | {...} | Finally.cs:54:10:54:11 | M3 | | Finally.cs:65:9:67:9 | [exception: Exception] catch (...) {...} | Finally.cs:54:10:54:11 | M3 | -| Finally.cs:65:9:67:9 | [exception: OutOfMemoryException] catch (...) {...} | Finally.cs:54:10:54:11 | M3 | | Finally.cs:65:26:65:26 | [exception: Exception] Exception e | Finally.cs:54:10:54:11 | M3 | -| Finally.cs:65:26:65:26 | [exception: OutOfMemoryException] Exception e | Finally.cs:54:10:54:11 | M3 | | Finally.cs:66:9:67:9 | {...} | Finally.cs:54:10:54:11 | M3 | | Finally.cs:69:9:71:9 | [finally: exception(Exception)] {...} | Finally.cs:54:10:54:11 | M3 | -| Finally.cs:69:9:71:9 | [finally: exception(OutOfMemoryException)] {...} | Finally.cs:54:10:54:11 | M3 | | Finally.cs:74:10:74:11 | enter M4 | Finally.cs:74:10:74:11 | M4 | | Finally.cs:74:10:74:11 | exit M4 | Finally.cs:74:10:74:11 | M4 | | Finally.cs:74:10:74:11 | exit M4 (abnormal) | Finally.cs:74:10:74:11 | M4 | @@ -5102,12 +5321,12 @@ blockEnclosing | Finally.cs:93:31:93:45 | [finally: continue] object creation of type Exception | Finally.cs:74:10:74:11 | M4 | | Finally.cs:93:31:93:45 | [finally: return] object creation of type Exception | Finally.cs:74:10:74:11 | M4 | | Finally.cs:93:31:93:45 | object creation of type Exception | Finally.cs:74:10:74:11 | M4 | -| Finally.cs:96:17:98:17 | [finally(2): exception(Exception)] {...} | Finally.cs:74:10:74:11 | M4 | -| Finally.cs:96:17:98:17 | [finally: break, finally(2): exception(Exception)] {...} | Finally.cs:74:10:74:11 | M4 | +| Finally.cs:96:17:98:17 | [finally(1): exception(Exception)] {...} | Finally.cs:74:10:74:11 | M4 | +| Finally.cs:96:17:98:17 | [finally: break, finally(1): exception(Exception)] {...} | Finally.cs:74:10:74:11 | M4 | | Finally.cs:96:17:98:17 | [finally: break] {...} | Finally.cs:74:10:74:11 | M4 | -| Finally.cs:96:17:98:17 | [finally: continue, finally(2): exception(Exception)] {...} | Finally.cs:74:10:74:11 | M4 | +| Finally.cs:96:17:98:17 | [finally: continue, finally(1): exception(Exception)] {...} | Finally.cs:74:10:74:11 | M4 | | Finally.cs:96:17:98:17 | [finally: continue] {...} | Finally.cs:74:10:74:11 | M4 | -| Finally.cs:96:17:98:17 | [finally: return, finally(2): exception(Exception)] {...} | Finally.cs:74:10:74:11 | M4 | +| Finally.cs:96:17:98:17 | [finally: return, finally(1): exception(Exception)] {...} | Finally.cs:74:10:74:11 | M4 | | Finally.cs:96:17:98:17 | [finally: return] {...} | Finally.cs:74:10:74:11 | M4 | | Finally.cs:96:17:98:17 | {...} | Finally.cs:74:10:74:11 | M4 | | Finally.cs:103:10:103:11 | enter M5 | Finally.cs:103:10:103:11 | M5 | @@ -5153,9 +5372,7 @@ blockEnclosing | Finally.cs:121:10:121:11 | enter M6 | Finally.cs:121:10:121:11 | M6 | | Finally.cs:133:10:133:11 | enter M7 | Finally.cs:133:10:133:11 | M7 | | Finally.cs:133:10:133:11 | exit M7 (abnormal) | Finally.cs:133:10:133:11 | M7 | -| Finally.cs:137:13:137:36 | call to method WriteLine | Finally.cs:133:10:133:11 | M7 | | Finally.cs:140:9:143:9 | [finally: exception(Exception)] {...} | Finally.cs:133:10:133:11 | M7 | -| Finally.cs:140:9:143:9 | [finally: exception(OutOfMemoryException)] {...} | Finally.cs:133:10:133:11 | M7 | | Finally.cs:140:9:143:9 | {...} | Finally.cs:133:10:133:11 | M7 | | Finally.cs:147:10:147:11 | enter M8 | Finally.cs:147:10:147:11 | M8 | | Finally.cs:147:10:147:11 | exit M8 | Finally.cs:147:10:147:11 | M8 | @@ -5171,30 +5388,21 @@ blockEnclosing | Finally.cs:159:21:159:45 | [finally: exception(ArgumentNullException)] throw ...; | Finally.cs:147:10:147:11 | M8 | | Finally.cs:159:21:159:45 | [finally: exception(Exception)] throw ...; | Finally.cs:147:10:147:11 | M8 | | Finally.cs:159:21:159:45 | throw ...; | Finally.cs:147:10:147:11 | M8 | -| Finally.cs:159:27:159:44 | [finally: exception(ArgumentNullException)] object creation of type Exception | Finally.cs:147:10:147:11 | M8 | -| Finally.cs:159:27:159:44 | [finally: exception(Exception)] object creation of type Exception | Finally.cs:147:10:147:11 | M8 | -| Finally.cs:159:27:159:44 | object creation of type Exception | Finally.cs:147:10:147:11 | M8 | | Finally.cs:159:41:159:43 | "1" | Finally.cs:147:10:147:11 | M8 | | Finally.cs:159:41:159:43 | [finally: exception(ArgumentNullException)] "1" | Finally.cs:147:10:147:11 | M8 | | Finally.cs:159:41:159:43 | [finally: exception(Exception)] "1" | Finally.cs:147:10:147:11 | M8 | | Finally.cs:161:13:164:13 | [exception: Exception] catch (...) {...} | Finally.cs:147:10:147:11 | M8 | | Finally.cs:161:13:164:13 | [exception: NullReferenceException] catch (...) {...} | Finally.cs:147:10:147:11 | M8 | -| Finally.cs:161:13:164:13 | [exception: OutOfMemoryException] catch (...) {...} | Finally.cs:147:10:147:11 | M8 | | Finally.cs:161:13:164:13 | [finally: exception(ArgumentNullException), exception: Exception] catch (...) {...} | Finally.cs:147:10:147:11 | M8 | | Finally.cs:161:13:164:13 | [finally: exception(ArgumentNullException), exception: NullReferenceException] catch (...) {...} | Finally.cs:147:10:147:11 | M8 | -| Finally.cs:161:13:164:13 | [finally: exception(ArgumentNullException), exception: OutOfMemoryException] catch (...) {...} | Finally.cs:147:10:147:11 | M8 | | Finally.cs:161:13:164:13 | [finally: exception(Exception), exception: Exception] catch (...) {...} | Finally.cs:147:10:147:11 | M8 | | Finally.cs:161:13:164:13 | [finally: exception(Exception), exception: NullReferenceException] catch (...) {...} | Finally.cs:147:10:147:11 | M8 | -| Finally.cs:161:13:164:13 | [finally: exception(Exception), exception: OutOfMemoryException] catch (...) {...} | Finally.cs:147:10:147:11 | M8 | | Finally.cs:161:30:161:30 | [exception: Exception] Exception e | Finally.cs:147:10:147:11 | M8 | | Finally.cs:161:30:161:30 | [exception: NullReferenceException] Exception e | Finally.cs:147:10:147:11 | M8 | -| Finally.cs:161:30:161:30 | [exception: OutOfMemoryException] Exception e | Finally.cs:147:10:147:11 | M8 | | Finally.cs:161:30:161:30 | [finally: exception(ArgumentNullException), exception: Exception] Exception e | Finally.cs:147:10:147:11 | M8 | | Finally.cs:161:30:161:30 | [finally: exception(ArgumentNullException), exception: NullReferenceException] Exception e | Finally.cs:147:10:147:11 | M8 | -| Finally.cs:161:30:161:30 | [finally: exception(ArgumentNullException), exception: OutOfMemoryException] Exception e | Finally.cs:147:10:147:11 | M8 | | Finally.cs:161:30:161:30 | [finally: exception(Exception), exception: Exception] Exception e | Finally.cs:147:10:147:11 | M8 | | Finally.cs:161:30:161:30 | [finally: exception(Exception), exception: NullReferenceException] Exception e | Finally.cs:147:10:147:11 | M8 | -| Finally.cs:161:30:161:30 | [finally: exception(Exception), exception: OutOfMemoryException] Exception e | Finally.cs:147:10:147:11 | M8 | | Finally.cs:162:13:164:13 | [finally: exception(ArgumentNullException)] {...} | Finally.cs:147:10:147:11 | M8 | | Finally.cs:162:13:164:13 | [finally: exception(Exception)] {...} | Finally.cs:147:10:147:11 | M8 | | Finally.cs:162:13:164:13 | {...} | Finally.cs:147:10:147:11 | M8 | @@ -5242,28 +5450,53 @@ blockEnclosing | Finally.cs:205:31:205:46 | [finally: exception(Exception)] object creation of type ExceptionB | Finally.cs:195:10:195:12 | M10 | | Finally.cs:205:31:205:46 | [finally: exception(ExceptionA)] object creation of type ExceptionB | Finally.cs:195:10:195:12 | M10 | | Finally.cs:205:31:205:46 | object creation of type ExceptionB | Finally.cs:195:10:195:12 | M10 | -| Finally.cs:208:13:210:13 | [finally(2): exception(Exception)] {...} | Finally.cs:195:10:195:12 | M10 | -| Finally.cs:208:13:210:13 | [finally: exception(Exception), finally(2): exception(Exception)] {...} | Finally.cs:195:10:195:12 | M10 | +| Finally.cs:208:13:210:13 | [finally(1): exception(Exception)] {...} | Finally.cs:195:10:195:12 | M10 | +| Finally.cs:208:13:210:13 | [finally: exception(Exception), finally(1): exception(Exception)] {...} | Finally.cs:195:10:195:12 | M10 | | Finally.cs:208:13:210:13 | [finally: exception(Exception)] {...} | Finally.cs:195:10:195:12 | M10 | -| Finally.cs:208:13:210:13 | [finally: exception(ExceptionA), finally(2): exception(Exception)] {...} | Finally.cs:195:10:195:12 | M10 | +| Finally.cs:208:13:210:13 | [finally: exception(ExceptionA), finally(1): exception(Exception)] {...} | Finally.cs:195:10:195:12 | M10 | | Finally.cs:208:13:210:13 | [finally: exception(ExceptionA)] {...} | Finally.cs:195:10:195:12 | M10 | | Finally.cs:208:13:210:13 | {...} | Finally.cs:195:10:195:12 | M10 | -| Finally.cs:209:31:209:46 | [finally(2): exception(Exception)] object creation of type ExceptionC | Finally.cs:195:10:195:12 | M10 | -| Finally.cs:209:31:209:46 | [finally(2): exception(ExceptionB)] object creation of type ExceptionC | Finally.cs:195:10:195:12 | M10 | -| Finally.cs:209:31:209:46 | [finally: exception(Exception), finally(2): exception(Exception)] object creation of type ExceptionC | Finally.cs:195:10:195:12 | M10 | -| Finally.cs:209:31:209:46 | [finally: exception(Exception), finally(2): exception(ExceptionB)] object creation of type ExceptionC | Finally.cs:195:10:195:12 | M10 | +| Finally.cs:209:31:209:46 | [finally(1): exception(Exception)] object creation of type ExceptionC | Finally.cs:195:10:195:12 | M10 | +| Finally.cs:209:31:209:46 | [finally(1): exception(ExceptionB)] object creation of type ExceptionC | Finally.cs:195:10:195:12 | M10 | +| Finally.cs:209:31:209:46 | [finally: exception(Exception), finally(1): exception(Exception)] object creation of type ExceptionC | Finally.cs:195:10:195:12 | M10 | +| Finally.cs:209:31:209:46 | [finally: exception(Exception), finally(1): exception(ExceptionB)] object creation of type ExceptionC | Finally.cs:195:10:195:12 | M10 | | Finally.cs:209:31:209:46 | [finally: exception(Exception)] object creation of type ExceptionC | Finally.cs:195:10:195:12 | M10 | -| Finally.cs:209:31:209:46 | [finally: exception(ExceptionA), finally(2): exception(Exception)] object creation of type ExceptionC | Finally.cs:195:10:195:12 | M10 | -| Finally.cs:209:31:209:46 | [finally: exception(ExceptionA), finally(2): exception(ExceptionB)] object creation of type ExceptionC | Finally.cs:195:10:195:12 | M10 | +| Finally.cs:209:31:209:46 | [finally: exception(ExceptionA), finally(1): exception(Exception)] object creation of type ExceptionC | Finally.cs:195:10:195:12 | M10 | +| Finally.cs:209:31:209:46 | [finally: exception(ExceptionA), finally(1): exception(ExceptionB)] object creation of type ExceptionC | Finally.cs:195:10:195:12 | M10 | | Finally.cs:209:31:209:46 | [finally: exception(ExceptionA)] object creation of type ExceptionC | Finally.cs:195:10:195:12 | M10 | | Finally.cs:209:31:209:46 | object creation of type ExceptionC | Finally.cs:195:10:195:12 | M10 | | Finally.cs:211:13:211:29 | ...; | Finally.cs:195:10:195:12 | M10 | | Finally.cs:211:13:211:29 | [finally: exception(Exception)] ...; | Finally.cs:195:10:195:12 | M10 | | Finally.cs:211:13:211:29 | [finally: exception(ExceptionA)] ...; | Finally.cs:195:10:195:12 | M10 | | Finally.cs:216:10:216:12 | enter M11 | Finally.cs:216:10:216:12 | M11 | -| Finally.cs:220:13:220:36 | call to method WriteLine | Finally.cs:216:10:216:12 | M11 | | Finally.cs:222:9:225:9 | catch {...} | Finally.cs:216:10:216:12 | M11 | | Finally.cs:227:9:229:9 | {...} | Finally.cs:216:10:216:12 | M11 | +| Finally.cs:233:10:233:12 | enter M12 | Finally.cs:233:10:233:12 | M12 | +| Finally.cs:233:10:233:12 | exit M12 | Finally.cs:233:10:233:12 | M12 | +| Finally.cs:233:10:233:12 | exit M12 (abnormal) | Finally.cs:233:10:233:12 | M12 | +| Finally.cs:240:21:240:43 | throw ...; | Finally.cs:233:10:233:12 | M12 | +| Finally.cs:240:27:240:42 | object creation of type ExceptionA | Finally.cs:233:10:233:12 | M12 | +| Finally.cs:243:13:253:13 | [finally: exception(Exception)] {...} | Finally.cs:233:10:233:12 | M12 | +| Finally.cs:243:13:253:13 | {...} | Finally.cs:233:10:233:12 | M12 | +| Finally.cs:247:25:247:47 | [finally: exception(Exception)] throw ...; | Finally.cs:233:10:233:12 | M12 | +| Finally.cs:247:25:247:47 | [finally: exception(ExceptionA)] throw ...; | Finally.cs:233:10:233:12 | M12 | +| Finally.cs:247:25:247:47 | throw ...; | Finally.cs:233:10:233:12 | M12 | +| Finally.cs:247:31:247:46 | [finally: exception(Exception)] object creation of type ExceptionA | Finally.cs:233:10:233:12 | M12 | +| Finally.cs:247:31:247:46 | [finally: exception(ExceptionA)] object creation of type ExceptionA | Finally.cs:233:10:233:12 | M12 | +| Finally.cs:247:31:247:46 | object creation of type ExceptionA | Finally.cs:233:10:233:12 | M12 | +| Finally.cs:250:17:252:17 | [finally(1): exception(Exception)] {...} | Finally.cs:233:10:233:12 | M12 | +| Finally.cs:250:17:252:17 | [finally: exception(Exception), finally(1): exception(Exception)] {...} | Finally.cs:233:10:233:12 | M12 | +| Finally.cs:250:17:252:17 | [finally: exception(Exception)] {...} | Finally.cs:233:10:233:12 | M12 | +| Finally.cs:250:17:252:17 | [finally: exception(ExceptionA), finally(1): exception(Exception)] {...} | Finally.cs:233:10:233:12 | M12 | +| Finally.cs:250:17:252:17 | [finally: exception(ExceptionA)] {...} | Finally.cs:233:10:233:12 | M12 | +| Finally.cs:250:17:252:17 | {...} | Finally.cs:233:10:233:12 | M12 | +| Finally.cs:257:9:259:9 | [finally: exception(Exception)] {...} | Finally.cs:233:10:233:12 | M12 | +| Finally.cs:257:9:259:9 | [finally: exception(ExceptionA)] {...} | Finally.cs:233:10:233:12 | M12 | +| Finally.cs:257:9:259:9 | {...} | Finally.cs:233:10:233:12 | M12 | +| Finally.cs:263:10:263:12 | enter M13 | Finally.cs:263:10:263:12 | M13 | +| Finally.cs:263:10:263:12 | exit M13 | Finally.cs:263:10:263:12 | M13 | +| Finally.cs:270:9:273:9 | [finally: exception(Exception)] {...} | Finally.cs:263:10:263:12 | M13 | +| Finally.cs:270:9:273:9 | {...} | Finally.cs:263:10:263:12 | M13 | | Foreach.cs:6:10:6:11 | enter M1 | Foreach.cs:6:10:6:11 | M1 | | Foreach.cs:6:10:6:11 | exit M1 (normal) | Foreach.cs:6:10:6:11 | M1 | | Foreach.cs:8:9:9:13 | foreach (... ... in ...) ... | Foreach.cs:6:10:6:11 | M1 | @@ -5556,32 +5789,110 @@ blockEnclosing | NullCoalescing.cs:15:31:15:31 | 0 | NullCoalescing.cs:13:10:13:11 | M6 | | NullCoalescing.cs:16:17:16:25 | ... ?? ... | NullCoalescing.cs:13:10:13:11 | M6 | | NullCoalescing.cs:17:13:17:24 | ... ?? ... | NullCoalescing.cs:13:10:13:11 | M6 | -| Patterns.cs:5:10:5:13 | enter Test | Patterns.cs:5:10:5:13 | Test | -| Patterns.cs:9:9:11:9 | {...} | Patterns.cs:5:10:5:13 | Test | -| Patterns.cs:12:14:18:9 | if (...) ... | Patterns.cs:5:10:5:13 | Test | -| Patterns.cs:13:9:15:9 | {...} | Patterns.cs:5:10:5:13 | Test | -| Patterns.cs:16:14:18:9 | if (...) ... | Patterns.cs:5:10:5:13 | Test | -| Patterns.cs:17:9:18:9 | {...} | Patterns.cs:5:10:5:13 | Test | -| Patterns.cs:20:9:38:9 | switch (...) {...} | Patterns.cs:5:10:5:13 | Test | -| Patterns.cs:23:17:23:22 | break; | Patterns.cs:5:10:5:13 | Test | -| Patterns.cs:24:13:24:36 | case ...: | Patterns.cs:5:10:5:13 | Test | -| Patterns.cs:24:30:24:31 | access to local variable i2 | Patterns.cs:5:10:5:13 | Test | -| Patterns.cs:25:17:25:52 | ...; | Patterns.cs:5:10:5:13 | Test | -| Patterns.cs:27:13:27:24 | case ...: | Patterns.cs:5:10:5:13 | Test | -| Patterns.cs:28:17:28:47 | ...; | Patterns.cs:5:10:5:13 | Test | -| Patterns.cs:30:13:30:27 | case ...: | Patterns.cs:5:10:5:13 | Test | -| Patterns.cs:31:17:31:50 | ...; | Patterns.cs:5:10:5:13 | Test | -| Patterns.cs:33:13:33:24 | case ...: | Patterns.cs:5:10:5:13 | Test | -| Patterns.cs:34:17:34:22 | break; | Patterns.cs:5:10:5:13 | Test | -| Patterns.cs:35:13:35:20 | default: | Patterns.cs:5:10:5:13 | Test | -| Patterns.cs:40:9:42:9 | switch (...) {...} | Patterns.cs:5:10:5:13 | Test | +| Patterns.cs:5:10:5:11 | enter M1 | Patterns.cs:5:10:5:11 | M1 | +| Patterns.cs:8:13:8:23 | [false] ... is ... | Patterns.cs:5:10:5:11 | M1 | +| Patterns.cs:8:13:8:23 | [true] ... is ... | Patterns.cs:5:10:5:11 | M1 | +| Patterns.cs:9:9:11:9 | {...} | Patterns.cs:5:10:5:11 | M1 | +| Patterns.cs:12:14:18:9 | if (...) ... | Patterns.cs:5:10:5:11 | M1 | +| Patterns.cs:12:18:12:31 | [false] ... is ... | Patterns.cs:5:10:5:11 | M1 | +| Patterns.cs:12:18:12:31 | [true] ... is ... | Patterns.cs:5:10:5:11 | M1 | +| Patterns.cs:13:9:15:9 | {...} | Patterns.cs:5:10:5:11 | M1 | +| Patterns.cs:16:14:18:9 | if (...) ... | Patterns.cs:5:10:5:11 | M1 | +| Patterns.cs:16:18:16:28 | [false] ... is ... | Patterns.cs:5:10:5:11 | M1 | +| Patterns.cs:16:18:16:28 | [true] ... is ... | Patterns.cs:5:10:5:11 | M1 | +| Patterns.cs:17:9:18:9 | {...} | Patterns.cs:5:10:5:11 | M1 | +| Patterns.cs:20:9:38:9 | switch (...) {...} | Patterns.cs:5:10:5:11 | M1 | +| Patterns.cs:23:17:23:22 | break; | Patterns.cs:5:10:5:11 | M1 | +| Patterns.cs:24:13:24:36 | case ...: | Patterns.cs:5:10:5:11 | M1 | +| Patterns.cs:24:30:24:31 | access to local variable i2 | Patterns.cs:5:10:5:11 | M1 | +| Patterns.cs:25:17:25:52 | ...; | Patterns.cs:5:10:5:11 | M1 | +| Patterns.cs:27:13:27:24 | case ...: | Patterns.cs:5:10:5:11 | M1 | +| Patterns.cs:28:17:28:47 | ...; | Patterns.cs:5:10:5:11 | M1 | +| Patterns.cs:30:13:30:27 | case ...: | Patterns.cs:5:10:5:11 | M1 | +| Patterns.cs:31:17:31:50 | ...; | Patterns.cs:5:10:5:11 | M1 | +| Patterns.cs:33:13:33:24 | case ...: | Patterns.cs:5:10:5:11 | M1 | +| Patterns.cs:34:17:34:22 | break; | Patterns.cs:5:10:5:11 | M1 | +| Patterns.cs:35:13:35:20 | default: | Patterns.cs:5:10:5:11 | M1 | +| Patterns.cs:40:9:42:9 | switch (...) {...} | Patterns.cs:5:10:5:11 | M1 | +| Patterns.cs:47:24:47:25 | enter M2 | Patterns.cs:47:24:47:25 | M2 | +| Patterns.cs:50:24:50:25 | enter M3 | Patterns.cs:50:24:50:25 | M3 | +| Patterns.cs:51:9:51:21 | [false] ... is ... | Patterns.cs:50:24:50:25 | M3 | +| Patterns.cs:51:9:51:21 | [true] ... is ... | Patterns.cs:50:24:50:25 | M3 | +| Patterns.cs:51:9:51:39 | ... ? ... : ... | Patterns.cs:50:24:50:25 | M3 | +| Patterns.cs:51:14:51:21 | [match] not ... | Patterns.cs:50:24:50:25 | M3 | +| Patterns.cs:51:14:51:21 | [no-match] not ... | Patterns.cs:50:24:50:25 | M3 | +| Patterns.cs:51:25:51:25 | access to parameter c | Patterns.cs:50:24:50:25 | M3 | +| Patterns.cs:51:34:51:34 | access to parameter c | Patterns.cs:50:24:50:25 | M3 | +| Patterns.cs:53:24:53:25 | enter M4 | Patterns.cs:53:24:53:25 | M4 | +| Patterns.cs:54:18:54:37 | { ... } | Patterns.cs:53:24:53:25 | M4 | +| Patterns.cs:54:27:54:35 | [match] { ... } | Patterns.cs:53:24:53:25 | M4 | +| Patterns.cs:54:27:54:35 | [no-match] { ... } | Patterns.cs:53:24:53:25 | M4 | +| Patterns.cs:54:33:54:33 | 1 | Patterns.cs:53:24:53:25 | M4 | +| Patterns.cs:56:26:56:27 | enter M5 | Patterns.cs:56:26:56:27 | M5 | +| Patterns.cs:58:16:62:9 | ... switch { ... } | Patterns.cs:56:26:56:27 | M5 | +| Patterns.cs:60:13:60:17 | [match] not ... | Patterns.cs:56:26:56:27 | M5 | +| Patterns.cs:60:13:60:17 | [no-match] not ... | Patterns.cs:56:26:56:27 | M5 | +| Patterns.cs:60:22:60:28 | "not 1" | Patterns.cs:56:26:56:27 | M5 | +| Patterns.cs:61:13:61:13 | _ | Patterns.cs:56:26:56:27 | M5 | +| Patterns.cs:61:18:61:24 | "other" | Patterns.cs:56:26:56:27 | M5 | +| Patterns.cs:65:26:65:27 | enter M6 | Patterns.cs:65:26:65:27 | M6 | +| Patterns.cs:69:13:69:17 | [no-match] not ... | Patterns.cs:65:26:65:27 | M6 | +| Patterns.cs:70:13:70:13 | 2 | Patterns.cs:65:26:65:27 | M6 | +| Patterns.cs:70:18:70:27 | "possible" | Patterns.cs:65:26:65:27 | M6 | +| Patterns.cs:74:26:74:27 | enter M7 | Patterns.cs:74:26:74:27 | M7 | +| Patterns.cs:76:16:82:9 | ... switch { ... } | Patterns.cs:74:26:74:27 | M7 | +| Patterns.cs:78:20:78:24 | "> 1" | Patterns.cs:74:26:74:27 | M7 | +| Patterns.cs:79:15:79:15 | 0 | Patterns.cs:74:26:74:27 | M7 | +| Patterns.cs:79:20:79:24 | "< 0" | Patterns.cs:74:26:74:27 | M7 | +| Patterns.cs:80:13:80:13 | 1 | Patterns.cs:74:26:74:27 | M7 | +| Patterns.cs:80:18:80:20 | "1" | Patterns.cs:74:26:74:27 | M7 | +| Patterns.cs:81:13:81:13 | _ | Patterns.cs:74:26:74:27 | M7 | +| Patterns.cs:81:18:81:20 | "0" | Patterns.cs:74:26:74:27 | M7 | +| Patterns.cs:85:26:85:27 | enter M8 | Patterns.cs:85:26:85:27 | M8 | +| Patterns.cs:85:39:85:53 | [false] ... is ... | Patterns.cs:85:26:85:27 | M8 | +| Patterns.cs:85:39:85:53 | [true] ... is ... | Patterns.cs:85:26:85:27 | M8 | +| Patterns.cs:85:39:85:69 | ... ? ... : ... | Patterns.cs:85:26:85:27 | M8 | +| Patterns.cs:85:44:85:53 | [match] ... or ... | Patterns.cs:85:26:85:27 | M8 | +| Patterns.cs:85:44:85:53 | [no-match] ... or ... | Patterns.cs:85:26:85:27 | M8 | +| Patterns.cs:85:49:85:53 | [match] not ... | Patterns.cs:85:26:85:27 | M8 | +| Patterns.cs:85:49:85:53 | [no-match] not ... | Patterns.cs:85:26:85:27 | M8 | +| Patterns.cs:85:53:85:53 | 2 | Patterns.cs:85:26:85:27 | M8 | +| Patterns.cs:85:57:85:63 | "not 2" | Patterns.cs:85:26:85:27 | M8 | +| Patterns.cs:85:67:85:69 | "2" | Patterns.cs:85:26:85:27 | M8 | +| Patterns.cs:87:26:87:27 | enter M9 | Patterns.cs:87:26:87:27 | M9 | +| Patterns.cs:87:39:87:54 | [false] ... is ... | Patterns.cs:87:26:87:27 | M9 | +| Patterns.cs:87:39:87:54 | [true] ... is ... | Patterns.cs:87:26:87:27 | M9 | +| Patterns.cs:87:39:87:70 | ... ? ... : ... | Patterns.cs:87:26:87:27 | M9 | +| Patterns.cs:87:44:87:54 | [match] ... and ... | Patterns.cs:87:26:87:27 | M9 | +| Patterns.cs:87:44:87:54 | [no-match] ... and ... | Patterns.cs:87:26:87:27 | M9 | +| Patterns.cs:87:50:87:54 | [match] not ... | Patterns.cs:87:26:87:27 | M9 | +| Patterns.cs:87:50:87:54 | [no-match] not ... | Patterns.cs:87:26:87:27 | M9 | +| Patterns.cs:87:54:87:54 | 2 | Patterns.cs:87:26:87:27 | M9 | +| Patterns.cs:87:58:87:60 | "1" | Patterns.cs:87:26:87:27 | M9 | +| Patterns.cs:87:64:87:70 | "not 1" | Patterns.cs:87:26:87:27 | M9 | +| Patterns.cs:93:17:93:19 | enter M10 | Patterns.cs:93:17:93:19 | M10 | +| Patterns.cs:93:17:93:19 | exit M10 (normal) | Patterns.cs:93:17:93:19 | M10 | +| Patterns.cs:95:13:95:40 | [false] ... is ... | Patterns.cs:93:17:93:19 | M10 | +| Patterns.cs:95:13:95:40 | [true] ... is ... | Patterns.cs:93:17:93:19 | M10 | +| Patterns.cs:95:21:95:40 | [match] { ... } | Patterns.cs:93:17:93:19 | M10 | +| Patterns.cs:95:21:95:40 | [match] { ... } | Patterns.cs:93:17:93:19 | M10 | +| Patterns.cs:95:21:95:40 | [no-match] { ... } | Patterns.cs:93:17:93:19 | M10 | +| Patterns.cs:95:21:95:40 | [no-match] { ... } | Patterns.cs:93:17:93:19 | M10 | +| Patterns.cs:95:29:95:38 | [match] ... or ... | Patterns.cs:93:17:93:19 | M10 | +| Patterns.cs:95:29:95:38 | [no-match] ... or ... | Patterns.cs:93:17:93:19 | M10 | +| Patterns.cs:95:36:95:38 | access to constant B | Patterns.cs:93:17:93:19 | M10 | +| Patterns.cs:96:9:98:9 | {...} | Patterns.cs:93:17:93:19 | M10 | | PostDominance.cs:5:10:5:11 | enter M1 | PostDominance.cs:5:10:5:11 | M1 | | PostDominance.cs:10:10:10:11 | enter M2 | PostDominance.cs:10:10:10:11 | M2 | | PostDominance.cs:10:10:10:11 | exit M2 (normal) | PostDominance.cs:10:10:10:11 | M2 | +| PostDominance.cs:12:13:12:21 | [false] ... is ... | PostDominance.cs:10:10:10:11 | M2 | +| PostDominance.cs:12:13:12:21 | [true] ... is ... | PostDominance.cs:10:10:10:11 | M2 | | PostDominance.cs:13:13:13:19 | return ...; | PostDominance.cs:10:10:10:11 | M2 | | PostDominance.cs:14:9:14:29 | ...; | PostDominance.cs:10:10:10:11 | M2 | | PostDominance.cs:17:10:17:11 | enter M3 | PostDominance.cs:17:10:17:11 | M3 | | PostDominance.cs:17:10:17:11 | exit M3 | PostDominance.cs:17:10:17:11 | M3 | +| PostDominance.cs:19:13:19:21 | [false] ... is ... | PostDominance.cs:17:10:17:11 | M3 | +| PostDominance.cs:19:13:19:21 | [true] ... is ... | PostDominance.cs:17:10:17:11 | M3 | | PostDominance.cs:20:45:20:53 | nameof(...) | PostDominance.cs:17:10:17:11 | M3 | | PostDominance.cs:21:9:21:29 | ...; | PostDominance.cs:17:10:17:11 | M3 | | Qualifiers.cs:7:16:7:21 | enter Method | Qualifiers.cs:7:16:7:21 | Method | @@ -5698,6 +6009,8 @@ blockEnclosing | Switch.cs:158:13:158:49 | ...; | Switch.cs:154:10:154:12 | M15 | | Switch.cs:160:13:160:49 | ...; | Switch.cs:154:10:154:12 | M15 | | TypeAccesses.cs:3:10:3:10 | enter M | TypeAccesses.cs:3:10:3:10 | M | +| TypeAccesses.cs:7:13:7:22 | [false] ... is ... | TypeAccesses.cs:3:10:3:10 | M | +| TypeAccesses.cs:7:13:7:22 | [true] ... is ... | TypeAccesses.cs:3:10:3:10 | M | | TypeAccesses.cs:7:25:7:25 | ; | TypeAccesses.cs:3:10:3:10 | M | | TypeAccesses.cs:8:9:8:28 | ... ...; | TypeAccesses.cs:3:10:3:10 | M | | VarDecls.cs:5:18:5:19 | enter M1 | VarDecls.cs:5:18:5:19 | M1 | diff --git a/csharp/ql/test/library-tests/controlflow/graph/EntryElement.expected b/csharp/ql/test/library-tests/controlflow/graph/EntryElement.expected index e7011799f62..28fd165909c 100644 --- a/csharp/ql/test/library-tests/controlflow/graph/EntryElement.expected +++ b/csharp/ql/test/library-tests/controlflow/graph/EntryElement.expected @@ -189,7 +189,6 @@ | AccessorCalls.cs:58:22:58:25 | this access | AccessorCalls.cs:58:22:58:25 | this access | | AccessorCalls.cs:58:22:58:30 | access to property Prop | AccessorCalls.cs:58:22:58:25 | this access | | AccessorCalls.cs:58:33:58:44 | (..., ...) | AccessorCalls.cs:58:37:58:40 | this access | -| AccessorCalls.cs:58:34:58:34 | 1 | AccessorCalls.cs:58:34:58:34 | 1 | | AccessorCalls.cs:58:37:58:40 | this access | AccessorCalls.cs:58:37:58:40 | this access | | AccessorCalls.cs:58:37:58:43 | access to indexer | AccessorCalls.cs:58:37:58:40 | this access | | AccessorCalls.cs:58:42:58:42 | 0 | AccessorCalls.cs:58:42:58:42 | 0 | @@ -660,8 +659,6 @@ | Assert.cs:128:9:128:36 | ...; | Assert.cs:128:9:128:36 | ...; | | Assert.cs:128:27:128:27 | access to local variable s | Assert.cs:128:27:128:27 | access to local variable s | | Assert.cs:128:27:128:34 | access to property Length | Assert.cs:128:27:128:27 | access to local variable s | -| Assert.cs:132:61:132:65 | false | Assert.cs:132:61:132:65 | false | -| Assert.cs:133:61:133:64 | true | Assert.cs:133:61:133:64 | true | | Assert.cs:135:5:136:5 | {...} | Assert.cs:135:5:136:5 | {...} | | Assert.cs:139:5:142:5 | {...} | Assert.cs:139:5:142:5 | {...} | | Assert.cs:140:9:140:35 | call to method AssertTrueFalse | Assert.cs:140:9:140:35 | this access | @@ -1149,132 +1146,145 @@ | Conditions.cs:149:38:149:47 | $"..." | Conditions.cs:149:40:149:43 | "b = " | | Conditions.cs:149:40:149:43 | "b = " | Conditions.cs:149:40:149:43 | "b = " | | Conditions.cs:149:45:149:45 | access to local variable s | Conditions.cs:149:45:149:45 | access to local variable s | -| ExitMethods.cs:8:5:11:5 | {...} | ExitMethods.cs:8:5:11:5 | {...} | -| ExitMethods.cs:9:9:9:24 | call to method ErrorMaybe | ExitMethods.cs:9:20:9:23 | true | -| ExitMethods.cs:9:9:9:25 | ...; | ExitMethods.cs:9:9:9:25 | ...; | -| ExitMethods.cs:9:20:9:23 | true | ExitMethods.cs:9:20:9:23 | true | -| ExitMethods.cs:10:9:10:15 | return ...; | ExitMethods.cs:10:9:10:15 | return ...; | -| ExitMethods.cs:14:5:17:5 | {...} | ExitMethods.cs:14:5:17:5 | {...} | -| ExitMethods.cs:15:9:15:25 | call to method ErrorMaybe | ExitMethods.cs:15:20:15:24 | false | -| ExitMethods.cs:15:9:15:26 | ...; | ExitMethods.cs:15:9:15:26 | ...; | -| ExitMethods.cs:15:20:15:24 | false | ExitMethods.cs:15:20:15:24 | false | -| ExitMethods.cs:16:9:16:15 | return ...; | ExitMethods.cs:16:9:16:15 | return ...; | -| ExitMethods.cs:20:5:23:5 | {...} | ExitMethods.cs:20:5:23:5 | {...} | -| ExitMethods.cs:21:9:21:25 | call to method ErrorAlways | ExitMethods.cs:21:21:21:24 | true | -| ExitMethods.cs:21:9:21:26 | ...; | ExitMethods.cs:21:9:21:26 | ...; | -| ExitMethods.cs:21:21:21:24 | true | ExitMethods.cs:21:21:21:24 | true | -| ExitMethods.cs:22:9:22:15 | return ...; | ExitMethods.cs:22:9:22:15 | return ...; | -| ExitMethods.cs:26:5:29:5 | {...} | ExitMethods.cs:26:5:29:5 | {...} | -| ExitMethods.cs:27:9:27:14 | call to method Exit | ExitMethods.cs:27:9:27:14 | this access | -| ExitMethods.cs:27:9:27:14 | this access | ExitMethods.cs:27:9:27:14 | this access | -| ExitMethods.cs:27:9:27:15 | ...; | ExitMethods.cs:27:9:27:15 | ...; | -| ExitMethods.cs:28:9:28:15 | return ...; | ExitMethods.cs:28:9:28:15 | return ...; | -| ExitMethods.cs:32:5:35:5 | {...} | ExitMethods.cs:32:5:35:5 | {...} | -| ExitMethods.cs:33:9:33:25 | call to method ApplicationExit | ExitMethods.cs:33:9:33:25 | this access | -| ExitMethods.cs:33:9:33:25 | this access | ExitMethods.cs:33:9:33:25 | this access | -| ExitMethods.cs:33:9:33:26 | ...; | ExitMethods.cs:33:9:33:26 | ...; | -| ExitMethods.cs:34:9:34:15 | return ...; | ExitMethods.cs:34:9:34:15 | return ...; | -| ExitMethods.cs:38:5:51:5 | {...} | ExitMethods.cs:38:5:51:5 | {...} | -| ExitMethods.cs:39:9:50:9 | try {...} ... | ExitMethods.cs:39:9:50:9 | try {...} ... | -| ExitMethods.cs:40:9:42:9 | {...} | ExitMethods.cs:40:9:42:9 | {...} | -| ExitMethods.cs:41:13:41:30 | call to method ErrorAlways | ExitMethods.cs:41:25:41:29 | false | -| ExitMethods.cs:41:13:41:31 | ...; | ExitMethods.cs:41:13:41:31 | ...; | -| ExitMethods.cs:41:25:41:29 | false | ExitMethods.cs:41:25:41:29 | false | -| ExitMethods.cs:43:9:46:9 | catch (...) {...} | ExitMethods.cs:43:9:46:9 | catch (...) {...} | -| ExitMethods.cs:44:9:46:9 | {...} | ExitMethods.cs:44:9:46:9 | {...} | -| ExitMethods.cs:45:13:45:19 | return ...; | ExitMethods.cs:45:13:45:19 | return ...; | -| ExitMethods.cs:47:9:50:9 | catch (...) {...} | ExitMethods.cs:47:9:50:9 | catch (...) {...} | -| ExitMethods.cs:48:9:50:9 | {...} | ExitMethods.cs:48:9:50:9 | {...} | -| ExitMethods.cs:49:13:49:19 | return ...; | ExitMethods.cs:49:13:49:19 | return ...; | -| ExitMethods.cs:54:5:57:5 | {...} | ExitMethods.cs:54:5:57:5 | {...} | -| ExitMethods.cs:55:9:55:22 | call to method ErrorAlways2 | ExitMethods.cs:55:9:55:22 | call to method ErrorAlways2 | -| ExitMethods.cs:55:9:55:23 | ...; | ExitMethods.cs:55:9:55:23 | ...; | -| ExitMethods.cs:56:9:56:15 | return ...; | ExitMethods.cs:56:9:56:15 | return ...; | -| ExitMethods.cs:60:5:63:5 | {...} | ExitMethods.cs:60:5:63:5 | {...} | -| ExitMethods.cs:61:9:61:22 | call to method ErrorAlways3 | ExitMethods.cs:61:9:61:22 | call to method ErrorAlways3 | -| ExitMethods.cs:61:9:61:23 | ...; | ExitMethods.cs:61:9:61:23 | ...; | -| ExitMethods.cs:62:9:62:15 | return ...; | ExitMethods.cs:62:9:62:15 | return ...; | -| ExitMethods.cs:66:5:69:5 | {...} | ExitMethods.cs:66:5:69:5 | {...} | -| ExitMethods.cs:67:9:68:34 | if (...) ... | ExitMethods.cs:67:9:68:34 | if (...) ... | -| ExitMethods.cs:67:13:67:13 | access to parameter b | ExitMethods.cs:67:13:67:13 | access to parameter b | -| ExitMethods.cs:68:13:68:34 | throw ...; | ExitMethods.cs:68:19:68:33 | object creation of type Exception | -| ExitMethods.cs:68:19:68:33 | object creation of type Exception | ExitMethods.cs:68:19:68:33 | object creation of type Exception | -| ExitMethods.cs:72:5:77:5 | {...} | ExitMethods.cs:72:5:77:5 | {...} | -| ExitMethods.cs:73:9:76:45 | if (...) ... | ExitMethods.cs:73:9:76:45 | if (...) ... | -| ExitMethods.cs:73:13:73:13 | access to parameter b | ExitMethods.cs:73:13:73:13 | access to parameter b | -| ExitMethods.cs:74:13:74:34 | throw ...; | ExitMethods.cs:74:19:74:33 | object creation of type Exception | -| ExitMethods.cs:74:19:74:33 | object creation of type Exception | ExitMethods.cs:74:19:74:33 | object creation of type Exception | -| ExitMethods.cs:76:13:76:45 | throw ...; | ExitMethods.cs:76:41:76:43 | "b" | -| ExitMethods.cs:76:19:76:44 | object creation of type ArgumentException | ExitMethods.cs:76:41:76:43 | "b" | -| ExitMethods.cs:76:41:76:43 | "b" | ExitMethods.cs:76:41:76:43 | "b" | -| ExitMethods.cs:80:5:82:5 | {...} | ExitMethods.cs:80:5:82:5 | {...} | -| ExitMethods.cs:81:9:81:30 | throw ...; | ExitMethods.cs:81:15:81:29 | object creation of type Exception | -| ExitMethods.cs:81:15:81:29 | object creation of type Exception | ExitMethods.cs:81:15:81:29 | object creation of type Exception | -| ExitMethods.cs:84:35:84:55 | throw ... | ExitMethods.cs:84:41:84:55 | object creation of type Exception | -| ExitMethods.cs:84:41:84:55 | object creation of type Exception | ExitMethods.cs:84:41:84:55 | object creation of type Exception | -| ExitMethods.cs:87:5:89:5 | {...} | ExitMethods.cs:87:5:89:5 | {...} | -| ExitMethods.cs:88:9:88:27 | call to method Exit | ExitMethods.cs:88:26:88:26 | 0 | -| ExitMethods.cs:88:9:88:28 | ...; | ExitMethods.cs:88:9:88:28 | ...; | -| ExitMethods.cs:88:26:88:26 | 0 | ExitMethods.cs:88:26:88:26 | 0 | -| ExitMethods.cs:92:5:102:5 | {...} | ExitMethods.cs:92:5:102:5 | {...} | -| ExitMethods.cs:93:9:101:9 | try {...} ... | ExitMethods.cs:93:9:101:9 | try {...} ... | -| ExitMethods.cs:94:9:96:9 | {...} | ExitMethods.cs:94:9:96:9 | {...} | -| ExitMethods.cs:95:13:95:18 | call to method Exit | ExitMethods.cs:95:13:95:18 | this access | -| ExitMethods.cs:95:13:95:18 | this access | ExitMethods.cs:95:13:95:18 | this access | -| ExitMethods.cs:95:13:95:19 | ...; | ExitMethods.cs:95:13:95:19 | ...; | -| ExitMethods.cs:98:9:101:9 | {...} | ExitMethods.cs:98:9:101:9 | {...} | -| ExitMethods.cs:100:13:100:40 | call to method WriteLine | ExitMethods.cs:100:38:100:39 | "" | -| ExitMethods.cs:100:13:100:41 | ...; | ExitMethods.cs:100:13:100:41 | ...; | -| ExitMethods.cs:100:38:100:39 | "" | ExitMethods.cs:100:38:100:39 | "" | -| ExitMethods.cs:105:5:107:5 | {...} | ExitMethods.cs:105:5:107:5 | {...} | -| ExitMethods.cs:106:9:106:47 | call to method Exit | ExitMethods.cs:106:9:106:47 | call to method Exit | -| ExitMethods.cs:106:9:106:48 | ...; | ExitMethods.cs:106:9:106:48 | ...; | -| ExitMethods.cs:110:5:112:5 | {...} | ExitMethods.cs:110:5:112:5 | {...} | -| ExitMethods.cs:111:9:111:77 | return ...; | ExitMethods.cs:111:16:111:20 | access to parameter input | -| ExitMethods.cs:111:16:111:20 | access to parameter input | ExitMethods.cs:111:16:111:20 | access to parameter input | -| ExitMethods.cs:111:16:111:25 | ... != ... | ExitMethods.cs:111:16:111:20 | access to parameter input | -| ExitMethods.cs:111:16:111:76 | ... ? ... : ... | ExitMethods.cs:111:16:111:20 | access to parameter input | -| ExitMethods.cs:111:25:111:25 | 0 | ExitMethods.cs:111:25:111:25 | 0 | -| ExitMethods.cs:111:25:111:25 | (...) ... | ExitMethods.cs:111:25:111:25 | 0 | -| ExitMethods.cs:111:29:111:29 | 1 | ExitMethods.cs:111:29:111:29 | 1 | -| ExitMethods.cs:111:29:111:29 | (...) ... | ExitMethods.cs:111:29:111:29 | 1 | -| ExitMethods.cs:111:29:111:37 | ... / ... | ExitMethods.cs:111:29:111:29 | 1 | -| ExitMethods.cs:111:33:111:37 | access to parameter input | ExitMethods.cs:111:33:111:37 | access to parameter input | -| ExitMethods.cs:111:41:111:76 | throw ... | ExitMethods.cs:111:69:111:75 | "input" | -| ExitMethods.cs:111:47:111:76 | object creation of type ArgumentException | ExitMethods.cs:111:69:111:75 | "input" | -| ExitMethods.cs:111:69:111:75 | "input" | ExitMethods.cs:111:69:111:75 | "input" | -| ExitMethods.cs:115:5:117:5 | {...} | ExitMethods.cs:115:5:117:5 | {...} | -| ExitMethods.cs:116:9:116:39 | return ...; | ExitMethods.cs:116:16:116:16 | access to parameter s | -| ExitMethods.cs:116:16:116:16 | access to parameter s | ExitMethods.cs:116:16:116:16 | access to parameter s | -| ExitMethods.cs:116:16:116:30 | call to method Contains | ExitMethods.cs:116:16:116:16 | access to parameter s | -| ExitMethods.cs:116:16:116:38 | ... ? ... : ... | ExitMethods.cs:116:16:116:16 | access to parameter s | -| ExitMethods.cs:116:27:116:29 | - | ExitMethods.cs:116:27:116:29 | - | -| ExitMethods.cs:116:34:116:34 | 0 | ExitMethods.cs:116:34:116:34 | 0 | -| ExitMethods.cs:116:38:116:38 | 1 | ExitMethods.cs:116:38:116:38 | 1 | -| ExitMethods.cs:120:5:123:5 | {...} | ExitMethods.cs:120:5:123:5 | {...} | -| ExitMethods.cs:121:9:121:28 | call to method IsTrue | ExitMethods.cs:121:23:121:27 | false | -| ExitMethods.cs:121:9:121:29 | ...; | ExitMethods.cs:121:9:121:29 | ...; | -| ExitMethods.cs:121:23:121:27 | false | ExitMethods.cs:121:23:121:27 | false | -| ExitMethods.cs:122:9:122:18 | ... ...; | ExitMethods.cs:122:9:122:18 | ... ...; | -| ExitMethods.cs:122:13:122:17 | Int32 x = ... | ExitMethods.cs:122:17:122:17 | 0 | -| ExitMethods.cs:122:17:122:17 | 0 | ExitMethods.cs:122:17:122:17 | 0 | -| ExitMethods.cs:126:5:129:5 | {...} | ExitMethods.cs:126:5:129:5 | {...} | -| ExitMethods.cs:127:9:127:26 | call to method FailingAssertion | ExitMethods.cs:127:9:127:26 | this access | -| ExitMethods.cs:127:9:127:26 | this access | ExitMethods.cs:127:9:127:26 | this access | -| ExitMethods.cs:127:9:127:27 | ...; | ExitMethods.cs:127:9:127:27 | ...; | -| ExitMethods.cs:128:9:128:18 | ... ...; | ExitMethods.cs:128:9:128:18 | ... ...; | -| ExitMethods.cs:128:13:128:17 | Int32 x = ... | ExitMethods.cs:128:17:128:17 | 0 | -| ExitMethods.cs:128:17:128:17 | 0 | ExitMethods.cs:128:17:128:17 | 0 | -| ExitMethods.cs:131:33:131:49 | call to method IsFalse | ExitMethods.cs:131:48:131:48 | access to parameter b | -| ExitMethods.cs:131:48:131:48 | access to parameter b | ExitMethods.cs:131:48:131:48 | access to parameter b | -| ExitMethods.cs:134:5:137:5 | {...} | ExitMethods.cs:134:5:137:5 | {...} | -| ExitMethods.cs:135:9:135:25 | call to method AssertFalse | ExitMethods.cs:135:9:135:25 | this access | -| ExitMethods.cs:135:9:135:25 | this access | ExitMethods.cs:135:9:135:25 | this access | -| ExitMethods.cs:135:9:135:26 | ...; | ExitMethods.cs:135:9:135:26 | ...; | -| ExitMethods.cs:135:21:135:24 | true | ExitMethods.cs:135:21:135:24 | true | -| ExitMethods.cs:136:9:136:18 | ... ...; | ExitMethods.cs:136:9:136:18 | ... ...; | -| ExitMethods.cs:136:13:136:17 | Int32 x = ... | ExitMethods.cs:136:17:136:17 | 0 | -| ExitMethods.cs:136:17:136:17 | 0 | ExitMethods.cs:136:17:136:17 | 0 | +| ExitMethods.cs:9:5:12:5 | {...} | ExitMethods.cs:9:5:12:5 | {...} | +| ExitMethods.cs:10:9:10:24 | call to method ErrorMaybe | ExitMethods.cs:10:20:10:23 | true | +| ExitMethods.cs:10:9:10:25 | ...; | ExitMethods.cs:10:9:10:25 | ...; | +| ExitMethods.cs:10:20:10:23 | true | ExitMethods.cs:10:20:10:23 | true | +| ExitMethods.cs:11:9:11:15 | return ...; | ExitMethods.cs:11:9:11:15 | return ...; | +| ExitMethods.cs:15:5:18:5 | {...} | ExitMethods.cs:15:5:18:5 | {...} | +| ExitMethods.cs:16:9:16:25 | call to method ErrorMaybe | ExitMethods.cs:16:20:16:24 | false | +| ExitMethods.cs:16:9:16:26 | ...; | ExitMethods.cs:16:9:16:26 | ...; | +| ExitMethods.cs:16:20:16:24 | false | ExitMethods.cs:16:20:16:24 | false | +| ExitMethods.cs:17:9:17:15 | return ...; | ExitMethods.cs:17:9:17:15 | return ...; | +| ExitMethods.cs:21:5:24:5 | {...} | ExitMethods.cs:21:5:24:5 | {...} | +| ExitMethods.cs:22:9:22:25 | call to method ErrorAlways | ExitMethods.cs:22:21:22:24 | true | +| ExitMethods.cs:22:9:22:26 | ...; | ExitMethods.cs:22:9:22:26 | ...; | +| ExitMethods.cs:22:21:22:24 | true | ExitMethods.cs:22:21:22:24 | true | +| ExitMethods.cs:23:9:23:15 | return ...; | ExitMethods.cs:23:9:23:15 | return ...; | +| ExitMethods.cs:27:5:30:5 | {...} | ExitMethods.cs:27:5:30:5 | {...} | +| ExitMethods.cs:28:9:28:14 | call to method Exit | ExitMethods.cs:28:9:28:14 | this access | +| ExitMethods.cs:28:9:28:14 | this access | ExitMethods.cs:28:9:28:14 | this access | +| ExitMethods.cs:28:9:28:15 | ...; | ExitMethods.cs:28:9:28:15 | ...; | +| ExitMethods.cs:29:9:29:15 | return ...; | ExitMethods.cs:29:9:29:15 | return ...; | +| ExitMethods.cs:33:5:36:5 | {...} | ExitMethods.cs:33:5:36:5 | {...} | +| ExitMethods.cs:34:9:34:25 | call to method ApplicationExit | ExitMethods.cs:34:9:34:25 | this access | +| ExitMethods.cs:34:9:34:25 | this access | ExitMethods.cs:34:9:34:25 | this access | +| ExitMethods.cs:34:9:34:26 | ...; | ExitMethods.cs:34:9:34:26 | ...; | +| ExitMethods.cs:35:9:35:15 | return ...; | ExitMethods.cs:35:9:35:15 | return ...; | +| ExitMethods.cs:39:5:52:5 | {...} | ExitMethods.cs:39:5:52:5 | {...} | +| ExitMethods.cs:40:9:51:9 | try {...} ... | ExitMethods.cs:40:9:51:9 | try {...} ... | +| ExitMethods.cs:41:9:43:9 | {...} | ExitMethods.cs:41:9:43:9 | {...} | +| ExitMethods.cs:42:13:42:30 | call to method ErrorAlways | ExitMethods.cs:42:25:42:29 | false | +| ExitMethods.cs:42:13:42:31 | ...; | ExitMethods.cs:42:13:42:31 | ...; | +| ExitMethods.cs:42:25:42:29 | false | ExitMethods.cs:42:25:42:29 | false | +| ExitMethods.cs:44:9:47:9 | catch (...) {...} | ExitMethods.cs:44:9:47:9 | catch (...) {...} | +| ExitMethods.cs:45:9:47:9 | {...} | ExitMethods.cs:45:9:47:9 | {...} | +| ExitMethods.cs:46:13:46:19 | return ...; | ExitMethods.cs:46:13:46:19 | return ...; | +| ExitMethods.cs:48:9:51:9 | catch (...) {...} | ExitMethods.cs:48:9:51:9 | catch (...) {...} | +| ExitMethods.cs:49:9:51:9 | {...} | ExitMethods.cs:49:9:51:9 | {...} | +| ExitMethods.cs:50:13:50:19 | return ...; | ExitMethods.cs:50:13:50:19 | return ...; | +| ExitMethods.cs:55:5:58:5 | {...} | ExitMethods.cs:55:5:58:5 | {...} | +| ExitMethods.cs:56:9:56:22 | call to method ErrorAlways2 | ExitMethods.cs:56:9:56:22 | call to method ErrorAlways2 | +| ExitMethods.cs:56:9:56:23 | ...; | ExitMethods.cs:56:9:56:23 | ...; | +| ExitMethods.cs:57:9:57:15 | return ...; | ExitMethods.cs:57:9:57:15 | return ...; | +| ExitMethods.cs:61:5:64:5 | {...} | ExitMethods.cs:61:5:64:5 | {...} | +| ExitMethods.cs:62:9:62:22 | call to method ErrorAlways3 | ExitMethods.cs:62:9:62:22 | call to method ErrorAlways3 | +| ExitMethods.cs:62:9:62:23 | ...; | ExitMethods.cs:62:9:62:23 | ...; | +| ExitMethods.cs:63:9:63:15 | return ...; | ExitMethods.cs:63:9:63:15 | return ...; | +| ExitMethods.cs:67:5:70:5 | {...} | ExitMethods.cs:67:5:70:5 | {...} | +| ExitMethods.cs:68:9:69:34 | if (...) ... | ExitMethods.cs:68:9:69:34 | if (...) ... | +| ExitMethods.cs:68:13:68:13 | access to parameter b | ExitMethods.cs:68:13:68:13 | access to parameter b | +| ExitMethods.cs:69:13:69:34 | throw ...; | ExitMethods.cs:69:19:69:33 | object creation of type Exception | +| ExitMethods.cs:69:19:69:33 | object creation of type Exception | ExitMethods.cs:69:19:69:33 | object creation of type Exception | +| ExitMethods.cs:73:5:78:5 | {...} | ExitMethods.cs:73:5:78:5 | {...} | +| ExitMethods.cs:74:9:77:45 | if (...) ... | ExitMethods.cs:74:9:77:45 | if (...) ... | +| ExitMethods.cs:74:13:74:13 | access to parameter b | ExitMethods.cs:74:13:74:13 | access to parameter b | +| ExitMethods.cs:75:13:75:34 | throw ...; | ExitMethods.cs:75:19:75:33 | object creation of type Exception | +| ExitMethods.cs:75:19:75:33 | object creation of type Exception | ExitMethods.cs:75:19:75:33 | object creation of type Exception | +| ExitMethods.cs:77:13:77:45 | throw ...; | ExitMethods.cs:77:41:77:43 | "b" | +| ExitMethods.cs:77:19:77:44 | object creation of type ArgumentException | ExitMethods.cs:77:41:77:43 | "b" | +| ExitMethods.cs:77:41:77:43 | "b" | ExitMethods.cs:77:41:77:43 | "b" | +| ExitMethods.cs:81:5:83:5 | {...} | ExitMethods.cs:81:5:83:5 | {...} | +| ExitMethods.cs:82:9:82:30 | throw ...; | ExitMethods.cs:82:15:82:29 | object creation of type Exception | +| ExitMethods.cs:82:15:82:29 | object creation of type Exception | ExitMethods.cs:82:15:82:29 | object creation of type Exception | +| ExitMethods.cs:85:35:85:55 | throw ... | ExitMethods.cs:85:41:85:55 | object creation of type Exception | +| ExitMethods.cs:85:41:85:55 | object creation of type Exception | ExitMethods.cs:85:41:85:55 | object creation of type Exception | +| ExitMethods.cs:88:5:90:5 | {...} | ExitMethods.cs:88:5:90:5 | {...} | +| ExitMethods.cs:89:9:89:27 | call to method Exit | ExitMethods.cs:89:26:89:26 | 0 | +| ExitMethods.cs:89:9:89:28 | ...; | ExitMethods.cs:89:9:89:28 | ...; | +| ExitMethods.cs:89:26:89:26 | 0 | ExitMethods.cs:89:26:89:26 | 0 | +| ExitMethods.cs:93:5:103:5 | {...} | ExitMethods.cs:93:5:103:5 | {...} | +| ExitMethods.cs:94:9:102:9 | try {...} ... | ExitMethods.cs:94:9:102:9 | try {...} ... | +| ExitMethods.cs:95:9:97:9 | {...} | ExitMethods.cs:95:9:97:9 | {...} | +| ExitMethods.cs:96:13:96:18 | call to method Exit | ExitMethods.cs:96:13:96:18 | this access | +| ExitMethods.cs:96:13:96:18 | this access | ExitMethods.cs:96:13:96:18 | this access | +| ExitMethods.cs:96:13:96:19 | ...; | ExitMethods.cs:96:13:96:19 | ...; | +| ExitMethods.cs:99:9:102:9 | {...} | ExitMethods.cs:99:9:102:9 | {...} | +| ExitMethods.cs:101:13:101:40 | call to method WriteLine | ExitMethods.cs:101:38:101:39 | "" | +| ExitMethods.cs:101:13:101:41 | ...; | ExitMethods.cs:101:13:101:41 | ...; | +| ExitMethods.cs:101:38:101:39 | "" | ExitMethods.cs:101:38:101:39 | "" | +| ExitMethods.cs:106:5:108:5 | {...} | ExitMethods.cs:106:5:108:5 | {...} | +| ExitMethods.cs:107:9:107:47 | call to method Exit | ExitMethods.cs:107:9:107:47 | call to method Exit | +| ExitMethods.cs:107:9:107:48 | ...; | ExitMethods.cs:107:9:107:48 | ...; | +| ExitMethods.cs:111:5:113:5 | {...} | ExitMethods.cs:111:5:113:5 | {...} | +| ExitMethods.cs:112:9:112:77 | return ...; | ExitMethods.cs:112:16:112:20 | access to parameter input | +| ExitMethods.cs:112:16:112:20 | access to parameter input | ExitMethods.cs:112:16:112:20 | access to parameter input | +| ExitMethods.cs:112:16:112:25 | ... != ... | ExitMethods.cs:112:16:112:20 | access to parameter input | +| ExitMethods.cs:112:16:112:76 | ... ? ... : ... | ExitMethods.cs:112:16:112:20 | access to parameter input | +| ExitMethods.cs:112:25:112:25 | 0 | ExitMethods.cs:112:25:112:25 | 0 | +| ExitMethods.cs:112:25:112:25 | (...) ... | ExitMethods.cs:112:25:112:25 | 0 | +| ExitMethods.cs:112:29:112:29 | 1 | ExitMethods.cs:112:29:112:29 | 1 | +| ExitMethods.cs:112:29:112:29 | (...) ... | ExitMethods.cs:112:29:112:29 | 1 | +| ExitMethods.cs:112:29:112:37 | ... / ... | ExitMethods.cs:112:29:112:29 | 1 | +| ExitMethods.cs:112:33:112:37 | access to parameter input | ExitMethods.cs:112:33:112:37 | access to parameter input | +| ExitMethods.cs:112:41:112:76 | throw ... | ExitMethods.cs:112:69:112:75 | "input" | +| ExitMethods.cs:112:47:112:76 | object creation of type ArgumentException | ExitMethods.cs:112:69:112:75 | "input" | +| ExitMethods.cs:112:69:112:75 | "input" | ExitMethods.cs:112:69:112:75 | "input" | +| ExitMethods.cs:116:5:118:5 | {...} | ExitMethods.cs:116:5:118:5 | {...} | +| ExitMethods.cs:117:9:117:39 | return ...; | ExitMethods.cs:117:16:117:16 | access to parameter s | +| ExitMethods.cs:117:16:117:16 | access to parameter s | ExitMethods.cs:117:16:117:16 | access to parameter s | +| ExitMethods.cs:117:16:117:30 | call to method Contains | ExitMethods.cs:117:16:117:16 | access to parameter s | +| ExitMethods.cs:117:16:117:38 | ... ? ... : ... | ExitMethods.cs:117:16:117:16 | access to parameter s | +| ExitMethods.cs:117:27:117:29 | - | ExitMethods.cs:117:27:117:29 | - | +| ExitMethods.cs:117:34:117:34 | 0 | ExitMethods.cs:117:34:117:34 | 0 | +| ExitMethods.cs:117:38:117:38 | 1 | ExitMethods.cs:117:38:117:38 | 1 | +| ExitMethods.cs:121:5:124:5 | {...} | ExitMethods.cs:121:5:124:5 | {...} | +| ExitMethods.cs:122:9:122:28 | call to method IsTrue | ExitMethods.cs:122:23:122:27 | false | +| ExitMethods.cs:122:9:122:29 | ...; | ExitMethods.cs:122:9:122:29 | ...; | +| ExitMethods.cs:122:23:122:27 | false | ExitMethods.cs:122:23:122:27 | false | +| ExitMethods.cs:123:9:123:18 | ... ...; | ExitMethods.cs:123:9:123:18 | ... ...; | +| ExitMethods.cs:123:13:123:17 | Int32 x = ... | ExitMethods.cs:123:17:123:17 | 0 | +| ExitMethods.cs:123:17:123:17 | 0 | ExitMethods.cs:123:17:123:17 | 0 | +| ExitMethods.cs:127:5:130:5 | {...} | ExitMethods.cs:127:5:130:5 | {...} | +| ExitMethods.cs:128:9:128:26 | call to method FailingAssertion | ExitMethods.cs:128:9:128:26 | this access | +| ExitMethods.cs:128:9:128:26 | this access | ExitMethods.cs:128:9:128:26 | this access | +| ExitMethods.cs:128:9:128:27 | ...; | ExitMethods.cs:128:9:128:27 | ...; | +| ExitMethods.cs:129:9:129:18 | ... ...; | ExitMethods.cs:129:9:129:18 | ... ...; | +| ExitMethods.cs:129:13:129:17 | Int32 x = ... | ExitMethods.cs:129:17:129:17 | 0 | +| ExitMethods.cs:129:17:129:17 | 0 | ExitMethods.cs:129:17:129:17 | 0 | +| ExitMethods.cs:132:33:132:49 | call to method IsFalse | ExitMethods.cs:132:48:132:48 | access to parameter b | +| ExitMethods.cs:132:48:132:48 | access to parameter b | ExitMethods.cs:132:48:132:48 | access to parameter b | +| ExitMethods.cs:135:5:138:5 | {...} | ExitMethods.cs:135:5:138:5 | {...} | +| ExitMethods.cs:136:9:136:25 | call to method AssertFalse | ExitMethods.cs:136:9:136:25 | this access | +| ExitMethods.cs:136:9:136:25 | this access | ExitMethods.cs:136:9:136:25 | this access | +| ExitMethods.cs:136:9:136:26 | ...; | ExitMethods.cs:136:9:136:26 | ...; | +| ExitMethods.cs:136:21:136:24 | true | ExitMethods.cs:136:21:136:24 | true | +| ExitMethods.cs:137:9:137:18 | ... ...; | ExitMethods.cs:137:9:137:18 | ... ...; | +| ExitMethods.cs:137:13:137:17 | Int32 x = ... | ExitMethods.cs:137:17:137:17 | 0 | +| ExitMethods.cs:137:17:137:17 | 0 | ExitMethods.cs:137:17:137:17 | 0 | +| ExitMethods.cs:141:5:147:5 | {...} | ExitMethods.cs:141:5:147:5 | {...} | +| ExitMethods.cs:142:9:145:53 | if (...) ... | ExitMethods.cs:142:9:145:53 | if (...) ... | +| ExitMethods.cs:142:13:142:13 | access to parameter b | ExitMethods.cs:142:13:142:13 | access to parameter b | +| ExitMethods.cs:143:13:143:42 | call to method Throw | ExitMethods.cs:143:41:143:41 | access to parameter e | +| ExitMethods.cs:143:13:143:43 | ...; | ExitMethods.cs:143:13:143:43 | ...; | +| ExitMethods.cs:143:41:143:41 | access to parameter e | ExitMethods.cs:143:41:143:41 | access to parameter e | +| ExitMethods.cs:145:13:145:44 | call to method Capture | ExitMethods.cs:145:43:145:43 | access to parameter e | +| ExitMethods.cs:145:13:145:52 | call to method Throw | ExitMethods.cs:145:43:145:43 | access to parameter e | +| ExitMethods.cs:145:13:145:53 | ...; | ExitMethods.cs:145:13:145:53 | ...; | +| ExitMethods.cs:145:43:145:43 | access to parameter e | ExitMethods.cs:145:43:145:43 | access to parameter e | +| ExitMethods.cs:146:9:146:33 | call to method WriteLine | ExitMethods.cs:146:27:146:32 | "dead" | +| ExitMethods.cs:146:9:146:34 | ...; | ExitMethods.cs:146:9:146:34 | ...; | +| ExitMethods.cs:146:27:146:32 | "dead" | ExitMethods.cs:146:27:146:32 | "dead" | | Extensions.cs:6:5:8:5 | {...} | Extensions.cs:6:5:8:5 | {...} | | Extensions.cs:7:9:7:30 | return ...; | Extensions.cs:7:28:7:28 | access to parameter s | | Extensions.cs:7:16:7:29 | call to method Parse | Extensions.cs:7:28:7:28 | access to parameter s | @@ -1580,6 +1590,52 @@ | Finally.cs:230:9:230:33 | call to method WriteLine | Finally.cs:230:27:230:32 | "Done" | | Finally.cs:230:9:230:34 | ...; | Finally.cs:230:9:230:34 | ...; | | Finally.cs:230:27:230:32 | "Done" | Finally.cs:230:27:230:32 | "Done" | +| Finally.cs:234:5:261:5 | {...} | Finally.cs:234:5:261:5 | {...} | +| Finally.cs:235:9:259:9 | try {...} ... | Finally.cs:235:9:259:9 | try {...} ... | +| Finally.cs:236:9:255:9 | {...} | Finally.cs:236:9:255:9 | {...} | +| Finally.cs:237:13:253:13 | try {...} ... | Finally.cs:237:13:253:13 | try {...} ... | +| Finally.cs:238:13:241:13 | {...} | Finally.cs:238:13:241:13 | {...} | +| Finally.cs:239:17:240:43 | if (...) ... | Finally.cs:239:17:240:43 | if (...) ... | +| Finally.cs:239:21:239:22 | access to parameter b1 | Finally.cs:239:21:239:22 | access to parameter b1 | +| Finally.cs:240:21:240:43 | throw ...; | Finally.cs:240:27:240:42 | object creation of type ExceptionA | +| Finally.cs:240:27:240:42 | object creation of type ExceptionA | Finally.cs:240:27:240:42 | object creation of type ExceptionA | +| Finally.cs:243:13:253:13 | {...} | Finally.cs:243:13:253:13 | {...} | +| Finally.cs:244:17:252:17 | try {...} ... | Finally.cs:244:17:252:17 | try {...} ... | +| Finally.cs:245:17:248:17 | {...} | Finally.cs:245:17:248:17 | {...} | +| Finally.cs:246:21:247:47 | if (...) ... | Finally.cs:246:21:247:47 | if (...) ... | +| Finally.cs:246:25:246:26 | access to parameter b2 | Finally.cs:246:25:246:26 | access to parameter b2 | +| Finally.cs:247:25:247:47 | throw ...; | Finally.cs:247:31:247:46 | object creation of type ExceptionA | +| Finally.cs:247:31:247:46 | object creation of type ExceptionA | Finally.cs:247:31:247:46 | object creation of type ExceptionA | +| Finally.cs:250:17:252:17 | {...} | Finally.cs:250:17:252:17 | {...} | +| Finally.cs:251:21:251:54 | call to method WriteLine | Finally.cs:251:39:251:53 | "Inner finally" | +| Finally.cs:251:21:251:55 | ...; | Finally.cs:251:21:251:55 | ...; | +| Finally.cs:251:39:251:53 | "Inner finally" | Finally.cs:251:39:251:53 | "Inner finally" | +| Finally.cs:254:13:254:44 | call to method WriteLine | Finally.cs:254:31:254:43 | "Mid finally" | +| Finally.cs:254:13:254:45 | ...; | Finally.cs:254:13:254:45 | ...; | +| Finally.cs:254:31:254:43 | "Mid finally" | Finally.cs:254:31:254:43 | "Mid finally" | +| Finally.cs:257:9:259:9 | {...} | Finally.cs:257:9:259:9 | {...} | +| Finally.cs:258:13:258:46 | call to method WriteLine | Finally.cs:258:31:258:45 | "Outer finally" | +| Finally.cs:258:13:258:47 | ...; | Finally.cs:258:13:258:47 | ...; | +| Finally.cs:258:31:258:45 | "Outer finally" | Finally.cs:258:31:258:45 | "Outer finally" | +| Finally.cs:260:9:260:33 | call to method WriteLine | Finally.cs:260:27:260:32 | "Done" | +| Finally.cs:260:9:260:34 | ...; | Finally.cs:260:9:260:34 | ...; | +| Finally.cs:260:27:260:32 | "Done" | Finally.cs:260:27:260:32 | "Done" | +| Finally.cs:264:5:274:5 | {...} | Finally.cs:264:5:274:5 | {...} | +| Finally.cs:265:9:273:9 | try {...} ... | Finally.cs:265:9:273:9 | try {...} ... | +| Finally.cs:266:9:268:9 | {...} | Finally.cs:266:9:268:9 | {...} | +| Finally.cs:267:13:267:34 | call to method WriteLine | Finally.cs:267:31:267:33 | "1" | +| Finally.cs:267:13:267:35 | ...; | Finally.cs:267:13:267:35 | ...; | +| Finally.cs:267:31:267:33 | "1" | Finally.cs:267:31:267:33 | "1" | +| Finally.cs:270:9:273:9 | {...} | Finally.cs:270:9:273:9 | {...} | +| Finally.cs:271:13:271:34 | call to method WriteLine | Finally.cs:271:31:271:33 | "3" | +| Finally.cs:271:13:271:35 | ...; | Finally.cs:271:13:271:35 | ...; | +| Finally.cs:271:31:271:33 | "3" | Finally.cs:271:31:271:33 | "3" | +| Finally.cs:272:13:272:13 | access to parameter i | Finally.cs:272:13:272:13 | access to parameter i | +| Finally.cs:272:13:272:18 | ... + ... | Finally.cs:272:13:272:13 | access to parameter i | +| Finally.cs:272:13:272:18 | ... += ... | Finally.cs:272:13:272:13 | access to parameter i | +| Finally.cs:272:13:272:18 | ... = ... | Finally.cs:272:13:272:13 | access to parameter i | +| Finally.cs:272:13:272:19 | ...; | Finally.cs:272:13:272:19 | ...; | +| Finally.cs:272:18:272:18 | 3 | Finally.cs:272:18:272:18 | 3 | | Foreach.cs:7:5:10:5 | {...} | Foreach.cs:7:5:10:5 | {...} | | Foreach.cs:8:9:9:13 | foreach (... ... in ...) ... | Foreach.cs:8:29:8:32 | access to parameter args | | Foreach.cs:8:22:8:24 | String arg | Foreach.cs:8:22:8:24 | String arg | @@ -1601,9 +1657,7 @@ | Foreach.cs:25:5:28:5 | {...} | Foreach.cs:25:5:28:5 | {...} | | Foreach.cs:26:9:27:11 | foreach (... ... in ...) ... | Foreach.cs:26:36:26:39 | access to parameter args | | Foreach.cs:26:18:26:31 | (..., ...) | Foreach.cs:26:23:26:23 | String x | -| Foreach.cs:26:19:26:23 | 1 | Foreach.cs:26:19:26:23 | 1 | | Foreach.cs:26:23:26:23 | String x | Foreach.cs:26:23:26:23 | String x | -| Foreach.cs:26:26:26:30 | 1 | Foreach.cs:26:26:26:30 | 1 | | Foreach.cs:26:30:26:30 | Int32 y | Foreach.cs:26:30:26:30 | Int32 y | | Foreach.cs:26:36:26:39 | access to parameter args | Foreach.cs:26:36:26:39 | access to parameter args | | Foreach.cs:27:11:27:11 | ; | Foreach.cs:27:11:27:11 | ; | @@ -2170,6 +2224,100 @@ | Patterns.cs:37:17:37:22 | break; | Patterns.cs:37:17:37:22 | break; | | Patterns.cs:40:9:42:9 | switch (...) {...} | Patterns.cs:40:9:42:9 | switch (...) {...} | | Patterns.cs:40:17:40:17 | access to local variable o | Patterns.cs:40:17:40:17 | access to local variable o | +| Patterns.cs:48:9:48:9 | access to parameter c | Patterns.cs:48:9:48:9 | access to parameter c | +| Patterns.cs:48:9:48:20 | ... is ... | Patterns.cs:48:9:48:9 | access to parameter c | +| Patterns.cs:48:14:48:20 | not ... | Patterns.cs:48:18:48:20 | a | +| Patterns.cs:48:18:48:20 | a | Patterns.cs:48:18:48:20 | a | +| Patterns.cs:51:9:51:9 | access to parameter c | Patterns.cs:51:9:51:9 | access to parameter c | +| Patterns.cs:51:9:51:21 | ... is ... | Patterns.cs:51:9:51:9 | access to parameter c | +| Patterns.cs:51:9:51:39 | ... ? ... : ... | Patterns.cs:51:9:51:9 | access to parameter c | +| Patterns.cs:51:14:51:21 | not ... | Patterns.cs:51:18:51:21 | null | +| Patterns.cs:51:18:51:21 | null | Patterns.cs:51:18:51:21 | null | +| Patterns.cs:51:25:51:25 | access to parameter c | Patterns.cs:51:25:51:25 | access to parameter c | +| Patterns.cs:51:25:51:30 | ... is ... | Patterns.cs:51:25:51:25 | access to parameter c | +| Patterns.cs:51:30:51:30 | 1 | Patterns.cs:51:30:51:30 | 1 | +| Patterns.cs:51:34:51:34 | access to parameter c | Patterns.cs:51:34:51:34 | access to parameter c | +| Patterns.cs:51:34:51:39 | ... is ... | Patterns.cs:51:34:51:34 | access to parameter c | +| Patterns.cs:51:39:51:39 | 2 | Patterns.cs:51:39:51:39 | 2 | +| Patterns.cs:54:9:54:9 | access to parameter c | Patterns.cs:54:9:54:9 | access to parameter c | +| Patterns.cs:54:9:54:37 | ... is ... | Patterns.cs:54:9:54:9 | access to parameter c | +| Patterns.cs:54:14:54:37 | not ... | Patterns.cs:54:18:54:37 | Patterns u | +| Patterns.cs:54:18:54:25 | access to type Patterns | Patterns.cs:54:18:54:25 | access to type Patterns | +| Patterns.cs:54:18:54:37 | Patterns u | Patterns.cs:54:18:54:37 | Patterns u | +| Patterns.cs:54:18:54:37 | { ... } | Patterns.cs:54:18:54:37 | Patterns u | +| Patterns.cs:54:27:54:35 | { ... } | Patterns.cs:54:33:54:33 | 1 | +| Patterns.cs:54:33:54:33 | 1 | Patterns.cs:54:33:54:33 | 1 | +| Patterns.cs:57:5:63:5 | {...} | Patterns.cs:57:5:63:5 | {...} | +| Patterns.cs:58:9:62:10 | return ...; | Patterns.cs:58:16:58:16 | access to parameter i | +| Patterns.cs:58:16:58:16 | access to parameter i | Patterns.cs:58:16:58:16 | access to parameter i | +| Patterns.cs:58:16:62:9 | ... switch { ... } | Patterns.cs:58:16:58:16 | access to parameter i | +| Patterns.cs:60:13:60:17 | not ... | Patterns.cs:60:17:60:17 | 1 | +| Patterns.cs:60:13:60:28 | ... => ... | Patterns.cs:60:17:60:17 | 1 | +| Patterns.cs:60:17:60:17 | 1 | Patterns.cs:60:17:60:17 | 1 | +| Patterns.cs:60:22:60:28 | "not 1" | Patterns.cs:60:22:60:28 | "not 1" | +| Patterns.cs:61:13:61:13 | _ | Patterns.cs:61:13:61:13 | _ | +| Patterns.cs:61:13:61:24 | ... => ... | Patterns.cs:61:13:61:13 | _ | +| Patterns.cs:61:18:61:24 | "other" | Patterns.cs:61:18:61:24 | "other" | +| Patterns.cs:66:5:72:5 | {...} | Patterns.cs:66:5:72:5 | {...} | +| Patterns.cs:67:9:71:10 | return ...; | Patterns.cs:67:16:67:16 | 2 | +| Patterns.cs:67:16:67:16 | 2 | Patterns.cs:67:16:67:16 | 2 | +| Patterns.cs:67:16:71:9 | ... switch { ... } | Patterns.cs:67:16:67:16 | 2 | +| Patterns.cs:69:13:69:17 | not ... | Patterns.cs:69:17:69:17 | 2 | +| Patterns.cs:69:13:69:33 | ... => ... | Patterns.cs:69:17:69:17 | 2 | +| Patterns.cs:69:17:69:17 | 2 | Patterns.cs:69:17:69:17 | 2 | +| Patterns.cs:69:22:69:33 | "impossible" | Patterns.cs:69:22:69:33 | "impossible" | +| Patterns.cs:70:13:70:13 | 2 | Patterns.cs:70:13:70:13 | 2 | +| Patterns.cs:70:13:70:27 | ... => ... | Patterns.cs:70:13:70:13 | 2 | +| Patterns.cs:70:18:70:27 | "possible" | Patterns.cs:70:18:70:27 | "possible" | +| Patterns.cs:75:5:83:5 | {...} | Patterns.cs:75:5:83:5 | {...} | +| Patterns.cs:76:9:82:10 | return ...; | Patterns.cs:76:16:76:16 | access to parameter i | +| Patterns.cs:76:16:76:16 | access to parameter i | Patterns.cs:76:16:76:16 | access to parameter i | +| Patterns.cs:76:16:82:9 | ... switch { ... } | Patterns.cs:76:16:76:16 | access to parameter i | +| Patterns.cs:78:13:78:15 | > ... | Patterns.cs:78:15:78:15 | 1 | +| Patterns.cs:78:13:78:24 | ... => ... | Patterns.cs:78:15:78:15 | 1 | +| Patterns.cs:78:15:78:15 | 1 | Patterns.cs:78:15:78:15 | 1 | +| Patterns.cs:78:20:78:24 | "> 1" | Patterns.cs:78:20:78:24 | "> 1" | +| Patterns.cs:79:13:79:15 | < ... | Patterns.cs:79:15:79:15 | 0 | +| Patterns.cs:79:13:79:24 | ... => ... | Patterns.cs:79:15:79:15 | 0 | +| Patterns.cs:79:15:79:15 | 0 | Patterns.cs:79:15:79:15 | 0 | +| Patterns.cs:79:20:79:24 | "< 0" | Patterns.cs:79:20:79:24 | "< 0" | +| Patterns.cs:80:13:80:13 | 1 | Patterns.cs:80:13:80:13 | 1 | +| Patterns.cs:80:13:80:20 | ... => ... | Patterns.cs:80:13:80:13 | 1 | +| Patterns.cs:80:18:80:20 | "1" | Patterns.cs:80:18:80:20 | "1" | +| Patterns.cs:81:13:81:13 | _ | Patterns.cs:81:13:81:13 | _ | +| Patterns.cs:81:13:81:20 | ... => ... | Patterns.cs:81:13:81:13 | _ | +| Patterns.cs:81:18:81:20 | "0" | Patterns.cs:81:18:81:20 | "0" | +| Patterns.cs:85:39:85:39 | access to parameter i | Patterns.cs:85:39:85:39 | access to parameter i | +| Patterns.cs:85:39:85:53 | ... is ... | Patterns.cs:85:39:85:39 | access to parameter i | +| Patterns.cs:85:39:85:69 | ... ? ... : ... | Patterns.cs:85:39:85:39 | access to parameter i | +| Patterns.cs:85:44:85:44 | 1 | Patterns.cs:85:44:85:44 | 1 | +| Patterns.cs:85:44:85:53 | ... or ... | Patterns.cs:85:44:85:44 | 1 | +| Patterns.cs:85:49:85:53 | not ... | Patterns.cs:85:53:85:53 | 2 | +| Patterns.cs:85:53:85:53 | 2 | Patterns.cs:85:53:85:53 | 2 | +| Patterns.cs:85:57:85:63 | "not 2" | Patterns.cs:85:57:85:63 | "not 2" | +| Patterns.cs:85:67:85:69 | "2" | Patterns.cs:85:67:85:69 | "2" | +| Patterns.cs:87:39:87:39 | access to parameter i | Patterns.cs:87:39:87:39 | access to parameter i | +| Patterns.cs:87:39:87:54 | ... is ... | Patterns.cs:87:39:87:39 | access to parameter i | +| Patterns.cs:87:39:87:70 | ... ? ... : ... | Patterns.cs:87:39:87:39 | access to parameter i | +| Patterns.cs:87:44:87:44 | 1 | Patterns.cs:87:44:87:44 | 1 | +| Patterns.cs:87:44:87:54 | ... and ... | Patterns.cs:87:44:87:44 | 1 | +| Patterns.cs:87:50:87:54 | not ... | Patterns.cs:87:54:87:54 | 2 | +| Patterns.cs:87:54:87:54 | 2 | Patterns.cs:87:54:87:54 | 2 | +| Patterns.cs:87:58:87:60 | "1" | Patterns.cs:87:58:87:60 | "1" | +| Patterns.cs:87:64:87:70 | "not 1" | Patterns.cs:87:64:87:70 | "not 1" | +| Patterns.cs:94:5:99:5 | {...} | Patterns.cs:94:5:99:5 | {...} | +| Patterns.cs:95:9:98:9 | if (...) ... | Patterns.cs:95:9:98:9 | if (...) ... | +| Patterns.cs:95:13:95:16 | this access | Patterns.cs:95:13:95:16 | this access | +| Patterns.cs:95:13:95:40 | ... is ... | Patterns.cs:95:13:95:16 | this access | +| Patterns.cs:95:21:95:40 | { ... } | Patterns.cs:95:29:95:31 | access to constant A | +| Patterns.cs:95:21:95:40 | { ... } | Patterns.cs:95:29:95:31 | access to constant A | +| Patterns.cs:95:29:95:31 | access to constant A | Patterns.cs:95:29:95:31 | access to constant A | +| Patterns.cs:95:29:95:38 | ... or ... | Patterns.cs:95:29:95:31 | access to constant A | +| Patterns.cs:95:36:95:38 | access to constant B | Patterns.cs:95:36:95:38 | access to constant B | +| Patterns.cs:96:9:98:9 | {...} | Patterns.cs:96:9:98:9 | {...} | +| Patterns.cs:97:13:97:38 | call to method WriteLine | Patterns.cs:97:31:97:37 | "not C" | +| Patterns.cs:97:13:97:39 | ...; | Patterns.cs:97:13:97:39 | ...; | +| Patterns.cs:97:31:97:37 | "not C" | Patterns.cs:97:31:97:37 | "not C" | | PostDominance.cs:6:5:8:5 | {...} | PostDominance.cs:6:5:8:5 | {...} | | PostDominance.cs:7:9:7:28 | call to method WriteLine | PostDominance.cs:7:27:7:27 | access to parameter s | | PostDominance.cs:7:9:7:29 | ...; | PostDominance.cs:7:9:7:29 | ...; | diff --git a/csharp/ql/test/library-tests/controlflow/graph/ExitElement.expected b/csharp/ql/test/library-tests/controlflow/graph/ExitElement.expected index 63de557d245..df6d8eb416f 100644 --- a/csharp/ql/test/library-tests/controlflow/graph/ExitElement.expected +++ b/csharp/ql/test/library-tests/controlflow/graph/ExitElement.expected @@ -189,7 +189,6 @@ | AccessorCalls.cs:58:22:58:25 | this access | AccessorCalls.cs:58:22:58:25 | this access | normal | | AccessorCalls.cs:58:22:58:30 | access to property Prop | AccessorCalls.cs:58:22:58:25 | this access | normal | | AccessorCalls.cs:58:33:58:44 | (..., ...) | AccessorCalls.cs:58:33:58:44 | (..., ...) | normal | -| AccessorCalls.cs:58:34:58:34 | 1 | AccessorCalls.cs:58:34:58:34 | 1 | normal | | AccessorCalls.cs:58:37:58:40 | this access | AccessorCalls.cs:58:37:58:40 | this access | normal | | AccessorCalls.cs:58:37:58:43 | access to indexer | AccessorCalls.cs:58:42:58:42 | 0 | normal | | AccessorCalls.cs:58:42:58:42 | 0 | AccessorCalls.cs:58:42:58:42 | 0 | normal | @@ -788,8 +787,6 @@ | Assert.cs:128:9:128:36 | ...; | Assert.cs:128:9:128:35 | call to method WriteLine | normal | | Assert.cs:128:27:128:27 | access to local variable s | Assert.cs:128:27:128:27 | access to local variable s | normal | | Assert.cs:128:27:128:34 | access to property Length | Assert.cs:128:27:128:34 | access to property Length | normal | -| Assert.cs:132:61:132:65 | false | Assert.cs:132:61:132:65 | false | normal | -| Assert.cs:133:61:133:64 | true | Assert.cs:133:61:133:64 | true | normal | | Assert.cs:135:5:136:5 | {...} | Assert.cs:135:5:136:5 | {...} | normal | | Assert.cs:139:5:142:5 | {...} | Assert.cs:140:9:140:35 | call to method AssertTrueFalse | throw(Exception) | | Assert.cs:139:5:142:5 | {...} | Assert.cs:141:9:141:15 | return ...; | return | @@ -847,9 +844,9 @@ | BreakInTry.cs:5:9:17:9 | try {...} ... | BreakInTry.cs:15:17:15:28 | ... == ... | false | | BreakInTry.cs:5:9:17:9 | try {...} ... | BreakInTry.cs:16:17:16:17 | ; | normal | | BreakInTry.cs:6:9:12:9 | {...} | BreakInTry.cs:7:13:11:13 | foreach (... ... in ...) ... | empty | -| BreakInTry.cs:6:9:12:9 | {...} | BreakInTry.cs:10:21:10:26 | break; | normal [break] | +| BreakInTry.cs:6:9:12:9 | {...} | BreakInTry.cs:10:21:10:26 | break; | normal [break] (0) | | BreakInTry.cs:7:13:11:13 | foreach (... ... in ...) ... | BreakInTry.cs:7:13:11:13 | foreach (... ... in ...) ... | empty | -| BreakInTry.cs:7:13:11:13 | foreach (... ... in ...) ... | BreakInTry.cs:10:21:10:26 | break; | normal [break] | +| BreakInTry.cs:7:13:11:13 | foreach (... ... in ...) ... | BreakInTry.cs:10:21:10:26 | break; | normal [break] (0) | | BreakInTry.cs:7:26:7:28 | String arg | BreakInTry.cs:7:26:7:28 | String arg | normal | | BreakInTry.cs:7:33:7:36 | access to parameter args | BreakInTry.cs:7:33:7:36 | access to parameter args | normal | | BreakInTry.cs:8:13:11:13 | {...} | BreakInTry.cs:9:21:9:31 | ... == ... | false | @@ -872,17 +869,17 @@ | BreakInTry.cs:16:17:16:17 | ; | BreakInTry.cs:16:17:16:17 | ; | normal | | BreakInTry.cs:21:5:36:5 | {...} | BreakInTry.cs:35:7:35:7 | ; | normal | | BreakInTry.cs:22:9:34:9 | foreach (... ... in ...) ... | BreakInTry.cs:22:9:34:9 | foreach (... ... in ...) ... | empty | -| BreakInTry.cs:22:9:34:9 | foreach (... ... in ...) ... | BreakInTry.cs:31:21:31:32 | ... == ... | false [break] | -| BreakInTry.cs:22:9:34:9 | foreach (... ... in ...) ... | BreakInTry.cs:32:21:32:21 | ; | normal [break] | +| BreakInTry.cs:22:9:34:9 | foreach (... ... in ...) ... | BreakInTry.cs:31:21:31:32 | ... == ... | false [break] (0) | +| BreakInTry.cs:22:9:34:9 | foreach (... ... in ...) ... | BreakInTry.cs:32:21:32:21 | ; | normal [break] (0) | | BreakInTry.cs:22:22:22:24 | String arg | BreakInTry.cs:22:22:22:24 | String arg | normal | | BreakInTry.cs:22:29:22:32 | access to parameter args | BreakInTry.cs:22:29:22:32 | access to parameter args | normal | -| BreakInTry.cs:23:9:34:9 | {...} | BreakInTry.cs:31:21:31:32 | ... == ... | break [false] | +| BreakInTry.cs:23:9:34:9 | {...} | BreakInTry.cs:31:21:31:32 | ... == ... | break [false] (0) | | BreakInTry.cs:23:9:34:9 | {...} | BreakInTry.cs:31:21:31:32 | ... == ... | false | -| BreakInTry.cs:23:9:34:9 | {...} | BreakInTry.cs:32:21:32:21 | ; | break [normal] | +| BreakInTry.cs:23:9:34:9 | {...} | BreakInTry.cs:32:21:32:21 | ; | break [normal] (0) | | BreakInTry.cs:23:9:34:9 | {...} | BreakInTry.cs:32:21:32:21 | ; | normal | -| BreakInTry.cs:24:13:33:13 | try {...} ... | BreakInTry.cs:31:21:31:32 | ... == ... | break [false] | +| BreakInTry.cs:24:13:33:13 | try {...} ... | BreakInTry.cs:31:21:31:32 | ... == ... | break [false] (0) | | BreakInTry.cs:24:13:33:13 | try {...} ... | BreakInTry.cs:31:21:31:32 | ... == ... | false | -| BreakInTry.cs:24:13:33:13 | try {...} ... | BreakInTry.cs:32:21:32:21 | ; | break [normal] | +| BreakInTry.cs:24:13:33:13 | try {...} ... | BreakInTry.cs:32:21:32:21 | ; | break [normal] (0) | | BreakInTry.cs:24:13:33:13 | try {...} ... | BreakInTry.cs:32:21:32:21 | ; | normal | | BreakInTry.cs:25:13:28:13 | {...} | BreakInTry.cs:26:21:26:31 | ... == ... | false | | BreakInTry.cs:25:13:28:13 | {...} | BreakInTry.cs:27:21:27:26 | break; | break | @@ -903,13 +900,13 @@ | BreakInTry.cs:31:29:31:32 | null | BreakInTry.cs:31:29:31:32 | null | normal | | BreakInTry.cs:32:21:32:21 | ; | BreakInTry.cs:32:21:32:21 | ; | normal | | BreakInTry.cs:35:7:35:7 | ; | BreakInTry.cs:35:7:35:7 | ; | normal | -| BreakInTry.cs:39:5:54:5 | {...} | BreakInTry.cs:47:13:51:13 | foreach (... ... in ...) ... | return [empty] | -| BreakInTry.cs:39:5:54:5 | {...} | BreakInTry.cs:50:21:50:26 | break; | return [normal] | +| BreakInTry.cs:39:5:54:5 | {...} | BreakInTry.cs:47:13:51:13 | foreach (... ... in ...) ... | return [empty] (0) | +| BreakInTry.cs:39:5:54:5 | {...} | BreakInTry.cs:50:21:50:26 | break; | return [normal] (0) | | BreakInTry.cs:39:5:54:5 | {...} | BreakInTry.cs:53:7:53:7 | ; | normal | | BreakInTry.cs:40:9:52:9 | try {...} ... | BreakInTry.cs:47:13:51:13 | foreach (... ... in ...) ... | empty | -| BreakInTry.cs:40:9:52:9 | try {...} ... | BreakInTry.cs:47:13:51:13 | foreach (... ... in ...) ... | return [empty] | -| BreakInTry.cs:40:9:52:9 | try {...} ... | BreakInTry.cs:50:21:50:26 | break; | normal [break] | -| BreakInTry.cs:40:9:52:9 | try {...} ... | BreakInTry.cs:50:21:50:26 | break; | return [normal] | +| BreakInTry.cs:40:9:52:9 | try {...} ... | BreakInTry.cs:47:13:51:13 | foreach (... ... in ...) ... | return [empty] (0) | +| BreakInTry.cs:40:9:52:9 | try {...} ... | BreakInTry.cs:50:21:50:26 | break; | normal [break] (0) | +| BreakInTry.cs:40:9:52:9 | try {...} ... | BreakInTry.cs:50:21:50:26 | break; | return [normal] (0) | | BreakInTry.cs:41:9:44:9 | {...} | BreakInTry.cs:42:17:42:28 | ... == ... | false | | BreakInTry.cs:41:9:44:9 | {...} | BreakInTry.cs:43:17:43:23 | return ...; | return | | BreakInTry.cs:42:13:43:23 | if (...) ... | BreakInTry.cs:42:17:42:28 | ... == ... | false | @@ -920,9 +917,9 @@ | BreakInTry.cs:42:25:42:28 | null | BreakInTry.cs:42:25:42:28 | null | normal | | BreakInTry.cs:43:17:43:23 | return ...; | BreakInTry.cs:43:17:43:23 | return ...; | return | | BreakInTry.cs:46:9:52:9 | {...} | BreakInTry.cs:47:13:51:13 | foreach (... ... in ...) ... | empty | -| BreakInTry.cs:46:9:52:9 | {...} | BreakInTry.cs:50:21:50:26 | break; | normal [break] | +| BreakInTry.cs:46:9:52:9 | {...} | BreakInTry.cs:50:21:50:26 | break; | normal [break] (0) | | BreakInTry.cs:47:13:51:13 | foreach (... ... in ...) ... | BreakInTry.cs:47:13:51:13 | foreach (... ... in ...) ... | empty | -| BreakInTry.cs:47:13:51:13 | foreach (... ... in ...) ... | BreakInTry.cs:50:21:50:26 | break; | normal [break] | +| BreakInTry.cs:47:13:51:13 | foreach (... ... in ...) ... | BreakInTry.cs:50:21:50:26 | break; | normal [break] (0) | | BreakInTry.cs:47:26:47:28 | String arg | BreakInTry.cs:47:26:47:28 | String arg | normal | | BreakInTry.cs:47:33:47:36 | access to parameter args | BreakInTry.cs:47:33:47:36 | access to parameter args | normal | | BreakInTry.cs:48:13:51:13 | {...} | BreakInTry.cs:49:21:49:31 | ... == ... | false | @@ -936,13 +933,13 @@ | BreakInTry.cs:50:21:50:26 | break; | BreakInTry.cs:50:21:50:26 | break; | break | | BreakInTry.cs:53:7:53:7 | ; | BreakInTry.cs:53:7:53:7 | ; | normal | | BreakInTry.cs:57:5:71:5 | {...} | BreakInTry.cs:65:13:69:13 | foreach (... ... in ...) ... | empty | -| BreakInTry.cs:57:5:71:5 | {...} | BreakInTry.cs:65:13:69:13 | foreach (... ... in ...) ... | return [empty] | -| BreakInTry.cs:57:5:71:5 | {...} | BreakInTry.cs:68:21:68:26 | break; | normal [break] | -| BreakInTry.cs:57:5:71:5 | {...} | BreakInTry.cs:68:21:68:26 | break; | return [normal] | +| BreakInTry.cs:57:5:71:5 | {...} | BreakInTry.cs:65:13:69:13 | foreach (... ... in ...) ... | return [empty] (0) | +| BreakInTry.cs:57:5:71:5 | {...} | BreakInTry.cs:68:21:68:26 | break; | normal [break] (0) | +| BreakInTry.cs:57:5:71:5 | {...} | BreakInTry.cs:68:21:68:26 | break; | return [normal] (0) | | BreakInTry.cs:58:9:70:9 | try {...} ... | BreakInTry.cs:65:13:69:13 | foreach (... ... in ...) ... | empty | -| BreakInTry.cs:58:9:70:9 | try {...} ... | BreakInTry.cs:65:13:69:13 | foreach (... ... in ...) ... | return [empty] | -| BreakInTry.cs:58:9:70:9 | try {...} ... | BreakInTry.cs:68:21:68:26 | break; | normal [break] | -| BreakInTry.cs:58:9:70:9 | try {...} ... | BreakInTry.cs:68:21:68:26 | break; | return [normal] | +| BreakInTry.cs:58:9:70:9 | try {...} ... | BreakInTry.cs:65:13:69:13 | foreach (... ... in ...) ... | return [empty] (0) | +| BreakInTry.cs:58:9:70:9 | try {...} ... | BreakInTry.cs:68:21:68:26 | break; | normal [break] (0) | +| BreakInTry.cs:58:9:70:9 | try {...} ... | BreakInTry.cs:68:21:68:26 | break; | return [normal] (0) | | BreakInTry.cs:59:9:62:9 | {...} | BreakInTry.cs:60:17:60:28 | ... == ... | false | | BreakInTry.cs:59:9:62:9 | {...} | BreakInTry.cs:61:17:61:23 | return ...; | return | | BreakInTry.cs:60:13:61:23 | if (...) ... | BreakInTry.cs:60:17:60:28 | ... == ... | false | @@ -953,9 +950,9 @@ | BreakInTry.cs:60:25:60:28 | null | BreakInTry.cs:60:25:60:28 | null | normal | | BreakInTry.cs:61:17:61:23 | return ...; | BreakInTry.cs:61:17:61:23 | return ...; | return | | BreakInTry.cs:64:9:70:9 | {...} | BreakInTry.cs:65:13:69:13 | foreach (... ... in ...) ... | empty | -| BreakInTry.cs:64:9:70:9 | {...} | BreakInTry.cs:68:21:68:26 | break; | normal [break] | +| BreakInTry.cs:64:9:70:9 | {...} | BreakInTry.cs:68:21:68:26 | break; | normal [break] (0) | | BreakInTry.cs:65:13:69:13 | foreach (... ... in ...) ... | BreakInTry.cs:65:13:69:13 | foreach (... ... in ...) ... | empty | -| BreakInTry.cs:65:13:69:13 | foreach (... ... in ...) ... | BreakInTry.cs:68:21:68:26 | break; | normal [break] | +| BreakInTry.cs:65:13:69:13 | foreach (... ... in ...) ... | BreakInTry.cs:68:21:68:26 | break; | normal [break] (0) | | BreakInTry.cs:65:26:65:28 | String arg | BreakInTry.cs:65:26:65:28 | String arg | normal | | BreakInTry.cs:65:33:65:36 | access to parameter args | BreakInTry.cs:65:33:65:36 | access to parameter args | normal | | BreakInTry.cs:66:13:69:13 | {...} | BreakInTry.cs:67:21:67:31 | ... == ... | false | @@ -980,27 +977,21 @@ | CompileTimeOperators.cs:22:9:22:25 | return ...; | CompileTimeOperators.cs:22:9:22:25 | return ...; | return | | CompileTimeOperators.cs:22:16:22:24 | nameof(...) | CompileTimeOperators.cs:22:16:22:24 | nameof(...) | normal | | CompileTimeOperators.cs:22:23:22:23 | access to parameter i | CompileTimeOperators.cs:22:23:22:23 | access to parameter i | normal | -| CompileTimeOperators.cs:29:5:41:5 | {...} | CompileTimeOperators.cs:37:13:37:40 | call to method WriteLine | goto(End) [normal] | -| CompileTimeOperators.cs:29:5:41:5 | {...} | CompileTimeOperators.cs:37:13:37:40 | call to method WriteLine | throw(Exception) [normal] | -| CompileTimeOperators.cs:29:5:41:5 | {...} | CompileTimeOperators.cs:37:13:37:40 | call to method WriteLine | throw(OutOfMemoryException) [normal] | +| CompileTimeOperators.cs:29:5:41:5 | {...} | CompileTimeOperators.cs:37:13:37:40 | call to method WriteLine | goto(End) [normal] (0) | +| CompileTimeOperators.cs:29:5:41:5 | {...} | CompileTimeOperators.cs:37:13:37:40 | call to method WriteLine | throw(Exception) [normal] (0) | | CompileTimeOperators.cs:29:5:41:5 | {...} | CompileTimeOperators.cs:40:14:40:37 | call to method WriteLine | normal | -| CompileTimeOperators.cs:30:9:38:9 | try {...} ... | CompileTimeOperators.cs:37:13:37:40 | call to method WriteLine | goto(End) [normal] | +| CompileTimeOperators.cs:30:9:38:9 | try {...} ... | CompileTimeOperators.cs:37:13:37:40 | call to method WriteLine | goto(End) [normal] (0) | | CompileTimeOperators.cs:30:9:38:9 | try {...} ... | CompileTimeOperators.cs:37:13:37:40 | call to method WriteLine | normal | -| CompileTimeOperators.cs:30:9:38:9 | try {...} ... | CompileTimeOperators.cs:37:13:37:40 | call to method WriteLine | throw(Exception) [normal] | -| CompileTimeOperators.cs:30:9:38:9 | try {...} ... | CompileTimeOperators.cs:37:13:37:40 | call to method WriteLine | throw(OutOfMemoryException) [normal] | +| CompileTimeOperators.cs:30:9:38:9 | try {...} ... | CompileTimeOperators.cs:37:13:37:40 | call to method WriteLine | throw(Exception) [normal] (0) | | CompileTimeOperators.cs:31:9:34:9 | {...} | CompileTimeOperators.cs:32:13:32:21 | goto ...; | goto(End) | | CompileTimeOperators.cs:31:9:34:9 | {...} | CompileTimeOperators.cs:33:13:33:37 | call to method WriteLine | normal | | CompileTimeOperators.cs:31:9:34:9 | {...} | CompileTimeOperators.cs:33:13:33:37 | call to method WriteLine | throw(Exception) | -| CompileTimeOperators.cs:31:9:34:9 | {...} | CompileTimeOperators.cs:33:31:33:36 | "Dead" | throw(OutOfMemoryException) | | CompileTimeOperators.cs:32:13:32:21 | goto ...; | CompileTimeOperators.cs:32:13:32:21 | goto ...; | goto(End) | | CompileTimeOperators.cs:33:13:33:37 | call to method WriteLine | CompileTimeOperators.cs:33:13:33:37 | call to method WriteLine | normal | | CompileTimeOperators.cs:33:13:33:37 | call to method WriteLine | CompileTimeOperators.cs:33:13:33:37 | call to method WriteLine | throw(Exception) | -| CompileTimeOperators.cs:33:13:33:37 | call to method WriteLine | CompileTimeOperators.cs:33:31:33:36 | "Dead" | throw(OutOfMemoryException) | | CompileTimeOperators.cs:33:13:33:38 | ...; | CompileTimeOperators.cs:33:13:33:37 | call to method WriteLine | normal | | CompileTimeOperators.cs:33:13:33:38 | ...; | CompileTimeOperators.cs:33:13:33:37 | call to method WriteLine | throw(Exception) | -| CompileTimeOperators.cs:33:13:33:38 | ...; | CompileTimeOperators.cs:33:31:33:36 | "Dead" | throw(OutOfMemoryException) | | CompileTimeOperators.cs:33:31:33:36 | "Dead" | CompileTimeOperators.cs:33:31:33:36 | "Dead" | normal | -| CompileTimeOperators.cs:33:31:33:36 | "Dead" | CompileTimeOperators.cs:33:31:33:36 | "Dead" | throw(OutOfMemoryException) | | CompileTimeOperators.cs:36:9:38:9 | {...} | CompileTimeOperators.cs:37:13:37:40 | call to method WriteLine | normal | | CompileTimeOperators.cs:37:13:37:40 | call to method WriteLine | CompileTimeOperators.cs:37:13:37:40 | call to method WriteLine | normal | | CompileTimeOperators.cs:37:13:37:41 | ...; | CompileTimeOperators.cs:37:13:37:40 | call to method WriteLine | normal | @@ -1449,164 +1440,179 @@ | Conditions.cs:149:38:149:47 | $"..." | Conditions.cs:149:38:149:47 | $"..." | normal | | Conditions.cs:149:40:149:43 | "b = " | Conditions.cs:149:40:149:43 | "b = " | normal | | Conditions.cs:149:45:149:45 | access to local variable s | Conditions.cs:149:45:149:45 | access to local variable s | normal | -| ExitMethods.cs:8:5:11:5 | {...} | ExitMethods.cs:10:9:10:15 | return ...; | return | -| ExitMethods.cs:9:9:9:24 | call to method ErrorMaybe | ExitMethods.cs:9:9:9:24 | call to method ErrorMaybe | normal | -| ExitMethods.cs:9:9:9:25 | ...; | ExitMethods.cs:9:9:9:24 | call to method ErrorMaybe | normal | -| ExitMethods.cs:9:20:9:23 | true | ExitMethods.cs:9:20:9:23 | true | normal | -| ExitMethods.cs:10:9:10:15 | return ...; | ExitMethods.cs:10:9:10:15 | return ...; | return | -| ExitMethods.cs:14:5:17:5 | {...} | ExitMethods.cs:16:9:16:15 | return ...; | return | -| ExitMethods.cs:15:9:15:25 | call to method ErrorMaybe | ExitMethods.cs:15:9:15:25 | call to method ErrorMaybe | normal | -| ExitMethods.cs:15:9:15:26 | ...; | ExitMethods.cs:15:9:15:25 | call to method ErrorMaybe | normal | -| ExitMethods.cs:15:20:15:24 | false | ExitMethods.cs:15:20:15:24 | false | normal | -| ExitMethods.cs:16:9:16:15 | return ...; | ExitMethods.cs:16:9:16:15 | return ...; | return | -| ExitMethods.cs:20:5:23:5 | {...} | ExitMethods.cs:21:9:21:25 | call to method ErrorAlways | throw(ArgumentException) | -| ExitMethods.cs:20:5:23:5 | {...} | ExitMethods.cs:21:9:21:25 | call to method ErrorAlways | throw(Exception) | -| ExitMethods.cs:20:5:23:5 | {...} | ExitMethods.cs:22:9:22:15 | return ...; | return | -| ExitMethods.cs:21:9:21:25 | call to method ErrorAlways | ExitMethods.cs:21:9:21:25 | call to method ErrorAlways | throw(ArgumentException) | -| ExitMethods.cs:21:9:21:25 | call to method ErrorAlways | ExitMethods.cs:21:9:21:25 | call to method ErrorAlways | throw(Exception) | -| ExitMethods.cs:21:9:21:26 | ...; | ExitMethods.cs:21:9:21:25 | call to method ErrorAlways | throw(ArgumentException) | -| ExitMethods.cs:21:9:21:26 | ...; | ExitMethods.cs:21:9:21:25 | call to method ErrorAlways | throw(Exception) | -| ExitMethods.cs:21:21:21:24 | true | ExitMethods.cs:21:21:21:24 | true | normal | -| ExitMethods.cs:22:9:22:15 | return ...; | ExitMethods.cs:22:9:22:15 | return ...; | return | -| ExitMethods.cs:26:5:29:5 | {...} | ExitMethods.cs:27:9:27:14 | call to method Exit | exit | -| ExitMethods.cs:26:5:29:5 | {...} | ExitMethods.cs:28:9:28:15 | return ...; | return | -| ExitMethods.cs:27:9:27:14 | call to method Exit | ExitMethods.cs:27:9:27:14 | call to method Exit | exit | -| ExitMethods.cs:27:9:27:14 | this access | ExitMethods.cs:27:9:27:14 | this access | normal | -| ExitMethods.cs:27:9:27:15 | ...; | ExitMethods.cs:27:9:27:14 | call to method Exit | exit | -| ExitMethods.cs:28:9:28:15 | return ...; | ExitMethods.cs:28:9:28:15 | return ...; | return | -| ExitMethods.cs:32:5:35:5 | {...} | ExitMethods.cs:33:9:33:25 | call to method ApplicationExit | exit | -| ExitMethods.cs:32:5:35:5 | {...} | ExitMethods.cs:34:9:34:15 | return ...; | return | -| ExitMethods.cs:33:9:33:25 | call to method ApplicationExit | ExitMethods.cs:33:9:33:25 | call to method ApplicationExit | exit | -| ExitMethods.cs:33:9:33:25 | this access | ExitMethods.cs:33:9:33:25 | this access | normal | -| ExitMethods.cs:33:9:33:26 | ...; | ExitMethods.cs:33:9:33:25 | call to method ApplicationExit | exit | -| ExitMethods.cs:34:9:34:15 | return ...; | ExitMethods.cs:34:9:34:15 | return ...; | return | -| ExitMethods.cs:38:5:51:5 | {...} | ExitMethods.cs:45:13:45:19 | return ...; | return | -| ExitMethods.cs:38:5:51:5 | {...} | ExitMethods.cs:49:13:49:19 | return ...; | return | -| ExitMethods.cs:39:9:50:9 | try {...} ... | ExitMethods.cs:45:13:45:19 | return ...; | return | -| ExitMethods.cs:39:9:50:9 | try {...} ... | ExitMethods.cs:49:13:49:19 | return ...; | return | -| ExitMethods.cs:40:9:42:9 | {...} | ExitMethods.cs:41:13:41:30 | call to method ErrorAlways | throw(ArgumentException) | -| ExitMethods.cs:40:9:42:9 | {...} | ExitMethods.cs:41:13:41:30 | call to method ErrorAlways | throw(Exception) | -| ExitMethods.cs:41:13:41:30 | call to method ErrorAlways | ExitMethods.cs:41:13:41:30 | call to method ErrorAlways | throw(ArgumentException) | -| ExitMethods.cs:41:13:41:30 | call to method ErrorAlways | ExitMethods.cs:41:13:41:30 | call to method ErrorAlways | throw(Exception) | -| ExitMethods.cs:41:13:41:31 | ...; | ExitMethods.cs:41:13:41:30 | call to method ErrorAlways | throw(ArgumentException) | -| ExitMethods.cs:41:13:41:31 | ...; | ExitMethods.cs:41:13:41:30 | call to method ErrorAlways | throw(Exception) | -| ExitMethods.cs:41:25:41:29 | false | ExitMethods.cs:41:25:41:29 | false | normal | -| ExitMethods.cs:43:9:46:9 | catch (...) {...} | ExitMethods.cs:43:9:46:9 | catch (...) {...} | no-match | -| ExitMethods.cs:43:9:46:9 | catch (...) {...} | ExitMethods.cs:45:13:45:19 | return ...; | return | -| ExitMethods.cs:44:9:46:9 | {...} | ExitMethods.cs:45:13:45:19 | return ...; | return | -| ExitMethods.cs:45:13:45:19 | return ...; | ExitMethods.cs:45:13:45:19 | return ...; | return | -| ExitMethods.cs:47:9:50:9 | catch (...) {...} | ExitMethods.cs:49:13:49:19 | return ...; | return | -| ExitMethods.cs:48:9:50:9 | {...} | ExitMethods.cs:49:13:49:19 | return ...; | return | -| ExitMethods.cs:49:13:49:19 | return ...; | ExitMethods.cs:49:13:49:19 | return ...; | return | -| ExitMethods.cs:54:5:57:5 | {...} | ExitMethods.cs:55:9:55:22 | call to method ErrorAlways2 | throw(Exception) | -| ExitMethods.cs:54:5:57:5 | {...} | ExitMethods.cs:56:9:56:15 | return ...; | return | -| ExitMethods.cs:55:9:55:22 | call to method ErrorAlways2 | ExitMethods.cs:55:9:55:22 | call to method ErrorAlways2 | throw(Exception) | -| ExitMethods.cs:55:9:55:23 | ...; | ExitMethods.cs:55:9:55:22 | call to method ErrorAlways2 | throw(Exception) | -| ExitMethods.cs:56:9:56:15 | return ...; | ExitMethods.cs:56:9:56:15 | return ...; | return | -| ExitMethods.cs:60:5:63:5 | {...} | ExitMethods.cs:61:9:61:22 | call to method ErrorAlways3 | throw(Exception) | -| ExitMethods.cs:60:5:63:5 | {...} | ExitMethods.cs:62:9:62:15 | return ...; | return | -| ExitMethods.cs:61:9:61:22 | call to method ErrorAlways3 | ExitMethods.cs:61:9:61:22 | call to method ErrorAlways3 | throw(Exception) | -| ExitMethods.cs:61:9:61:23 | ...; | ExitMethods.cs:61:9:61:22 | call to method ErrorAlways3 | throw(Exception) | -| ExitMethods.cs:62:9:62:15 | return ...; | ExitMethods.cs:62:9:62:15 | return ...; | return | -| ExitMethods.cs:66:5:69:5 | {...} | ExitMethods.cs:67:13:67:13 | access to parameter b | false | -| ExitMethods.cs:66:5:69:5 | {...} | ExitMethods.cs:68:13:68:34 | throw ...; | throw(Exception) | -| ExitMethods.cs:67:9:68:34 | if (...) ... | ExitMethods.cs:67:13:67:13 | access to parameter b | false | -| ExitMethods.cs:67:9:68:34 | if (...) ... | ExitMethods.cs:68:13:68:34 | throw ...; | throw(Exception) | -| ExitMethods.cs:67:13:67:13 | access to parameter b | ExitMethods.cs:67:13:67:13 | access to parameter b | false | -| ExitMethods.cs:67:13:67:13 | access to parameter b | ExitMethods.cs:67:13:67:13 | access to parameter b | true | -| ExitMethods.cs:68:13:68:34 | throw ...; | ExitMethods.cs:68:13:68:34 | throw ...; | throw(Exception) | -| ExitMethods.cs:68:19:68:33 | object creation of type Exception | ExitMethods.cs:68:19:68:33 | object creation of type Exception | normal | -| ExitMethods.cs:72:5:77:5 | {...} | ExitMethods.cs:74:13:74:34 | throw ...; | throw(Exception) | -| ExitMethods.cs:72:5:77:5 | {...} | ExitMethods.cs:76:13:76:45 | throw ...; | throw(ArgumentException) | -| ExitMethods.cs:73:9:76:45 | if (...) ... | ExitMethods.cs:74:13:74:34 | throw ...; | throw(Exception) | -| ExitMethods.cs:73:9:76:45 | if (...) ... | ExitMethods.cs:76:13:76:45 | throw ...; | throw(ArgumentException) | -| ExitMethods.cs:73:13:73:13 | access to parameter b | ExitMethods.cs:73:13:73:13 | access to parameter b | false | -| ExitMethods.cs:73:13:73:13 | access to parameter b | ExitMethods.cs:73:13:73:13 | access to parameter b | true | -| ExitMethods.cs:74:13:74:34 | throw ...; | ExitMethods.cs:74:13:74:34 | throw ...; | throw(Exception) | -| ExitMethods.cs:74:19:74:33 | object creation of type Exception | ExitMethods.cs:74:19:74:33 | object creation of type Exception | normal | -| ExitMethods.cs:76:13:76:45 | throw ...; | ExitMethods.cs:76:13:76:45 | throw ...; | throw(ArgumentException) | -| ExitMethods.cs:76:19:76:44 | object creation of type ArgumentException | ExitMethods.cs:76:19:76:44 | object creation of type ArgumentException | normal | -| ExitMethods.cs:76:41:76:43 | "b" | ExitMethods.cs:76:41:76:43 | "b" | normal | -| ExitMethods.cs:80:5:82:5 | {...} | ExitMethods.cs:81:9:81:30 | throw ...; | throw(Exception) | -| ExitMethods.cs:81:9:81:30 | throw ...; | ExitMethods.cs:81:9:81:30 | throw ...; | throw(Exception) | -| ExitMethods.cs:81:15:81:29 | object creation of type Exception | ExitMethods.cs:81:15:81:29 | object creation of type Exception | normal | -| ExitMethods.cs:84:35:84:55 | throw ... | ExitMethods.cs:84:35:84:55 | throw ... | throw(Exception) | -| ExitMethods.cs:84:41:84:55 | object creation of type Exception | ExitMethods.cs:84:41:84:55 | object creation of type Exception | normal | -| ExitMethods.cs:87:5:89:5 | {...} | ExitMethods.cs:88:9:88:27 | call to method Exit | exit | -| ExitMethods.cs:88:9:88:27 | call to method Exit | ExitMethods.cs:88:9:88:27 | call to method Exit | exit | -| ExitMethods.cs:88:9:88:28 | ...; | ExitMethods.cs:88:9:88:27 | call to method Exit | exit | -| ExitMethods.cs:88:26:88:26 | 0 | ExitMethods.cs:88:26:88:26 | 0 | normal | -| ExitMethods.cs:92:5:102:5 | {...} | ExitMethods.cs:95:13:95:18 | call to method Exit | exit | -| ExitMethods.cs:92:5:102:5 | {...} | ExitMethods.cs:100:13:100:40 | call to method WriteLine | exit [normal] | -| ExitMethods.cs:93:9:101:9 | try {...} ... | ExitMethods.cs:95:13:95:18 | call to method Exit | exit | -| ExitMethods.cs:93:9:101:9 | try {...} ... | ExitMethods.cs:100:13:100:40 | call to method WriteLine | exit [normal] | -| ExitMethods.cs:94:9:96:9 | {...} | ExitMethods.cs:95:13:95:18 | call to method Exit | exit | -| ExitMethods.cs:95:13:95:18 | call to method Exit | ExitMethods.cs:95:13:95:18 | call to method Exit | exit | -| ExitMethods.cs:95:13:95:18 | this access | ExitMethods.cs:95:13:95:18 | this access | normal | -| ExitMethods.cs:95:13:95:19 | ...; | ExitMethods.cs:95:13:95:18 | call to method Exit | exit | -| ExitMethods.cs:98:9:101:9 | {...} | ExitMethods.cs:100:13:100:40 | call to method WriteLine | normal | -| ExitMethods.cs:100:13:100:40 | call to method WriteLine | ExitMethods.cs:100:13:100:40 | call to method WriteLine | normal | -| ExitMethods.cs:100:13:100:41 | ...; | ExitMethods.cs:100:13:100:40 | call to method WriteLine | normal | -| ExitMethods.cs:100:38:100:39 | "" | ExitMethods.cs:100:38:100:39 | "" | normal | -| ExitMethods.cs:105:5:107:5 | {...} | ExitMethods.cs:106:9:106:47 | call to method Exit | exit | -| ExitMethods.cs:106:9:106:47 | call to method Exit | ExitMethods.cs:106:9:106:47 | call to method Exit | exit | -| ExitMethods.cs:106:9:106:48 | ...; | ExitMethods.cs:106:9:106:47 | call to method Exit | exit | -| ExitMethods.cs:110:5:112:5 | {...} | ExitMethods.cs:111:9:111:77 | return ...; | return | -| ExitMethods.cs:110:5:112:5 | {...} | ExitMethods.cs:111:41:111:76 | throw ... | throw(ArgumentException) | -| ExitMethods.cs:111:9:111:77 | return ...; | ExitMethods.cs:111:9:111:77 | return ...; | return | -| ExitMethods.cs:111:9:111:77 | return ...; | ExitMethods.cs:111:41:111:76 | throw ... | throw(ArgumentException) | -| ExitMethods.cs:111:16:111:20 | access to parameter input | ExitMethods.cs:111:16:111:20 | access to parameter input | normal | -| ExitMethods.cs:111:16:111:25 | ... != ... | ExitMethods.cs:111:16:111:25 | ... != ... | false | -| ExitMethods.cs:111:16:111:25 | ... != ... | ExitMethods.cs:111:16:111:25 | ... != ... | true | -| ExitMethods.cs:111:16:111:76 | ... ? ... : ... | ExitMethods.cs:111:16:111:76 | ... ? ... : ... | normal | -| ExitMethods.cs:111:16:111:76 | ... ? ... : ... | ExitMethods.cs:111:41:111:76 | throw ... | throw(ArgumentException) | -| ExitMethods.cs:111:25:111:25 | 0 | ExitMethods.cs:111:25:111:25 | 0 | normal | -| ExitMethods.cs:111:25:111:25 | (...) ... | ExitMethods.cs:111:25:111:25 | (...) ... | normal | -| ExitMethods.cs:111:29:111:29 | 1 | ExitMethods.cs:111:29:111:29 | 1 | normal | -| ExitMethods.cs:111:29:111:29 | (...) ... | ExitMethods.cs:111:29:111:29 | (...) ... | normal | -| ExitMethods.cs:111:29:111:37 | ... / ... | ExitMethods.cs:111:29:111:37 | ... / ... | normal | -| ExitMethods.cs:111:33:111:37 | access to parameter input | ExitMethods.cs:111:33:111:37 | access to parameter input | normal | -| ExitMethods.cs:111:41:111:76 | throw ... | ExitMethods.cs:111:41:111:76 | throw ... | throw(ArgumentException) | -| ExitMethods.cs:111:47:111:76 | object creation of type ArgumentException | ExitMethods.cs:111:47:111:76 | object creation of type ArgumentException | normal | -| ExitMethods.cs:111:69:111:75 | "input" | ExitMethods.cs:111:69:111:75 | "input" | normal | -| ExitMethods.cs:115:5:117:5 | {...} | ExitMethods.cs:116:9:116:39 | return ...; | return | -| ExitMethods.cs:116:9:116:39 | return ...; | ExitMethods.cs:116:9:116:39 | return ...; | return | -| ExitMethods.cs:116:16:116:16 | access to parameter s | ExitMethods.cs:116:16:116:16 | access to parameter s | normal | -| ExitMethods.cs:116:16:116:30 | call to method Contains | ExitMethods.cs:116:16:116:30 | call to method Contains | false | -| ExitMethods.cs:116:16:116:30 | call to method Contains | ExitMethods.cs:116:16:116:30 | call to method Contains | true | -| ExitMethods.cs:116:16:116:38 | ... ? ... : ... | ExitMethods.cs:116:16:116:38 | ... ? ... : ... | normal | -| ExitMethods.cs:116:27:116:29 | - | ExitMethods.cs:116:27:116:29 | - | normal | -| ExitMethods.cs:116:34:116:34 | 0 | ExitMethods.cs:116:34:116:34 | 0 | normal | -| ExitMethods.cs:116:38:116:38 | 1 | ExitMethods.cs:116:38:116:38 | 1 | normal | -| ExitMethods.cs:120:5:123:5 | {...} | ExitMethods.cs:121:9:121:28 | call to method IsTrue | throw(AssertFailedException) | -| ExitMethods.cs:120:5:123:5 | {...} | ExitMethods.cs:122:13:122:17 | Int32 x = ... | normal | -| ExitMethods.cs:121:9:121:28 | call to method IsTrue | ExitMethods.cs:121:9:121:28 | call to method IsTrue | throw(AssertFailedException) | -| ExitMethods.cs:121:9:121:29 | ...; | ExitMethods.cs:121:9:121:28 | call to method IsTrue | throw(AssertFailedException) | -| ExitMethods.cs:121:23:121:27 | false | ExitMethods.cs:121:23:121:27 | false | false | -| ExitMethods.cs:122:9:122:18 | ... ...; | ExitMethods.cs:122:13:122:17 | Int32 x = ... | normal | -| ExitMethods.cs:122:13:122:17 | Int32 x = ... | ExitMethods.cs:122:13:122:17 | Int32 x = ... | normal | -| ExitMethods.cs:122:17:122:17 | 0 | ExitMethods.cs:122:17:122:17 | 0 | normal | -| ExitMethods.cs:126:5:129:5 | {...} | ExitMethods.cs:127:9:127:26 | call to method FailingAssertion | throw(AssertFailedException) | -| ExitMethods.cs:126:5:129:5 | {...} | ExitMethods.cs:128:13:128:17 | Int32 x = ... | normal | -| ExitMethods.cs:127:9:127:26 | call to method FailingAssertion | ExitMethods.cs:127:9:127:26 | call to method FailingAssertion | throw(AssertFailedException) | -| ExitMethods.cs:127:9:127:26 | this access | ExitMethods.cs:127:9:127:26 | this access | normal | -| ExitMethods.cs:127:9:127:27 | ...; | ExitMethods.cs:127:9:127:26 | call to method FailingAssertion | throw(AssertFailedException) | -| ExitMethods.cs:128:9:128:18 | ... ...; | ExitMethods.cs:128:13:128:17 | Int32 x = ... | normal | -| ExitMethods.cs:128:13:128:17 | Int32 x = ... | ExitMethods.cs:128:13:128:17 | Int32 x = ... | normal | -| ExitMethods.cs:128:17:128:17 | 0 | ExitMethods.cs:128:17:128:17 | 0 | normal | -| ExitMethods.cs:131:33:131:49 | call to method IsFalse | ExitMethods.cs:131:33:131:49 | call to method IsFalse | normal | -| ExitMethods.cs:131:33:131:49 | call to method IsFalse | ExitMethods.cs:131:33:131:49 | call to method IsFalse | throw(AssertFailedException) | -| ExitMethods.cs:131:48:131:48 | access to parameter b | ExitMethods.cs:131:48:131:48 | access to parameter b | false | -| ExitMethods.cs:131:48:131:48 | access to parameter b | ExitMethods.cs:131:48:131:48 | access to parameter b | true | -| ExitMethods.cs:134:5:137:5 | {...} | ExitMethods.cs:135:9:135:25 | call to method AssertFalse | throw(AssertFailedException) | -| ExitMethods.cs:134:5:137:5 | {...} | ExitMethods.cs:136:13:136:17 | Int32 x = ... | normal | -| ExitMethods.cs:135:9:135:25 | call to method AssertFalse | ExitMethods.cs:135:9:135:25 | call to method AssertFalse | throw(AssertFailedException) | -| ExitMethods.cs:135:9:135:25 | this access | ExitMethods.cs:135:9:135:25 | this access | normal | -| ExitMethods.cs:135:9:135:26 | ...; | ExitMethods.cs:135:9:135:25 | call to method AssertFalse | throw(AssertFailedException) | -| ExitMethods.cs:135:21:135:24 | true | ExitMethods.cs:135:21:135:24 | true | true | -| ExitMethods.cs:136:9:136:18 | ... ...; | ExitMethods.cs:136:13:136:17 | Int32 x = ... | normal | -| ExitMethods.cs:136:13:136:17 | Int32 x = ... | ExitMethods.cs:136:13:136:17 | Int32 x = ... | normal | -| ExitMethods.cs:136:17:136:17 | 0 | ExitMethods.cs:136:17:136:17 | 0 | normal | +| ExitMethods.cs:9:5:12:5 | {...} | ExitMethods.cs:11:9:11:15 | return ...; | return | +| ExitMethods.cs:10:9:10:24 | call to method ErrorMaybe | ExitMethods.cs:10:9:10:24 | call to method ErrorMaybe | normal | +| ExitMethods.cs:10:9:10:25 | ...; | ExitMethods.cs:10:9:10:24 | call to method ErrorMaybe | normal | +| ExitMethods.cs:10:20:10:23 | true | ExitMethods.cs:10:20:10:23 | true | normal | +| ExitMethods.cs:11:9:11:15 | return ...; | ExitMethods.cs:11:9:11:15 | return ...; | return | +| ExitMethods.cs:15:5:18:5 | {...} | ExitMethods.cs:17:9:17:15 | return ...; | return | +| ExitMethods.cs:16:9:16:25 | call to method ErrorMaybe | ExitMethods.cs:16:9:16:25 | call to method ErrorMaybe | normal | +| ExitMethods.cs:16:9:16:26 | ...; | ExitMethods.cs:16:9:16:25 | call to method ErrorMaybe | normal | +| ExitMethods.cs:16:20:16:24 | false | ExitMethods.cs:16:20:16:24 | false | normal | +| ExitMethods.cs:17:9:17:15 | return ...; | ExitMethods.cs:17:9:17:15 | return ...; | return | +| ExitMethods.cs:21:5:24:5 | {...} | ExitMethods.cs:22:9:22:25 | call to method ErrorAlways | throw(ArgumentException) | +| ExitMethods.cs:21:5:24:5 | {...} | ExitMethods.cs:22:9:22:25 | call to method ErrorAlways | throw(Exception) | +| ExitMethods.cs:21:5:24:5 | {...} | ExitMethods.cs:23:9:23:15 | return ...; | return | +| ExitMethods.cs:22:9:22:25 | call to method ErrorAlways | ExitMethods.cs:22:9:22:25 | call to method ErrorAlways | throw(ArgumentException) | +| ExitMethods.cs:22:9:22:25 | call to method ErrorAlways | ExitMethods.cs:22:9:22:25 | call to method ErrorAlways | throw(Exception) | +| ExitMethods.cs:22:9:22:26 | ...; | ExitMethods.cs:22:9:22:25 | call to method ErrorAlways | throw(ArgumentException) | +| ExitMethods.cs:22:9:22:26 | ...; | ExitMethods.cs:22:9:22:25 | call to method ErrorAlways | throw(Exception) | +| ExitMethods.cs:22:21:22:24 | true | ExitMethods.cs:22:21:22:24 | true | normal | +| ExitMethods.cs:23:9:23:15 | return ...; | ExitMethods.cs:23:9:23:15 | return ...; | return | +| ExitMethods.cs:27:5:30:5 | {...} | ExitMethods.cs:28:9:28:14 | call to method Exit | exit | +| ExitMethods.cs:27:5:30:5 | {...} | ExitMethods.cs:29:9:29:15 | return ...; | return | +| ExitMethods.cs:28:9:28:14 | call to method Exit | ExitMethods.cs:28:9:28:14 | call to method Exit | exit | +| ExitMethods.cs:28:9:28:14 | this access | ExitMethods.cs:28:9:28:14 | this access | normal | +| ExitMethods.cs:28:9:28:15 | ...; | ExitMethods.cs:28:9:28:14 | call to method Exit | exit | +| ExitMethods.cs:29:9:29:15 | return ...; | ExitMethods.cs:29:9:29:15 | return ...; | return | +| ExitMethods.cs:33:5:36:5 | {...} | ExitMethods.cs:34:9:34:25 | call to method ApplicationExit | exit | +| ExitMethods.cs:33:5:36:5 | {...} | ExitMethods.cs:35:9:35:15 | return ...; | return | +| ExitMethods.cs:34:9:34:25 | call to method ApplicationExit | ExitMethods.cs:34:9:34:25 | call to method ApplicationExit | exit | +| ExitMethods.cs:34:9:34:25 | this access | ExitMethods.cs:34:9:34:25 | this access | normal | +| ExitMethods.cs:34:9:34:26 | ...; | ExitMethods.cs:34:9:34:25 | call to method ApplicationExit | exit | +| ExitMethods.cs:35:9:35:15 | return ...; | ExitMethods.cs:35:9:35:15 | return ...; | return | +| ExitMethods.cs:39:5:52:5 | {...} | ExitMethods.cs:46:13:46:19 | return ...; | return | +| ExitMethods.cs:39:5:52:5 | {...} | ExitMethods.cs:50:13:50:19 | return ...; | return | +| ExitMethods.cs:40:9:51:9 | try {...} ... | ExitMethods.cs:46:13:46:19 | return ...; | return | +| ExitMethods.cs:40:9:51:9 | try {...} ... | ExitMethods.cs:50:13:50:19 | return ...; | return | +| ExitMethods.cs:41:9:43:9 | {...} | ExitMethods.cs:42:13:42:30 | call to method ErrorAlways | throw(ArgumentException) | +| ExitMethods.cs:41:9:43:9 | {...} | ExitMethods.cs:42:13:42:30 | call to method ErrorAlways | throw(Exception) | +| ExitMethods.cs:42:13:42:30 | call to method ErrorAlways | ExitMethods.cs:42:13:42:30 | call to method ErrorAlways | throw(ArgumentException) | +| ExitMethods.cs:42:13:42:30 | call to method ErrorAlways | ExitMethods.cs:42:13:42:30 | call to method ErrorAlways | throw(Exception) | +| ExitMethods.cs:42:13:42:31 | ...; | ExitMethods.cs:42:13:42:30 | call to method ErrorAlways | throw(ArgumentException) | +| ExitMethods.cs:42:13:42:31 | ...; | ExitMethods.cs:42:13:42:30 | call to method ErrorAlways | throw(Exception) | +| ExitMethods.cs:42:25:42:29 | false | ExitMethods.cs:42:25:42:29 | false | normal | +| ExitMethods.cs:44:9:47:9 | catch (...) {...} | ExitMethods.cs:44:9:47:9 | catch (...) {...} | no-match | +| ExitMethods.cs:44:9:47:9 | catch (...) {...} | ExitMethods.cs:46:13:46:19 | return ...; | return | +| ExitMethods.cs:45:9:47:9 | {...} | ExitMethods.cs:46:13:46:19 | return ...; | return | +| ExitMethods.cs:46:13:46:19 | return ...; | ExitMethods.cs:46:13:46:19 | return ...; | return | +| ExitMethods.cs:48:9:51:9 | catch (...) {...} | ExitMethods.cs:50:13:50:19 | return ...; | return | +| ExitMethods.cs:49:9:51:9 | {...} | ExitMethods.cs:50:13:50:19 | return ...; | return | +| ExitMethods.cs:50:13:50:19 | return ...; | ExitMethods.cs:50:13:50:19 | return ...; | return | +| ExitMethods.cs:55:5:58:5 | {...} | ExitMethods.cs:56:9:56:22 | call to method ErrorAlways2 | throw(Exception) | +| ExitMethods.cs:55:5:58:5 | {...} | ExitMethods.cs:57:9:57:15 | return ...; | return | +| ExitMethods.cs:56:9:56:22 | call to method ErrorAlways2 | ExitMethods.cs:56:9:56:22 | call to method ErrorAlways2 | throw(Exception) | +| ExitMethods.cs:56:9:56:23 | ...; | ExitMethods.cs:56:9:56:22 | call to method ErrorAlways2 | throw(Exception) | +| ExitMethods.cs:57:9:57:15 | return ...; | ExitMethods.cs:57:9:57:15 | return ...; | return | +| ExitMethods.cs:61:5:64:5 | {...} | ExitMethods.cs:62:9:62:22 | call to method ErrorAlways3 | throw(Exception) | +| ExitMethods.cs:61:5:64:5 | {...} | ExitMethods.cs:63:9:63:15 | return ...; | return | +| ExitMethods.cs:62:9:62:22 | call to method ErrorAlways3 | ExitMethods.cs:62:9:62:22 | call to method ErrorAlways3 | throw(Exception) | +| ExitMethods.cs:62:9:62:23 | ...; | ExitMethods.cs:62:9:62:22 | call to method ErrorAlways3 | throw(Exception) | +| ExitMethods.cs:63:9:63:15 | return ...; | ExitMethods.cs:63:9:63:15 | return ...; | return | +| ExitMethods.cs:67:5:70:5 | {...} | ExitMethods.cs:68:13:68:13 | access to parameter b | false | +| ExitMethods.cs:67:5:70:5 | {...} | ExitMethods.cs:69:13:69:34 | throw ...; | throw(Exception) | +| ExitMethods.cs:68:9:69:34 | if (...) ... | ExitMethods.cs:68:13:68:13 | access to parameter b | false | +| ExitMethods.cs:68:9:69:34 | if (...) ... | ExitMethods.cs:69:13:69:34 | throw ...; | throw(Exception) | +| ExitMethods.cs:68:13:68:13 | access to parameter b | ExitMethods.cs:68:13:68:13 | access to parameter b | false | +| ExitMethods.cs:68:13:68:13 | access to parameter b | ExitMethods.cs:68:13:68:13 | access to parameter b | true | +| ExitMethods.cs:69:13:69:34 | throw ...; | ExitMethods.cs:69:13:69:34 | throw ...; | throw(Exception) | +| ExitMethods.cs:69:19:69:33 | object creation of type Exception | ExitMethods.cs:69:19:69:33 | object creation of type Exception | normal | +| ExitMethods.cs:73:5:78:5 | {...} | ExitMethods.cs:75:13:75:34 | throw ...; | throw(Exception) | +| ExitMethods.cs:73:5:78:5 | {...} | ExitMethods.cs:77:13:77:45 | throw ...; | throw(ArgumentException) | +| ExitMethods.cs:74:9:77:45 | if (...) ... | ExitMethods.cs:75:13:75:34 | throw ...; | throw(Exception) | +| ExitMethods.cs:74:9:77:45 | if (...) ... | ExitMethods.cs:77:13:77:45 | throw ...; | throw(ArgumentException) | +| ExitMethods.cs:74:13:74:13 | access to parameter b | ExitMethods.cs:74:13:74:13 | access to parameter b | false | +| ExitMethods.cs:74:13:74:13 | access to parameter b | ExitMethods.cs:74:13:74:13 | access to parameter b | true | +| ExitMethods.cs:75:13:75:34 | throw ...; | ExitMethods.cs:75:13:75:34 | throw ...; | throw(Exception) | +| ExitMethods.cs:75:19:75:33 | object creation of type Exception | ExitMethods.cs:75:19:75:33 | object creation of type Exception | normal | +| ExitMethods.cs:77:13:77:45 | throw ...; | ExitMethods.cs:77:13:77:45 | throw ...; | throw(ArgumentException) | +| ExitMethods.cs:77:19:77:44 | object creation of type ArgumentException | ExitMethods.cs:77:19:77:44 | object creation of type ArgumentException | normal | +| ExitMethods.cs:77:41:77:43 | "b" | ExitMethods.cs:77:41:77:43 | "b" | normal | +| ExitMethods.cs:81:5:83:5 | {...} | ExitMethods.cs:82:9:82:30 | throw ...; | throw(Exception) | +| ExitMethods.cs:82:9:82:30 | throw ...; | ExitMethods.cs:82:9:82:30 | throw ...; | throw(Exception) | +| ExitMethods.cs:82:15:82:29 | object creation of type Exception | ExitMethods.cs:82:15:82:29 | object creation of type Exception | normal | +| ExitMethods.cs:85:35:85:55 | throw ... | ExitMethods.cs:85:35:85:55 | throw ... | throw(Exception) | +| ExitMethods.cs:85:41:85:55 | object creation of type Exception | ExitMethods.cs:85:41:85:55 | object creation of type Exception | normal | +| ExitMethods.cs:88:5:90:5 | {...} | ExitMethods.cs:89:9:89:27 | call to method Exit | exit | +| ExitMethods.cs:89:9:89:27 | call to method Exit | ExitMethods.cs:89:9:89:27 | call to method Exit | exit | +| ExitMethods.cs:89:9:89:28 | ...; | ExitMethods.cs:89:9:89:27 | call to method Exit | exit | +| ExitMethods.cs:89:26:89:26 | 0 | ExitMethods.cs:89:26:89:26 | 0 | normal | +| ExitMethods.cs:93:5:103:5 | {...} | ExitMethods.cs:96:13:96:18 | call to method Exit | exit | +| ExitMethods.cs:94:9:102:9 | try {...} ... | ExitMethods.cs:96:13:96:18 | call to method Exit | exit | +| ExitMethods.cs:95:9:97:9 | {...} | ExitMethods.cs:96:13:96:18 | call to method Exit | exit | +| ExitMethods.cs:96:13:96:18 | call to method Exit | ExitMethods.cs:96:13:96:18 | call to method Exit | exit | +| ExitMethods.cs:96:13:96:18 | this access | ExitMethods.cs:96:13:96:18 | this access | normal | +| ExitMethods.cs:96:13:96:19 | ...; | ExitMethods.cs:96:13:96:18 | call to method Exit | exit | +| ExitMethods.cs:99:9:102:9 | {...} | ExitMethods.cs:101:13:101:40 | call to method WriteLine | normal | +| ExitMethods.cs:101:13:101:40 | call to method WriteLine | ExitMethods.cs:101:13:101:40 | call to method WriteLine | normal | +| ExitMethods.cs:101:13:101:41 | ...; | ExitMethods.cs:101:13:101:40 | call to method WriteLine | normal | +| ExitMethods.cs:101:38:101:39 | "" | ExitMethods.cs:101:38:101:39 | "" | normal | +| ExitMethods.cs:106:5:108:5 | {...} | ExitMethods.cs:107:9:107:47 | call to method Exit | exit | +| ExitMethods.cs:107:9:107:47 | call to method Exit | ExitMethods.cs:107:9:107:47 | call to method Exit | exit | +| ExitMethods.cs:107:9:107:48 | ...; | ExitMethods.cs:107:9:107:47 | call to method Exit | exit | +| ExitMethods.cs:111:5:113:5 | {...} | ExitMethods.cs:112:9:112:77 | return ...; | return | +| ExitMethods.cs:111:5:113:5 | {...} | ExitMethods.cs:112:41:112:76 | throw ... | throw(ArgumentException) | +| ExitMethods.cs:112:9:112:77 | return ...; | ExitMethods.cs:112:9:112:77 | return ...; | return | +| ExitMethods.cs:112:9:112:77 | return ...; | ExitMethods.cs:112:41:112:76 | throw ... | throw(ArgumentException) | +| ExitMethods.cs:112:16:112:20 | access to parameter input | ExitMethods.cs:112:16:112:20 | access to parameter input | normal | +| ExitMethods.cs:112:16:112:25 | ... != ... | ExitMethods.cs:112:16:112:25 | ... != ... | false | +| ExitMethods.cs:112:16:112:25 | ... != ... | ExitMethods.cs:112:16:112:25 | ... != ... | true | +| ExitMethods.cs:112:16:112:76 | ... ? ... : ... | ExitMethods.cs:112:16:112:76 | ... ? ... : ... | normal | +| ExitMethods.cs:112:16:112:76 | ... ? ... : ... | ExitMethods.cs:112:41:112:76 | throw ... | throw(ArgumentException) | +| ExitMethods.cs:112:25:112:25 | 0 | ExitMethods.cs:112:25:112:25 | 0 | normal | +| ExitMethods.cs:112:25:112:25 | (...) ... | ExitMethods.cs:112:25:112:25 | (...) ... | normal | +| ExitMethods.cs:112:29:112:29 | 1 | ExitMethods.cs:112:29:112:29 | 1 | normal | +| ExitMethods.cs:112:29:112:29 | (...) ... | ExitMethods.cs:112:29:112:29 | (...) ... | normal | +| ExitMethods.cs:112:29:112:37 | ... / ... | ExitMethods.cs:112:29:112:37 | ... / ... | normal | +| ExitMethods.cs:112:33:112:37 | access to parameter input | ExitMethods.cs:112:33:112:37 | access to parameter input | normal | +| ExitMethods.cs:112:41:112:76 | throw ... | ExitMethods.cs:112:41:112:76 | throw ... | throw(ArgumentException) | +| ExitMethods.cs:112:47:112:76 | object creation of type ArgumentException | ExitMethods.cs:112:47:112:76 | object creation of type ArgumentException | normal | +| ExitMethods.cs:112:69:112:75 | "input" | ExitMethods.cs:112:69:112:75 | "input" | normal | +| ExitMethods.cs:116:5:118:5 | {...} | ExitMethods.cs:117:9:117:39 | return ...; | return | +| ExitMethods.cs:117:9:117:39 | return ...; | ExitMethods.cs:117:9:117:39 | return ...; | return | +| ExitMethods.cs:117:16:117:16 | access to parameter s | ExitMethods.cs:117:16:117:16 | access to parameter s | normal | +| ExitMethods.cs:117:16:117:30 | call to method Contains | ExitMethods.cs:117:16:117:30 | call to method Contains | false | +| ExitMethods.cs:117:16:117:30 | call to method Contains | ExitMethods.cs:117:16:117:30 | call to method Contains | true | +| ExitMethods.cs:117:16:117:38 | ... ? ... : ... | ExitMethods.cs:117:16:117:38 | ... ? ... : ... | normal | +| ExitMethods.cs:117:27:117:29 | - | ExitMethods.cs:117:27:117:29 | - | normal | +| ExitMethods.cs:117:34:117:34 | 0 | ExitMethods.cs:117:34:117:34 | 0 | normal | +| ExitMethods.cs:117:38:117:38 | 1 | ExitMethods.cs:117:38:117:38 | 1 | normal | +| ExitMethods.cs:121:5:124:5 | {...} | ExitMethods.cs:122:9:122:28 | call to method IsTrue | throw(AssertFailedException) | +| ExitMethods.cs:121:5:124:5 | {...} | ExitMethods.cs:123:13:123:17 | Int32 x = ... | normal | +| ExitMethods.cs:122:9:122:28 | call to method IsTrue | ExitMethods.cs:122:9:122:28 | call to method IsTrue | throw(AssertFailedException) | +| ExitMethods.cs:122:9:122:29 | ...; | ExitMethods.cs:122:9:122:28 | call to method IsTrue | throw(AssertFailedException) | +| ExitMethods.cs:122:23:122:27 | false | ExitMethods.cs:122:23:122:27 | false | false | +| ExitMethods.cs:123:9:123:18 | ... ...; | ExitMethods.cs:123:13:123:17 | Int32 x = ... | normal | +| ExitMethods.cs:123:13:123:17 | Int32 x = ... | ExitMethods.cs:123:13:123:17 | Int32 x = ... | normal | +| ExitMethods.cs:123:17:123:17 | 0 | ExitMethods.cs:123:17:123:17 | 0 | normal | +| ExitMethods.cs:127:5:130:5 | {...} | ExitMethods.cs:128:9:128:26 | call to method FailingAssertion | throw(AssertFailedException) | +| ExitMethods.cs:127:5:130:5 | {...} | ExitMethods.cs:129:13:129:17 | Int32 x = ... | normal | +| ExitMethods.cs:128:9:128:26 | call to method FailingAssertion | ExitMethods.cs:128:9:128:26 | call to method FailingAssertion | throw(AssertFailedException) | +| ExitMethods.cs:128:9:128:26 | this access | ExitMethods.cs:128:9:128:26 | this access | normal | +| ExitMethods.cs:128:9:128:27 | ...; | ExitMethods.cs:128:9:128:26 | call to method FailingAssertion | throw(AssertFailedException) | +| ExitMethods.cs:129:9:129:18 | ... ...; | ExitMethods.cs:129:13:129:17 | Int32 x = ... | normal | +| ExitMethods.cs:129:13:129:17 | Int32 x = ... | ExitMethods.cs:129:13:129:17 | Int32 x = ... | normal | +| ExitMethods.cs:129:17:129:17 | 0 | ExitMethods.cs:129:17:129:17 | 0 | normal | +| ExitMethods.cs:132:33:132:49 | call to method IsFalse | ExitMethods.cs:132:33:132:49 | call to method IsFalse | normal | +| ExitMethods.cs:132:33:132:49 | call to method IsFalse | ExitMethods.cs:132:33:132:49 | call to method IsFalse | throw(AssertFailedException) | +| ExitMethods.cs:132:48:132:48 | access to parameter b | ExitMethods.cs:132:48:132:48 | access to parameter b | false | +| ExitMethods.cs:132:48:132:48 | access to parameter b | ExitMethods.cs:132:48:132:48 | access to parameter b | true | +| ExitMethods.cs:135:5:138:5 | {...} | ExitMethods.cs:136:9:136:25 | call to method AssertFalse | throw(AssertFailedException) | +| ExitMethods.cs:135:5:138:5 | {...} | ExitMethods.cs:137:13:137:17 | Int32 x = ... | normal | +| ExitMethods.cs:136:9:136:25 | call to method AssertFalse | ExitMethods.cs:136:9:136:25 | call to method AssertFalse | throw(AssertFailedException) | +| ExitMethods.cs:136:9:136:25 | this access | ExitMethods.cs:136:9:136:25 | this access | normal | +| ExitMethods.cs:136:9:136:26 | ...; | ExitMethods.cs:136:9:136:25 | call to method AssertFalse | throw(AssertFailedException) | +| ExitMethods.cs:136:21:136:24 | true | ExitMethods.cs:136:21:136:24 | true | true | +| ExitMethods.cs:137:9:137:18 | ... ...; | ExitMethods.cs:137:13:137:17 | Int32 x = ... | normal | +| ExitMethods.cs:137:13:137:17 | Int32 x = ... | ExitMethods.cs:137:13:137:17 | Int32 x = ... | normal | +| ExitMethods.cs:137:17:137:17 | 0 | ExitMethods.cs:137:17:137:17 | 0 | normal | +| ExitMethods.cs:141:5:147:5 | {...} | ExitMethods.cs:143:13:143:42 | call to method Throw | throw(ArgumentException) | +| ExitMethods.cs:141:5:147:5 | {...} | ExitMethods.cs:145:13:145:52 | call to method Throw | throw(Exception) | +| ExitMethods.cs:141:5:147:5 | {...} | ExitMethods.cs:146:9:146:33 | call to method WriteLine | normal | +| ExitMethods.cs:142:9:145:53 | if (...) ... | ExitMethods.cs:143:13:143:42 | call to method Throw | throw(ArgumentException) | +| ExitMethods.cs:142:9:145:53 | if (...) ... | ExitMethods.cs:145:13:145:52 | call to method Throw | throw(Exception) | +| ExitMethods.cs:142:13:142:13 | access to parameter b | ExitMethods.cs:142:13:142:13 | access to parameter b | false | +| ExitMethods.cs:142:13:142:13 | access to parameter b | ExitMethods.cs:142:13:142:13 | access to parameter b | true | +| ExitMethods.cs:143:13:143:42 | call to method Throw | ExitMethods.cs:143:13:143:42 | call to method Throw | throw(ArgumentException) | +| ExitMethods.cs:143:13:143:43 | ...; | ExitMethods.cs:143:13:143:42 | call to method Throw | throw(ArgumentException) | +| ExitMethods.cs:143:41:143:41 | access to parameter e | ExitMethods.cs:143:41:143:41 | access to parameter e | normal | +| ExitMethods.cs:145:13:145:44 | call to method Capture | ExitMethods.cs:145:13:145:44 | call to method Capture | normal | +| ExitMethods.cs:145:13:145:52 | call to method Throw | ExitMethods.cs:145:13:145:52 | call to method Throw | throw(Exception) | +| ExitMethods.cs:145:13:145:53 | ...; | ExitMethods.cs:145:13:145:52 | call to method Throw | throw(Exception) | +| ExitMethods.cs:145:43:145:43 | access to parameter e | ExitMethods.cs:145:43:145:43 | access to parameter e | normal | +| ExitMethods.cs:146:9:146:33 | call to method WriteLine | ExitMethods.cs:146:9:146:33 | call to method WriteLine | normal | +| ExitMethods.cs:146:9:146:34 | ...; | ExitMethods.cs:146:9:146:33 | call to method WriteLine | normal | +| ExitMethods.cs:146:27:146:32 | "dead" | ExitMethods.cs:146:27:146:32 | "dead" | normal | | Extensions.cs:6:5:8:5 | {...} | Extensions.cs:7:9:7:30 | return ...; | return | | Extensions.cs:7:9:7:30 | return ...; | Extensions.cs:7:9:7:30 | return ...; | return | | Extensions.cs:7:16:7:29 | call to method Parse | Extensions.cs:7:16:7:29 | call to method Parse | normal | @@ -1636,45 +1642,35 @@ | Extensions.cs:25:23:25:32 | access to method Parse | Extensions.cs:25:23:25:32 | access to method Parse | normal | | Extensions.cs:25:23:25:32 | delegate creation of type Func<String,Boolean> | Extensions.cs:25:23:25:32 | delegate creation of type Func<String,Boolean> | normal | | Finally.cs:8:5:17:5 | {...} | Finally.cs:15:13:15:40 | call to method WriteLine | normal | -| Finally.cs:8:5:17:5 | {...} | Finally.cs:15:13:15:40 | call to method WriteLine | throw(Exception) [normal] | -| Finally.cs:8:5:17:5 | {...} | Finally.cs:15:13:15:40 | call to method WriteLine | throw(OutOfMemoryException) [normal] | +| Finally.cs:8:5:17:5 | {...} | Finally.cs:15:13:15:40 | call to method WriteLine | throw(Exception) [normal] (0) | | Finally.cs:9:9:16:9 | try {...} ... | Finally.cs:15:13:15:40 | call to method WriteLine | normal | -| Finally.cs:9:9:16:9 | try {...} ... | Finally.cs:15:13:15:40 | call to method WriteLine | throw(Exception) [normal] | -| Finally.cs:9:9:16:9 | try {...} ... | Finally.cs:15:13:15:40 | call to method WriteLine | throw(OutOfMemoryException) [normal] | +| Finally.cs:9:9:16:9 | try {...} ... | Finally.cs:15:13:15:40 | call to method WriteLine | throw(Exception) [normal] (0) | | Finally.cs:10:9:12:9 | {...} | Finally.cs:11:13:11:37 | call to method WriteLine | normal | | Finally.cs:10:9:12:9 | {...} | Finally.cs:11:13:11:37 | call to method WriteLine | throw(Exception) | -| Finally.cs:10:9:12:9 | {...} | Finally.cs:11:31:11:36 | "Try1" | throw(OutOfMemoryException) | | Finally.cs:11:13:11:37 | call to method WriteLine | Finally.cs:11:13:11:37 | call to method WriteLine | normal | | Finally.cs:11:13:11:37 | call to method WriteLine | Finally.cs:11:13:11:37 | call to method WriteLine | throw(Exception) | -| Finally.cs:11:13:11:37 | call to method WriteLine | Finally.cs:11:31:11:36 | "Try1" | throw(OutOfMemoryException) | | Finally.cs:11:13:11:38 | ...; | Finally.cs:11:13:11:37 | call to method WriteLine | normal | | Finally.cs:11:13:11:38 | ...; | Finally.cs:11:13:11:37 | call to method WriteLine | throw(Exception) | -| Finally.cs:11:13:11:38 | ...; | Finally.cs:11:31:11:36 | "Try1" | throw(OutOfMemoryException) | | Finally.cs:11:31:11:36 | "Try1" | Finally.cs:11:31:11:36 | "Try1" | normal | -| Finally.cs:11:31:11:36 | "Try1" | Finally.cs:11:31:11:36 | "Try1" | throw(OutOfMemoryException) | | Finally.cs:14:9:16:9 | {...} | Finally.cs:15:13:15:40 | call to method WriteLine | normal | | Finally.cs:15:13:15:40 | call to method WriteLine | Finally.cs:15:13:15:40 | call to method WriteLine | normal | | Finally.cs:15:13:15:41 | ...; | Finally.cs:15:13:15:40 | call to method WriteLine | normal | | Finally.cs:15:31:15:39 | "Finally" | Finally.cs:15:31:15:39 | "Finally" | normal | | Finally.cs:20:5:52:5 | {...} | Finally.cs:50:13:50:40 | call to method WriteLine | normal | -| Finally.cs:20:5:52:5 | {...} | Finally.cs:50:13:50:40 | call to method WriteLine | return [normal] | -| Finally.cs:20:5:52:5 | {...} | Finally.cs:50:13:50:40 | call to method WriteLine | throw(Exception) [normal] | -| Finally.cs:20:5:52:5 | {...} | Finally.cs:50:13:50:40 | call to method WriteLine | throw(IOException) [normal] | +| Finally.cs:20:5:52:5 | {...} | Finally.cs:50:13:50:40 | call to method WriteLine | return [normal] (0) | +| Finally.cs:20:5:52:5 | {...} | Finally.cs:50:13:50:40 | call to method WriteLine | throw(Exception) [normal] (0) | +| Finally.cs:20:5:52:5 | {...} | Finally.cs:50:13:50:40 | call to method WriteLine | throw(IOException) [normal] (0) | | Finally.cs:21:9:51:9 | try {...} ... | Finally.cs:50:13:50:40 | call to method WriteLine | normal | -| Finally.cs:21:9:51:9 | try {...} ... | Finally.cs:50:13:50:40 | call to method WriteLine | return [normal] | -| Finally.cs:21:9:51:9 | try {...} ... | Finally.cs:50:13:50:40 | call to method WriteLine | throw(Exception) [normal] | -| Finally.cs:21:9:51:9 | try {...} ... | Finally.cs:50:13:50:40 | call to method WriteLine | throw(IOException) [normal] | +| Finally.cs:21:9:51:9 | try {...} ... | Finally.cs:50:13:50:40 | call to method WriteLine | return [normal] (0) | +| Finally.cs:21:9:51:9 | try {...} ... | Finally.cs:50:13:50:40 | call to method WriteLine | throw(Exception) [normal] (0) | +| Finally.cs:21:9:51:9 | try {...} ... | Finally.cs:50:13:50:40 | call to method WriteLine | throw(IOException) [normal] (0) | | Finally.cs:22:9:25:9 | {...} | Finally.cs:23:13:23:37 | call to method WriteLine | throw(Exception) | -| Finally.cs:22:9:25:9 | {...} | Finally.cs:23:31:23:36 | "Try2" | throw(OutOfMemoryException) | | Finally.cs:22:9:25:9 | {...} | Finally.cs:24:13:24:19 | return ...; | return | | Finally.cs:23:13:23:37 | call to method WriteLine | Finally.cs:23:13:23:37 | call to method WriteLine | normal | | Finally.cs:23:13:23:37 | call to method WriteLine | Finally.cs:23:13:23:37 | call to method WriteLine | throw(Exception) | -| Finally.cs:23:13:23:37 | call to method WriteLine | Finally.cs:23:31:23:36 | "Try2" | throw(OutOfMemoryException) | | Finally.cs:23:13:23:38 | ...; | Finally.cs:23:13:23:37 | call to method WriteLine | normal | | Finally.cs:23:13:23:38 | ...; | Finally.cs:23:13:23:37 | call to method WriteLine | throw(Exception) | -| Finally.cs:23:13:23:38 | ...; | Finally.cs:23:31:23:36 | "Try2" | throw(OutOfMemoryException) | | Finally.cs:23:31:23:36 | "Try2" | Finally.cs:23:31:23:36 | "Try2" | normal | -| Finally.cs:23:31:23:36 | "Try2" | Finally.cs:23:31:23:36 | "Try2" | throw(OutOfMemoryException) | | Finally.cs:24:13:24:19 | return ...; | Finally.cs:24:13:24:19 | return ...; | return | | Finally.cs:26:9:29:9 | catch (...) {...} | Finally.cs:26:9:29:9 | catch (...) {...} | no-match | | Finally.cs:26:9:29:9 | catch (...) {...} | Finally.cs:28:13:28:18 | throw ...; | throw(IOException) | @@ -1706,26 +1702,20 @@ | Finally.cs:50:13:50:41 | ...; | Finally.cs:50:13:50:40 | call to method WriteLine | normal | | Finally.cs:50:31:50:39 | "Finally" | Finally.cs:50:31:50:39 | "Finally" | normal | | Finally.cs:55:5:72:5 | {...} | Finally.cs:70:13:70:40 | call to method WriteLine | normal | -| Finally.cs:55:5:72:5 | {...} | Finally.cs:70:13:70:40 | call to method WriteLine | return [normal] | -| Finally.cs:55:5:72:5 | {...} | Finally.cs:70:13:70:40 | call to method WriteLine | throw(Exception) [normal] | -| Finally.cs:55:5:72:5 | {...} | Finally.cs:70:13:70:40 | call to method WriteLine | throw(IOException) [normal] | -| Finally.cs:55:5:72:5 | {...} | Finally.cs:70:13:70:40 | call to method WriteLine | throw(OutOfMemoryException) [normal] | +| Finally.cs:55:5:72:5 | {...} | Finally.cs:70:13:70:40 | call to method WriteLine | return [normal] (0) | +| Finally.cs:55:5:72:5 | {...} | Finally.cs:70:13:70:40 | call to method WriteLine | throw(Exception) [normal] (0) | +| Finally.cs:55:5:72:5 | {...} | Finally.cs:70:13:70:40 | call to method WriteLine | throw(IOException) [normal] (0) | | Finally.cs:56:9:71:9 | try {...} ... | Finally.cs:70:13:70:40 | call to method WriteLine | normal | -| Finally.cs:56:9:71:9 | try {...} ... | Finally.cs:70:13:70:40 | call to method WriteLine | return [normal] | -| Finally.cs:56:9:71:9 | try {...} ... | Finally.cs:70:13:70:40 | call to method WriteLine | throw(Exception) [normal] | -| Finally.cs:56:9:71:9 | try {...} ... | Finally.cs:70:13:70:40 | call to method WriteLine | throw(IOException) [normal] | -| Finally.cs:56:9:71:9 | try {...} ... | Finally.cs:70:13:70:40 | call to method WriteLine | throw(OutOfMemoryException) [normal] | +| Finally.cs:56:9:71:9 | try {...} ... | Finally.cs:70:13:70:40 | call to method WriteLine | return [normal] (0) | +| Finally.cs:56:9:71:9 | try {...} ... | Finally.cs:70:13:70:40 | call to method WriteLine | throw(Exception) [normal] (0) | +| Finally.cs:56:9:71:9 | try {...} ... | Finally.cs:70:13:70:40 | call to method WriteLine | throw(IOException) [normal] (0) | | Finally.cs:57:9:60:9 | {...} | Finally.cs:58:13:58:37 | call to method WriteLine | throw(Exception) | -| Finally.cs:57:9:60:9 | {...} | Finally.cs:58:31:58:36 | "Try3" | throw(OutOfMemoryException) | | Finally.cs:57:9:60:9 | {...} | Finally.cs:59:13:59:19 | return ...; | return | | Finally.cs:58:13:58:37 | call to method WriteLine | Finally.cs:58:13:58:37 | call to method WriteLine | normal | | Finally.cs:58:13:58:37 | call to method WriteLine | Finally.cs:58:13:58:37 | call to method WriteLine | throw(Exception) | -| Finally.cs:58:13:58:37 | call to method WriteLine | Finally.cs:58:31:58:36 | "Try3" | throw(OutOfMemoryException) | | Finally.cs:58:13:58:38 | ...; | Finally.cs:58:13:58:37 | call to method WriteLine | normal | | Finally.cs:58:13:58:38 | ...; | Finally.cs:58:13:58:37 | call to method WriteLine | throw(Exception) | -| Finally.cs:58:13:58:38 | ...; | Finally.cs:58:31:58:36 | "Try3" | throw(OutOfMemoryException) | | Finally.cs:58:31:58:36 | "Try3" | Finally.cs:58:31:58:36 | "Try3" | normal | -| Finally.cs:58:31:58:36 | "Try3" | Finally.cs:58:31:58:36 | "Try3" | throw(OutOfMemoryException) | | Finally.cs:59:13:59:19 | return ...; | Finally.cs:59:13:59:19 | return ...; | return | | Finally.cs:61:9:64:9 | catch (...) {...} | Finally.cs:61:9:64:9 | catch (...) {...} | no-match | | Finally.cs:61:9:64:9 | catch (...) {...} | Finally.cs:63:13:63:18 | throw ...; | throw(IOException) | @@ -1733,10 +1723,8 @@ | Finally.cs:61:48:61:51 | true | Finally.cs:61:48:61:51 | true | true | | Finally.cs:62:9:64:9 | {...} | Finally.cs:63:13:63:18 | throw ...; | throw(IOException) | | Finally.cs:63:13:63:18 | throw ...; | Finally.cs:63:13:63:18 | throw ...; | throw(IOException) | -| Finally.cs:65:9:67:9 | catch (...) {...} | Finally.cs:65:9:67:9 | catch (...) {...} | throw(Exception) [no-match] | -| Finally.cs:65:9:67:9 | catch (...) {...} | Finally.cs:65:9:67:9 | catch (...) {...} | throw(OutOfMemoryException) [no-match] | -| Finally.cs:65:9:67:9 | catch (...) {...} | Finally.cs:65:35:65:51 | ... != ... | throw(Exception) [false] | -| Finally.cs:65:9:67:9 | catch (...) {...} | Finally.cs:65:35:65:51 | ... != ... | throw(OutOfMemoryException) [false] | +| Finally.cs:65:9:67:9 | catch (...) {...} | Finally.cs:65:9:67:9 | catch (...) {...} | throw(Exception) [no-match] (0) | +| Finally.cs:65:9:67:9 | catch (...) {...} | Finally.cs:65:35:65:51 | ... != ... | throw(Exception) [false] (0) | | Finally.cs:65:9:67:9 | catch (...) {...} | Finally.cs:66:9:67:9 | {...} | normal | | Finally.cs:65:26:65:26 | Exception e | Finally.cs:65:26:65:26 | Exception e | normal | | Finally.cs:65:35:65:35 | access to local variable e | Finally.cs:65:35:65:35 | access to local variable e | normal | @@ -1750,30 +1738,30 @@ | Finally.cs:70:13:70:41 | ...; | Finally.cs:70:13:70:40 | call to method WriteLine | normal | | Finally.cs:70:31:70:39 | "Finally" | Finally.cs:70:31:70:39 | "Finally" | normal | | Finally.cs:75:5:101:5 | {...} | Finally.cs:77:16:77:20 | ... > ... | false | -| Finally.cs:75:5:101:5 | {...} | Finally.cs:97:21:97:23 | ...-- | normal [break] | -| Finally.cs:75:5:101:5 | {...} | Finally.cs:97:21:97:23 | ...-- | return [normal] | -| Finally.cs:75:5:101:5 | {...} | Finally.cs:97:21:97:23 | ...-- | throw(Exception) [normal] | +| Finally.cs:75:5:101:5 | {...} | Finally.cs:97:21:97:23 | ...-- | normal [break] (0) | +| Finally.cs:75:5:101:5 | {...} | Finally.cs:97:21:97:23 | ...-- | return [normal] (0) | +| Finally.cs:75:5:101:5 | {...} | Finally.cs:97:21:97:23 | ...-- | throw(Exception) [normal] (1) | | Finally.cs:76:9:76:19 | ... ...; | Finally.cs:76:13:76:18 | Int32 i = ... | normal | | Finally.cs:76:13:76:18 | Int32 i = ... | Finally.cs:76:13:76:18 | Int32 i = ... | normal | | Finally.cs:76:17:76:18 | 10 | Finally.cs:76:17:76:18 | 10 | normal | | Finally.cs:77:9:100:9 | while (...) ... | Finally.cs:77:16:77:20 | ... > ... | false | -| Finally.cs:77:9:100:9 | while (...) ... | Finally.cs:97:21:97:23 | ...-- | normal [break] | -| Finally.cs:77:9:100:9 | while (...) ... | Finally.cs:97:21:97:23 | ...-- | return [normal] | -| Finally.cs:77:9:100:9 | while (...) ... | Finally.cs:97:21:97:23 | ...-- | throw(Exception) [normal] | +| Finally.cs:77:9:100:9 | while (...) ... | Finally.cs:97:21:97:23 | ...-- | normal [break] (0) | +| Finally.cs:77:9:100:9 | while (...) ... | Finally.cs:97:21:97:23 | ...-- | return [normal] (0) | +| Finally.cs:77:9:100:9 | while (...) ... | Finally.cs:97:21:97:23 | ...-- | throw(Exception) [normal] (1) | | Finally.cs:77:16:77:16 | access to local variable i | Finally.cs:77:16:77:16 | access to local variable i | normal | | Finally.cs:77:16:77:20 | ... > ... | Finally.cs:77:16:77:20 | ... > ... | false | | Finally.cs:77:16:77:20 | ... > ... | Finally.cs:77:16:77:20 | ... > ... | true | | Finally.cs:77:20:77:20 | 0 | Finally.cs:77:20:77:20 | 0 | normal | -| Finally.cs:78:9:100:9 | {...} | Finally.cs:97:21:97:23 | ...-- | break [normal] | -| Finally.cs:78:9:100:9 | {...} | Finally.cs:97:21:97:23 | ...-- | continue [normal] | +| Finally.cs:78:9:100:9 | {...} | Finally.cs:97:21:97:23 | ...-- | break [normal] (0) | +| Finally.cs:78:9:100:9 | {...} | Finally.cs:97:21:97:23 | ...-- | continue [normal] (0) | | Finally.cs:78:9:100:9 | {...} | Finally.cs:97:21:97:23 | ...-- | normal | -| Finally.cs:78:9:100:9 | {...} | Finally.cs:97:21:97:23 | ...-- | return [normal] | -| Finally.cs:78:9:100:9 | {...} | Finally.cs:97:21:97:23 | ...-- | throw(Exception) [normal] | -| Finally.cs:79:13:99:13 | try {...} ... | Finally.cs:97:21:97:23 | ...-- | break [normal] | -| Finally.cs:79:13:99:13 | try {...} ... | Finally.cs:97:21:97:23 | ...-- | continue [normal] | +| Finally.cs:78:9:100:9 | {...} | Finally.cs:97:21:97:23 | ...-- | return [normal] (0) | +| Finally.cs:78:9:100:9 | {...} | Finally.cs:97:21:97:23 | ...-- | throw(Exception) [normal] (1) | +| Finally.cs:79:13:99:13 | try {...} ... | Finally.cs:97:21:97:23 | ...-- | break [normal] (0) | +| Finally.cs:79:13:99:13 | try {...} ... | Finally.cs:97:21:97:23 | ...-- | continue [normal] (0) | | Finally.cs:79:13:99:13 | try {...} ... | Finally.cs:97:21:97:23 | ...-- | normal | -| Finally.cs:79:13:99:13 | try {...} ... | Finally.cs:97:21:97:23 | ...-- | return [normal] | -| Finally.cs:79:13:99:13 | try {...} ... | Finally.cs:97:21:97:23 | ...-- | throw(Exception) [normal] | +| Finally.cs:79:13:99:13 | try {...} ... | Finally.cs:97:21:97:23 | ...-- | return [normal] (0) | +| Finally.cs:79:13:99:13 | try {...} ... | Finally.cs:97:21:97:23 | ...-- | throw(Exception) [normal] (1) | | Finally.cs:80:13:87:13 | {...} | Finally.cs:82:21:82:27 | return ...; | return | | Finally.cs:80:13:87:13 | {...} | Finally.cs:84:21:84:29 | continue; | continue | | Finally.cs:80:13:87:13 | {...} | Finally.cs:85:21:85:26 | ... == ... | false | @@ -1800,9 +1788,9 @@ | Finally.cs:85:26:85:26 | 2 | Finally.cs:85:26:85:26 | 2 | normal | | Finally.cs:86:21:86:26 | break; | Finally.cs:86:21:86:26 | break; | break | | Finally.cs:89:13:99:13 | {...} | Finally.cs:97:21:97:23 | ...-- | normal | -| Finally.cs:89:13:99:13 | {...} | Finally.cs:97:21:97:23 | ...-- | throw(Exception) [normal] | +| Finally.cs:89:13:99:13 | {...} | Finally.cs:97:21:97:23 | ...-- | throw(Exception) [normal] (1) | | Finally.cs:90:17:98:17 | try {...} ... | Finally.cs:97:21:97:23 | ...-- | normal | -| Finally.cs:90:17:98:17 | try {...} ... | Finally.cs:97:21:97:23 | ...-- | throw(Exception) [normal] | +| Finally.cs:90:17:98:17 | try {...} ... | Finally.cs:97:21:97:23 | ...-- | throw(Exception) [normal] (1) | | Finally.cs:91:17:94:17 | {...} | Finally.cs:92:25:92:30 | ... == ... | false | | Finally.cs:91:17:94:17 | {...} | Finally.cs:93:25:93:46 | throw ...; | throw(Exception) | | Finally.cs:91:17:94:17 | {...} | Finally.cs:93:31:93:45 | object creation of type Exception | throw(Exception) | @@ -1822,25 +1810,25 @@ | Finally.cs:97:21:97:23 | ...-- | Finally.cs:97:21:97:23 | ...-- | normal | | Finally.cs:97:21:97:24 | ...; | Finally.cs:97:21:97:23 | ...-- | normal | | Finally.cs:104:5:119:5 | {...} | Finally.cs:116:17:116:32 | ... > ... | false | -| Finally.cs:104:5:119:5 | {...} | Finally.cs:116:17:116:32 | ... > ... | return [false] | -| Finally.cs:104:5:119:5 | {...} | Finally.cs:116:17:116:32 | ... > ... | throw(Exception) [false] | -| Finally.cs:104:5:119:5 | {...} | Finally.cs:116:17:116:32 | ... > ... | throw(NullReferenceException) [false] | -| Finally.cs:104:5:119:5 | {...} | Finally.cs:116:17:116:32 | ... > ... | throw(OutOfMemoryException) [false] | +| Finally.cs:104:5:119:5 | {...} | Finally.cs:116:17:116:32 | ... > ... | return [false] (0) | +| Finally.cs:104:5:119:5 | {...} | Finally.cs:116:17:116:32 | ... > ... | throw(Exception) [false] (0) | +| Finally.cs:104:5:119:5 | {...} | Finally.cs:116:17:116:32 | ... > ... | throw(NullReferenceException) [false] (0) | +| Finally.cs:104:5:119:5 | {...} | Finally.cs:116:17:116:32 | ... > ... | throw(OutOfMemoryException) [false] (0) | | Finally.cs:104:5:119:5 | {...} | Finally.cs:117:17:117:36 | call to method WriteLine | normal | -| Finally.cs:104:5:119:5 | {...} | Finally.cs:117:17:117:36 | call to method WriteLine | return [normal] | -| Finally.cs:104:5:119:5 | {...} | Finally.cs:117:17:117:36 | call to method WriteLine | throw(Exception) [normal] | -| Finally.cs:104:5:119:5 | {...} | Finally.cs:117:17:117:36 | call to method WriteLine | throw(NullReferenceException) [normal] | -| Finally.cs:104:5:119:5 | {...} | Finally.cs:117:17:117:36 | call to method WriteLine | throw(OutOfMemoryException) [normal] | +| Finally.cs:104:5:119:5 | {...} | Finally.cs:117:17:117:36 | call to method WriteLine | return [normal] (0) | +| Finally.cs:104:5:119:5 | {...} | Finally.cs:117:17:117:36 | call to method WriteLine | throw(Exception) [normal] (0) | +| Finally.cs:104:5:119:5 | {...} | Finally.cs:117:17:117:36 | call to method WriteLine | throw(NullReferenceException) [normal] (0) | +| Finally.cs:104:5:119:5 | {...} | Finally.cs:117:17:117:36 | call to method WriteLine | throw(OutOfMemoryException) [normal] (0) | | Finally.cs:105:9:118:9 | try {...} ... | Finally.cs:116:17:116:32 | ... > ... | false | -| Finally.cs:105:9:118:9 | try {...} ... | Finally.cs:116:17:116:32 | ... > ... | return [false] | -| Finally.cs:105:9:118:9 | try {...} ... | Finally.cs:116:17:116:32 | ... > ... | throw(Exception) [false] | -| Finally.cs:105:9:118:9 | try {...} ... | Finally.cs:116:17:116:32 | ... > ... | throw(NullReferenceException) [false] | -| Finally.cs:105:9:118:9 | try {...} ... | Finally.cs:116:17:116:32 | ... > ... | throw(OutOfMemoryException) [false] | +| Finally.cs:105:9:118:9 | try {...} ... | Finally.cs:116:17:116:32 | ... > ... | return [false] (0) | +| Finally.cs:105:9:118:9 | try {...} ... | Finally.cs:116:17:116:32 | ... > ... | throw(Exception) [false] (0) | +| Finally.cs:105:9:118:9 | try {...} ... | Finally.cs:116:17:116:32 | ... > ... | throw(NullReferenceException) [false] (0) | +| Finally.cs:105:9:118:9 | try {...} ... | Finally.cs:116:17:116:32 | ... > ... | throw(OutOfMemoryException) [false] (0) | | Finally.cs:105:9:118:9 | try {...} ... | Finally.cs:117:17:117:36 | call to method WriteLine | normal | -| Finally.cs:105:9:118:9 | try {...} ... | Finally.cs:117:17:117:36 | call to method WriteLine | return [normal] | -| Finally.cs:105:9:118:9 | try {...} ... | Finally.cs:117:17:117:36 | call to method WriteLine | throw(Exception) [normal] | -| Finally.cs:105:9:118:9 | try {...} ... | Finally.cs:117:17:117:36 | call to method WriteLine | throw(NullReferenceException) [normal] | -| Finally.cs:105:9:118:9 | try {...} ... | Finally.cs:117:17:117:36 | call to method WriteLine | throw(OutOfMemoryException) [normal] | +| Finally.cs:105:9:118:9 | try {...} ... | Finally.cs:117:17:117:36 | call to method WriteLine | return [normal] (0) | +| Finally.cs:105:9:118:9 | try {...} ... | Finally.cs:117:17:117:36 | call to method WriteLine | throw(Exception) [normal] (0) | +| Finally.cs:105:9:118:9 | try {...} ... | Finally.cs:117:17:117:36 | call to method WriteLine | throw(NullReferenceException) [normal] (0) | +| Finally.cs:105:9:118:9 | try {...} ... | Finally.cs:117:17:117:36 | call to method WriteLine | throw(OutOfMemoryException) [normal] (0) | | Finally.cs:106:9:111:9 | {...} | Finally.cs:107:17:107:21 | access to field Field | throw(NullReferenceException) | | Finally.cs:106:9:111:9 | {...} | Finally.cs:107:17:107:28 | access to property Length | throw(Exception) | | Finally.cs:106:9:111:9 | {...} | Finally.cs:107:17:107:28 | access to property Length | throw(NullReferenceException) | @@ -1935,24 +1923,18 @@ | Finally.cs:128:9:130:9 | {...} | Finally.cs:129:13:129:13 | ; | normal | | Finally.cs:129:13:129:13 | ; | Finally.cs:129:13:129:13 | ; | normal | | Finally.cs:134:5:145:5 | {...} | Finally.cs:141:13:141:44 | throw ...; | throw(ArgumentException) | -| Finally.cs:134:5:145:5 | {...} | Finally.cs:142:13:142:37 | call to method WriteLine | throw(Exception) [normal] | -| Finally.cs:134:5:145:5 | {...} | Finally.cs:142:13:142:37 | call to method WriteLine | throw(OutOfMemoryException) [normal] | +| Finally.cs:134:5:145:5 | {...} | Finally.cs:142:13:142:37 | call to method WriteLine | throw(Exception) [normal] (0) | | Finally.cs:134:5:145:5 | {...} | Finally.cs:144:9:144:33 | call to method WriteLine | normal | | Finally.cs:135:9:143:9 | try {...} ... | Finally.cs:141:13:141:44 | throw ...; | throw(ArgumentException) | | Finally.cs:135:9:143:9 | try {...} ... | Finally.cs:142:13:142:37 | call to method WriteLine | normal | -| Finally.cs:135:9:143:9 | try {...} ... | Finally.cs:142:13:142:37 | call to method WriteLine | throw(Exception) [normal] | -| Finally.cs:135:9:143:9 | try {...} ... | Finally.cs:142:13:142:37 | call to method WriteLine | throw(OutOfMemoryException) [normal] | +| Finally.cs:135:9:143:9 | try {...} ... | Finally.cs:142:13:142:37 | call to method WriteLine | throw(Exception) [normal] (0) | | Finally.cs:136:9:138:9 | {...} | Finally.cs:137:13:137:36 | call to method WriteLine | normal | | Finally.cs:136:9:138:9 | {...} | Finally.cs:137:13:137:36 | call to method WriteLine | throw(Exception) | -| Finally.cs:136:9:138:9 | {...} | Finally.cs:137:31:137:35 | "Try" | throw(OutOfMemoryException) | | Finally.cs:137:13:137:36 | call to method WriteLine | Finally.cs:137:13:137:36 | call to method WriteLine | normal | | Finally.cs:137:13:137:36 | call to method WriteLine | Finally.cs:137:13:137:36 | call to method WriteLine | throw(Exception) | -| Finally.cs:137:13:137:36 | call to method WriteLine | Finally.cs:137:31:137:35 | "Try" | throw(OutOfMemoryException) | | Finally.cs:137:13:137:37 | ...; | Finally.cs:137:13:137:36 | call to method WriteLine | normal | | Finally.cs:137:13:137:37 | ...; | Finally.cs:137:13:137:36 | call to method WriteLine | throw(Exception) | -| Finally.cs:137:13:137:37 | ...; | Finally.cs:137:31:137:35 | "Try" | throw(OutOfMemoryException) | | Finally.cs:137:31:137:35 | "Try" | Finally.cs:137:31:137:35 | "Try" | normal | -| Finally.cs:137:31:137:35 | "Try" | Finally.cs:137:31:137:35 | "Try" | throw(OutOfMemoryException) | | Finally.cs:140:9:143:9 | {...} | Finally.cs:141:13:141:44 | throw ...; | throw(ArgumentException) | | Finally.cs:140:9:143:9 | {...} | Finally.cs:142:13:142:37 | call to method WriteLine | normal | | Finally.cs:141:13:141:44 | throw ...; | Finally.cs:141:13:141:44 | throw ...; | throw(ArgumentException) | @@ -1965,23 +1947,23 @@ | Finally.cs:144:9:144:34 | ...; | Finally.cs:144:9:144:33 | call to method WriteLine | normal | | Finally.cs:144:27:144:32 | "Dead" | Finally.cs:144:27:144:32 | "Dead" | normal | | Finally.cs:148:5:170:5 | {...} | Finally.cs:158:21:158:36 | ... == ... | false | -| Finally.cs:148:5:170:5 | {...} | Finally.cs:158:21:158:36 | ... == ... | throw(ArgumentNullException) [false] | -| Finally.cs:148:5:170:5 | {...} | Finally.cs:158:21:158:36 | ... == ... | throw(Exception) [false] | +| Finally.cs:148:5:170:5 | {...} | Finally.cs:158:21:158:36 | ... == ... | throw(ArgumentNullException) [false] (0) | +| Finally.cs:148:5:170:5 | {...} | Finally.cs:158:21:158:36 | ... == ... | throw(Exception) [false] (0) | | Finally.cs:148:5:170:5 | {...} | Finally.cs:163:17:163:42 | call to method WriteLine | normal | -| Finally.cs:148:5:170:5 | {...} | Finally.cs:163:17:163:42 | call to method WriteLine | throw(ArgumentNullException) [normal] | -| Finally.cs:148:5:170:5 | {...} | Finally.cs:163:17:163:42 | call to method WriteLine | throw(Exception) [normal] | +| Finally.cs:148:5:170:5 | {...} | Finally.cs:163:17:163:42 | call to method WriteLine | throw(ArgumentNullException) [normal] (0) | +| Finally.cs:148:5:170:5 | {...} | Finally.cs:163:17:163:42 | call to method WriteLine | throw(Exception) [normal] (0) | | Finally.cs:148:5:170:5 | {...} | Finally.cs:167:17:167:37 | call to method WriteLine | normal | -| Finally.cs:148:5:170:5 | {...} | Finally.cs:167:17:167:37 | call to method WriteLine | throw(ArgumentNullException) [normal] | -| Finally.cs:148:5:170:5 | {...} | Finally.cs:167:17:167:37 | call to method WriteLine | throw(Exception) [normal] | +| Finally.cs:148:5:170:5 | {...} | Finally.cs:167:17:167:37 | call to method WriteLine | throw(ArgumentNullException) [normal] (0) | +| Finally.cs:148:5:170:5 | {...} | Finally.cs:167:17:167:37 | call to method WriteLine | throw(Exception) [normal] (0) | | Finally.cs:149:9:169:9 | try {...} ... | Finally.cs:158:21:158:36 | ... == ... | false | -| Finally.cs:149:9:169:9 | try {...} ... | Finally.cs:158:21:158:36 | ... == ... | throw(ArgumentNullException) [false] | -| Finally.cs:149:9:169:9 | try {...} ... | Finally.cs:158:21:158:36 | ... == ... | throw(Exception) [false] | +| Finally.cs:149:9:169:9 | try {...} ... | Finally.cs:158:21:158:36 | ... == ... | throw(ArgumentNullException) [false] (0) | +| Finally.cs:149:9:169:9 | try {...} ... | Finally.cs:158:21:158:36 | ... == ... | throw(Exception) [false] (0) | | Finally.cs:149:9:169:9 | try {...} ... | Finally.cs:163:17:163:42 | call to method WriteLine | normal | -| Finally.cs:149:9:169:9 | try {...} ... | Finally.cs:163:17:163:42 | call to method WriteLine | throw(ArgumentNullException) [normal] | -| Finally.cs:149:9:169:9 | try {...} ... | Finally.cs:163:17:163:42 | call to method WriteLine | throw(Exception) [normal] | +| Finally.cs:149:9:169:9 | try {...} ... | Finally.cs:163:17:163:42 | call to method WriteLine | throw(ArgumentNullException) [normal] (0) | +| Finally.cs:149:9:169:9 | try {...} ... | Finally.cs:163:17:163:42 | call to method WriteLine | throw(Exception) [normal] (0) | | Finally.cs:149:9:169:9 | try {...} ... | Finally.cs:167:17:167:37 | call to method WriteLine | normal | -| Finally.cs:149:9:169:9 | try {...} ... | Finally.cs:167:17:167:37 | call to method WriteLine | throw(ArgumentNullException) [normal] | -| Finally.cs:149:9:169:9 | try {...} ... | Finally.cs:167:17:167:37 | call to method WriteLine | throw(Exception) [normal] | +| Finally.cs:149:9:169:9 | try {...} ... | Finally.cs:167:17:167:37 | call to method WriteLine | throw(ArgumentNullException) [normal] (0) | +| Finally.cs:149:9:169:9 | try {...} ... | Finally.cs:167:17:167:37 | call to method WriteLine | throw(Exception) [normal] (0) | | Finally.cs:150:9:153:9 | {...} | Finally.cs:151:17:151:28 | ... == ... | false | | Finally.cs:150:9:153:9 | {...} | Finally.cs:152:17:152:50 | throw ...; | throw(ArgumentNullException) | | Finally.cs:150:9:153:9 | {...} | Finally.cs:152:23:152:49 | object creation of type ArgumentNullException | throw(Exception) | @@ -2007,13 +1989,11 @@ | Finally.cs:157:13:160:13 | {...} | Finally.cs:158:21:158:36 | ... == ... | false | | Finally.cs:157:13:160:13 | {...} | Finally.cs:159:21:159:45 | throw ...; | throw(Exception) | | Finally.cs:157:13:160:13 | {...} | Finally.cs:159:27:159:44 | object creation of type Exception | throw(Exception) | -| Finally.cs:157:13:160:13 | {...} | Finally.cs:159:41:159:43 | "1" | throw(OutOfMemoryException) | | Finally.cs:158:17:159:45 | if (...) ... | Finally.cs:158:21:158:31 | access to property Length | throw(Exception) | | Finally.cs:158:17:159:45 | if (...) ... | Finally.cs:158:21:158:31 | access to property Length | throw(NullReferenceException) | | Finally.cs:158:17:159:45 | if (...) ... | Finally.cs:158:21:158:36 | ... == ... | false | | Finally.cs:158:17:159:45 | if (...) ... | Finally.cs:159:21:159:45 | throw ...; | throw(Exception) | | Finally.cs:158:17:159:45 | if (...) ... | Finally.cs:159:27:159:44 | object creation of type Exception | throw(Exception) | -| Finally.cs:158:17:159:45 | if (...) ... | Finally.cs:159:41:159:43 | "1" | throw(OutOfMemoryException) | | Finally.cs:158:21:158:24 | access to parameter args | Finally.cs:158:21:158:24 | access to parameter args | normal | | Finally.cs:158:21:158:31 | access to property Length | Finally.cs:158:21:158:31 | access to property Length | normal | | Finally.cs:158:21:158:31 | access to property Length | Finally.cs:158:21:158:31 | access to property Length | throw(Exception) | @@ -2025,12 +2005,9 @@ | Finally.cs:158:36:158:36 | 1 | Finally.cs:158:36:158:36 | 1 | normal | | Finally.cs:159:21:159:45 | throw ...; | Finally.cs:159:21:159:45 | throw ...; | throw(Exception) | | Finally.cs:159:21:159:45 | throw ...; | Finally.cs:159:27:159:44 | object creation of type Exception | throw(Exception) | -| Finally.cs:159:21:159:45 | throw ...; | Finally.cs:159:41:159:43 | "1" | throw(OutOfMemoryException) | | Finally.cs:159:27:159:44 | object creation of type Exception | Finally.cs:159:27:159:44 | object creation of type Exception | normal | | Finally.cs:159:27:159:44 | object creation of type Exception | Finally.cs:159:27:159:44 | object creation of type Exception | throw(Exception) | -| Finally.cs:159:27:159:44 | object creation of type Exception | Finally.cs:159:41:159:43 | "1" | throw(OutOfMemoryException) | | Finally.cs:159:41:159:43 | "1" | Finally.cs:159:41:159:43 | "1" | normal | -| Finally.cs:159:41:159:43 | "1" | Finally.cs:159:41:159:43 | "1" | throw(OutOfMemoryException) | | Finally.cs:161:13:164:13 | catch (...) {...} | Finally.cs:161:13:164:13 | catch (...) {...} | no-match | | Finally.cs:161:13:164:13 | catch (...) {...} | Finally.cs:161:39:161:54 | ... == ... | false | | Finally.cs:161:13:164:13 | catch (...) {...} | Finally.cs:163:17:163:42 | call to method WriteLine | normal | @@ -2052,26 +2029,26 @@ | Finally.cs:167:17:167:38 | ...; | Finally.cs:167:17:167:37 | call to method WriteLine | normal | | Finally.cs:167:35:167:36 | "" | Finally.cs:167:35:167:36 | "" | normal | | Finally.cs:177:5:193:5 | {...} | Finally.cs:186:21:186:22 | access to parameter b2 | false | -| Finally.cs:177:5:193:5 | {...} | Finally.cs:186:21:186:22 | access to parameter b2 | throw(Exception) [false] | -| Finally.cs:177:5:193:5 | {...} | Finally.cs:186:21:186:22 | access to parameter b2 | throw(ExceptionA) [false] | -| Finally.cs:177:5:193:5 | {...} | Finally.cs:188:13:191:13 | catch (...) {...} | throw(Exception) [no-match] | -| Finally.cs:177:5:193:5 | {...} | Finally.cs:188:13:191:13 | catch (...) {...} | throw(ExceptionB) [no-match] | -| Finally.cs:177:5:193:5 | {...} | Finally.cs:188:38:188:39 | access to parameter b2 | throw(Exception) [false] | -| Finally.cs:177:5:193:5 | {...} | Finally.cs:188:38:188:39 | access to parameter b2 | throw(ExceptionB) [false] | +| Finally.cs:177:5:193:5 | {...} | Finally.cs:186:21:186:22 | access to parameter b2 | throw(Exception) [false] (0) | +| Finally.cs:177:5:193:5 | {...} | Finally.cs:186:21:186:22 | access to parameter b2 | throw(ExceptionA) [false] (0) | +| Finally.cs:177:5:193:5 | {...} | Finally.cs:188:13:191:13 | catch (...) {...} | throw(Exception) [no-match] (0) | +| Finally.cs:177:5:193:5 | {...} | Finally.cs:188:13:191:13 | catch (...) {...} | throw(ExceptionB) [no-match] (0) | +| Finally.cs:177:5:193:5 | {...} | Finally.cs:188:38:188:39 | access to parameter b2 | throw(Exception) [false] (0) | +| Finally.cs:177:5:193:5 | {...} | Finally.cs:188:38:188:39 | access to parameter b2 | throw(ExceptionB) [false] (0) | | Finally.cs:177:5:193:5 | {...} | Finally.cs:190:21:190:22 | access to parameter b1 | false | -| Finally.cs:177:5:193:5 | {...} | Finally.cs:190:21:190:22 | access to parameter b1 | throw(Exception) [false] | -| Finally.cs:177:5:193:5 | {...} | Finally.cs:190:21:190:22 | access to parameter b1 | throw(ExceptionA) [false] | +| Finally.cs:177:5:193:5 | {...} | Finally.cs:190:21:190:22 | access to parameter b1 | throw(Exception) [false] (0) | +| Finally.cs:177:5:193:5 | {...} | Finally.cs:190:21:190:22 | access to parameter b1 | throw(ExceptionA) [false] (0) | | Finally.cs:177:5:193:5 | {...} | Finally.cs:190:25:190:47 | throw ...; | throw(ExceptionC) | | Finally.cs:178:9:192:9 | try {...} ... | Finally.cs:186:21:186:22 | access to parameter b2 | false | -| Finally.cs:178:9:192:9 | try {...} ... | Finally.cs:186:21:186:22 | access to parameter b2 | throw(Exception) [false] | -| Finally.cs:178:9:192:9 | try {...} ... | Finally.cs:186:21:186:22 | access to parameter b2 | throw(ExceptionA) [false] | -| Finally.cs:178:9:192:9 | try {...} ... | Finally.cs:188:13:191:13 | catch (...) {...} | throw(Exception) [no-match] | -| Finally.cs:178:9:192:9 | try {...} ... | Finally.cs:188:13:191:13 | catch (...) {...} | throw(ExceptionB) [no-match] | -| Finally.cs:178:9:192:9 | try {...} ... | Finally.cs:188:38:188:39 | access to parameter b2 | throw(Exception) [false] | -| Finally.cs:178:9:192:9 | try {...} ... | Finally.cs:188:38:188:39 | access to parameter b2 | throw(ExceptionB) [false] | +| Finally.cs:178:9:192:9 | try {...} ... | Finally.cs:186:21:186:22 | access to parameter b2 | throw(Exception) [false] (0) | +| Finally.cs:178:9:192:9 | try {...} ... | Finally.cs:186:21:186:22 | access to parameter b2 | throw(ExceptionA) [false] (0) | +| Finally.cs:178:9:192:9 | try {...} ... | Finally.cs:188:13:191:13 | catch (...) {...} | throw(Exception) [no-match] (0) | +| Finally.cs:178:9:192:9 | try {...} ... | Finally.cs:188:13:191:13 | catch (...) {...} | throw(ExceptionB) [no-match] (0) | +| Finally.cs:178:9:192:9 | try {...} ... | Finally.cs:188:38:188:39 | access to parameter b2 | throw(Exception) [false] (0) | +| Finally.cs:178:9:192:9 | try {...} ... | Finally.cs:188:38:188:39 | access to parameter b2 | throw(ExceptionB) [false] (0) | | Finally.cs:178:9:192:9 | try {...} ... | Finally.cs:190:21:190:22 | access to parameter b1 | false | -| Finally.cs:178:9:192:9 | try {...} ... | Finally.cs:190:21:190:22 | access to parameter b1 | throw(Exception) [false] | -| Finally.cs:178:9:192:9 | try {...} ... | Finally.cs:190:21:190:22 | access to parameter b1 | throw(ExceptionA) [false] | +| Finally.cs:178:9:192:9 | try {...} ... | Finally.cs:190:21:190:22 | access to parameter b1 | throw(Exception) [false] (0) | +| Finally.cs:178:9:192:9 | try {...} ... | Finally.cs:190:21:190:22 | access to parameter b1 | throw(ExceptionA) [false] (0) | | Finally.cs:178:9:192:9 | try {...} ... | Finally.cs:190:25:190:47 | throw ...; | throw(ExceptionC) | | Finally.cs:179:9:181:9 | {...} | Finally.cs:180:17:180:18 | access to parameter b1 | false | | Finally.cs:179:9:181:9 | {...} | Finally.cs:180:21:180:43 | throw ...; | throw(ExceptionA) | @@ -2086,17 +2063,17 @@ | Finally.cs:180:27:180:42 | object creation of type ExceptionA | Finally.cs:180:27:180:42 | object creation of type ExceptionA | normal | | Finally.cs:180:27:180:42 | object creation of type ExceptionA | Finally.cs:180:27:180:42 | object creation of type ExceptionA | throw(Exception) | | Finally.cs:183:9:192:9 | {...} | Finally.cs:186:21:186:22 | access to parameter b2 | false | -| Finally.cs:183:9:192:9 | {...} | Finally.cs:188:13:191:13 | catch (...) {...} | throw(Exception) [no-match] | -| Finally.cs:183:9:192:9 | {...} | Finally.cs:188:13:191:13 | catch (...) {...} | throw(ExceptionB) [no-match] | -| Finally.cs:183:9:192:9 | {...} | Finally.cs:188:38:188:39 | access to parameter b2 | throw(Exception) [false] | -| Finally.cs:183:9:192:9 | {...} | Finally.cs:188:38:188:39 | access to parameter b2 | throw(ExceptionB) [false] | +| Finally.cs:183:9:192:9 | {...} | Finally.cs:188:13:191:13 | catch (...) {...} | throw(Exception) [no-match] (0) | +| Finally.cs:183:9:192:9 | {...} | Finally.cs:188:13:191:13 | catch (...) {...} | throw(ExceptionB) [no-match] (0) | +| Finally.cs:183:9:192:9 | {...} | Finally.cs:188:38:188:39 | access to parameter b2 | throw(Exception) [false] (0) | +| Finally.cs:183:9:192:9 | {...} | Finally.cs:188:38:188:39 | access to parameter b2 | throw(ExceptionB) [false] (0) | | Finally.cs:183:9:192:9 | {...} | Finally.cs:190:21:190:22 | access to parameter b1 | false | | Finally.cs:183:9:192:9 | {...} | Finally.cs:190:25:190:47 | throw ...; | throw(ExceptionC) | | Finally.cs:184:13:191:13 | try {...} ... | Finally.cs:186:21:186:22 | access to parameter b2 | false | -| Finally.cs:184:13:191:13 | try {...} ... | Finally.cs:188:13:191:13 | catch (...) {...} | throw(Exception) [no-match] | -| Finally.cs:184:13:191:13 | try {...} ... | Finally.cs:188:13:191:13 | catch (...) {...} | throw(ExceptionB) [no-match] | -| Finally.cs:184:13:191:13 | try {...} ... | Finally.cs:188:38:188:39 | access to parameter b2 | throw(Exception) [false] | -| Finally.cs:184:13:191:13 | try {...} ... | Finally.cs:188:38:188:39 | access to parameter b2 | throw(ExceptionB) [false] | +| Finally.cs:184:13:191:13 | try {...} ... | Finally.cs:188:13:191:13 | catch (...) {...} | throw(Exception) [no-match] (0) | +| Finally.cs:184:13:191:13 | try {...} ... | Finally.cs:188:13:191:13 | catch (...) {...} | throw(ExceptionB) [no-match] (0) | +| Finally.cs:184:13:191:13 | try {...} ... | Finally.cs:188:38:188:39 | access to parameter b2 | throw(Exception) [false] (0) | +| Finally.cs:184:13:191:13 | try {...} ... | Finally.cs:188:38:188:39 | access to parameter b2 | throw(ExceptionB) [false] (0) | | Finally.cs:184:13:191:13 | try {...} ... | Finally.cs:190:21:190:22 | access to parameter b1 | false | | Finally.cs:184:13:191:13 | try {...} ... | Finally.cs:190:25:190:47 | throw ...; | throw(ExceptionC) | | Finally.cs:185:13:187:13 | {...} | Finally.cs:186:21:186:22 | access to parameter b2 | false | @@ -2111,10 +2088,10 @@ | Finally.cs:186:25:186:47 | throw ...; | Finally.cs:186:31:186:46 | object creation of type ExceptionB | throw(Exception) | | Finally.cs:186:31:186:46 | object creation of type ExceptionB | Finally.cs:186:31:186:46 | object creation of type ExceptionB | normal | | Finally.cs:186:31:186:46 | object creation of type ExceptionB | Finally.cs:186:31:186:46 | object creation of type ExceptionB | throw(Exception) | -| Finally.cs:188:13:191:13 | catch (...) {...} | Finally.cs:188:13:191:13 | catch (...) {...} | throw(Exception) [no-match] | -| Finally.cs:188:13:191:13 | catch (...) {...} | Finally.cs:188:13:191:13 | catch (...) {...} | throw(ExceptionB) [no-match] | -| Finally.cs:188:13:191:13 | catch (...) {...} | Finally.cs:188:38:188:39 | access to parameter b2 | throw(Exception) [false] | -| Finally.cs:188:13:191:13 | catch (...) {...} | Finally.cs:188:38:188:39 | access to parameter b2 | throw(ExceptionB) [false] | +| Finally.cs:188:13:191:13 | catch (...) {...} | Finally.cs:188:13:191:13 | catch (...) {...} | throw(Exception) [no-match] (0) | +| Finally.cs:188:13:191:13 | catch (...) {...} | Finally.cs:188:13:191:13 | catch (...) {...} | throw(ExceptionB) [no-match] (0) | +| Finally.cs:188:13:191:13 | catch (...) {...} | Finally.cs:188:38:188:39 | access to parameter b2 | throw(Exception) [false] (0) | +| Finally.cs:188:13:191:13 | catch (...) {...} | Finally.cs:188:38:188:39 | access to parameter b2 | throw(ExceptionB) [false] (0) | | Finally.cs:188:13:191:13 | catch (...) {...} | Finally.cs:190:21:190:22 | access to parameter b1 | false | | Finally.cs:188:13:191:13 | catch (...) {...} | Finally.cs:190:25:190:47 | throw ...; | throw(ExceptionC) | | Finally.cs:188:38:188:39 | access to parameter b2 | Finally.cs:188:38:188:39 | access to parameter b2 | false | @@ -2127,18 +2104,18 @@ | Finally.cs:190:21:190:22 | access to parameter b1 | Finally.cs:190:21:190:22 | access to parameter b1 | true | | Finally.cs:190:25:190:47 | throw ...; | Finally.cs:190:25:190:47 | throw ...; | throw(ExceptionC) | | Finally.cs:190:31:190:46 | object creation of type ExceptionC | Finally.cs:190:31:190:46 | object creation of type ExceptionC | normal | -| Finally.cs:196:5:214:5 | {...} | Finally.cs:209:21:209:22 | access to parameter b3 | throw(Exception) [false] | -| Finally.cs:196:5:214:5 | {...} | Finally.cs:209:21:209:22 | access to parameter b3 | throw(ExceptionB) [false] | +| Finally.cs:196:5:214:5 | {...} | Finally.cs:209:21:209:22 | access to parameter b3 | throw(Exception) [false] (1) | +| Finally.cs:196:5:214:5 | {...} | Finally.cs:209:21:209:22 | access to parameter b3 | throw(ExceptionB) [false] (1) | | Finally.cs:196:5:214:5 | {...} | Finally.cs:209:25:209:47 | throw ...; | throw(ExceptionC) | -| Finally.cs:196:5:214:5 | {...} | Finally.cs:211:13:211:28 | ... = ... | throw(Exception) [normal] | -| Finally.cs:196:5:214:5 | {...} | Finally.cs:211:13:211:28 | ... = ... | throw(ExceptionA) [normal] | +| Finally.cs:196:5:214:5 | {...} | Finally.cs:211:13:211:28 | ... = ... | throw(Exception) [normal] (0) | +| Finally.cs:196:5:214:5 | {...} | Finally.cs:211:13:211:28 | ... = ... | throw(ExceptionA) [normal] (0) | | Finally.cs:196:5:214:5 | {...} | Finally.cs:213:9:213:24 | ... = ... | normal | -| Finally.cs:197:9:212:9 | try {...} ... | Finally.cs:209:21:209:22 | access to parameter b3 | throw(Exception) [false] | -| Finally.cs:197:9:212:9 | try {...} ... | Finally.cs:209:21:209:22 | access to parameter b3 | throw(ExceptionB) [false] | +| Finally.cs:197:9:212:9 | try {...} ... | Finally.cs:209:21:209:22 | access to parameter b3 | throw(Exception) [false] (1) | +| Finally.cs:197:9:212:9 | try {...} ... | Finally.cs:209:21:209:22 | access to parameter b3 | throw(ExceptionB) [false] (1) | | Finally.cs:197:9:212:9 | try {...} ... | Finally.cs:209:25:209:47 | throw ...; | throw(ExceptionC) | | Finally.cs:197:9:212:9 | try {...} ... | Finally.cs:211:13:211:28 | ... = ... | normal | -| Finally.cs:197:9:212:9 | try {...} ... | Finally.cs:211:13:211:28 | ... = ... | throw(Exception) [normal] | -| Finally.cs:197:9:212:9 | try {...} ... | Finally.cs:211:13:211:28 | ... = ... | throw(ExceptionA) [normal] | +| Finally.cs:197:9:212:9 | try {...} ... | Finally.cs:211:13:211:28 | ... = ... | throw(Exception) [normal] (0) | +| Finally.cs:197:9:212:9 | try {...} ... | Finally.cs:211:13:211:28 | ... = ... | throw(ExceptionA) [normal] (0) | | Finally.cs:198:9:200:9 | {...} | Finally.cs:199:17:199:18 | access to parameter b1 | false | | Finally.cs:198:9:200:9 | {...} | Finally.cs:199:21:199:43 | throw ...; | throw(ExceptionA) | | Finally.cs:198:9:200:9 | {...} | Finally.cs:199:27:199:42 | object creation of type ExceptionA | throw(Exception) | @@ -2151,13 +2128,13 @@ | Finally.cs:199:21:199:43 | throw ...; | Finally.cs:199:27:199:42 | object creation of type ExceptionA | throw(Exception) | | Finally.cs:199:27:199:42 | object creation of type ExceptionA | Finally.cs:199:27:199:42 | object creation of type ExceptionA | normal | | Finally.cs:199:27:199:42 | object creation of type ExceptionA | Finally.cs:199:27:199:42 | object creation of type ExceptionA | throw(Exception) | -| Finally.cs:202:9:212:9 | {...} | Finally.cs:209:21:209:22 | access to parameter b3 | throw(Exception) [false] | -| Finally.cs:202:9:212:9 | {...} | Finally.cs:209:21:209:22 | access to parameter b3 | throw(ExceptionB) [false] | +| Finally.cs:202:9:212:9 | {...} | Finally.cs:209:21:209:22 | access to parameter b3 | throw(Exception) [false] (1) | +| Finally.cs:202:9:212:9 | {...} | Finally.cs:209:21:209:22 | access to parameter b3 | throw(ExceptionB) [false] (1) | | Finally.cs:202:9:212:9 | {...} | Finally.cs:209:25:209:47 | throw ...; | throw(ExceptionC) | | Finally.cs:202:9:212:9 | {...} | Finally.cs:211:13:211:28 | ... = ... | normal | | Finally.cs:203:13:210:13 | try {...} ... | Finally.cs:209:21:209:22 | access to parameter b3 | false | -| Finally.cs:203:13:210:13 | try {...} ... | Finally.cs:209:21:209:22 | access to parameter b3 | throw(Exception) [false] | -| Finally.cs:203:13:210:13 | try {...} ... | Finally.cs:209:21:209:22 | access to parameter b3 | throw(ExceptionB) [false] | +| Finally.cs:203:13:210:13 | try {...} ... | Finally.cs:209:21:209:22 | access to parameter b3 | throw(Exception) [false] (1) | +| Finally.cs:203:13:210:13 | try {...} ... | Finally.cs:209:21:209:22 | access to parameter b3 | throw(ExceptionB) [false] (1) | | Finally.cs:203:13:210:13 | try {...} ... | Finally.cs:209:25:209:47 | throw ...; | throw(ExceptionC) | | Finally.cs:204:13:206:13 | {...} | Finally.cs:205:21:205:22 | access to parameter b2 | false | | Finally.cs:204:13:206:13 | {...} | Finally.cs:205:25:205:47 | throw ...; | throw(ExceptionB) | @@ -2193,15 +2170,11 @@ | Finally.cs:218:9:229:9 | try {...} ... | Finally.cs:228:13:228:40 | call to method WriteLine | normal | | Finally.cs:219:9:221:9 | {...} | Finally.cs:220:13:220:36 | call to method WriteLine | normal | | Finally.cs:219:9:221:9 | {...} | Finally.cs:220:13:220:36 | call to method WriteLine | throw(Exception) | -| Finally.cs:219:9:221:9 | {...} | Finally.cs:220:31:220:35 | "Try" | throw(OutOfMemoryException) | | Finally.cs:220:13:220:36 | call to method WriteLine | Finally.cs:220:13:220:36 | call to method WriteLine | normal | | Finally.cs:220:13:220:36 | call to method WriteLine | Finally.cs:220:13:220:36 | call to method WriteLine | throw(Exception) | -| Finally.cs:220:13:220:36 | call to method WriteLine | Finally.cs:220:31:220:35 | "Try" | throw(OutOfMemoryException) | | Finally.cs:220:13:220:37 | ...; | Finally.cs:220:13:220:36 | call to method WriteLine | normal | | Finally.cs:220:13:220:37 | ...; | Finally.cs:220:13:220:36 | call to method WriteLine | throw(Exception) | -| Finally.cs:220:13:220:37 | ...; | Finally.cs:220:31:220:35 | "Try" | throw(OutOfMemoryException) | | Finally.cs:220:31:220:35 | "Try" | Finally.cs:220:31:220:35 | "Try" | normal | -| Finally.cs:220:31:220:35 | "Try" | Finally.cs:220:31:220:35 | "Try" | throw(OutOfMemoryException) | | Finally.cs:222:9:225:9 | catch {...} | Finally.cs:224:13:224:38 | call to method WriteLine | normal | | Finally.cs:223:9:225:9 | {...} | Finally.cs:224:13:224:38 | call to method WriteLine | normal | | Finally.cs:224:13:224:38 | call to method WriteLine | Finally.cs:224:13:224:38 | call to method WriteLine | normal | @@ -2214,6 +2187,90 @@ | Finally.cs:230:9:230:33 | call to method WriteLine | Finally.cs:230:9:230:33 | call to method WriteLine | normal | | Finally.cs:230:9:230:34 | ...; | Finally.cs:230:9:230:33 | call to method WriteLine | normal | | Finally.cs:230:27:230:32 | "Done" | Finally.cs:230:27:230:32 | "Done" | normal | +| Finally.cs:234:5:261:5 | {...} | Finally.cs:258:13:258:46 | call to method WriteLine | throw(Exception) [normal] (0) | +| Finally.cs:234:5:261:5 | {...} | Finally.cs:258:13:258:46 | call to method WriteLine | throw(ExceptionA) [normal] (0) | +| Finally.cs:234:5:261:5 | {...} | Finally.cs:260:9:260:33 | call to method WriteLine | normal | +| Finally.cs:235:9:259:9 | try {...} ... | Finally.cs:258:13:258:46 | call to method WriteLine | normal | +| Finally.cs:235:9:259:9 | try {...} ... | Finally.cs:258:13:258:46 | call to method WriteLine | throw(Exception) [normal] (0) | +| Finally.cs:235:9:259:9 | try {...} ... | Finally.cs:258:13:258:46 | call to method WriteLine | throw(ExceptionA) [normal] (0) | +| Finally.cs:236:9:255:9 | {...} | Finally.cs:251:21:251:54 | call to method WriteLine | throw(Exception) [normal] (0) | +| Finally.cs:236:9:255:9 | {...} | Finally.cs:251:21:251:54 | call to method WriteLine | throw(Exception) [normal] (1) | +| Finally.cs:236:9:255:9 | {...} | Finally.cs:251:21:251:54 | call to method WriteLine | throw(ExceptionA) [normal] (0) | +| Finally.cs:236:9:255:9 | {...} | Finally.cs:251:21:251:54 | call to method WriteLine | throw(ExceptionA) [normal] (1) | +| Finally.cs:236:9:255:9 | {...} | Finally.cs:254:13:254:44 | call to method WriteLine | normal | +| Finally.cs:236:9:255:9 | {...} | Finally.cs:254:13:254:44 | call to method WriteLine | throw(Exception) | +| Finally.cs:237:13:253:13 | try {...} ... | Finally.cs:251:21:251:54 | call to method WriteLine | normal | +| Finally.cs:237:13:253:13 | try {...} ... | Finally.cs:251:21:251:54 | call to method WriteLine | throw(Exception) [normal] (0) | +| Finally.cs:237:13:253:13 | try {...} ... | Finally.cs:251:21:251:54 | call to method WriteLine | throw(Exception) [normal] (1) | +| Finally.cs:237:13:253:13 | try {...} ... | Finally.cs:251:21:251:54 | call to method WriteLine | throw(ExceptionA) [normal] (0) | +| Finally.cs:237:13:253:13 | try {...} ... | Finally.cs:251:21:251:54 | call to method WriteLine | throw(ExceptionA) [normal] (1) | +| Finally.cs:238:13:241:13 | {...} | Finally.cs:239:21:239:22 | access to parameter b1 | false | +| Finally.cs:238:13:241:13 | {...} | Finally.cs:240:21:240:43 | throw ...; | throw(ExceptionA) | +| Finally.cs:238:13:241:13 | {...} | Finally.cs:240:27:240:42 | object creation of type ExceptionA | throw(Exception) | +| Finally.cs:239:17:240:43 | if (...) ... | Finally.cs:239:21:239:22 | access to parameter b1 | false | +| Finally.cs:239:17:240:43 | if (...) ... | Finally.cs:240:21:240:43 | throw ...; | throw(ExceptionA) | +| Finally.cs:239:17:240:43 | if (...) ... | Finally.cs:240:27:240:42 | object creation of type ExceptionA | throw(Exception) | +| Finally.cs:239:21:239:22 | access to parameter b1 | Finally.cs:239:21:239:22 | access to parameter b1 | false | +| Finally.cs:239:21:239:22 | access to parameter b1 | Finally.cs:239:21:239:22 | access to parameter b1 | true | +| Finally.cs:240:21:240:43 | throw ...; | Finally.cs:240:21:240:43 | throw ...; | throw(ExceptionA) | +| Finally.cs:240:21:240:43 | throw ...; | Finally.cs:240:27:240:42 | object creation of type ExceptionA | throw(Exception) | +| Finally.cs:240:27:240:42 | object creation of type ExceptionA | Finally.cs:240:27:240:42 | object creation of type ExceptionA | normal | +| Finally.cs:240:27:240:42 | object creation of type ExceptionA | Finally.cs:240:27:240:42 | object creation of type ExceptionA | throw(Exception) | +| Finally.cs:243:13:253:13 | {...} | Finally.cs:251:21:251:54 | call to method WriteLine | normal | +| Finally.cs:243:13:253:13 | {...} | Finally.cs:251:21:251:54 | call to method WriteLine | throw(Exception) [normal] (1) | +| Finally.cs:243:13:253:13 | {...} | Finally.cs:251:21:251:54 | call to method WriteLine | throw(ExceptionA) [normal] (1) | +| Finally.cs:244:17:252:17 | try {...} ... | Finally.cs:251:21:251:54 | call to method WriteLine | normal | +| Finally.cs:244:17:252:17 | try {...} ... | Finally.cs:251:21:251:54 | call to method WriteLine | throw(Exception) [normal] (1) | +| Finally.cs:244:17:252:17 | try {...} ... | Finally.cs:251:21:251:54 | call to method WriteLine | throw(ExceptionA) [normal] (1) | +| Finally.cs:245:17:248:17 | {...} | Finally.cs:246:25:246:26 | access to parameter b2 | false | +| Finally.cs:245:17:248:17 | {...} | Finally.cs:247:25:247:47 | throw ...; | throw(ExceptionA) | +| Finally.cs:245:17:248:17 | {...} | Finally.cs:247:31:247:46 | object creation of type ExceptionA | throw(Exception) | +| Finally.cs:246:21:247:47 | if (...) ... | Finally.cs:246:25:246:26 | access to parameter b2 | false | +| Finally.cs:246:21:247:47 | if (...) ... | Finally.cs:247:25:247:47 | throw ...; | throw(ExceptionA) | +| Finally.cs:246:21:247:47 | if (...) ... | Finally.cs:247:31:247:46 | object creation of type ExceptionA | throw(Exception) | +| Finally.cs:246:25:246:26 | access to parameter b2 | Finally.cs:246:25:246:26 | access to parameter b2 | false | +| Finally.cs:246:25:246:26 | access to parameter b2 | Finally.cs:246:25:246:26 | access to parameter b2 | true | +| Finally.cs:247:25:247:47 | throw ...; | Finally.cs:247:25:247:47 | throw ...; | throw(ExceptionA) | +| Finally.cs:247:25:247:47 | throw ...; | Finally.cs:247:31:247:46 | object creation of type ExceptionA | throw(Exception) | +| Finally.cs:247:31:247:46 | object creation of type ExceptionA | Finally.cs:247:31:247:46 | object creation of type ExceptionA | normal | +| Finally.cs:247:31:247:46 | object creation of type ExceptionA | Finally.cs:247:31:247:46 | object creation of type ExceptionA | throw(Exception) | +| Finally.cs:250:17:252:17 | {...} | Finally.cs:251:21:251:54 | call to method WriteLine | normal | +| Finally.cs:251:21:251:54 | call to method WriteLine | Finally.cs:251:21:251:54 | call to method WriteLine | normal | +| Finally.cs:251:21:251:55 | ...; | Finally.cs:251:21:251:54 | call to method WriteLine | normal | +| Finally.cs:251:39:251:53 | "Inner finally" | Finally.cs:251:39:251:53 | "Inner finally" | normal | +| Finally.cs:254:13:254:44 | call to method WriteLine | Finally.cs:254:13:254:44 | call to method WriteLine | normal | +| Finally.cs:254:13:254:44 | call to method WriteLine | Finally.cs:254:13:254:44 | call to method WriteLine | throw(Exception) | +| Finally.cs:254:13:254:45 | ...; | Finally.cs:254:13:254:44 | call to method WriteLine | normal | +| Finally.cs:254:13:254:45 | ...; | Finally.cs:254:13:254:44 | call to method WriteLine | throw(Exception) | +| Finally.cs:254:31:254:43 | "Mid finally" | Finally.cs:254:31:254:43 | "Mid finally" | normal | +| Finally.cs:257:9:259:9 | {...} | Finally.cs:258:13:258:46 | call to method WriteLine | normal | +| Finally.cs:258:13:258:46 | call to method WriteLine | Finally.cs:258:13:258:46 | call to method WriteLine | normal | +| Finally.cs:258:13:258:47 | ...; | Finally.cs:258:13:258:46 | call to method WriteLine | normal | +| Finally.cs:258:31:258:45 | "Outer finally" | Finally.cs:258:31:258:45 | "Outer finally" | normal | +| Finally.cs:260:9:260:33 | call to method WriteLine | Finally.cs:260:9:260:33 | call to method WriteLine | normal | +| Finally.cs:260:9:260:34 | ...; | Finally.cs:260:9:260:33 | call to method WriteLine | normal | +| Finally.cs:260:27:260:32 | "Done" | Finally.cs:260:27:260:32 | "Done" | normal | +| Finally.cs:264:5:274:5 | {...} | Finally.cs:272:13:272:18 | ... = ... | normal | +| Finally.cs:264:5:274:5 | {...} | Finally.cs:272:13:272:18 | ... = ... | throw(Exception) [normal] (0) | +| Finally.cs:265:9:273:9 | try {...} ... | Finally.cs:272:13:272:18 | ... = ... | normal | +| Finally.cs:265:9:273:9 | try {...} ... | Finally.cs:272:13:272:18 | ... = ... | throw(Exception) [normal] (0) | +| Finally.cs:266:9:268:9 | {...} | Finally.cs:267:13:267:34 | call to method WriteLine | normal | +| Finally.cs:266:9:268:9 | {...} | Finally.cs:267:13:267:34 | call to method WriteLine | throw(Exception) | +| Finally.cs:267:13:267:34 | call to method WriteLine | Finally.cs:267:13:267:34 | call to method WriteLine | normal | +| Finally.cs:267:13:267:34 | call to method WriteLine | Finally.cs:267:13:267:34 | call to method WriteLine | throw(Exception) | +| Finally.cs:267:13:267:35 | ...; | Finally.cs:267:13:267:34 | call to method WriteLine | normal | +| Finally.cs:267:13:267:35 | ...; | Finally.cs:267:13:267:34 | call to method WriteLine | throw(Exception) | +| Finally.cs:267:31:267:33 | "1" | Finally.cs:267:31:267:33 | "1" | normal | +| Finally.cs:270:9:273:9 | {...} | Finally.cs:272:13:272:18 | ... = ... | normal | +| Finally.cs:271:13:271:34 | call to method WriteLine | Finally.cs:271:13:271:34 | call to method WriteLine | normal | +| Finally.cs:271:13:271:35 | ...; | Finally.cs:271:13:271:34 | call to method WriteLine | normal | +| Finally.cs:271:31:271:33 | "3" | Finally.cs:271:31:271:33 | "3" | normal | +| Finally.cs:272:13:272:13 | access to parameter i | Finally.cs:272:13:272:13 | access to parameter i | normal | +| Finally.cs:272:13:272:18 | ... + ... | Finally.cs:272:13:272:18 | ... + ... | normal | +| Finally.cs:272:13:272:18 | ... += ... | Finally.cs:272:13:272:18 | ... = ... | normal | +| Finally.cs:272:13:272:18 | ... = ... | Finally.cs:272:13:272:18 | ... = ... | normal | +| Finally.cs:272:13:272:19 | ...; | Finally.cs:272:13:272:18 | ... = ... | normal | +| Finally.cs:272:18:272:18 | 3 | Finally.cs:272:18:272:18 | 3 | normal | | Foreach.cs:7:5:10:5 | {...} | Foreach.cs:8:9:9:13 | foreach (... ... in ...) ... | empty | | Foreach.cs:8:9:9:13 | foreach (... ... in ...) ... | Foreach.cs:8:9:9:13 | foreach (... ... in ...) ... | empty | | Foreach.cs:8:22:8:24 | String arg | Foreach.cs:8:22:8:24 | String arg | normal | @@ -2238,9 +2295,7 @@ | Foreach.cs:25:5:28:5 | {...} | Foreach.cs:26:9:27:11 | foreach (... ... in ...) ... | empty | | Foreach.cs:26:9:27:11 | foreach (... ... in ...) ... | Foreach.cs:26:9:27:11 | foreach (... ... in ...) ... | empty | | Foreach.cs:26:18:26:31 | (..., ...) | Foreach.cs:26:18:26:31 | (..., ...) | normal | -| Foreach.cs:26:19:26:23 | 1 | Foreach.cs:26:19:26:23 | 1 | normal | | Foreach.cs:26:23:26:23 | String x | Foreach.cs:26:23:26:23 | String x | normal | -| Foreach.cs:26:26:26:30 | 1 | Foreach.cs:26:26:26:30 | 1 | normal | | Foreach.cs:26:30:26:30 | Int32 y | Foreach.cs:26:30:26:30 | Int32 y | normal | | Foreach.cs:26:36:26:39 | access to parameter args | Foreach.cs:26:36:26:39 | access to parameter args | normal | | Foreach.cs:27:11:27:11 | ; | Foreach.cs:27:11:27:11 | ; | normal | @@ -2777,7 +2832,8 @@ | Patterns.cs:8:13:8:13 | access to local variable o | Patterns.cs:8:13:8:13 | access to local variable o | normal | | Patterns.cs:8:13:8:23 | ... is ... | Patterns.cs:8:13:8:23 | ... is ... | false | | Patterns.cs:8:13:8:23 | ... is ... | Patterns.cs:8:13:8:23 | ... is ... | true | -| Patterns.cs:8:18:8:23 | Int32 i1 | Patterns.cs:8:18:8:23 | Int32 i1 | normal | +| Patterns.cs:8:18:8:23 | Int32 i1 | Patterns.cs:8:18:8:23 | Int32 i1 | match | +| Patterns.cs:8:18:8:23 | Int32 i1 | Patterns.cs:8:18:8:23 | Int32 i1 | no-match | | Patterns.cs:9:9:11:9 | {...} | Patterns.cs:10:13:10:42 | call to method WriteLine | normal | | Patterns.cs:10:13:10:42 | call to method WriteLine | Patterns.cs:10:13:10:42 | call to method WriteLine | normal | | Patterns.cs:10:13:10:43 | ...; | Patterns.cs:10:13:10:42 | call to method WriteLine | normal | @@ -2790,7 +2846,8 @@ | Patterns.cs:12:18:12:18 | access to local variable o | Patterns.cs:12:18:12:18 | access to local variable o | normal | | Patterns.cs:12:18:12:31 | ... is ... | Patterns.cs:12:18:12:31 | ... is ... | false | | Patterns.cs:12:18:12:31 | ... is ... | Patterns.cs:12:18:12:31 | ... is ... | true | -| Patterns.cs:12:23:12:31 | String s1 | Patterns.cs:12:23:12:31 | String s1 | normal | +| Patterns.cs:12:23:12:31 | String s1 | Patterns.cs:12:23:12:31 | String s1 | match | +| Patterns.cs:12:23:12:31 | String s1 | Patterns.cs:12:23:12:31 | String s1 | no-match | | Patterns.cs:13:9:15:9 | {...} | Patterns.cs:14:13:14:45 | call to method WriteLine | normal | | Patterns.cs:14:13:14:45 | call to method WriteLine | Patterns.cs:14:13:14:45 | call to method WriteLine | normal | | Patterns.cs:14:13:14:46 | ...; | Patterns.cs:14:13:14:45 | call to method WriteLine | normal | @@ -2802,14 +2859,15 @@ | Patterns.cs:16:18:16:18 | access to local variable o | Patterns.cs:16:18:16:18 | access to local variable o | normal | | Patterns.cs:16:18:16:28 | ... is ... | Patterns.cs:16:18:16:28 | ... is ... | false | | Patterns.cs:16:18:16:28 | ... is ... | Patterns.cs:16:18:16:28 | ... is ... | true | -| Patterns.cs:16:23:16:28 | Object v1 | Patterns.cs:16:23:16:28 | Object v1 | normal | +| Patterns.cs:16:23:16:28 | Object v1 | Patterns.cs:16:23:16:28 | Object v1 | match | +| Patterns.cs:16:23:16:28 | Object v1 | Patterns.cs:16:23:16:28 | Object v1 | no-match | | Patterns.cs:17:9:18:9 | {...} | Patterns.cs:17:9:18:9 | {...} | normal | -| Patterns.cs:20:9:38:9 | switch (...) {...} | Patterns.cs:23:17:23:22 | break; | normal [break] | -| Patterns.cs:20:9:38:9 | switch (...) {...} | Patterns.cs:26:17:26:22 | break; | normal [break] | -| Patterns.cs:20:9:38:9 | switch (...) {...} | Patterns.cs:29:17:29:22 | break; | normal [break] | -| Patterns.cs:20:9:38:9 | switch (...) {...} | Patterns.cs:32:17:32:22 | break; | normal [break] | -| Patterns.cs:20:9:38:9 | switch (...) {...} | Patterns.cs:34:17:34:22 | break; | normal [break] | -| Patterns.cs:20:9:38:9 | switch (...) {...} | Patterns.cs:37:17:37:22 | break; | normal [break] | +| Patterns.cs:20:9:38:9 | switch (...) {...} | Patterns.cs:23:17:23:22 | break; | normal [break] (0) | +| Patterns.cs:20:9:38:9 | switch (...) {...} | Patterns.cs:26:17:26:22 | break; | normal [break] (0) | +| Patterns.cs:20:9:38:9 | switch (...) {...} | Patterns.cs:29:17:29:22 | break; | normal [break] (0) | +| Patterns.cs:20:9:38:9 | switch (...) {...} | Patterns.cs:32:17:32:22 | break; | normal [break] (0) | +| Patterns.cs:20:9:38:9 | switch (...) {...} | Patterns.cs:34:17:34:22 | break; | normal [break] (0) | +| Patterns.cs:20:9:38:9 | switch (...) {...} | Patterns.cs:37:17:37:22 | break; | normal [break] (0) | | Patterns.cs:20:17:20:17 | access to local variable o | Patterns.cs:20:17:20:17 | access to local variable o | normal | | Patterns.cs:22:13:22:23 | case ...: | Patterns.cs:22:18:22:22 | "xyz" | no-match | | Patterns.cs:22:13:22:23 | case ...: | Patterns.cs:23:17:23:22 | break; | break | @@ -2863,6 +2921,131 @@ | Patterns.cs:37:17:37:22 | break; | Patterns.cs:37:17:37:22 | break; | break | | Patterns.cs:40:9:42:9 | switch (...) {...} | Patterns.cs:40:17:40:17 | access to local variable o | normal | | Patterns.cs:40:17:40:17 | access to local variable o | Patterns.cs:40:17:40:17 | access to local variable o | normal | +| Patterns.cs:48:9:48:9 | access to parameter c | Patterns.cs:48:9:48:9 | access to parameter c | normal | +| Patterns.cs:48:9:48:20 | ... is ... | Patterns.cs:48:9:48:20 | ... is ... | normal | +| Patterns.cs:48:14:48:20 | not ... | Patterns.cs:48:14:48:20 | not ... | normal | +| Patterns.cs:48:18:48:20 | a | Patterns.cs:48:18:48:20 | a | normal | +| Patterns.cs:51:9:51:9 | access to parameter c | Patterns.cs:51:9:51:9 | access to parameter c | normal | +| Patterns.cs:51:9:51:21 | ... is ... | Patterns.cs:51:9:51:21 | ... is ... | false | +| Patterns.cs:51:9:51:21 | ... is ... | Patterns.cs:51:9:51:21 | ... is ... | true | +| Patterns.cs:51:9:51:39 | ... ? ... : ... | Patterns.cs:51:9:51:39 | ... ? ... : ... | normal | +| Patterns.cs:51:14:51:21 | not ... | Patterns.cs:51:14:51:21 | not ... | match | +| Patterns.cs:51:14:51:21 | not ... | Patterns.cs:51:14:51:21 | not ... | no-match | +| Patterns.cs:51:18:51:21 | null | Patterns.cs:51:18:51:21 | null | match | +| Patterns.cs:51:18:51:21 | null | Patterns.cs:51:18:51:21 | null | no-match | +| Patterns.cs:51:25:51:25 | access to parameter c | Patterns.cs:51:25:51:25 | access to parameter c | normal | +| Patterns.cs:51:25:51:30 | ... is ... | Patterns.cs:51:25:51:30 | ... is ... | normal | +| Patterns.cs:51:30:51:30 | 1 | Patterns.cs:51:30:51:30 | 1 | normal | +| Patterns.cs:51:34:51:34 | access to parameter c | Patterns.cs:51:34:51:34 | access to parameter c | normal | +| Patterns.cs:51:34:51:39 | ... is ... | Patterns.cs:51:34:51:39 | ... is ... | normal | +| Patterns.cs:51:39:51:39 | 2 | Patterns.cs:51:39:51:39 | 2 | normal | +| Patterns.cs:54:9:54:9 | access to parameter c | Patterns.cs:54:9:54:9 | access to parameter c | normal | +| Patterns.cs:54:9:54:37 | ... is ... | Patterns.cs:54:9:54:37 | ... is ... | normal | +| Patterns.cs:54:14:54:37 | not ... | Patterns.cs:54:14:54:37 | not ... | normal | +| Patterns.cs:54:18:54:25 | access to type Patterns | Patterns.cs:54:18:54:25 | access to type Patterns | match | +| Patterns.cs:54:18:54:25 | access to type Patterns | Patterns.cs:54:18:54:25 | access to type Patterns | no-match | +| Patterns.cs:54:18:54:37 | Patterns u | Patterns.cs:54:18:54:37 | Patterns u | match | +| Patterns.cs:54:18:54:37 | Patterns u | Patterns.cs:54:18:54:37 | Patterns u | no-match | +| Patterns.cs:54:18:54:37 | { ... } | Patterns.cs:54:18:54:37 | { ... } | normal | +| Patterns.cs:54:27:54:35 | { ... } | Patterns.cs:54:27:54:35 | { ... } | match | +| Patterns.cs:54:27:54:35 | { ... } | Patterns.cs:54:27:54:35 | { ... } | no-match | +| Patterns.cs:54:33:54:33 | 1 | Patterns.cs:54:33:54:33 | 1 | match | +| Patterns.cs:54:33:54:33 | 1 | Patterns.cs:54:33:54:33 | 1 | no-match | +| Patterns.cs:57:5:63:5 | {...} | Patterns.cs:58:9:62:10 | return ...; | return | +| Patterns.cs:58:9:62:10 | return ...; | Patterns.cs:58:9:62:10 | return ...; | return | +| Patterns.cs:58:16:58:16 | access to parameter i | Patterns.cs:58:16:58:16 | access to parameter i | normal | +| Patterns.cs:58:16:62:9 | ... switch { ... } | Patterns.cs:58:16:62:9 | ... switch { ... } | normal | +| Patterns.cs:60:13:60:17 | not ... | Patterns.cs:60:13:60:17 | not ... | match | +| Patterns.cs:60:13:60:17 | not ... | Patterns.cs:60:13:60:17 | not ... | no-match | +| Patterns.cs:60:13:60:28 | ... => ... | Patterns.cs:60:13:60:28 | ... => ... | normal | +| Patterns.cs:60:17:60:17 | 1 | Patterns.cs:60:17:60:17 | 1 | match | +| Patterns.cs:60:17:60:17 | 1 | Patterns.cs:60:17:60:17 | 1 | no-match | +| Patterns.cs:60:22:60:28 | "not 1" | Patterns.cs:60:22:60:28 | "not 1" | normal | +| Patterns.cs:61:13:61:13 | _ | Patterns.cs:61:13:61:13 | _ | match | +| Patterns.cs:61:13:61:24 | ... => ... | Patterns.cs:61:13:61:24 | ... => ... | normal | +| Patterns.cs:61:18:61:24 | "other" | Patterns.cs:61:18:61:24 | "other" | normal | +| Patterns.cs:66:5:72:5 | {...} | Patterns.cs:67:9:71:10 | return ...; | return | +| Patterns.cs:67:9:71:10 | return ...; | Patterns.cs:67:9:71:10 | return ...; | return | +| Patterns.cs:67:16:67:16 | 2 | Patterns.cs:67:16:67:16 | 2 | normal | +| Patterns.cs:67:16:71:9 | ... switch { ... } | Patterns.cs:67:16:71:9 | ... switch { ... } | normal | +| Patterns.cs:69:13:69:17 | not ... | Patterns.cs:69:13:69:17 | not ... | match | +| Patterns.cs:69:13:69:17 | not ... | Patterns.cs:69:13:69:17 | not ... | no-match | +| Patterns.cs:69:13:69:33 | ... => ... | Patterns.cs:69:13:69:33 | ... => ... | normal | +| Patterns.cs:69:17:69:17 | 2 | Patterns.cs:69:17:69:17 | 2 | match | +| Patterns.cs:69:22:69:33 | "impossible" | Patterns.cs:69:22:69:33 | "impossible" | normal | +| Patterns.cs:70:13:70:13 | 2 | Patterns.cs:70:13:70:13 | 2 | match | +| Patterns.cs:70:13:70:27 | ... => ... | Patterns.cs:70:13:70:27 | ... => ... | normal | +| Patterns.cs:70:18:70:27 | "possible" | Patterns.cs:70:18:70:27 | "possible" | normal | +| Patterns.cs:75:5:83:5 | {...} | Patterns.cs:76:9:82:10 | return ...; | return | +| Patterns.cs:76:9:82:10 | return ...; | Patterns.cs:76:9:82:10 | return ...; | return | +| Patterns.cs:76:16:76:16 | access to parameter i | Patterns.cs:76:16:76:16 | access to parameter i | normal | +| Patterns.cs:76:16:82:9 | ... switch { ... } | Patterns.cs:76:16:82:9 | ... switch { ... } | normal | +| Patterns.cs:78:13:78:15 | > ... | Patterns.cs:78:13:78:15 | > ... | match | +| Patterns.cs:78:13:78:15 | > ... | Patterns.cs:78:13:78:15 | > ... | no-match | +| Patterns.cs:78:13:78:24 | ... => ... | Patterns.cs:78:13:78:24 | ... => ... | normal | +| Patterns.cs:78:15:78:15 | 1 | Patterns.cs:78:15:78:15 | 1 | normal | +| Patterns.cs:78:20:78:24 | "> 1" | Patterns.cs:78:20:78:24 | "> 1" | normal | +| Patterns.cs:79:13:79:15 | < ... | Patterns.cs:79:13:79:15 | < ... | match | +| Patterns.cs:79:13:79:15 | < ... | Patterns.cs:79:13:79:15 | < ... | no-match | +| Patterns.cs:79:13:79:24 | ... => ... | Patterns.cs:79:13:79:24 | ... => ... | normal | +| Patterns.cs:79:15:79:15 | 0 | Patterns.cs:79:15:79:15 | 0 | normal | +| Patterns.cs:79:20:79:24 | "< 0" | Patterns.cs:79:20:79:24 | "< 0" | normal | +| Patterns.cs:80:13:80:13 | 1 | Patterns.cs:80:13:80:13 | 1 | match | +| Patterns.cs:80:13:80:13 | 1 | Patterns.cs:80:13:80:13 | 1 | no-match | +| Patterns.cs:80:13:80:20 | ... => ... | Patterns.cs:80:13:80:20 | ... => ... | normal | +| Patterns.cs:80:18:80:20 | "1" | Patterns.cs:80:18:80:20 | "1" | normal | +| Patterns.cs:81:13:81:13 | _ | Patterns.cs:81:13:81:13 | _ | match | +| Patterns.cs:81:13:81:20 | ... => ... | Patterns.cs:81:13:81:20 | ... => ... | normal | +| Patterns.cs:81:18:81:20 | "0" | Patterns.cs:81:18:81:20 | "0" | normal | +| Patterns.cs:85:39:85:39 | access to parameter i | Patterns.cs:85:39:85:39 | access to parameter i | normal | +| Patterns.cs:85:39:85:53 | ... is ... | Patterns.cs:85:39:85:53 | ... is ... | false | +| Patterns.cs:85:39:85:53 | ... is ... | Patterns.cs:85:39:85:53 | ... is ... | true | +| Patterns.cs:85:39:85:69 | ... ? ... : ... | Patterns.cs:85:39:85:69 | ... ? ... : ... | normal | +| Patterns.cs:85:44:85:44 | 1 | Patterns.cs:85:44:85:44 | 1 | match | +| Patterns.cs:85:44:85:44 | 1 | Patterns.cs:85:44:85:44 | 1 | no-match | +| Patterns.cs:85:44:85:53 | ... or ... | Patterns.cs:85:44:85:53 | ... or ... | match | +| Patterns.cs:85:44:85:53 | ... or ... | Patterns.cs:85:44:85:53 | ... or ... | no-match | +| Patterns.cs:85:49:85:53 | not ... | Patterns.cs:85:49:85:53 | not ... | match | +| Patterns.cs:85:49:85:53 | not ... | Patterns.cs:85:49:85:53 | not ... | no-match | +| Patterns.cs:85:53:85:53 | 2 | Patterns.cs:85:53:85:53 | 2 | match | +| Patterns.cs:85:53:85:53 | 2 | Patterns.cs:85:53:85:53 | 2 | no-match | +| Patterns.cs:85:57:85:63 | "not 2" | Patterns.cs:85:57:85:63 | "not 2" | normal | +| Patterns.cs:85:67:85:69 | "2" | Patterns.cs:85:67:85:69 | "2" | normal | +| Patterns.cs:87:39:87:39 | access to parameter i | Patterns.cs:87:39:87:39 | access to parameter i | normal | +| Patterns.cs:87:39:87:54 | ... is ... | Patterns.cs:87:39:87:54 | ... is ... | false | +| Patterns.cs:87:39:87:54 | ... is ... | Patterns.cs:87:39:87:54 | ... is ... | true | +| Patterns.cs:87:39:87:70 | ... ? ... : ... | Patterns.cs:87:39:87:70 | ... ? ... : ... | normal | +| Patterns.cs:87:44:87:44 | 1 | Patterns.cs:87:44:87:44 | 1 | match | +| Patterns.cs:87:44:87:44 | 1 | Patterns.cs:87:44:87:44 | 1 | no-match | +| Patterns.cs:87:44:87:54 | ... and ... | Patterns.cs:87:44:87:54 | ... and ... | match | +| Patterns.cs:87:44:87:54 | ... and ... | Patterns.cs:87:44:87:54 | ... and ... | no-match | +| Patterns.cs:87:50:87:54 | not ... | Patterns.cs:87:50:87:54 | not ... | match | +| Patterns.cs:87:50:87:54 | not ... | Patterns.cs:87:50:87:54 | not ... | no-match | +| Patterns.cs:87:54:87:54 | 2 | Patterns.cs:87:54:87:54 | 2 | match | +| Patterns.cs:87:54:87:54 | 2 | Patterns.cs:87:54:87:54 | 2 | no-match | +| Patterns.cs:87:58:87:60 | "1" | Patterns.cs:87:58:87:60 | "1" | normal | +| Patterns.cs:87:64:87:70 | "not 1" | Patterns.cs:87:64:87:70 | "not 1" | normal | +| Patterns.cs:94:5:99:5 | {...} | Patterns.cs:95:13:95:40 | ... is ... | false | +| Patterns.cs:94:5:99:5 | {...} | Patterns.cs:97:13:97:38 | call to method WriteLine | normal | +| Patterns.cs:95:9:98:9 | if (...) ... | Patterns.cs:95:13:95:40 | ... is ... | false | +| Patterns.cs:95:9:98:9 | if (...) ... | Patterns.cs:97:13:97:38 | call to method WriteLine | normal | +| Patterns.cs:95:13:95:16 | this access | Patterns.cs:95:13:95:16 | this access | normal | +| Patterns.cs:95:13:95:40 | ... is ... | Patterns.cs:95:13:95:40 | ... is ... | false | +| Patterns.cs:95:13:95:40 | ... is ... | Patterns.cs:95:13:95:40 | ... is ... | true | +| Patterns.cs:95:21:95:40 | { ... } | Patterns.cs:95:21:95:40 | { ... } | match | +| Patterns.cs:95:21:95:40 | { ... } | Patterns.cs:95:21:95:40 | { ... } | match | +| Patterns.cs:95:21:95:40 | { ... } | Patterns.cs:95:21:95:40 | { ... } | no-match | +| Patterns.cs:95:21:95:40 | { ... } | Patterns.cs:95:21:95:40 | { ... } | no-match | +| Patterns.cs:95:29:95:31 | access to constant A | Patterns.cs:95:29:95:31 | access to constant A | match | +| Patterns.cs:95:29:95:31 | access to constant A | Patterns.cs:95:29:95:31 | access to constant A | no-match | +| Patterns.cs:95:29:95:38 | ... or ... | Patterns.cs:95:29:95:38 | ... or ... | match | +| Patterns.cs:95:29:95:38 | ... or ... | Patterns.cs:95:29:95:38 | ... or ... | no-match | +| Patterns.cs:95:36:95:38 | access to constant B | Patterns.cs:95:36:95:38 | access to constant B | match | +| Patterns.cs:95:36:95:38 | access to constant B | Patterns.cs:95:36:95:38 | access to constant B | no-match | +| Patterns.cs:96:9:98:9 | {...} | Patterns.cs:97:13:97:38 | call to method WriteLine | normal | +| Patterns.cs:97:13:97:38 | call to method WriteLine | Patterns.cs:97:13:97:38 | call to method WriteLine | normal | +| Patterns.cs:97:13:97:39 | ...; | Patterns.cs:97:13:97:38 | call to method WriteLine | normal | +| Patterns.cs:97:31:97:37 | "not C" | Patterns.cs:97:31:97:37 | "not C" | normal | | PostDominance.cs:6:5:8:5 | {...} | PostDominance.cs:7:9:7:28 | call to method WriteLine | normal | | PostDominance.cs:7:9:7:28 | call to method WriteLine | PostDominance.cs:7:9:7:28 | call to method WriteLine | normal | | PostDominance.cs:7:9:7:29 | ...; | PostDominance.cs:7:9:7:28 | call to method WriteLine | normal | @@ -2874,7 +3057,8 @@ | PostDominance.cs:12:13:12:13 | access to parameter s | PostDominance.cs:12:13:12:13 | access to parameter s | normal | | PostDominance.cs:12:13:12:21 | ... is ... | PostDominance.cs:12:13:12:21 | ... is ... | false | | PostDominance.cs:12:13:12:21 | ... is ... | PostDominance.cs:12:13:12:21 | ... is ... | true | -| PostDominance.cs:12:18:12:21 | null | PostDominance.cs:12:18:12:21 | null | normal | +| PostDominance.cs:12:18:12:21 | null | PostDominance.cs:12:18:12:21 | null | match | +| PostDominance.cs:12:18:12:21 | null | PostDominance.cs:12:18:12:21 | null | no-match | | PostDominance.cs:13:13:13:19 | return ...; | PostDominance.cs:13:13:13:19 | return ...; | return | | PostDominance.cs:14:9:14:28 | call to method WriteLine | PostDominance.cs:14:9:14:28 | call to method WriteLine | normal | | PostDominance.cs:14:9:14:29 | ...; | PostDominance.cs:14:9:14:28 | call to method WriteLine | normal | @@ -2886,7 +3070,8 @@ | PostDominance.cs:19:13:19:13 | access to parameter s | PostDominance.cs:19:13:19:13 | access to parameter s | normal | | PostDominance.cs:19:13:19:21 | ... is ... | PostDominance.cs:19:13:19:21 | ... is ... | false | | PostDominance.cs:19:13:19:21 | ... is ... | PostDominance.cs:19:13:19:21 | ... is ... | true | -| PostDominance.cs:19:18:19:21 | null | PostDominance.cs:19:18:19:21 | null | normal | +| PostDominance.cs:19:18:19:21 | null | PostDominance.cs:19:18:19:21 | null | match | +| PostDominance.cs:19:18:19:21 | null | PostDominance.cs:19:18:19:21 | null | no-match | | PostDominance.cs:20:13:20:55 | throw ...; | PostDominance.cs:20:13:20:55 | throw ...; | throw(ArgumentNullException) | | PostDominance.cs:20:19:20:54 | object creation of type ArgumentNullException | PostDominance.cs:20:19:20:54 | object creation of type ArgumentNullException | normal | | PostDominance.cs:20:45:20:53 | nameof(...) | PostDominance.cs:20:45:20:53 | nameof(...) | normal | @@ -3036,14 +3221,14 @@ | Switch.cs:37:17:37:23 | call to method Throw | Switch.cs:37:17:37:23 | call to method Throw | throw(Exception) | | Switch.cs:39:13:39:20 | default: | Switch.cs:40:17:40:23 | return ...; | return | | Switch.cs:40:17:40:23 | return ...; | Switch.cs:40:17:40:23 | return ...; | return | -| Switch.cs:45:5:53:5 | {...} | Switch.cs:49:17:49:22 | break; | normal [break] | +| Switch.cs:45:5:53:5 | {...} | Switch.cs:49:17:49:22 | break; | normal [break] (0) | | Switch.cs:45:5:53:5 | {...} | Switch.cs:50:18:50:21 | access to type Boolean | no-match | | Switch.cs:45:5:53:5 | {...} | Switch.cs:50:30:50:38 | ... != ... | false | -| Switch.cs:45:5:53:5 | {...} | Switch.cs:51:17:51:22 | break; | normal [break] | -| Switch.cs:46:9:52:9 | switch (...) {...} | Switch.cs:49:17:49:22 | break; | normal [break] | +| Switch.cs:45:5:53:5 | {...} | Switch.cs:51:17:51:22 | break; | normal [break] (0) | +| Switch.cs:46:9:52:9 | switch (...) {...} | Switch.cs:49:17:49:22 | break; | normal [break] (0) | | Switch.cs:46:9:52:9 | switch (...) {...} | Switch.cs:50:18:50:21 | access to type Boolean | no-match | | Switch.cs:46:9:52:9 | switch (...) {...} | Switch.cs:50:30:50:38 | ... != ... | false | -| Switch.cs:46:9:52:9 | switch (...) {...} | Switch.cs:51:17:51:22 | break; | normal [break] | +| Switch.cs:46:9:52:9 | switch (...) {...} | Switch.cs:51:17:51:22 | break; | normal [break] (0) | | Switch.cs:46:17:46:17 | access to parameter o | Switch.cs:46:17:46:17 | access to parameter o | normal | | Switch.cs:48:13:48:23 | case ...: | Switch.cs:48:18:48:20 | access to type Int32 | no-match | | Switch.cs:48:13:48:23 | case ...: | Switch.cs:49:17:49:22 | break; | break | @@ -3060,10 +3245,10 @@ | Switch.cs:50:30:50:38 | ... != ... | Switch.cs:50:30:50:38 | ... != ... | true | | Switch.cs:50:35:50:38 | null | Switch.cs:50:35:50:38 | null | normal | | Switch.cs:51:17:51:22 | break; | Switch.cs:51:17:51:22 | break; | break | -| Switch.cs:56:5:64:5 | {...} | Switch.cs:60:17:60:22 | break; | normal [break] | -| Switch.cs:56:5:64:5 | {...} | Switch.cs:62:17:62:22 | break; | normal [break] | -| Switch.cs:57:9:63:9 | switch (...) {...} | Switch.cs:60:17:60:22 | break; | normal [break] | -| Switch.cs:57:9:63:9 | switch (...) {...} | Switch.cs:62:17:62:22 | break; | normal [break] | +| Switch.cs:56:5:64:5 | {...} | Switch.cs:60:17:60:22 | break; | normal [break] (0) | +| Switch.cs:56:5:64:5 | {...} | Switch.cs:62:17:62:22 | break; | normal [break] (0) | +| Switch.cs:57:9:63:9 | switch (...) {...} | Switch.cs:60:17:60:22 | break; | normal [break] (0) | +| Switch.cs:57:9:63:9 | switch (...) {...} | Switch.cs:62:17:62:22 | break; | normal [break] (0) | | Switch.cs:57:17:57:17 | 1 | Switch.cs:57:17:57:17 | 1 | normal | | Switch.cs:57:17:57:21 | ... + ... | Switch.cs:57:17:57:21 | ... + ... | normal | | Switch.cs:57:21:57:21 | 2 | Switch.cs:57:21:57:21 | 2 | normal | @@ -3074,12 +3259,12 @@ | Switch.cs:61:13:61:19 | case ...: | Switch.cs:62:17:62:22 | break; | break | | Switch.cs:61:18:61:18 | 3 | Switch.cs:61:18:61:18 | 3 | match | | Switch.cs:62:17:62:22 | break; | Switch.cs:62:17:62:22 | break; | break | -| Switch.cs:67:5:75:5 | {...} | Switch.cs:71:17:71:22 | break; | normal [break] | +| Switch.cs:67:5:75:5 | {...} | Switch.cs:71:17:71:22 | break; | normal [break] (0) | | Switch.cs:67:5:75:5 | {...} | Switch.cs:72:18:72:19 | "" | no-match | -| Switch.cs:67:5:75:5 | {...} | Switch.cs:73:17:73:22 | break; | normal [break] | -| Switch.cs:68:9:74:9 | switch (...) {...} | Switch.cs:71:17:71:22 | break; | normal [break] | +| Switch.cs:67:5:75:5 | {...} | Switch.cs:73:17:73:22 | break; | normal [break] (0) | +| Switch.cs:68:9:74:9 | switch (...) {...} | Switch.cs:71:17:71:22 | break; | normal [break] (0) | | Switch.cs:68:9:74:9 | switch (...) {...} | Switch.cs:72:18:72:19 | "" | no-match | -| Switch.cs:68:9:74:9 | switch (...) {...} | Switch.cs:73:17:73:22 | break; | normal [break] | +| Switch.cs:68:9:74:9 | switch (...) {...} | Switch.cs:73:17:73:22 | break; | normal [break] (0) | | Switch.cs:68:17:68:25 | (...) ... | Switch.cs:68:17:68:25 | (...) ... | normal | | Switch.cs:68:25:68:25 | access to parameter s | Switch.cs:68:25:68:25 | access to parameter s | normal | | Switch.cs:70:13:70:23 | case ...: | Switch.cs:70:18:70:20 | access to type Int32 | no-match | @@ -3096,7 +3281,7 @@ | Switch.cs:78:5:89:5 | {...} | Switch.cs:88:9:88:21 | return ...; | return | | Switch.cs:79:9:87:9 | switch (...) {...} | Switch.cs:82:17:82:28 | return ...; | return | | Switch.cs:79:9:87:9 | switch (...) {...} | Switch.cs:83:18:83:18 | 2 | no-match | -| Switch.cs:79:9:87:9 | switch (...) {...} | Switch.cs:85:21:85:26 | break; | normal [break] | +| Switch.cs:79:9:87:9 | switch (...) {...} | Switch.cs:85:21:85:26 | break; | normal [break] (0) | | Switch.cs:79:9:87:9 | switch (...) {...} | Switch.cs:86:17:86:28 | return ...; | return | | Switch.cs:79:17:79:17 | access to parameter i | Switch.cs:79:17:79:17 | access to parameter i | normal | | Switch.cs:81:13:81:19 | case ...: | Switch.cs:81:18:81:18 | 1 | no-match | @@ -3276,23 +3461,23 @@ | Switch.cs:150:18:150:18 | 2 | Switch.cs:150:18:150:18 | 2 | no-match | | Switch.cs:150:21:150:29 | return ...; | Switch.cs:150:21:150:29 | return ...; | return | | Switch.cs:150:28:150:28 | 2 | Switch.cs:150:28:150:28 | 2 | normal | -| Switch.cs:155:5:161:5 | {...} | Switch.cs:156:41:156:45 | false | throw(InvalidOperationException) [no-match] | +| Switch.cs:155:5:161:5 | {...} | Switch.cs:156:41:156:45 | false | throw(InvalidOperationException) [no-match] (0) | | Switch.cs:155:5:161:5 | {...} | Switch.cs:158:13:158:48 | call to method WriteLine | normal | | Switch.cs:155:5:161:5 | {...} | Switch.cs:160:13:160:48 | call to method WriteLine | normal | | Switch.cs:156:9:156:55 | ... ...; | Switch.cs:156:13:156:54 | String s = ... | normal | -| Switch.cs:156:9:156:55 | ... ...; | Switch.cs:156:41:156:45 | false | throw(InvalidOperationException) [no-match] | +| Switch.cs:156:9:156:55 | ... ...; | Switch.cs:156:41:156:45 | false | throw(InvalidOperationException) [no-match] (0) | | Switch.cs:156:13:156:54 | String s = ... | Switch.cs:156:13:156:54 | String s = ... | normal | -| Switch.cs:156:13:156:54 | String s = ... | Switch.cs:156:41:156:45 | false | throw(InvalidOperationException) [no-match] | +| Switch.cs:156:13:156:54 | String s = ... | Switch.cs:156:41:156:45 | false | throw(InvalidOperationException) [no-match] (0) | | Switch.cs:156:17:156:17 | access to parameter b | Switch.cs:156:17:156:17 | access to parameter b | normal | | Switch.cs:156:17:156:54 | ... switch { ... } | Switch.cs:156:17:156:54 | ... switch { ... } | normal | -| Switch.cs:156:17:156:54 | ... switch { ... } | Switch.cs:156:41:156:45 | false | throw(InvalidOperationException) [no-match] | +| Switch.cs:156:17:156:54 | ... switch { ... } | Switch.cs:156:41:156:45 | false | throw(InvalidOperationException) [no-match] (0) | | Switch.cs:156:28:156:31 | true | Switch.cs:156:28:156:31 | true | match | | Switch.cs:156:28:156:31 | true | Switch.cs:156:28:156:31 | true | no-match | | Switch.cs:156:28:156:38 | ... => ... | Switch.cs:156:28:156:38 | ... => ... | normal | | Switch.cs:156:36:156:38 | "a" | Switch.cs:156:36:156:38 | "a" | normal | | Switch.cs:156:41:156:45 | false | Switch.cs:156:41:156:45 | false | match | | Switch.cs:156:41:156:45 | false | Switch.cs:156:41:156:45 | false | no-match | -| Switch.cs:156:41:156:52 | ... => ... | Switch.cs:156:41:156:45 | false | throw(InvalidOperationException) [no-match] | +| Switch.cs:156:41:156:52 | ... => ... | Switch.cs:156:41:156:45 | false | throw(InvalidOperationException) [no-match] (0) | | Switch.cs:156:41:156:52 | ... => ... | Switch.cs:156:41:156:52 | ... => ... | normal | | Switch.cs:156:50:156:52 | "b" | Switch.cs:156:50:156:52 | "b" | normal | | Switch.cs:157:9:160:49 | if (...) ... | Switch.cs:158:13:158:48 | call to method WriteLine | normal | @@ -3323,7 +3508,8 @@ | TypeAccesses.cs:7:13:7:13 | access to parameter o | TypeAccesses.cs:7:13:7:13 | access to parameter o | normal | | TypeAccesses.cs:7:13:7:22 | ... is ... | TypeAccesses.cs:7:13:7:22 | ... is ... | false | | TypeAccesses.cs:7:13:7:22 | ... is ... | TypeAccesses.cs:7:13:7:22 | ... is ... | true | -| TypeAccesses.cs:7:18:7:22 | Int32 j | TypeAccesses.cs:7:18:7:22 | Int32 j | normal | +| TypeAccesses.cs:7:18:7:22 | Int32 j | TypeAccesses.cs:7:18:7:22 | Int32 j | match | +| TypeAccesses.cs:7:18:7:22 | Int32 j | TypeAccesses.cs:7:18:7:22 | Int32 j | no-match | | TypeAccesses.cs:7:25:7:25 | ; | TypeAccesses.cs:7:25:7:25 | ; | normal | | TypeAccesses.cs:8:9:8:28 | ... ...; | TypeAccesses.cs:8:13:8:27 | Type t = ... | normal | | TypeAccesses.cs:8:13:8:27 | Type t = ... | TypeAccesses.cs:8:13:8:27 | Type t = ... | normal | @@ -3475,7 +3661,7 @@ | cflow.cs:38:5:68:5 | {...} | cflow.cs:64:21:64:55 | throw ...; | throw(NullReferenceException) | | cflow.cs:38:5:68:5 | {...} | cflow.cs:67:9:67:17 | return ...; | return | | cflow.cs:39:9:50:9 | switch (...) {...} | cflow.cs:47:18:47:18 | 3 | no-match | -| cflow.cs:39:9:50:9 | switch (...) {...} | cflow.cs:49:17:49:22 | break; | normal [break] | +| cflow.cs:39:9:50:9 | switch (...) {...} | cflow.cs:49:17:49:22 | break; | normal [break] (0) | | cflow.cs:39:17:39:17 | access to parameter a | cflow.cs:39:17:39:17 | access to parameter a | normal | | cflow.cs:41:13:41:19 | case ...: | cflow.cs:41:18:41:18 | 1 | no-match | | cflow.cs:41:13:41:19 | case ...: | cflow.cs:42:17:42:38 | call to method WriteLine | normal | @@ -3503,8 +3689,8 @@ | cflow.cs:48:17:48:39 | ...; | cflow.cs:48:17:48:38 | call to method WriteLine | normal | | cflow.cs:48:35:48:37 | "3" | cflow.cs:48:35:48:37 | "3" | normal | | cflow.cs:49:17:49:22 | break; | cflow.cs:49:17:49:22 | break; | break | -| cflow.cs:51:9:59:9 | switch (...) {...} | cflow.cs:55:17:55:22 | break; | normal [break] | -| cflow.cs:51:9:59:9 | switch (...) {...} | cflow.cs:58:17:58:22 | break; | normal [break] | +| cflow.cs:51:9:59:9 | switch (...) {...} | cflow.cs:55:17:55:22 | break; | normal [break] (0) | +| cflow.cs:51:9:59:9 | switch (...) {...} | cflow.cs:58:17:58:22 | break; | normal [break] (0) | | cflow.cs:51:17:51:17 | access to parameter a | cflow.cs:51:17:51:17 | access to parameter a | normal | | cflow.cs:53:13:53:20 | case ...: | cflow.cs:53:18:53:19 | 42 | no-match | | cflow.cs:53:13:53:20 | case ...: | cflow.cs:54:17:54:47 | call to method WriteLine | normal | @@ -3521,7 +3707,7 @@ | cflow.cs:58:17:58:22 | break; | cflow.cs:58:17:58:22 | break; | break | | cflow.cs:60:9:66:9 | switch (...) {...} | cflow.cs:62:18:62:18 | 0 | no-match | | cflow.cs:60:9:66:9 | switch (...) {...} | cflow.cs:64:21:64:55 | throw ...; | throw(NullReferenceException) | -| cflow.cs:60:9:66:9 | switch (...) {...} | cflow.cs:65:17:65:22 | break; | normal [break] | +| cflow.cs:60:9:66:9 | switch (...) {...} | cflow.cs:65:17:65:22 | break; | normal [break] (0) | | cflow.cs:60:17:60:32 | call to method Parse | cflow.cs:60:17:60:32 | call to method Parse | normal | | cflow.cs:60:27:60:31 | access to field Field | cflow.cs:60:27:60:31 | access to field Field | normal | | cflow.cs:60:27:60:31 | this access | cflow.cs:60:27:60:31 | this access | normal | @@ -3726,7 +3912,7 @@ | cflow.cs:150:13:150:32 | call to method WriteLine | cflow.cs:150:13:150:32 | call to method WriteLine | normal | | cflow.cs:150:13:150:33 | ...; | cflow.cs:150:13:150:32 | call to method WriteLine | normal | | cflow.cs:150:31:150:31 | access to local variable x | cflow.cs:150:31:150:31 | access to local variable x | normal | -| cflow.cs:152:9:157:9 | for (...;...;...) ... | cflow.cs:156:17:156:22 | break; | normal [break] | +| cflow.cs:152:9:157:9 | for (...;...;...) ... | cflow.cs:156:17:156:22 | break; | normal [break] (0) | | cflow.cs:152:18:152:18 | access to local variable x | cflow.cs:152:18:152:18 | access to local variable x | normal | | cflow.cs:152:18:152:20 | ...++ | cflow.cs:152:18:152:20 | ...++ | normal | | cflow.cs:153:9:157:9 | {...} | cflow.cs:155:17:155:22 | ... > ... | false | @@ -3741,7 +3927,7 @@ | cflow.cs:155:17:155:22 | ... > ... | cflow.cs:155:17:155:22 | ... > ... | true | | cflow.cs:155:21:155:22 | 20 | cflow.cs:155:21:155:22 | 20 | normal | | cflow.cs:156:17:156:22 | break; | cflow.cs:156:17:156:22 | break; | break | -| cflow.cs:159:9:165:9 | for (...;...;...) ... | cflow.cs:164:17:164:22 | break; | normal [break] | +| cflow.cs:159:9:165:9 | for (...;...;...) ... | cflow.cs:164:17:164:22 | break; | normal [break] (0) | | cflow.cs:160:9:165:9 | {...} | cflow.cs:163:17:163:22 | ... > ... | false | | cflow.cs:160:9:165:9 | {...} | cflow.cs:164:17:164:22 | break; | break | | cflow.cs:161:13:161:32 | call to method WriteLine | cflow.cs:161:13:161:32 | call to method WriteLine | normal | @@ -3902,9 +4088,9 @@ | cflow.cs:202:13:204:13 | {...} | cflow.cs:203:17:203:38 | throw ...; | throw(Exception) | | cflow.cs:203:17:203:38 | throw ...; | cflow.cs:203:17:203:38 | throw ...; | throw(Exception) | | cflow.cs:203:23:203:37 | object creation of type Exception | cflow.cs:203:23:203:37 | object creation of type Exception | normal | -| cflow.cs:209:5:222:5 | {...} | cflow.cs:219:17:219:22 | break; | normal [break] | +| cflow.cs:209:5:222:5 | {...} | cflow.cs:219:17:219:22 | break; | normal [break] (0) | | cflow.cs:209:5:222:5 | {...} | cflow.cs:221:18:221:34 | ... < ... | false | -| cflow.cs:210:9:221:36 | do ... while (...); | cflow.cs:219:17:219:22 | break; | normal [break] | +| cflow.cs:210:9:221:36 | do ... while (...); | cflow.cs:219:17:219:22 | break; | normal [break] (0) | | cflow.cs:210:9:221:36 | do ... while (...); | cflow.cs:221:18:221:34 | ... < ... | false | | cflow.cs:211:9:221:9 | {...} | cflow.cs:215:17:215:25 | continue; | continue | | cflow.cs:211:9:221:9 | {...} | cflow.cs:217:17:217:32 | ... < ... | false | @@ -3945,9 +4131,9 @@ | cflow.cs:221:18:221:34 | ... < ... | cflow.cs:221:18:221:34 | ... < ... | true | | cflow.cs:221:33:221:34 | 10 | cflow.cs:221:33:221:34 | 10 | normal | | cflow.cs:225:5:238:5 | {...} | cflow.cs:226:9:237:9 | foreach (... ... in ...) ... | empty | -| cflow.cs:225:5:238:5 | {...} | cflow.cs:235:17:235:22 | break; | normal [break] | +| cflow.cs:225:5:238:5 | {...} | cflow.cs:235:17:235:22 | break; | normal [break] (0) | | cflow.cs:226:9:237:9 | foreach (... ... in ...) ... | cflow.cs:226:9:237:9 | foreach (... ... in ...) ... | empty | -| cflow.cs:226:9:237:9 | foreach (... ... in ...) ... | cflow.cs:235:17:235:22 | break; | normal [break] | +| cflow.cs:226:9:237:9 | foreach (... ... in ...) ... | cflow.cs:235:17:235:22 | break; | normal [break] (0) | | cflow.cs:226:22:226:22 | String x | cflow.cs:226:22:226:22 | String x | normal | | cflow.cs:226:27:226:64 | call to method Repeat | cflow.cs:226:27:226:64 | call to method Repeat | normal | | cflow.cs:226:57:226:59 | "a" | cflow.cs:226:57:226:59 | "a" | normal | @@ -3985,9 +4171,9 @@ | cflow.cs:234:13:236:13 | {...} | cflow.cs:235:17:235:22 | break; | break | | cflow.cs:235:17:235:22 | break; | cflow.cs:235:17:235:22 | break; | break | | cflow.cs:241:5:259:5 | {...} | cflow.cs:244:31:244:41 | goto ...; | goto(Label) | -| cflow.cs:241:5:259:5 | {...} | cflow.cs:252:17:252:22 | break; | normal [break] | +| cflow.cs:241:5:259:5 | {...} | cflow.cs:252:17:252:22 | break; | normal [break] (0) | | cflow.cs:241:5:259:5 | {...} | cflow.cs:254:17:254:27 | goto ...; | goto(Label) | -| cflow.cs:241:5:259:5 | {...} | cflow.cs:257:17:257:22 | break; | normal [break] | +| cflow.cs:241:5:259:5 | {...} | cflow.cs:257:17:257:22 | break; | normal [break] (0) | | cflow.cs:242:9:242:13 | Label: | cflow.cs:242:9:242:13 | Label: | normal | | cflow.cs:242:16:242:45 | if (...) ... | cflow.cs:242:20:242:40 | !... | false | | cflow.cs:242:16:242:45 | if (...) ... | cflow.cs:242:43:242:45 | {...} | normal | @@ -4011,9 +4197,9 @@ | cflow.cs:244:13:244:28 | ... > ... | cflow.cs:244:13:244:28 | ... > ... | true | | cflow.cs:244:28:244:28 | 0 | cflow.cs:244:28:244:28 | 0 | normal | | cflow.cs:244:31:244:41 | goto ...; | cflow.cs:244:31:244:41 | goto ...; | goto(Label) | -| cflow.cs:246:9:258:9 | switch (...) {...} | cflow.cs:252:17:252:22 | break; | normal [break] | +| cflow.cs:246:9:258:9 | switch (...) {...} | cflow.cs:252:17:252:22 | break; | normal [break] (0) | | cflow.cs:246:9:258:9 | switch (...) {...} | cflow.cs:254:17:254:27 | goto ...; | goto(Label) | -| cflow.cs:246:9:258:9 | switch (...) {...} | cflow.cs:257:17:257:22 | break; | normal [break] | +| cflow.cs:246:9:258:9 | switch (...) {...} | cflow.cs:257:17:257:22 | break; | normal [break] (0) | | cflow.cs:246:17:246:21 | access to field Field | cflow.cs:246:17:246:21 | access to field Field | normal | | cflow.cs:246:17:246:21 | this access | cflow.cs:246:17:246:21 | this access | normal | | cflow.cs:246:17:246:28 | access to property Length | cflow.cs:246:17:246:28 | access to property Length | normal | @@ -4043,9 +4229,8 @@ | cflow.cs:256:35:256:35 | 0 | cflow.cs:256:35:256:35 | 0 | normal | | cflow.cs:257:17:257:22 | break; | cflow.cs:257:17:257:22 | break; | break | | cflow.cs:262:5:277:5 | {...} | cflow.cs:275:13:275:41 | call to method WriteLine | normal | -| cflow.cs:262:5:277:5 | {...} | cflow.cs:275:13:275:41 | call to method WriteLine | return [normal] | -| cflow.cs:262:5:277:5 | {...} | cflow.cs:275:13:275:41 | call to method WriteLine | throw(Exception) [normal] | -| cflow.cs:262:5:277:5 | {...} | cflow.cs:275:13:275:41 | call to method WriteLine | throw(OutOfMemoryException) [normal] | +| cflow.cs:262:5:277:5 | {...} | cflow.cs:275:13:275:41 | call to method WriteLine | return [normal] (0) | +| cflow.cs:262:5:277:5 | {...} | cflow.cs:275:13:275:41 | call to method WriteLine | throw(Exception) [normal] (0) | | cflow.cs:263:9:263:23 | yield return ...; | cflow.cs:263:9:263:23 | yield return ...; | normal | | cflow.cs:263:22:263:22 | 0 | cflow.cs:263:22:263:22 | 0 | normal | | cflow.cs:264:9:267:9 | for (...;...;...) ... | cflow.cs:264:25:264:30 | ... < ... | false | @@ -4061,22 +4246,17 @@ | cflow.cs:266:13:266:27 | yield return ...; | cflow.cs:266:13:266:27 | yield return ...; | normal | | cflow.cs:266:26:266:26 | access to local variable i | cflow.cs:266:26:266:26 | access to local variable i | normal | | cflow.cs:268:9:276:9 | try {...} ... | cflow.cs:275:13:275:41 | call to method WriteLine | normal | -| cflow.cs:268:9:276:9 | try {...} ... | cflow.cs:275:13:275:41 | call to method WriteLine | return [normal] | -| cflow.cs:268:9:276:9 | try {...} ... | cflow.cs:275:13:275:41 | call to method WriteLine | throw(Exception) [normal] | -| cflow.cs:268:9:276:9 | try {...} ... | cflow.cs:275:13:275:41 | call to method WriteLine | throw(OutOfMemoryException) [normal] | +| cflow.cs:268:9:276:9 | try {...} ... | cflow.cs:275:13:275:41 | call to method WriteLine | return [normal] (0) | +| cflow.cs:268:9:276:9 | try {...} ... | cflow.cs:275:13:275:41 | call to method WriteLine | throw(Exception) [normal] (0) | | cflow.cs:269:9:272:9 | {...} | cflow.cs:270:13:270:24 | yield break; | return | | cflow.cs:269:9:272:9 | {...} | cflow.cs:271:13:271:42 | call to method WriteLine | normal | | cflow.cs:269:9:272:9 | {...} | cflow.cs:271:13:271:42 | call to method WriteLine | throw(Exception) | -| cflow.cs:269:9:272:9 | {...} | cflow.cs:271:31:271:41 | "dead code" | throw(OutOfMemoryException) | | cflow.cs:270:13:270:24 | yield break; | cflow.cs:270:13:270:24 | yield break; | return | | cflow.cs:271:13:271:42 | call to method WriteLine | cflow.cs:271:13:271:42 | call to method WriteLine | normal | | cflow.cs:271:13:271:42 | call to method WriteLine | cflow.cs:271:13:271:42 | call to method WriteLine | throw(Exception) | -| cflow.cs:271:13:271:42 | call to method WriteLine | cflow.cs:271:31:271:41 | "dead code" | throw(OutOfMemoryException) | | cflow.cs:271:13:271:43 | ...; | cflow.cs:271:13:271:42 | call to method WriteLine | normal | | cflow.cs:271:13:271:43 | ...; | cflow.cs:271:13:271:42 | call to method WriteLine | throw(Exception) | -| cflow.cs:271:13:271:43 | ...; | cflow.cs:271:31:271:41 | "dead code" | throw(OutOfMemoryException) | | cflow.cs:271:31:271:41 | "dead code" | cflow.cs:271:31:271:41 | "dead code" | normal | -| cflow.cs:271:31:271:41 | "dead code" | cflow.cs:271:31:271:41 | "dead code" | throw(OutOfMemoryException) | | cflow.cs:274:9:276:9 | {...} | cflow.cs:275:13:275:41 | call to method WriteLine | normal | | cflow.cs:275:13:275:41 | call to method WriteLine | cflow.cs:275:13:275:41 | call to method WriteLine | normal | | cflow.cs:275:13:275:42 | ...; | cflow.cs:275:13:275:41 | call to method WriteLine | normal | diff --git a/csharp/ql/test/library-tests/controlflow/graph/ExitMethods.cs b/csharp/ql/test/library-tests/controlflow/graph/ExitMethods.cs index 9a34ecd32f8..3d821a1d335 100644 --- a/csharp/ql/test/library-tests/controlflow/graph/ExitMethods.cs +++ b/csharp/ql/test/library-tests/controlflow/graph/ExitMethods.cs @@ -1,6 +1,7 @@ using System; using System.Linq; using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Runtime.ExceptionServices; class ExitMethods { @@ -135,6 +136,15 @@ class ExitMethods AssertFalse(true); var x = 0; // dead } + + public void ExceptionDispatchInfoThrow(bool b, ArgumentException e) + { + if (b) + ExceptionDispatchInfo.Throw(e); + else + ExceptionDispatchInfo.Capture(e).Throw(); + Console.WriteLine("dead"); + } } // semmle-extractor-options: ${testdir}/../../../resources/stubs/System.Windows.cs ${testdir}/../../../resources/stubs/Microsoft.VisualStudio.TestTools.UnitTesting.cs diff --git a/csharp/ql/test/library-tests/controlflow/graph/ExtractorOptions.cs b/csharp/ql/test/library-tests/controlflow/graph/ExtractorOptions.cs deleted file mode 100644 index 69249fa473a..00000000000 --- a/csharp/ql/test/library-tests/controlflow/graph/ExtractorOptions.cs +++ /dev/null @@ -1 +0,0 @@ -// semmle-extractor-options: /langversion:8.0 \ No newline at end of file diff --git a/csharp/ql/test/library-tests/controlflow/graph/Finally.cs b/csharp/ql/test/library-tests/controlflow/graph/Finally.cs index d130862a4df..563afdeb618 100644 --- a/csharp/ql/test/library-tests/controlflow/graph/Finally.cs +++ b/csharp/ql/test/library-tests/controlflow/graph/Finally.cs @@ -229,4 +229,47 @@ public class Finally } Console.WriteLine("Done"); } + + void M12(bool b1, bool b2) + { + try + { + try + { + if (b1) + throw new ExceptionA(); + } + finally + { + try + { + if (b2) + throw new ExceptionA(); + } + finally + { + Console.WriteLine("Inner finally"); + } + } + Console.WriteLine("Mid finally"); + } + finally + { + Console.WriteLine("Outer finally"); + } + Console.WriteLine("Done"); + } + + void M13(int i) + { + try + { + Console.WriteLine("1"); + } + finally + { + Console.WriteLine("3"); + i += 3; + } + } } diff --git a/csharp/ql/test/library-tests/controlflow/graph/NodeGraph.expected b/csharp/ql/test/library-tests/controlflow/graph/NodeGraph.expected index 0dab813fa6c..4ee65369ce6 100644 --- a/csharp/ql/test/library-tests/controlflow/graph/NodeGraph.expected +++ b/csharp/ql/test/library-tests/controlflow/graph/NodeGraph.expected @@ -1650,169 +1650,182 @@ | Conditions.cs:149:38:149:47 | $"..." | Conditions.cs:149:13:149:48 | call to method WriteLine | semmle.label | successor | | Conditions.cs:149:40:149:43 | "b = " | Conditions.cs:149:45:149:45 | access to local variable s | semmle.label | successor | | Conditions.cs:149:45:149:45 | access to local variable s | Conditions.cs:149:38:149:47 | $"..." | semmle.label | successor | -| ExitMethods.cs:7:10:7:11 | enter M1 | ExitMethods.cs:8:5:11:5 | {...} | semmle.label | successor | -| ExitMethods.cs:7:10:7:11 | exit M1 (normal) | ExitMethods.cs:7:10:7:11 | exit M1 | semmle.label | successor | -| ExitMethods.cs:8:5:11:5 | {...} | ExitMethods.cs:9:9:9:25 | ...; | semmle.label | successor | -| ExitMethods.cs:9:9:9:24 | call to method ErrorMaybe | ExitMethods.cs:10:9:10:15 | return ...; | semmle.label | successor | -| ExitMethods.cs:9:9:9:25 | ...; | ExitMethods.cs:9:20:9:23 | true | semmle.label | successor | -| ExitMethods.cs:9:20:9:23 | true | ExitMethods.cs:9:9:9:24 | call to method ErrorMaybe | semmle.label | successor | -| ExitMethods.cs:10:9:10:15 | return ...; | ExitMethods.cs:7:10:7:11 | exit M1 (normal) | semmle.label | return | -| ExitMethods.cs:13:10:13:11 | enter M2 | ExitMethods.cs:14:5:17:5 | {...} | semmle.label | successor | -| ExitMethods.cs:13:10:13:11 | exit M2 (normal) | ExitMethods.cs:13:10:13:11 | exit M2 | semmle.label | successor | -| ExitMethods.cs:14:5:17:5 | {...} | ExitMethods.cs:15:9:15:26 | ...; | semmle.label | successor | -| ExitMethods.cs:15:9:15:25 | call to method ErrorMaybe | ExitMethods.cs:16:9:16:15 | return ...; | semmle.label | successor | -| ExitMethods.cs:15:9:15:26 | ...; | ExitMethods.cs:15:20:15:24 | false | semmle.label | successor | -| ExitMethods.cs:15:20:15:24 | false | ExitMethods.cs:15:9:15:25 | call to method ErrorMaybe | semmle.label | successor | -| ExitMethods.cs:16:9:16:15 | return ...; | ExitMethods.cs:13:10:13:11 | exit M2 (normal) | semmle.label | return | -| ExitMethods.cs:19:10:19:11 | enter M3 | ExitMethods.cs:20:5:23:5 | {...} | semmle.label | successor | -| ExitMethods.cs:19:10:19:11 | exit M3 (abnormal) | ExitMethods.cs:19:10:19:11 | exit M3 | semmle.label | successor | -| ExitMethods.cs:20:5:23:5 | {...} | ExitMethods.cs:21:9:21:26 | ...; | semmle.label | successor | -| ExitMethods.cs:21:9:21:25 | call to method ErrorAlways | ExitMethods.cs:19:10:19:11 | exit M3 (abnormal) | semmle.label | exception(ArgumentException) | -| ExitMethods.cs:21:9:21:25 | call to method ErrorAlways | ExitMethods.cs:19:10:19:11 | exit M3 (abnormal) | semmle.label | exception(Exception) | -| ExitMethods.cs:21:9:21:26 | ...; | ExitMethods.cs:21:21:21:24 | true | semmle.label | successor | -| ExitMethods.cs:21:21:21:24 | true | ExitMethods.cs:21:9:21:25 | call to method ErrorAlways | semmle.label | successor | -| ExitMethods.cs:25:10:25:11 | enter M4 | ExitMethods.cs:26:5:29:5 | {...} | semmle.label | successor | -| ExitMethods.cs:25:10:25:11 | exit M4 (abnormal) | ExitMethods.cs:25:10:25:11 | exit M4 | semmle.label | successor | -| ExitMethods.cs:26:5:29:5 | {...} | ExitMethods.cs:27:9:27:15 | ...; | semmle.label | successor | -| ExitMethods.cs:27:9:27:14 | call to method Exit | ExitMethods.cs:25:10:25:11 | exit M4 (abnormal) | semmle.label | exit | -| ExitMethods.cs:27:9:27:14 | this access | ExitMethods.cs:27:9:27:14 | call to method Exit | semmle.label | successor | -| ExitMethods.cs:27:9:27:15 | ...; | ExitMethods.cs:27:9:27:14 | this access | semmle.label | successor | -| ExitMethods.cs:31:10:31:11 | enter M5 | ExitMethods.cs:32:5:35:5 | {...} | semmle.label | successor | -| ExitMethods.cs:31:10:31:11 | exit M5 (abnormal) | ExitMethods.cs:31:10:31:11 | exit M5 | semmle.label | successor | -| ExitMethods.cs:32:5:35:5 | {...} | ExitMethods.cs:33:9:33:26 | ...; | semmle.label | successor | -| ExitMethods.cs:33:9:33:25 | call to method ApplicationExit | ExitMethods.cs:31:10:31:11 | exit M5 (abnormal) | semmle.label | exit | -| ExitMethods.cs:33:9:33:25 | this access | ExitMethods.cs:33:9:33:25 | call to method ApplicationExit | semmle.label | successor | -| ExitMethods.cs:33:9:33:26 | ...; | ExitMethods.cs:33:9:33:25 | this access | semmle.label | successor | -| ExitMethods.cs:37:10:37:11 | enter M6 | ExitMethods.cs:38:5:51:5 | {...} | semmle.label | successor | -| ExitMethods.cs:37:10:37:11 | exit M6 (normal) | ExitMethods.cs:37:10:37:11 | exit M6 | semmle.label | successor | -| ExitMethods.cs:38:5:51:5 | {...} | ExitMethods.cs:39:9:50:9 | try {...} ... | semmle.label | successor | -| ExitMethods.cs:39:9:50:9 | try {...} ... | ExitMethods.cs:40:9:42:9 | {...} | semmle.label | successor | -| ExitMethods.cs:40:9:42:9 | {...} | ExitMethods.cs:41:13:41:31 | ...; | semmle.label | successor | -| ExitMethods.cs:41:13:41:30 | call to method ErrorAlways | ExitMethods.cs:43:9:46:9 | [exception: ArgumentException] catch (...) {...} | semmle.label | exception(ArgumentException) | -| ExitMethods.cs:41:13:41:30 | call to method ErrorAlways | ExitMethods.cs:43:9:46:9 | [exception: Exception] catch (...) {...} | semmle.label | exception(Exception) | -| ExitMethods.cs:41:13:41:31 | ...; | ExitMethods.cs:41:25:41:29 | false | semmle.label | successor | -| ExitMethods.cs:41:25:41:29 | false | ExitMethods.cs:41:13:41:30 | call to method ErrorAlways | semmle.label | successor | -| ExitMethods.cs:43:9:46:9 | [exception: ArgumentException] catch (...) {...} | ExitMethods.cs:44:9:46:9 | {...} | semmle.label | match | -| ExitMethods.cs:43:9:46:9 | [exception: Exception] catch (...) {...} | ExitMethods.cs:44:9:46:9 | {...} | semmle.label | match | -| ExitMethods.cs:43:9:46:9 | [exception: Exception] catch (...) {...} | ExitMethods.cs:47:9:50:9 | [exception: Exception] catch (...) {...} | semmle.label | no-match | -| ExitMethods.cs:44:9:46:9 | {...} | ExitMethods.cs:45:13:45:19 | return ...; | semmle.label | successor | -| ExitMethods.cs:45:13:45:19 | return ...; | ExitMethods.cs:37:10:37:11 | exit M6 (normal) | semmle.label | return | -| ExitMethods.cs:47:9:50:9 | [exception: Exception] catch (...) {...} | ExitMethods.cs:48:9:50:9 | {...} | semmle.label | match | -| ExitMethods.cs:48:9:50:9 | {...} | ExitMethods.cs:49:13:49:19 | return ...; | semmle.label | successor | -| ExitMethods.cs:49:13:49:19 | return ...; | ExitMethods.cs:37:10:37:11 | exit M6 (normal) | semmle.label | return | -| ExitMethods.cs:53:10:53:11 | enter M7 | ExitMethods.cs:54:5:57:5 | {...} | semmle.label | successor | -| ExitMethods.cs:53:10:53:11 | exit M7 (abnormal) | ExitMethods.cs:53:10:53:11 | exit M7 | semmle.label | successor | -| ExitMethods.cs:54:5:57:5 | {...} | ExitMethods.cs:55:9:55:23 | ...; | semmle.label | successor | -| ExitMethods.cs:55:9:55:22 | call to method ErrorAlways2 | ExitMethods.cs:53:10:53:11 | exit M7 (abnormal) | semmle.label | exception(Exception) | -| ExitMethods.cs:55:9:55:23 | ...; | ExitMethods.cs:55:9:55:22 | call to method ErrorAlways2 | semmle.label | successor | -| ExitMethods.cs:59:10:59:11 | enter M8 | ExitMethods.cs:60:5:63:5 | {...} | semmle.label | successor | -| ExitMethods.cs:59:10:59:11 | exit M8 (abnormal) | ExitMethods.cs:59:10:59:11 | exit M8 | semmle.label | successor | -| ExitMethods.cs:60:5:63:5 | {...} | ExitMethods.cs:61:9:61:23 | ...; | semmle.label | successor | -| ExitMethods.cs:61:9:61:22 | call to method ErrorAlways3 | ExitMethods.cs:59:10:59:11 | exit M8 (abnormal) | semmle.label | exception(Exception) | -| ExitMethods.cs:61:9:61:23 | ...; | ExitMethods.cs:61:9:61:22 | call to method ErrorAlways3 | semmle.label | successor | -| ExitMethods.cs:65:17:65:26 | enter ErrorMaybe | ExitMethods.cs:66:5:69:5 | {...} | semmle.label | successor | -| ExitMethods.cs:65:17:65:26 | exit ErrorMaybe (abnormal) | ExitMethods.cs:65:17:65:26 | exit ErrorMaybe | semmle.label | successor | -| ExitMethods.cs:65:17:65:26 | exit ErrorMaybe (normal) | ExitMethods.cs:65:17:65:26 | exit ErrorMaybe | semmle.label | successor | -| ExitMethods.cs:66:5:69:5 | {...} | ExitMethods.cs:67:9:68:34 | if (...) ... | semmle.label | successor | -| ExitMethods.cs:67:9:68:34 | if (...) ... | ExitMethods.cs:67:13:67:13 | access to parameter b | semmle.label | successor | -| ExitMethods.cs:67:13:67:13 | access to parameter b | ExitMethods.cs:65:17:65:26 | exit ErrorMaybe (normal) | semmle.label | false | -| ExitMethods.cs:67:13:67:13 | access to parameter b | ExitMethods.cs:68:19:68:33 | object creation of type Exception | semmle.label | true | -| ExitMethods.cs:68:13:68:34 | throw ...; | ExitMethods.cs:65:17:65:26 | exit ErrorMaybe (abnormal) | semmle.label | exception(Exception) | -| ExitMethods.cs:68:19:68:33 | object creation of type Exception | ExitMethods.cs:68:13:68:34 | throw ...; | semmle.label | successor | -| ExitMethods.cs:71:17:71:27 | enter ErrorAlways | ExitMethods.cs:72:5:77:5 | {...} | semmle.label | successor | -| ExitMethods.cs:71:17:71:27 | exit ErrorAlways (abnormal) | ExitMethods.cs:71:17:71:27 | exit ErrorAlways | semmle.label | successor | -| ExitMethods.cs:72:5:77:5 | {...} | ExitMethods.cs:73:9:76:45 | if (...) ... | semmle.label | successor | -| ExitMethods.cs:73:9:76:45 | if (...) ... | ExitMethods.cs:73:13:73:13 | access to parameter b | semmle.label | successor | -| ExitMethods.cs:73:13:73:13 | access to parameter b | ExitMethods.cs:74:19:74:33 | object creation of type Exception | semmle.label | true | -| ExitMethods.cs:73:13:73:13 | access to parameter b | ExitMethods.cs:76:41:76:43 | "b" | semmle.label | false | -| ExitMethods.cs:74:13:74:34 | throw ...; | ExitMethods.cs:71:17:71:27 | exit ErrorAlways (abnormal) | semmle.label | exception(Exception) | -| ExitMethods.cs:74:19:74:33 | object creation of type Exception | ExitMethods.cs:74:13:74:34 | throw ...; | semmle.label | successor | -| ExitMethods.cs:76:13:76:45 | throw ...; | ExitMethods.cs:71:17:71:27 | exit ErrorAlways (abnormal) | semmle.label | exception(ArgumentException) | -| ExitMethods.cs:76:19:76:44 | object creation of type ArgumentException | ExitMethods.cs:76:13:76:45 | throw ...; | semmle.label | successor | -| ExitMethods.cs:76:41:76:43 | "b" | ExitMethods.cs:76:19:76:44 | object creation of type ArgumentException | semmle.label | successor | -| ExitMethods.cs:79:17:79:28 | enter ErrorAlways2 | ExitMethods.cs:80:5:82:5 | {...} | semmle.label | successor | -| ExitMethods.cs:79:17:79:28 | exit ErrorAlways2 (abnormal) | ExitMethods.cs:79:17:79:28 | exit ErrorAlways2 | semmle.label | successor | -| ExitMethods.cs:80:5:82:5 | {...} | ExitMethods.cs:81:15:81:29 | object creation of type Exception | semmle.label | successor | -| ExitMethods.cs:81:9:81:30 | throw ...; | ExitMethods.cs:79:17:79:28 | exit ErrorAlways2 (abnormal) | semmle.label | exception(Exception) | -| ExitMethods.cs:81:15:81:29 | object creation of type Exception | ExitMethods.cs:81:9:81:30 | throw ...; | semmle.label | successor | -| ExitMethods.cs:84:17:84:28 | enter ErrorAlways3 | ExitMethods.cs:84:41:84:55 | object creation of type Exception | semmle.label | successor | -| ExitMethods.cs:84:17:84:28 | exit ErrorAlways3 (abnormal) | ExitMethods.cs:84:17:84:28 | exit ErrorAlways3 | semmle.label | successor | -| ExitMethods.cs:84:35:84:55 | throw ... | ExitMethods.cs:84:17:84:28 | exit ErrorAlways3 (abnormal) | semmle.label | exception(Exception) | -| ExitMethods.cs:84:41:84:55 | object creation of type Exception | ExitMethods.cs:84:35:84:55 | throw ... | semmle.label | successor | -| ExitMethods.cs:86:10:86:13 | enter Exit | ExitMethods.cs:87:5:89:5 | {...} | semmle.label | successor | -| ExitMethods.cs:86:10:86:13 | exit Exit (abnormal) | ExitMethods.cs:86:10:86:13 | exit Exit | semmle.label | successor | -| ExitMethods.cs:87:5:89:5 | {...} | ExitMethods.cs:88:9:88:28 | ...; | semmle.label | successor | -| ExitMethods.cs:88:9:88:27 | call to method Exit | ExitMethods.cs:86:10:86:13 | exit Exit (abnormal) | semmle.label | exit | -| ExitMethods.cs:88:9:88:28 | ...; | ExitMethods.cs:88:26:88:26 | 0 | semmle.label | successor | -| ExitMethods.cs:88:26:88:26 | 0 | ExitMethods.cs:88:9:88:27 | call to method Exit | semmle.label | successor | -| ExitMethods.cs:91:10:91:18 | enter ExitInTry | ExitMethods.cs:92:5:102:5 | {...} | semmle.label | successor | -| ExitMethods.cs:91:10:91:18 | exit ExitInTry (abnormal) | ExitMethods.cs:91:10:91:18 | exit ExitInTry | semmle.label | successor | -| ExitMethods.cs:92:5:102:5 | {...} | ExitMethods.cs:93:9:101:9 | try {...} ... | semmle.label | successor | -| ExitMethods.cs:93:9:101:9 | try {...} ... | ExitMethods.cs:94:9:96:9 | {...} | semmle.label | successor | -| ExitMethods.cs:94:9:96:9 | {...} | ExitMethods.cs:95:13:95:19 | ...; | semmle.label | successor | -| ExitMethods.cs:95:13:95:18 | call to method Exit | ExitMethods.cs:91:10:91:18 | exit ExitInTry (abnormal) | semmle.label | exit | -| ExitMethods.cs:95:13:95:18 | this access | ExitMethods.cs:95:13:95:18 | call to method Exit | semmle.label | successor | -| ExitMethods.cs:95:13:95:19 | ...; | ExitMethods.cs:95:13:95:18 | this access | semmle.label | successor | -| ExitMethods.cs:104:10:104:24 | enter ApplicationExit | ExitMethods.cs:105:5:107:5 | {...} | semmle.label | successor | -| ExitMethods.cs:104:10:104:24 | exit ApplicationExit (abnormal) | ExitMethods.cs:104:10:104:24 | exit ApplicationExit | semmle.label | successor | -| ExitMethods.cs:105:5:107:5 | {...} | ExitMethods.cs:106:9:106:48 | ...; | semmle.label | successor | -| ExitMethods.cs:106:9:106:47 | call to method Exit | ExitMethods.cs:104:10:104:24 | exit ApplicationExit (abnormal) | semmle.label | exit | -| ExitMethods.cs:106:9:106:48 | ...; | ExitMethods.cs:106:9:106:47 | call to method Exit | semmle.label | successor | -| ExitMethods.cs:109:13:109:21 | enter ThrowExpr | ExitMethods.cs:110:5:112:5 | {...} | semmle.label | successor | -| ExitMethods.cs:109:13:109:21 | exit ThrowExpr (abnormal) | ExitMethods.cs:109:13:109:21 | exit ThrowExpr | semmle.label | successor | -| ExitMethods.cs:109:13:109:21 | exit ThrowExpr (normal) | ExitMethods.cs:109:13:109:21 | exit ThrowExpr | semmle.label | successor | -| ExitMethods.cs:110:5:112:5 | {...} | ExitMethods.cs:111:16:111:20 | access to parameter input | semmle.label | successor | -| ExitMethods.cs:111:9:111:77 | return ...; | ExitMethods.cs:109:13:109:21 | exit ThrowExpr (normal) | semmle.label | return | -| ExitMethods.cs:111:16:111:20 | access to parameter input | ExitMethods.cs:111:25:111:25 | 0 | semmle.label | successor | -| ExitMethods.cs:111:16:111:25 | ... != ... | ExitMethods.cs:111:29:111:29 | 1 | semmle.label | true | -| ExitMethods.cs:111:16:111:25 | ... != ... | ExitMethods.cs:111:69:111:75 | "input" | semmle.label | false | -| ExitMethods.cs:111:16:111:76 | ... ? ... : ... | ExitMethods.cs:111:9:111:77 | return ...; | semmle.label | successor | -| ExitMethods.cs:111:25:111:25 | 0 | ExitMethods.cs:111:25:111:25 | (...) ... | semmle.label | successor | -| ExitMethods.cs:111:25:111:25 | (...) ... | ExitMethods.cs:111:16:111:25 | ... != ... | semmle.label | successor | -| ExitMethods.cs:111:29:111:29 | 1 | ExitMethods.cs:111:29:111:29 | (...) ... | semmle.label | successor | -| ExitMethods.cs:111:29:111:29 | (...) ... | ExitMethods.cs:111:33:111:37 | access to parameter input | semmle.label | successor | -| ExitMethods.cs:111:29:111:37 | ... / ... | ExitMethods.cs:111:16:111:76 | ... ? ... : ... | semmle.label | successor | -| ExitMethods.cs:111:33:111:37 | access to parameter input | ExitMethods.cs:111:29:111:37 | ... / ... | semmle.label | successor | -| ExitMethods.cs:111:41:111:76 | throw ... | ExitMethods.cs:109:13:109:21 | exit ThrowExpr (abnormal) | semmle.label | exception(ArgumentException) | -| ExitMethods.cs:111:47:111:76 | object creation of type ArgumentException | ExitMethods.cs:111:41:111:76 | throw ... | semmle.label | successor | -| ExitMethods.cs:111:69:111:75 | "input" | ExitMethods.cs:111:47:111:76 | object creation of type ArgumentException | semmle.label | successor | -| ExitMethods.cs:114:16:114:34 | enter ExtensionMethodCall | ExitMethods.cs:115:5:117:5 | {...} | semmle.label | successor | -| ExitMethods.cs:114:16:114:34 | exit ExtensionMethodCall (normal) | ExitMethods.cs:114:16:114:34 | exit ExtensionMethodCall | semmle.label | successor | -| ExitMethods.cs:115:5:117:5 | {...} | ExitMethods.cs:116:16:116:16 | access to parameter s | semmle.label | successor | -| ExitMethods.cs:116:9:116:39 | return ...; | ExitMethods.cs:114:16:114:34 | exit ExtensionMethodCall (normal) | semmle.label | return | -| ExitMethods.cs:116:16:116:16 | access to parameter s | ExitMethods.cs:116:27:116:29 | - | semmle.label | successor | -| ExitMethods.cs:116:16:116:30 | call to method Contains | ExitMethods.cs:116:34:116:34 | 0 | semmle.label | true | -| ExitMethods.cs:116:16:116:30 | call to method Contains | ExitMethods.cs:116:38:116:38 | 1 | semmle.label | false | -| ExitMethods.cs:116:16:116:38 | ... ? ... : ... | ExitMethods.cs:116:9:116:39 | return ...; | semmle.label | successor | -| ExitMethods.cs:116:27:116:29 | - | ExitMethods.cs:116:16:116:30 | call to method Contains | semmle.label | successor | -| ExitMethods.cs:116:34:116:34 | 0 | ExitMethods.cs:116:16:116:38 | ... ? ... : ... | semmle.label | successor | -| ExitMethods.cs:116:38:116:38 | 1 | ExitMethods.cs:116:16:116:38 | ... ? ... : ... | semmle.label | successor | -| ExitMethods.cs:119:17:119:32 | enter FailingAssertion | ExitMethods.cs:120:5:123:5 | {...} | semmle.label | successor | -| ExitMethods.cs:119:17:119:32 | exit FailingAssertion (abnormal) | ExitMethods.cs:119:17:119:32 | exit FailingAssertion | semmle.label | successor | -| ExitMethods.cs:120:5:123:5 | {...} | ExitMethods.cs:121:9:121:29 | ...; | semmle.label | successor | -| ExitMethods.cs:121:9:121:28 | [assertion failure] call to method IsTrue | ExitMethods.cs:119:17:119:32 | exit FailingAssertion (abnormal) | semmle.label | exception(AssertFailedException) | -| ExitMethods.cs:121:9:121:29 | ...; | ExitMethods.cs:121:23:121:27 | false | semmle.label | successor | -| ExitMethods.cs:121:23:121:27 | false | ExitMethods.cs:121:9:121:28 | [assertion failure] call to method IsTrue | semmle.label | false | -| ExitMethods.cs:125:17:125:33 | enter FailingAssertion2 | ExitMethods.cs:126:5:129:5 | {...} | semmle.label | successor | -| ExitMethods.cs:125:17:125:33 | exit FailingAssertion2 (abnormal) | ExitMethods.cs:125:17:125:33 | exit FailingAssertion2 | semmle.label | successor | -| ExitMethods.cs:126:5:129:5 | {...} | ExitMethods.cs:127:9:127:27 | ...; | semmle.label | successor | -| ExitMethods.cs:127:9:127:26 | call to method FailingAssertion | ExitMethods.cs:125:17:125:33 | exit FailingAssertion2 (abnormal) | semmle.label | exception(AssertFailedException) | -| ExitMethods.cs:127:9:127:26 | this access | ExitMethods.cs:127:9:127:26 | call to method FailingAssertion | semmle.label | successor | -| ExitMethods.cs:127:9:127:27 | ...; | ExitMethods.cs:127:9:127:26 | this access | semmle.label | successor | -| ExitMethods.cs:131:10:131:20 | enter AssertFalse | ExitMethods.cs:131:48:131:48 | access to parameter b | semmle.label | successor | -| ExitMethods.cs:131:10:131:20 | exit AssertFalse (abnormal) | ExitMethods.cs:131:10:131:20 | exit AssertFalse | semmle.label | successor | -| ExitMethods.cs:131:10:131:20 | exit AssertFalse (normal) | ExitMethods.cs:131:10:131:20 | exit AssertFalse | semmle.label | successor | -| ExitMethods.cs:131:33:131:49 | [assertion failure] call to method IsFalse | ExitMethods.cs:131:10:131:20 | exit AssertFalse (abnormal) | semmle.label | exception(AssertFailedException) | -| ExitMethods.cs:131:33:131:49 | [assertion success] call to method IsFalse | ExitMethods.cs:131:10:131:20 | exit AssertFalse (normal) | semmle.label | successor | -| ExitMethods.cs:131:48:131:48 | access to parameter b | ExitMethods.cs:131:33:131:49 | [assertion failure] call to method IsFalse | semmle.label | true | -| ExitMethods.cs:131:48:131:48 | access to parameter b | ExitMethods.cs:131:33:131:49 | [assertion success] call to method IsFalse | semmle.label | false | -| ExitMethods.cs:133:17:133:33 | enter FailingAssertion3 | ExitMethods.cs:134:5:137:5 | {...} | semmle.label | successor | -| ExitMethods.cs:133:17:133:33 | exit FailingAssertion3 (abnormal) | ExitMethods.cs:133:17:133:33 | exit FailingAssertion3 | semmle.label | successor | -| ExitMethods.cs:134:5:137:5 | {...} | ExitMethods.cs:135:9:135:26 | ...; | semmle.label | successor | -| ExitMethods.cs:135:9:135:25 | [assertion failure] call to method AssertFalse | ExitMethods.cs:133:17:133:33 | exit FailingAssertion3 (abnormal) | semmle.label | exception(AssertFailedException) | -| ExitMethods.cs:135:9:135:25 | this access | ExitMethods.cs:135:21:135:24 | true | semmle.label | successor | -| ExitMethods.cs:135:9:135:26 | ...; | ExitMethods.cs:135:9:135:25 | this access | semmle.label | successor | -| ExitMethods.cs:135:21:135:24 | true | ExitMethods.cs:135:9:135:25 | [assertion failure] call to method AssertFalse | semmle.label | true | +| ExitMethods.cs:8:10:8:11 | enter M1 | ExitMethods.cs:9:5:12:5 | {...} | semmle.label | successor | +| ExitMethods.cs:8:10:8:11 | exit M1 (normal) | ExitMethods.cs:8:10:8:11 | exit M1 | semmle.label | successor | +| ExitMethods.cs:9:5:12:5 | {...} | ExitMethods.cs:10:9:10:25 | ...; | semmle.label | successor | +| ExitMethods.cs:10:9:10:24 | call to method ErrorMaybe | ExitMethods.cs:11:9:11:15 | return ...; | semmle.label | successor | +| ExitMethods.cs:10:9:10:25 | ...; | ExitMethods.cs:10:20:10:23 | true | semmle.label | successor | +| ExitMethods.cs:10:20:10:23 | true | ExitMethods.cs:10:9:10:24 | call to method ErrorMaybe | semmle.label | successor | +| ExitMethods.cs:11:9:11:15 | return ...; | ExitMethods.cs:8:10:8:11 | exit M1 (normal) | semmle.label | return | +| ExitMethods.cs:14:10:14:11 | enter M2 | ExitMethods.cs:15:5:18:5 | {...} | semmle.label | successor | +| ExitMethods.cs:14:10:14:11 | exit M2 (normal) | ExitMethods.cs:14:10:14:11 | exit M2 | semmle.label | successor | +| ExitMethods.cs:15:5:18:5 | {...} | ExitMethods.cs:16:9:16:26 | ...; | semmle.label | successor | +| ExitMethods.cs:16:9:16:25 | call to method ErrorMaybe | ExitMethods.cs:17:9:17:15 | return ...; | semmle.label | successor | +| ExitMethods.cs:16:9:16:26 | ...; | ExitMethods.cs:16:20:16:24 | false | semmle.label | successor | +| ExitMethods.cs:16:20:16:24 | false | ExitMethods.cs:16:9:16:25 | call to method ErrorMaybe | semmle.label | successor | +| ExitMethods.cs:17:9:17:15 | return ...; | ExitMethods.cs:14:10:14:11 | exit M2 (normal) | semmle.label | return | +| ExitMethods.cs:20:10:20:11 | enter M3 | ExitMethods.cs:21:5:24:5 | {...} | semmle.label | successor | +| ExitMethods.cs:20:10:20:11 | exit M3 (abnormal) | ExitMethods.cs:20:10:20:11 | exit M3 | semmle.label | successor | +| ExitMethods.cs:21:5:24:5 | {...} | ExitMethods.cs:22:9:22:26 | ...; | semmle.label | successor | +| ExitMethods.cs:22:9:22:25 | call to method ErrorAlways | ExitMethods.cs:20:10:20:11 | exit M3 (abnormal) | semmle.label | exception(ArgumentException) | +| ExitMethods.cs:22:9:22:25 | call to method ErrorAlways | ExitMethods.cs:20:10:20:11 | exit M3 (abnormal) | semmle.label | exception(Exception) | +| ExitMethods.cs:22:9:22:26 | ...; | ExitMethods.cs:22:21:22:24 | true | semmle.label | successor | +| ExitMethods.cs:22:21:22:24 | true | ExitMethods.cs:22:9:22:25 | call to method ErrorAlways | semmle.label | successor | +| ExitMethods.cs:26:10:26:11 | enter M4 | ExitMethods.cs:27:5:30:5 | {...} | semmle.label | successor | +| ExitMethods.cs:26:10:26:11 | exit M4 (abnormal) | ExitMethods.cs:26:10:26:11 | exit M4 | semmle.label | successor | +| ExitMethods.cs:27:5:30:5 | {...} | ExitMethods.cs:28:9:28:15 | ...; | semmle.label | successor | +| ExitMethods.cs:28:9:28:14 | call to method Exit | ExitMethods.cs:26:10:26:11 | exit M4 (abnormal) | semmle.label | exit | +| ExitMethods.cs:28:9:28:14 | this access | ExitMethods.cs:28:9:28:14 | call to method Exit | semmle.label | successor | +| ExitMethods.cs:28:9:28:15 | ...; | ExitMethods.cs:28:9:28:14 | this access | semmle.label | successor | +| ExitMethods.cs:32:10:32:11 | enter M5 | ExitMethods.cs:33:5:36:5 | {...} | semmle.label | successor | +| ExitMethods.cs:32:10:32:11 | exit M5 (abnormal) | ExitMethods.cs:32:10:32:11 | exit M5 | semmle.label | successor | +| ExitMethods.cs:33:5:36:5 | {...} | ExitMethods.cs:34:9:34:26 | ...; | semmle.label | successor | +| ExitMethods.cs:34:9:34:25 | call to method ApplicationExit | ExitMethods.cs:32:10:32:11 | exit M5 (abnormal) | semmle.label | exit | +| ExitMethods.cs:34:9:34:25 | this access | ExitMethods.cs:34:9:34:25 | call to method ApplicationExit | semmle.label | successor | +| ExitMethods.cs:34:9:34:26 | ...; | ExitMethods.cs:34:9:34:25 | this access | semmle.label | successor | +| ExitMethods.cs:38:10:38:11 | enter M6 | ExitMethods.cs:39:5:52:5 | {...} | semmle.label | successor | +| ExitMethods.cs:38:10:38:11 | exit M6 (normal) | ExitMethods.cs:38:10:38:11 | exit M6 | semmle.label | successor | +| ExitMethods.cs:39:5:52:5 | {...} | ExitMethods.cs:40:9:51:9 | try {...} ... | semmle.label | successor | +| ExitMethods.cs:40:9:51:9 | try {...} ... | ExitMethods.cs:41:9:43:9 | {...} | semmle.label | successor | +| ExitMethods.cs:41:9:43:9 | {...} | ExitMethods.cs:42:13:42:31 | ...; | semmle.label | successor | +| ExitMethods.cs:42:13:42:30 | call to method ErrorAlways | ExitMethods.cs:44:9:47:9 | [exception: ArgumentException] catch (...) {...} | semmle.label | exception(ArgumentException) | +| ExitMethods.cs:42:13:42:30 | call to method ErrorAlways | ExitMethods.cs:44:9:47:9 | [exception: Exception] catch (...) {...} | semmle.label | exception(Exception) | +| ExitMethods.cs:42:13:42:31 | ...; | ExitMethods.cs:42:25:42:29 | false | semmle.label | successor | +| ExitMethods.cs:42:25:42:29 | false | ExitMethods.cs:42:13:42:30 | call to method ErrorAlways | semmle.label | successor | +| ExitMethods.cs:44:9:47:9 | [exception: ArgumentException] catch (...) {...} | ExitMethods.cs:45:9:47:9 | {...} | semmle.label | match | +| ExitMethods.cs:44:9:47:9 | [exception: Exception] catch (...) {...} | ExitMethods.cs:45:9:47:9 | {...} | semmle.label | match | +| ExitMethods.cs:44:9:47:9 | [exception: Exception] catch (...) {...} | ExitMethods.cs:48:9:51:9 | [exception: Exception] catch (...) {...} | semmle.label | no-match | +| ExitMethods.cs:45:9:47:9 | {...} | ExitMethods.cs:46:13:46:19 | return ...; | semmle.label | successor | +| ExitMethods.cs:46:13:46:19 | return ...; | ExitMethods.cs:38:10:38:11 | exit M6 (normal) | semmle.label | return | +| ExitMethods.cs:48:9:51:9 | [exception: Exception] catch (...) {...} | ExitMethods.cs:49:9:51:9 | {...} | semmle.label | match | +| ExitMethods.cs:49:9:51:9 | {...} | ExitMethods.cs:50:13:50:19 | return ...; | semmle.label | successor | +| ExitMethods.cs:50:13:50:19 | return ...; | ExitMethods.cs:38:10:38:11 | exit M6 (normal) | semmle.label | return | +| ExitMethods.cs:54:10:54:11 | enter M7 | ExitMethods.cs:55:5:58:5 | {...} | semmle.label | successor | +| ExitMethods.cs:54:10:54:11 | exit M7 (abnormal) | ExitMethods.cs:54:10:54:11 | exit M7 | semmle.label | successor | +| ExitMethods.cs:55:5:58:5 | {...} | ExitMethods.cs:56:9:56:23 | ...; | semmle.label | successor | +| ExitMethods.cs:56:9:56:22 | call to method ErrorAlways2 | ExitMethods.cs:54:10:54:11 | exit M7 (abnormal) | semmle.label | exception(Exception) | +| ExitMethods.cs:56:9:56:23 | ...; | ExitMethods.cs:56:9:56:22 | call to method ErrorAlways2 | semmle.label | successor | +| ExitMethods.cs:60:10:60:11 | enter M8 | ExitMethods.cs:61:5:64:5 | {...} | semmle.label | successor | +| ExitMethods.cs:60:10:60:11 | exit M8 (abnormal) | ExitMethods.cs:60:10:60:11 | exit M8 | semmle.label | successor | +| ExitMethods.cs:61:5:64:5 | {...} | ExitMethods.cs:62:9:62:23 | ...; | semmle.label | successor | +| ExitMethods.cs:62:9:62:22 | call to method ErrorAlways3 | ExitMethods.cs:60:10:60:11 | exit M8 (abnormal) | semmle.label | exception(Exception) | +| ExitMethods.cs:62:9:62:23 | ...; | ExitMethods.cs:62:9:62:22 | call to method ErrorAlways3 | semmle.label | successor | +| ExitMethods.cs:66:17:66:26 | enter ErrorMaybe | ExitMethods.cs:67:5:70:5 | {...} | semmle.label | successor | +| ExitMethods.cs:66:17:66:26 | exit ErrorMaybe (abnormal) | ExitMethods.cs:66:17:66:26 | exit ErrorMaybe | semmle.label | successor | +| ExitMethods.cs:66:17:66:26 | exit ErrorMaybe (normal) | ExitMethods.cs:66:17:66:26 | exit ErrorMaybe | semmle.label | successor | +| ExitMethods.cs:67:5:70:5 | {...} | ExitMethods.cs:68:9:69:34 | if (...) ... | semmle.label | successor | +| ExitMethods.cs:68:9:69:34 | if (...) ... | ExitMethods.cs:68:13:68:13 | access to parameter b | semmle.label | successor | +| ExitMethods.cs:68:13:68:13 | access to parameter b | ExitMethods.cs:66:17:66:26 | exit ErrorMaybe (normal) | semmle.label | false | +| ExitMethods.cs:68:13:68:13 | access to parameter b | ExitMethods.cs:69:19:69:33 | object creation of type Exception | semmle.label | true | +| ExitMethods.cs:69:13:69:34 | throw ...; | ExitMethods.cs:66:17:66:26 | exit ErrorMaybe (abnormal) | semmle.label | exception(Exception) | +| ExitMethods.cs:69:19:69:33 | object creation of type Exception | ExitMethods.cs:69:13:69:34 | throw ...; | semmle.label | successor | +| ExitMethods.cs:72:17:72:27 | enter ErrorAlways | ExitMethods.cs:73:5:78:5 | {...} | semmle.label | successor | +| ExitMethods.cs:72:17:72:27 | exit ErrorAlways (abnormal) | ExitMethods.cs:72:17:72:27 | exit ErrorAlways | semmle.label | successor | +| ExitMethods.cs:73:5:78:5 | {...} | ExitMethods.cs:74:9:77:45 | if (...) ... | semmle.label | successor | +| ExitMethods.cs:74:9:77:45 | if (...) ... | ExitMethods.cs:74:13:74:13 | access to parameter b | semmle.label | successor | +| ExitMethods.cs:74:13:74:13 | access to parameter b | ExitMethods.cs:75:19:75:33 | object creation of type Exception | semmle.label | true | +| ExitMethods.cs:74:13:74:13 | access to parameter b | ExitMethods.cs:77:41:77:43 | "b" | semmle.label | false | +| ExitMethods.cs:75:13:75:34 | throw ...; | ExitMethods.cs:72:17:72:27 | exit ErrorAlways (abnormal) | semmle.label | exception(Exception) | +| ExitMethods.cs:75:19:75:33 | object creation of type Exception | ExitMethods.cs:75:13:75:34 | throw ...; | semmle.label | successor | +| ExitMethods.cs:77:13:77:45 | throw ...; | ExitMethods.cs:72:17:72:27 | exit ErrorAlways (abnormal) | semmle.label | exception(ArgumentException) | +| ExitMethods.cs:77:19:77:44 | object creation of type ArgumentException | ExitMethods.cs:77:13:77:45 | throw ...; | semmle.label | successor | +| ExitMethods.cs:77:41:77:43 | "b" | ExitMethods.cs:77:19:77:44 | object creation of type ArgumentException | semmle.label | successor | +| ExitMethods.cs:80:17:80:28 | enter ErrorAlways2 | ExitMethods.cs:81:5:83:5 | {...} | semmle.label | successor | +| ExitMethods.cs:80:17:80:28 | exit ErrorAlways2 (abnormal) | ExitMethods.cs:80:17:80:28 | exit ErrorAlways2 | semmle.label | successor | +| ExitMethods.cs:81:5:83:5 | {...} | ExitMethods.cs:82:15:82:29 | object creation of type Exception | semmle.label | successor | +| ExitMethods.cs:82:9:82:30 | throw ...; | ExitMethods.cs:80:17:80:28 | exit ErrorAlways2 (abnormal) | semmle.label | exception(Exception) | +| ExitMethods.cs:82:15:82:29 | object creation of type Exception | ExitMethods.cs:82:9:82:30 | throw ...; | semmle.label | successor | +| ExitMethods.cs:85:17:85:28 | enter ErrorAlways3 | ExitMethods.cs:85:41:85:55 | object creation of type Exception | semmle.label | successor | +| ExitMethods.cs:85:17:85:28 | exit ErrorAlways3 (abnormal) | ExitMethods.cs:85:17:85:28 | exit ErrorAlways3 | semmle.label | successor | +| ExitMethods.cs:85:35:85:55 | throw ... | ExitMethods.cs:85:17:85:28 | exit ErrorAlways3 (abnormal) | semmle.label | exception(Exception) | +| ExitMethods.cs:85:41:85:55 | object creation of type Exception | ExitMethods.cs:85:35:85:55 | throw ... | semmle.label | successor | +| ExitMethods.cs:87:10:87:13 | enter Exit | ExitMethods.cs:88:5:90:5 | {...} | semmle.label | successor | +| ExitMethods.cs:87:10:87:13 | exit Exit (abnormal) | ExitMethods.cs:87:10:87:13 | exit Exit | semmle.label | successor | +| ExitMethods.cs:88:5:90:5 | {...} | ExitMethods.cs:89:9:89:28 | ...; | semmle.label | successor | +| ExitMethods.cs:89:9:89:27 | call to method Exit | ExitMethods.cs:87:10:87:13 | exit Exit (abnormal) | semmle.label | exit | +| ExitMethods.cs:89:9:89:28 | ...; | ExitMethods.cs:89:26:89:26 | 0 | semmle.label | successor | +| ExitMethods.cs:89:26:89:26 | 0 | ExitMethods.cs:89:9:89:27 | call to method Exit | semmle.label | successor | +| ExitMethods.cs:92:10:92:18 | enter ExitInTry | ExitMethods.cs:93:5:103:5 | {...} | semmle.label | successor | +| ExitMethods.cs:92:10:92:18 | exit ExitInTry (abnormal) | ExitMethods.cs:92:10:92:18 | exit ExitInTry | semmle.label | successor | +| ExitMethods.cs:93:5:103:5 | {...} | ExitMethods.cs:94:9:102:9 | try {...} ... | semmle.label | successor | +| ExitMethods.cs:94:9:102:9 | try {...} ... | ExitMethods.cs:95:9:97:9 | {...} | semmle.label | successor | +| ExitMethods.cs:95:9:97:9 | {...} | ExitMethods.cs:96:13:96:19 | ...; | semmle.label | successor | +| ExitMethods.cs:96:13:96:18 | call to method Exit | ExitMethods.cs:92:10:92:18 | exit ExitInTry (abnormal) | semmle.label | exit | +| ExitMethods.cs:96:13:96:18 | this access | ExitMethods.cs:96:13:96:18 | call to method Exit | semmle.label | successor | +| ExitMethods.cs:96:13:96:19 | ...; | ExitMethods.cs:96:13:96:18 | this access | semmle.label | successor | +| ExitMethods.cs:105:10:105:24 | enter ApplicationExit | ExitMethods.cs:106:5:108:5 | {...} | semmle.label | successor | +| ExitMethods.cs:105:10:105:24 | exit ApplicationExit (abnormal) | ExitMethods.cs:105:10:105:24 | exit ApplicationExit | semmle.label | successor | +| ExitMethods.cs:106:5:108:5 | {...} | ExitMethods.cs:107:9:107:48 | ...; | semmle.label | successor | +| ExitMethods.cs:107:9:107:47 | call to method Exit | ExitMethods.cs:105:10:105:24 | exit ApplicationExit (abnormal) | semmle.label | exit | +| ExitMethods.cs:107:9:107:48 | ...; | ExitMethods.cs:107:9:107:47 | call to method Exit | semmle.label | successor | +| ExitMethods.cs:110:13:110:21 | enter ThrowExpr | ExitMethods.cs:111:5:113:5 | {...} | semmle.label | successor | +| ExitMethods.cs:110:13:110:21 | exit ThrowExpr (abnormal) | ExitMethods.cs:110:13:110:21 | exit ThrowExpr | semmle.label | successor | +| ExitMethods.cs:110:13:110:21 | exit ThrowExpr (normal) | ExitMethods.cs:110:13:110:21 | exit ThrowExpr | semmle.label | successor | +| ExitMethods.cs:111:5:113:5 | {...} | ExitMethods.cs:112:16:112:20 | access to parameter input | semmle.label | successor | +| ExitMethods.cs:112:9:112:77 | return ...; | ExitMethods.cs:110:13:110:21 | exit ThrowExpr (normal) | semmle.label | return | +| ExitMethods.cs:112:16:112:20 | access to parameter input | ExitMethods.cs:112:25:112:25 | 0 | semmle.label | successor | +| ExitMethods.cs:112:16:112:25 | ... != ... | ExitMethods.cs:112:29:112:29 | 1 | semmle.label | true | +| ExitMethods.cs:112:16:112:25 | ... != ... | ExitMethods.cs:112:69:112:75 | "input" | semmle.label | false | +| ExitMethods.cs:112:16:112:76 | ... ? ... : ... | ExitMethods.cs:112:9:112:77 | return ...; | semmle.label | successor | +| ExitMethods.cs:112:25:112:25 | 0 | ExitMethods.cs:112:25:112:25 | (...) ... | semmle.label | successor | +| ExitMethods.cs:112:25:112:25 | (...) ... | ExitMethods.cs:112:16:112:25 | ... != ... | semmle.label | successor | +| ExitMethods.cs:112:29:112:29 | 1 | ExitMethods.cs:112:29:112:29 | (...) ... | semmle.label | successor | +| ExitMethods.cs:112:29:112:29 | (...) ... | ExitMethods.cs:112:33:112:37 | access to parameter input | semmle.label | successor | +| ExitMethods.cs:112:29:112:37 | ... / ... | ExitMethods.cs:112:16:112:76 | ... ? ... : ... | semmle.label | successor | +| ExitMethods.cs:112:33:112:37 | access to parameter input | ExitMethods.cs:112:29:112:37 | ... / ... | semmle.label | successor | +| ExitMethods.cs:112:41:112:76 | throw ... | ExitMethods.cs:110:13:110:21 | exit ThrowExpr (abnormal) | semmle.label | exception(ArgumentException) | +| ExitMethods.cs:112:47:112:76 | object creation of type ArgumentException | ExitMethods.cs:112:41:112:76 | throw ... | semmle.label | successor | +| ExitMethods.cs:112:69:112:75 | "input" | ExitMethods.cs:112:47:112:76 | object creation of type ArgumentException | semmle.label | successor | +| ExitMethods.cs:115:16:115:34 | enter ExtensionMethodCall | ExitMethods.cs:116:5:118:5 | {...} | semmle.label | successor | +| ExitMethods.cs:115:16:115:34 | exit ExtensionMethodCall (normal) | ExitMethods.cs:115:16:115:34 | exit ExtensionMethodCall | semmle.label | successor | +| ExitMethods.cs:116:5:118:5 | {...} | ExitMethods.cs:117:16:117:16 | access to parameter s | semmle.label | successor | +| ExitMethods.cs:117:9:117:39 | return ...; | ExitMethods.cs:115:16:115:34 | exit ExtensionMethodCall (normal) | semmle.label | return | +| ExitMethods.cs:117:16:117:16 | access to parameter s | ExitMethods.cs:117:27:117:29 | - | semmle.label | successor | +| ExitMethods.cs:117:16:117:30 | call to method Contains | ExitMethods.cs:117:34:117:34 | 0 | semmle.label | true | +| ExitMethods.cs:117:16:117:30 | call to method Contains | ExitMethods.cs:117:38:117:38 | 1 | semmle.label | false | +| ExitMethods.cs:117:16:117:38 | ... ? ... : ... | ExitMethods.cs:117:9:117:39 | return ...; | semmle.label | successor | +| ExitMethods.cs:117:27:117:29 | - | ExitMethods.cs:117:16:117:30 | call to method Contains | semmle.label | successor | +| ExitMethods.cs:117:34:117:34 | 0 | ExitMethods.cs:117:16:117:38 | ... ? ... : ... | semmle.label | successor | +| ExitMethods.cs:117:38:117:38 | 1 | ExitMethods.cs:117:16:117:38 | ... ? ... : ... | semmle.label | successor | +| ExitMethods.cs:120:17:120:32 | enter FailingAssertion | ExitMethods.cs:121:5:124:5 | {...} | semmle.label | successor | +| ExitMethods.cs:120:17:120:32 | exit FailingAssertion (abnormal) | ExitMethods.cs:120:17:120:32 | exit FailingAssertion | semmle.label | successor | +| ExitMethods.cs:121:5:124:5 | {...} | ExitMethods.cs:122:9:122:29 | ...; | semmle.label | successor | +| ExitMethods.cs:122:9:122:28 | [assertion failure] call to method IsTrue | ExitMethods.cs:120:17:120:32 | exit FailingAssertion (abnormal) | semmle.label | exception(AssertFailedException) | +| ExitMethods.cs:122:9:122:29 | ...; | ExitMethods.cs:122:23:122:27 | false | semmle.label | successor | +| ExitMethods.cs:122:23:122:27 | false | ExitMethods.cs:122:9:122:28 | [assertion failure] call to method IsTrue | semmle.label | false | +| ExitMethods.cs:126:17:126:33 | enter FailingAssertion2 | ExitMethods.cs:127:5:130:5 | {...} | semmle.label | successor | +| ExitMethods.cs:126:17:126:33 | exit FailingAssertion2 (abnormal) | ExitMethods.cs:126:17:126:33 | exit FailingAssertion2 | semmle.label | successor | +| ExitMethods.cs:127:5:130:5 | {...} | ExitMethods.cs:128:9:128:27 | ...; | semmle.label | successor | +| ExitMethods.cs:128:9:128:26 | call to method FailingAssertion | ExitMethods.cs:126:17:126:33 | exit FailingAssertion2 (abnormal) | semmle.label | exception(AssertFailedException) | +| ExitMethods.cs:128:9:128:26 | this access | ExitMethods.cs:128:9:128:26 | call to method FailingAssertion | semmle.label | successor | +| ExitMethods.cs:128:9:128:27 | ...; | ExitMethods.cs:128:9:128:26 | this access | semmle.label | successor | +| ExitMethods.cs:132:10:132:20 | enter AssertFalse | ExitMethods.cs:132:48:132:48 | access to parameter b | semmle.label | successor | +| ExitMethods.cs:132:10:132:20 | exit AssertFalse (abnormal) | ExitMethods.cs:132:10:132:20 | exit AssertFalse | semmle.label | successor | +| ExitMethods.cs:132:10:132:20 | exit AssertFalse (normal) | ExitMethods.cs:132:10:132:20 | exit AssertFalse | semmle.label | successor | +| ExitMethods.cs:132:33:132:49 | [assertion failure] call to method IsFalse | ExitMethods.cs:132:10:132:20 | exit AssertFalse (abnormal) | semmle.label | exception(AssertFailedException) | +| ExitMethods.cs:132:33:132:49 | [assertion success] call to method IsFalse | ExitMethods.cs:132:10:132:20 | exit AssertFalse (normal) | semmle.label | successor | +| ExitMethods.cs:132:48:132:48 | access to parameter b | ExitMethods.cs:132:33:132:49 | [assertion failure] call to method IsFalse | semmle.label | true | +| ExitMethods.cs:132:48:132:48 | access to parameter b | ExitMethods.cs:132:33:132:49 | [assertion success] call to method IsFalse | semmle.label | false | +| ExitMethods.cs:134:17:134:33 | enter FailingAssertion3 | ExitMethods.cs:135:5:138:5 | {...} | semmle.label | successor | +| ExitMethods.cs:134:17:134:33 | exit FailingAssertion3 (abnormal) | ExitMethods.cs:134:17:134:33 | exit FailingAssertion3 | semmle.label | successor | +| ExitMethods.cs:135:5:138:5 | {...} | ExitMethods.cs:136:9:136:26 | ...; | semmle.label | successor | +| ExitMethods.cs:136:9:136:25 | [assertion failure] call to method AssertFalse | ExitMethods.cs:134:17:134:33 | exit FailingAssertion3 (abnormal) | semmle.label | exception(AssertFailedException) | +| ExitMethods.cs:136:9:136:25 | this access | ExitMethods.cs:136:21:136:24 | true | semmle.label | successor | +| ExitMethods.cs:136:9:136:26 | ...; | ExitMethods.cs:136:9:136:25 | this access | semmle.label | successor | +| ExitMethods.cs:136:21:136:24 | true | ExitMethods.cs:136:9:136:25 | [assertion failure] call to method AssertFalse | semmle.label | true | +| ExitMethods.cs:140:17:140:42 | enter ExceptionDispatchInfoThrow | ExitMethods.cs:141:5:147:5 | {...} | semmle.label | successor | +| ExitMethods.cs:140:17:140:42 | exit ExceptionDispatchInfoThrow (abnormal) | ExitMethods.cs:140:17:140:42 | exit ExceptionDispatchInfoThrow | semmle.label | successor | +| ExitMethods.cs:141:5:147:5 | {...} | ExitMethods.cs:142:9:145:53 | if (...) ... | semmle.label | successor | +| ExitMethods.cs:142:9:145:53 | if (...) ... | ExitMethods.cs:142:13:142:13 | access to parameter b | semmle.label | successor | +| ExitMethods.cs:142:13:142:13 | access to parameter b | ExitMethods.cs:143:13:143:43 | ...; | semmle.label | true | +| ExitMethods.cs:142:13:142:13 | access to parameter b | ExitMethods.cs:145:13:145:53 | ...; | semmle.label | false | +| ExitMethods.cs:143:13:143:42 | call to method Throw | ExitMethods.cs:140:17:140:42 | exit ExceptionDispatchInfoThrow (abnormal) | semmle.label | exception(ArgumentException) | +| ExitMethods.cs:143:13:143:43 | ...; | ExitMethods.cs:143:41:143:41 | access to parameter e | semmle.label | successor | +| ExitMethods.cs:143:41:143:41 | access to parameter e | ExitMethods.cs:143:13:143:42 | call to method Throw | semmle.label | successor | +| ExitMethods.cs:145:13:145:44 | call to method Capture | ExitMethods.cs:145:13:145:52 | call to method Throw | semmle.label | successor | +| ExitMethods.cs:145:13:145:52 | call to method Throw | ExitMethods.cs:140:17:140:42 | exit ExceptionDispatchInfoThrow (abnormal) | semmle.label | exception(Exception) | +| ExitMethods.cs:145:13:145:53 | ...; | ExitMethods.cs:145:43:145:43 | access to parameter e | semmle.label | successor | +| ExitMethods.cs:145:43:145:43 | access to parameter e | ExitMethods.cs:145:13:145:44 | call to method Capture | semmle.label | successor | | Extensions.cs:5:23:5:29 | enter ToInt32 | Extensions.cs:6:5:8:5 | {...} | semmle.label | successor | | Extensions.cs:5:23:5:29 | exit ToInt32 (normal) | Extensions.cs:5:23:5:29 | exit ToInt32 | semmle.label | successor | | Extensions.cs:6:5:8:5 | {...} | Extensions.cs:7:28:7:28 | access to parameter s | semmle.label | successor | @@ -1859,19 +1872,14 @@ | Finally.cs:11:13:11:37 | call to method WriteLine | Finally.cs:14:9:16:9 | {...} | semmle.label | successor | | Finally.cs:11:13:11:38 | ...; | Finally.cs:11:31:11:36 | "Try1" | semmle.label | successor | | Finally.cs:11:31:11:36 | "Try1" | Finally.cs:11:13:11:37 | call to method WriteLine | semmle.label | successor | -| Finally.cs:11:31:11:36 | "Try1" | Finally.cs:14:9:16:9 | [finally: exception(OutOfMemoryException)] {...} | semmle.label | exception(OutOfMemoryException) | | Finally.cs:14:9:16:9 | [finally: exception(Exception)] {...} | Finally.cs:15:13:15:41 | [finally: exception(Exception)] ...; | semmle.label | successor | -| Finally.cs:14:9:16:9 | [finally: exception(OutOfMemoryException)] {...} | Finally.cs:15:13:15:41 | [finally: exception(OutOfMemoryException)] ...; | semmle.label | successor | | Finally.cs:14:9:16:9 | {...} | Finally.cs:15:13:15:41 | ...; | semmle.label | successor | | Finally.cs:15:13:15:40 | [finally: exception(Exception)] call to method WriteLine | Finally.cs:7:10:7:11 | exit M1 (abnormal) | semmle.label | exception(Exception) | -| Finally.cs:15:13:15:40 | [finally: exception(OutOfMemoryException)] call to method WriteLine | Finally.cs:7:10:7:11 | exit M1 (abnormal) | semmle.label | exception(OutOfMemoryException) | | Finally.cs:15:13:15:40 | call to method WriteLine | Finally.cs:7:10:7:11 | exit M1 (normal) | semmle.label | successor | | Finally.cs:15:13:15:41 | ...; | Finally.cs:15:31:15:39 | "Finally" | semmle.label | successor | | Finally.cs:15:13:15:41 | [finally: exception(Exception)] ...; | Finally.cs:15:31:15:39 | [finally: exception(Exception)] "Finally" | semmle.label | successor | -| Finally.cs:15:13:15:41 | [finally: exception(OutOfMemoryException)] ...; | Finally.cs:15:31:15:39 | [finally: exception(OutOfMemoryException)] "Finally" | semmle.label | successor | | Finally.cs:15:31:15:39 | "Finally" | Finally.cs:15:13:15:40 | call to method WriteLine | semmle.label | successor | | Finally.cs:15:31:15:39 | [finally: exception(Exception)] "Finally" | Finally.cs:15:13:15:40 | [finally: exception(Exception)] call to method WriteLine | semmle.label | successor | -| Finally.cs:15:31:15:39 | [finally: exception(OutOfMemoryException)] "Finally" | Finally.cs:15:13:15:40 | [finally: exception(OutOfMemoryException)] call to method WriteLine | semmle.label | successor | | Finally.cs:19:10:19:11 | enter M2 | Finally.cs:20:5:52:5 | {...} | semmle.label | successor | | Finally.cs:19:10:19:11 | exit M2 (abnormal) | Finally.cs:19:10:19:11 | exit M2 | semmle.label | successor | | Finally.cs:19:10:19:11 | exit M2 (normal) | Finally.cs:19:10:19:11 | exit M2 | semmle.label | successor | @@ -1882,18 +1890,15 @@ | Finally.cs:23:13:23:37 | call to method WriteLine | Finally.cs:26:9:29:9 | [exception: Exception] catch (...) {...} | semmle.label | exception(Exception) | | Finally.cs:23:13:23:38 | ...; | Finally.cs:23:31:23:36 | "Try2" | semmle.label | successor | | Finally.cs:23:31:23:36 | "Try2" | Finally.cs:23:13:23:37 | call to method WriteLine | semmle.label | successor | -| Finally.cs:23:31:23:36 | "Try2" | Finally.cs:26:9:29:9 | [exception: OutOfMemoryException] catch (...) {...} | semmle.label | exception(OutOfMemoryException) | | Finally.cs:24:13:24:19 | return ...; | Finally.cs:49:9:51:9 | [finally: return] {...} | semmle.label | return | | Finally.cs:26:9:29:9 | [exception: Exception] catch (...) {...} | Finally.cs:26:38:26:39 | [exception: Exception] IOException ex | semmle.label | match | | Finally.cs:26:9:29:9 | [exception: Exception] catch (...) {...} | Finally.cs:30:9:40:9 | [exception: Exception] catch (...) {...} | semmle.label | no-match | -| Finally.cs:26:9:29:9 | [exception: OutOfMemoryException] catch (...) {...} | Finally.cs:30:9:40:9 | [exception: OutOfMemoryException] catch (...) {...} | semmle.label | no-match | | Finally.cs:26:38:26:39 | [exception: Exception] IOException ex | Finally.cs:26:48:26:51 | [exception: Exception] true | semmle.label | successor | | Finally.cs:26:48:26:51 | [exception: Exception] true | Finally.cs:27:9:29:9 | {...} | semmle.label | true | | Finally.cs:27:9:29:9 | {...} | Finally.cs:28:13:28:18 | throw ...; | semmle.label | successor | | Finally.cs:28:13:28:18 | throw ...; | Finally.cs:49:9:51:9 | [finally: exception(IOException)] {...} | semmle.label | exception(IOException) | | Finally.cs:30:9:40:9 | [exception: Exception] catch (...) {...} | Finally.cs:30:41:30:42 | [exception: Exception] ArgumentException ex | semmle.label | match | | Finally.cs:30:9:40:9 | [exception: Exception] catch (...) {...} | Finally.cs:41:9:43:9 | [exception: Exception] catch (...) {...} | semmle.label | no-match | -| Finally.cs:30:9:40:9 | [exception: OutOfMemoryException] catch (...) {...} | Finally.cs:41:9:43:9 | [exception: OutOfMemoryException] catch (...) {...} | semmle.label | no-match | | Finally.cs:30:41:30:42 | [exception: Exception] ArgumentException ex | Finally.cs:31:9:40:9 | {...} | semmle.label | successor | | Finally.cs:31:9:40:9 | {...} | Finally.cs:32:13:39:13 | try {...} ... | semmle.label | successor | | Finally.cs:32:13:39:13 | try {...} ... | Finally.cs:33:13:35:13 | {...} | semmle.label | successor | @@ -1906,7 +1911,6 @@ | Finally.cs:38:23:38:43 | [finally: exception(ArgumentException)] object creation of type Exception | Finally.cs:38:17:38:44 | [finally: exception(ArgumentException)] throw ...; | semmle.label | successor | | Finally.cs:38:37:38:42 | [finally: exception(ArgumentException)] "Boo!" | Finally.cs:38:23:38:43 | [finally: exception(ArgumentException)] object creation of type Exception | semmle.label | successor | | Finally.cs:41:9:43:9 | [exception: Exception] catch (...) {...} | Finally.cs:42:9:43:9 | {...} | semmle.label | match | -| Finally.cs:41:9:43:9 | [exception: OutOfMemoryException] catch (...) {...} | Finally.cs:42:9:43:9 | {...} | semmle.label | match | | Finally.cs:42:9:43:9 | {...} | Finally.cs:49:9:51:9 | {...} | semmle.label | successor | | Finally.cs:49:9:51:9 | [finally: exception(Exception)] {...} | Finally.cs:50:13:50:41 | [finally: exception(Exception)] ...; | semmle.label | successor | | Finally.cs:49:9:51:9 | [finally: exception(IOException)] {...} | Finally.cs:50:13:50:41 | [finally: exception(IOException)] ...; | semmle.label | successor | @@ -1934,49 +1938,36 @@ | Finally.cs:58:13:58:37 | call to method WriteLine | Finally.cs:61:9:64:9 | [exception: Exception] catch (...) {...} | semmle.label | exception(Exception) | | Finally.cs:58:13:58:38 | ...; | Finally.cs:58:31:58:36 | "Try3" | semmle.label | successor | | Finally.cs:58:31:58:36 | "Try3" | Finally.cs:58:13:58:37 | call to method WriteLine | semmle.label | successor | -| Finally.cs:58:31:58:36 | "Try3" | Finally.cs:61:9:64:9 | [exception: OutOfMemoryException] catch (...) {...} | semmle.label | exception(OutOfMemoryException) | | Finally.cs:59:13:59:19 | return ...; | Finally.cs:69:9:71:9 | [finally: return] {...} | semmle.label | return | | Finally.cs:61:9:64:9 | [exception: Exception] catch (...) {...} | Finally.cs:61:38:61:39 | [exception: Exception] IOException ex | semmle.label | match | | Finally.cs:61:9:64:9 | [exception: Exception] catch (...) {...} | Finally.cs:65:9:67:9 | [exception: Exception] catch (...) {...} | semmle.label | no-match | -| Finally.cs:61:9:64:9 | [exception: OutOfMemoryException] catch (...) {...} | Finally.cs:65:9:67:9 | [exception: OutOfMemoryException] catch (...) {...} | semmle.label | no-match | | Finally.cs:61:38:61:39 | [exception: Exception] IOException ex | Finally.cs:61:48:61:51 | [exception: Exception] true | semmle.label | successor | | Finally.cs:61:48:61:51 | [exception: Exception] true | Finally.cs:62:9:64:9 | {...} | semmle.label | true | | Finally.cs:62:9:64:9 | {...} | Finally.cs:63:13:63:18 | throw ...; | semmle.label | successor | | Finally.cs:63:13:63:18 | throw ...; | Finally.cs:69:9:71:9 | [finally: exception(IOException)] {...} | semmle.label | exception(IOException) | | Finally.cs:65:9:67:9 | [exception: Exception] catch (...) {...} | Finally.cs:65:26:65:26 | [exception: Exception] Exception e | semmle.label | match | -| Finally.cs:65:9:67:9 | [exception: OutOfMemoryException] catch (...) {...} | Finally.cs:65:26:65:26 | [exception: OutOfMemoryException] Exception e | semmle.label | match | | Finally.cs:65:26:65:26 | [exception: Exception] Exception e | Finally.cs:65:35:65:35 | [exception: Exception] access to local variable e | semmle.label | successor | -| Finally.cs:65:26:65:26 | [exception: OutOfMemoryException] Exception e | Finally.cs:65:35:65:35 | [exception: OutOfMemoryException] access to local variable e | semmle.label | successor | | Finally.cs:65:35:65:35 | [exception: Exception] access to local variable e | Finally.cs:65:35:65:43 | [exception: Exception] access to property Message | semmle.label | successor | -| Finally.cs:65:35:65:35 | [exception: OutOfMemoryException] access to local variable e | Finally.cs:65:35:65:43 | [exception: OutOfMemoryException] access to property Message | semmle.label | successor | | Finally.cs:65:35:65:43 | [exception: Exception] access to property Message | Finally.cs:65:48:65:51 | [exception: Exception] null | semmle.label | successor | -| Finally.cs:65:35:65:43 | [exception: OutOfMemoryException] access to property Message | Finally.cs:65:48:65:51 | [exception: OutOfMemoryException] null | semmle.label | successor | | Finally.cs:65:35:65:51 | [exception: Exception] ... != ... | Finally.cs:66:9:67:9 | {...} | semmle.label | true | | Finally.cs:65:35:65:51 | [exception: Exception] ... != ... | Finally.cs:69:9:71:9 | [finally: exception(Exception)] {...} | semmle.label | exception(Exception) | -| Finally.cs:65:35:65:51 | [exception: OutOfMemoryException] ... != ... | Finally.cs:66:9:67:9 | {...} | semmle.label | true | -| Finally.cs:65:35:65:51 | [exception: OutOfMemoryException] ... != ... | Finally.cs:69:9:71:9 | [finally: exception(OutOfMemoryException)] {...} | semmle.label | exception(OutOfMemoryException) | | Finally.cs:65:48:65:51 | [exception: Exception] null | Finally.cs:65:35:65:51 | [exception: Exception] ... != ... | semmle.label | successor | -| Finally.cs:65:48:65:51 | [exception: OutOfMemoryException] null | Finally.cs:65:35:65:51 | [exception: OutOfMemoryException] ... != ... | semmle.label | successor | | Finally.cs:66:9:67:9 | {...} | Finally.cs:69:9:71:9 | {...} | semmle.label | successor | | Finally.cs:69:9:71:9 | [finally: exception(Exception)] {...} | Finally.cs:70:13:70:41 | [finally: exception(Exception)] ...; | semmle.label | successor | | Finally.cs:69:9:71:9 | [finally: exception(IOException)] {...} | Finally.cs:70:13:70:41 | [finally: exception(IOException)] ...; | semmle.label | successor | -| Finally.cs:69:9:71:9 | [finally: exception(OutOfMemoryException)] {...} | Finally.cs:70:13:70:41 | [finally: exception(OutOfMemoryException)] ...; | semmle.label | successor | | Finally.cs:69:9:71:9 | [finally: return] {...} | Finally.cs:70:13:70:41 | [finally: return] ...; | semmle.label | successor | | Finally.cs:69:9:71:9 | {...} | Finally.cs:70:13:70:41 | ...; | semmle.label | successor | | Finally.cs:70:13:70:40 | [finally: exception(Exception)] call to method WriteLine | Finally.cs:54:10:54:11 | exit M3 (abnormal) | semmle.label | exception(Exception) | | Finally.cs:70:13:70:40 | [finally: exception(IOException)] call to method WriteLine | Finally.cs:54:10:54:11 | exit M3 (abnormal) | semmle.label | exception(IOException) | -| Finally.cs:70:13:70:40 | [finally: exception(OutOfMemoryException)] call to method WriteLine | Finally.cs:54:10:54:11 | exit M3 (abnormal) | semmle.label | exception(OutOfMemoryException) | | Finally.cs:70:13:70:40 | [finally: return] call to method WriteLine | Finally.cs:54:10:54:11 | exit M3 (normal) | semmle.label | return | | Finally.cs:70:13:70:40 | call to method WriteLine | Finally.cs:54:10:54:11 | exit M3 (normal) | semmle.label | successor | | Finally.cs:70:13:70:41 | ...; | Finally.cs:70:31:70:39 | "Finally" | semmle.label | successor | | Finally.cs:70:13:70:41 | [finally: exception(Exception)] ...; | Finally.cs:70:31:70:39 | [finally: exception(Exception)] "Finally" | semmle.label | successor | | Finally.cs:70:13:70:41 | [finally: exception(IOException)] ...; | Finally.cs:70:31:70:39 | [finally: exception(IOException)] "Finally" | semmle.label | successor | -| Finally.cs:70:13:70:41 | [finally: exception(OutOfMemoryException)] ...; | Finally.cs:70:31:70:39 | [finally: exception(OutOfMemoryException)] "Finally" | semmle.label | successor | | Finally.cs:70:13:70:41 | [finally: return] ...; | Finally.cs:70:31:70:39 | [finally: return] "Finally" | semmle.label | successor | | Finally.cs:70:31:70:39 | "Finally" | Finally.cs:70:13:70:40 | call to method WriteLine | semmle.label | successor | | Finally.cs:70:31:70:39 | [finally: exception(Exception)] "Finally" | Finally.cs:70:13:70:40 | [finally: exception(Exception)] call to method WriteLine | semmle.label | successor | | Finally.cs:70:31:70:39 | [finally: exception(IOException)] "Finally" | Finally.cs:70:13:70:40 | [finally: exception(IOException)] call to method WriteLine | semmle.label | successor | -| Finally.cs:70:31:70:39 | [finally: exception(OutOfMemoryException)] "Finally" | Finally.cs:70:13:70:40 | [finally: exception(OutOfMemoryException)] call to method WriteLine | semmle.label | successor | | Finally.cs:70:31:70:39 | [finally: return] "Finally" | Finally.cs:70:13:70:40 | [finally: return] call to method WriteLine | semmle.label | successor | | Finally.cs:74:10:74:11 | enter M4 | Finally.cs:75:5:101:5 | {...} | semmle.label | successor | | Finally.cs:74:10:74:11 | exit M4 (abnormal) | Finally.cs:74:10:74:11 | exit M4 | semmle.label | successor | @@ -2043,49 +2034,49 @@ | Finally.cs:92:30:92:30 | [finally: break] 3 | Finally.cs:92:25:92:30 | [finally: break] ... == ... | semmle.label | successor | | Finally.cs:92:30:92:30 | [finally: continue] 3 | Finally.cs:92:25:92:30 | [finally: continue] ... == ... | semmle.label | successor | | Finally.cs:92:30:92:30 | [finally: return] 3 | Finally.cs:92:25:92:30 | [finally: return] ... == ... | semmle.label | successor | -| Finally.cs:93:25:93:46 | [finally: break] throw ...; | Finally.cs:96:17:98:17 | [finally: break, finally(2): exception(Exception)] {...} | semmle.label | exception(Exception) | -| Finally.cs:93:25:93:46 | [finally: continue] throw ...; | Finally.cs:96:17:98:17 | [finally: continue, finally(2): exception(Exception)] {...} | semmle.label | exception(Exception) | -| Finally.cs:93:25:93:46 | [finally: return] throw ...; | Finally.cs:96:17:98:17 | [finally: return, finally(2): exception(Exception)] {...} | semmle.label | exception(Exception) | -| Finally.cs:93:25:93:46 | throw ...; | Finally.cs:96:17:98:17 | [finally(2): exception(Exception)] {...} | semmle.label | exception(Exception) | +| Finally.cs:93:25:93:46 | [finally: break] throw ...; | Finally.cs:96:17:98:17 | [finally: break, finally(1): exception(Exception)] {...} | semmle.label | exception(Exception) | +| Finally.cs:93:25:93:46 | [finally: continue] throw ...; | Finally.cs:96:17:98:17 | [finally: continue, finally(1): exception(Exception)] {...} | semmle.label | exception(Exception) | +| Finally.cs:93:25:93:46 | [finally: return] throw ...; | Finally.cs:96:17:98:17 | [finally: return, finally(1): exception(Exception)] {...} | semmle.label | exception(Exception) | +| Finally.cs:93:25:93:46 | throw ...; | Finally.cs:96:17:98:17 | [finally(1): exception(Exception)] {...} | semmle.label | exception(Exception) | | Finally.cs:93:31:93:45 | [finally: break] object creation of type Exception | Finally.cs:93:25:93:46 | [finally: break] throw ...; | semmle.label | successor | -| Finally.cs:93:31:93:45 | [finally: break] object creation of type Exception | Finally.cs:96:17:98:17 | [finally: break, finally(2): exception(Exception)] {...} | semmle.label | exception(Exception) | +| Finally.cs:93:31:93:45 | [finally: break] object creation of type Exception | Finally.cs:96:17:98:17 | [finally: break, finally(1): exception(Exception)] {...} | semmle.label | exception(Exception) | | Finally.cs:93:31:93:45 | [finally: continue] object creation of type Exception | Finally.cs:93:25:93:46 | [finally: continue] throw ...; | semmle.label | successor | -| Finally.cs:93:31:93:45 | [finally: continue] object creation of type Exception | Finally.cs:96:17:98:17 | [finally: continue, finally(2): exception(Exception)] {...} | semmle.label | exception(Exception) | +| Finally.cs:93:31:93:45 | [finally: continue] object creation of type Exception | Finally.cs:96:17:98:17 | [finally: continue, finally(1): exception(Exception)] {...} | semmle.label | exception(Exception) | | Finally.cs:93:31:93:45 | [finally: return] object creation of type Exception | Finally.cs:93:25:93:46 | [finally: return] throw ...; | semmle.label | successor | -| Finally.cs:93:31:93:45 | [finally: return] object creation of type Exception | Finally.cs:96:17:98:17 | [finally: return, finally(2): exception(Exception)] {...} | semmle.label | exception(Exception) | +| Finally.cs:93:31:93:45 | [finally: return] object creation of type Exception | Finally.cs:96:17:98:17 | [finally: return, finally(1): exception(Exception)] {...} | semmle.label | exception(Exception) | | Finally.cs:93:31:93:45 | object creation of type Exception | Finally.cs:93:25:93:46 | throw ...; | semmle.label | successor | -| Finally.cs:93:31:93:45 | object creation of type Exception | Finally.cs:96:17:98:17 | [finally(2): exception(Exception)] {...} | semmle.label | exception(Exception) | -| Finally.cs:96:17:98:17 | [finally(2): exception(Exception)] {...} | Finally.cs:97:21:97:24 | [finally(2): exception(Exception)] ...; | semmle.label | successor | -| Finally.cs:96:17:98:17 | [finally: break, finally(2): exception(Exception)] {...} | Finally.cs:97:21:97:24 | [finally: break, finally(2): exception(Exception)] ...; | semmle.label | successor | +| Finally.cs:93:31:93:45 | object creation of type Exception | Finally.cs:96:17:98:17 | [finally(1): exception(Exception)] {...} | semmle.label | exception(Exception) | +| Finally.cs:96:17:98:17 | [finally(1): exception(Exception)] {...} | Finally.cs:97:21:97:24 | [finally(1): exception(Exception)] ...; | semmle.label | successor | +| Finally.cs:96:17:98:17 | [finally: break, finally(1): exception(Exception)] {...} | Finally.cs:97:21:97:24 | [finally: break, finally(1): exception(Exception)] ...; | semmle.label | successor | | Finally.cs:96:17:98:17 | [finally: break] {...} | Finally.cs:97:21:97:24 | [finally: break] ...; | semmle.label | successor | -| Finally.cs:96:17:98:17 | [finally: continue, finally(2): exception(Exception)] {...} | Finally.cs:97:21:97:24 | [finally: continue, finally(2): exception(Exception)] ...; | semmle.label | successor | +| Finally.cs:96:17:98:17 | [finally: continue, finally(1): exception(Exception)] {...} | Finally.cs:97:21:97:24 | [finally: continue, finally(1): exception(Exception)] ...; | semmle.label | successor | | Finally.cs:96:17:98:17 | [finally: continue] {...} | Finally.cs:97:21:97:24 | [finally: continue] ...; | semmle.label | successor | -| Finally.cs:96:17:98:17 | [finally: return, finally(2): exception(Exception)] {...} | Finally.cs:97:21:97:24 | [finally: return, finally(2): exception(Exception)] ...; | semmle.label | successor | +| Finally.cs:96:17:98:17 | [finally: return, finally(1): exception(Exception)] {...} | Finally.cs:97:21:97:24 | [finally: return, finally(1): exception(Exception)] ...; | semmle.label | successor | | Finally.cs:96:17:98:17 | [finally: return] {...} | Finally.cs:97:21:97:24 | [finally: return] ...; | semmle.label | successor | | Finally.cs:96:17:98:17 | {...} | Finally.cs:97:21:97:24 | ...; | semmle.label | successor | -| Finally.cs:97:21:97:21 | [finally(2): exception(Exception)] access to local variable i | Finally.cs:97:21:97:23 | [finally(2): exception(Exception)] ...-- | semmle.label | successor | -| Finally.cs:97:21:97:21 | [finally: break, finally(2): exception(Exception)] access to local variable i | Finally.cs:97:21:97:23 | [finally: break, finally(2): exception(Exception)] ...-- | semmle.label | successor | +| Finally.cs:97:21:97:21 | [finally(1): exception(Exception)] access to local variable i | Finally.cs:97:21:97:23 | [finally(1): exception(Exception)] ...-- | semmle.label | successor | +| Finally.cs:97:21:97:21 | [finally: break, finally(1): exception(Exception)] access to local variable i | Finally.cs:97:21:97:23 | [finally: break, finally(1): exception(Exception)] ...-- | semmle.label | successor | | Finally.cs:97:21:97:21 | [finally: break] access to local variable i | Finally.cs:97:21:97:23 | [finally: break] ...-- | semmle.label | successor | -| Finally.cs:97:21:97:21 | [finally: continue, finally(2): exception(Exception)] access to local variable i | Finally.cs:97:21:97:23 | [finally: continue, finally(2): exception(Exception)] ...-- | semmle.label | successor | +| Finally.cs:97:21:97:21 | [finally: continue, finally(1): exception(Exception)] access to local variable i | Finally.cs:97:21:97:23 | [finally: continue, finally(1): exception(Exception)] ...-- | semmle.label | successor | | Finally.cs:97:21:97:21 | [finally: continue] access to local variable i | Finally.cs:97:21:97:23 | [finally: continue] ...-- | semmle.label | successor | -| Finally.cs:97:21:97:21 | [finally: return, finally(2): exception(Exception)] access to local variable i | Finally.cs:97:21:97:23 | [finally: return, finally(2): exception(Exception)] ...-- | semmle.label | successor | +| Finally.cs:97:21:97:21 | [finally: return, finally(1): exception(Exception)] access to local variable i | Finally.cs:97:21:97:23 | [finally: return, finally(1): exception(Exception)] ...-- | semmle.label | successor | | Finally.cs:97:21:97:21 | [finally: return] access to local variable i | Finally.cs:97:21:97:23 | [finally: return] ...-- | semmle.label | successor | | Finally.cs:97:21:97:21 | access to local variable i | Finally.cs:97:21:97:23 | ...-- | semmle.label | successor | | Finally.cs:97:21:97:23 | ...-- | Finally.cs:77:16:77:16 | access to local variable i | semmle.label | successor | -| Finally.cs:97:21:97:23 | [finally(2): exception(Exception)] ...-- | Finally.cs:74:10:74:11 | exit M4 (abnormal) | semmle.label | exception(Exception) | -| Finally.cs:97:21:97:23 | [finally: break, finally(2): exception(Exception)] ...-- | Finally.cs:74:10:74:11 | exit M4 (abnormal) | semmle.label | exception(Exception) | +| Finally.cs:97:21:97:23 | [finally(1): exception(Exception)] ...-- | Finally.cs:74:10:74:11 | exit M4 (abnormal) | semmle.label | exception(Exception) | +| Finally.cs:97:21:97:23 | [finally: break, finally(1): exception(Exception)] ...-- | Finally.cs:74:10:74:11 | exit M4 (abnormal) | semmle.label | exception(Exception) | | Finally.cs:97:21:97:23 | [finally: break] ...-- | Finally.cs:74:10:74:11 | exit M4 (normal) | semmle.label | break | -| Finally.cs:97:21:97:23 | [finally: continue, finally(2): exception(Exception)] ...-- | Finally.cs:74:10:74:11 | exit M4 (abnormal) | semmle.label | exception(Exception) | +| Finally.cs:97:21:97:23 | [finally: continue, finally(1): exception(Exception)] ...-- | Finally.cs:74:10:74:11 | exit M4 (abnormal) | semmle.label | exception(Exception) | | Finally.cs:97:21:97:23 | [finally: continue] ...-- | Finally.cs:77:16:77:16 | access to local variable i | semmle.label | continue | -| Finally.cs:97:21:97:23 | [finally: return, finally(2): exception(Exception)] ...-- | Finally.cs:74:10:74:11 | exit M4 (abnormal) | semmle.label | exception(Exception) | +| Finally.cs:97:21:97:23 | [finally: return, finally(1): exception(Exception)] ...-- | Finally.cs:74:10:74:11 | exit M4 (abnormal) | semmle.label | exception(Exception) | | Finally.cs:97:21:97:23 | [finally: return] ...-- | Finally.cs:74:10:74:11 | exit M4 (normal) | semmle.label | return | | Finally.cs:97:21:97:24 | ...; | Finally.cs:97:21:97:21 | access to local variable i | semmle.label | successor | -| Finally.cs:97:21:97:24 | [finally(2): exception(Exception)] ...; | Finally.cs:97:21:97:21 | [finally(2): exception(Exception)] access to local variable i | semmle.label | successor | -| Finally.cs:97:21:97:24 | [finally: break, finally(2): exception(Exception)] ...; | Finally.cs:97:21:97:21 | [finally: break, finally(2): exception(Exception)] access to local variable i | semmle.label | successor | +| Finally.cs:97:21:97:24 | [finally(1): exception(Exception)] ...; | Finally.cs:97:21:97:21 | [finally(1): exception(Exception)] access to local variable i | semmle.label | successor | +| Finally.cs:97:21:97:24 | [finally: break, finally(1): exception(Exception)] ...; | Finally.cs:97:21:97:21 | [finally: break, finally(1): exception(Exception)] access to local variable i | semmle.label | successor | | Finally.cs:97:21:97:24 | [finally: break] ...; | Finally.cs:97:21:97:21 | [finally: break] access to local variable i | semmle.label | successor | -| Finally.cs:97:21:97:24 | [finally: continue, finally(2): exception(Exception)] ...; | Finally.cs:97:21:97:21 | [finally: continue, finally(2): exception(Exception)] access to local variable i | semmle.label | successor | +| Finally.cs:97:21:97:24 | [finally: continue, finally(1): exception(Exception)] ...; | Finally.cs:97:21:97:21 | [finally: continue, finally(1): exception(Exception)] access to local variable i | semmle.label | successor | | Finally.cs:97:21:97:24 | [finally: continue] ...; | Finally.cs:97:21:97:21 | [finally: continue] access to local variable i | semmle.label | successor | -| Finally.cs:97:21:97:24 | [finally: return, finally(2): exception(Exception)] ...; | Finally.cs:97:21:97:21 | [finally: return, finally(2): exception(Exception)] access to local variable i | semmle.label | successor | +| Finally.cs:97:21:97:24 | [finally: return, finally(1): exception(Exception)] ...; | Finally.cs:97:21:97:21 | [finally: return, finally(1): exception(Exception)] access to local variable i | semmle.label | successor | | Finally.cs:97:21:97:24 | [finally: return] ...; | Finally.cs:97:21:97:21 | [finally: return] access to local variable i | semmle.label | successor | | Finally.cs:103:10:103:11 | enter M5 | Finally.cs:104:5:119:5 | {...} | semmle.label | successor | | Finally.cs:103:10:103:11 | exit M5 (abnormal) | Finally.cs:103:10:103:11 | exit M5 | semmle.label | successor | @@ -2257,19 +2248,14 @@ | Finally.cs:137:13:137:36 | call to method WriteLine | Finally.cs:140:9:143:9 | {...} | semmle.label | successor | | Finally.cs:137:13:137:37 | ...; | Finally.cs:137:31:137:35 | "Try" | semmle.label | successor | | Finally.cs:137:31:137:35 | "Try" | Finally.cs:137:13:137:36 | call to method WriteLine | semmle.label | successor | -| Finally.cs:137:31:137:35 | "Try" | Finally.cs:140:9:143:9 | [finally: exception(OutOfMemoryException)] {...} | semmle.label | exception(OutOfMemoryException) | | Finally.cs:140:9:143:9 | [finally: exception(Exception)] {...} | Finally.cs:141:41:141:42 | [finally: exception(Exception)] "" | semmle.label | successor | -| Finally.cs:140:9:143:9 | [finally: exception(OutOfMemoryException)] {...} | Finally.cs:141:41:141:42 | [finally: exception(OutOfMemoryException)] "" | semmle.label | successor | | Finally.cs:140:9:143:9 | {...} | Finally.cs:141:41:141:42 | "" | semmle.label | successor | | Finally.cs:141:13:141:44 | [finally: exception(Exception)] throw ...; | Finally.cs:133:10:133:11 | exit M7 (abnormal) | semmle.label | exception(ArgumentException) | -| Finally.cs:141:13:141:44 | [finally: exception(OutOfMemoryException)] throw ...; | Finally.cs:133:10:133:11 | exit M7 (abnormal) | semmle.label | exception(ArgumentException) | | Finally.cs:141:13:141:44 | throw ...; | Finally.cs:133:10:133:11 | exit M7 (abnormal) | semmle.label | exception(ArgumentException) | | Finally.cs:141:19:141:43 | [finally: exception(Exception)] object creation of type ArgumentException | Finally.cs:141:13:141:44 | [finally: exception(Exception)] throw ...; | semmle.label | successor | -| Finally.cs:141:19:141:43 | [finally: exception(OutOfMemoryException)] object creation of type ArgumentException | Finally.cs:141:13:141:44 | [finally: exception(OutOfMemoryException)] throw ...; | semmle.label | successor | | Finally.cs:141:19:141:43 | object creation of type ArgumentException | Finally.cs:141:13:141:44 | throw ...; | semmle.label | successor | | Finally.cs:141:41:141:42 | "" | Finally.cs:141:19:141:43 | object creation of type ArgumentException | semmle.label | successor | | Finally.cs:141:41:141:42 | [finally: exception(Exception)] "" | Finally.cs:141:19:141:43 | [finally: exception(Exception)] object creation of type ArgumentException | semmle.label | successor | -| Finally.cs:141:41:141:42 | [finally: exception(OutOfMemoryException)] "" | Finally.cs:141:19:141:43 | [finally: exception(OutOfMemoryException)] object creation of type ArgumentException | semmle.label | successor | | Finally.cs:147:10:147:11 | enter M8 | Finally.cs:148:5:170:5 | {...} | semmle.label | successor | | Finally.cs:147:10:147:11 | exit M8 (abnormal) | Finally.cs:147:10:147:11 | exit M8 | semmle.label | successor | | Finally.cs:147:10:147:11 | exit M8 (normal) | Finally.cs:147:10:147:11 | exit M8 | semmle.label | successor | @@ -2327,74 +2313,50 @@ | Finally.cs:159:27:159:44 | object creation of type Exception | Finally.cs:159:21:159:45 | throw ...; | semmle.label | successor | | Finally.cs:159:27:159:44 | object creation of type Exception | Finally.cs:161:13:164:13 | [exception: Exception] catch (...) {...} | semmle.label | exception(Exception) | | Finally.cs:159:41:159:43 | "1" | Finally.cs:159:27:159:44 | object creation of type Exception | semmle.label | successor | -| Finally.cs:159:41:159:43 | "1" | Finally.cs:161:13:164:13 | [exception: OutOfMemoryException] catch (...) {...} | semmle.label | exception(OutOfMemoryException) | | Finally.cs:159:41:159:43 | [finally: exception(ArgumentNullException)] "1" | Finally.cs:159:27:159:44 | [finally: exception(ArgumentNullException)] object creation of type Exception | semmle.label | successor | -| Finally.cs:159:41:159:43 | [finally: exception(ArgumentNullException)] "1" | Finally.cs:161:13:164:13 | [finally: exception(ArgumentNullException), exception: OutOfMemoryException] catch (...) {...} | semmle.label | exception(OutOfMemoryException) | | Finally.cs:159:41:159:43 | [finally: exception(Exception)] "1" | Finally.cs:159:27:159:44 | [finally: exception(Exception)] object creation of type Exception | semmle.label | successor | -| Finally.cs:159:41:159:43 | [finally: exception(Exception)] "1" | Finally.cs:161:13:164:13 | [finally: exception(Exception), exception: OutOfMemoryException] catch (...) {...} | semmle.label | exception(OutOfMemoryException) | | Finally.cs:161:13:164:13 | [exception: Exception] catch (...) {...} | Finally.cs:161:30:161:30 | [exception: Exception] Exception e | semmle.label | match | | Finally.cs:161:13:164:13 | [exception: NullReferenceException] catch (...) {...} | Finally.cs:161:30:161:30 | [exception: NullReferenceException] Exception e | semmle.label | match | -| Finally.cs:161:13:164:13 | [exception: OutOfMemoryException] catch (...) {...} | Finally.cs:161:30:161:30 | [exception: OutOfMemoryException] Exception e | semmle.label | match | | Finally.cs:161:13:164:13 | [finally: exception(ArgumentNullException), exception: Exception] catch (...) {...} | Finally.cs:161:30:161:30 | [finally: exception(ArgumentNullException), exception: Exception] Exception e | semmle.label | match | | Finally.cs:161:13:164:13 | [finally: exception(ArgumentNullException), exception: NullReferenceException] catch (...) {...} | Finally.cs:161:30:161:30 | [finally: exception(ArgumentNullException), exception: NullReferenceException] Exception e | semmle.label | match | -| Finally.cs:161:13:164:13 | [finally: exception(ArgumentNullException), exception: OutOfMemoryException] catch (...) {...} | Finally.cs:161:30:161:30 | [finally: exception(ArgumentNullException), exception: OutOfMemoryException] Exception e | semmle.label | match | | Finally.cs:161:13:164:13 | [finally: exception(Exception), exception: Exception] catch (...) {...} | Finally.cs:161:30:161:30 | [finally: exception(Exception), exception: Exception] Exception e | semmle.label | match | | Finally.cs:161:13:164:13 | [finally: exception(Exception), exception: NullReferenceException] catch (...) {...} | Finally.cs:161:30:161:30 | [finally: exception(Exception), exception: NullReferenceException] Exception e | semmle.label | match | -| Finally.cs:161:13:164:13 | [finally: exception(Exception), exception: OutOfMemoryException] catch (...) {...} | Finally.cs:161:30:161:30 | [finally: exception(Exception), exception: OutOfMemoryException] Exception e | semmle.label | match | | Finally.cs:161:30:161:30 | [exception: Exception] Exception e | Finally.cs:161:39:161:39 | [exception: Exception] access to local variable e | semmle.label | successor | | Finally.cs:161:30:161:30 | [exception: NullReferenceException] Exception e | Finally.cs:161:39:161:39 | [exception: NullReferenceException] access to local variable e | semmle.label | successor | -| Finally.cs:161:30:161:30 | [exception: OutOfMemoryException] Exception e | Finally.cs:161:39:161:39 | [exception: OutOfMemoryException] access to local variable e | semmle.label | successor | | Finally.cs:161:30:161:30 | [finally: exception(ArgumentNullException), exception: Exception] Exception e | Finally.cs:161:39:161:39 | [finally: exception(ArgumentNullException), exception: Exception] access to local variable e | semmle.label | successor | | Finally.cs:161:30:161:30 | [finally: exception(ArgumentNullException), exception: NullReferenceException] Exception e | Finally.cs:161:39:161:39 | [finally: exception(ArgumentNullException), exception: NullReferenceException] access to local variable e | semmle.label | successor | -| Finally.cs:161:30:161:30 | [finally: exception(ArgumentNullException), exception: OutOfMemoryException] Exception e | Finally.cs:161:39:161:39 | [finally: exception(ArgumentNullException), exception: OutOfMemoryException] access to local variable e | semmle.label | successor | | Finally.cs:161:30:161:30 | [finally: exception(Exception), exception: Exception] Exception e | Finally.cs:161:39:161:39 | [finally: exception(Exception), exception: Exception] access to local variable e | semmle.label | successor | | Finally.cs:161:30:161:30 | [finally: exception(Exception), exception: NullReferenceException] Exception e | Finally.cs:161:39:161:39 | [finally: exception(Exception), exception: NullReferenceException] access to local variable e | semmle.label | successor | -| Finally.cs:161:30:161:30 | [finally: exception(Exception), exception: OutOfMemoryException] Exception e | Finally.cs:161:39:161:39 | [finally: exception(Exception), exception: OutOfMemoryException] access to local variable e | semmle.label | successor | | Finally.cs:161:39:161:39 | [exception: Exception] access to local variable e | Finally.cs:161:39:161:47 | [exception: Exception] access to property Message | semmle.label | successor | | Finally.cs:161:39:161:39 | [exception: NullReferenceException] access to local variable e | Finally.cs:161:39:161:47 | [exception: NullReferenceException] access to property Message | semmle.label | successor | -| Finally.cs:161:39:161:39 | [exception: OutOfMemoryException] access to local variable e | Finally.cs:161:39:161:47 | [exception: OutOfMemoryException] access to property Message | semmle.label | successor | | Finally.cs:161:39:161:39 | [finally: exception(ArgumentNullException), exception: Exception] access to local variable e | Finally.cs:161:39:161:47 | [finally: exception(ArgumentNullException), exception: Exception] access to property Message | semmle.label | successor | | Finally.cs:161:39:161:39 | [finally: exception(ArgumentNullException), exception: NullReferenceException] access to local variable e | Finally.cs:161:39:161:47 | [finally: exception(ArgumentNullException), exception: NullReferenceException] access to property Message | semmle.label | successor | -| Finally.cs:161:39:161:39 | [finally: exception(ArgumentNullException), exception: OutOfMemoryException] access to local variable e | Finally.cs:161:39:161:47 | [finally: exception(ArgumentNullException), exception: OutOfMemoryException] access to property Message | semmle.label | successor | | Finally.cs:161:39:161:39 | [finally: exception(Exception), exception: Exception] access to local variable e | Finally.cs:161:39:161:47 | [finally: exception(Exception), exception: Exception] access to property Message | semmle.label | successor | | Finally.cs:161:39:161:39 | [finally: exception(Exception), exception: NullReferenceException] access to local variable e | Finally.cs:161:39:161:47 | [finally: exception(Exception), exception: NullReferenceException] access to property Message | semmle.label | successor | -| Finally.cs:161:39:161:39 | [finally: exception(Exception), exception: OutOfMemoryException] access to local variable e | Finally.cs:161:39:161:47 | [finally: exception(Exception), exception: OutOfMemoryException] access to property Message | semmle.label | successor | | Finally.cs:161:39:161:47 | [exception: Exception] access to property Message | Finally.cs:161:52:161:54 | [exception: Exception] "1" | semmle.label | successor | | Finally.cs:161:39:161:47 | [exception: NullReferenceException] access to property Message | Finally.cs:161:52:161:54 | [exception: NullReferenceException] "1" | semmle.label | successor | -| Finally.cs:161:39:161:47 | [exception: OutOfMemoryException] access to property Message | Finally.cs:161:52:161:54 | [exception: OutOfMemoryException] "1" | semmle.label | successor | | Finally.cs:161:39:161:47 | [finally: exception(ArgumentNullException), exception: Exception] access to property Message | Finally.cs:161:52:161:54 | [finally: exception(ArgumentNullException), exception: Exception] "1" | semmle.label | successor | | Finally.cs:161:39:161:47 | [finally: exception(ArgumentNullException), exception: NullReferenceException] access to property Message | Finally.cs:161:52:161:54 | [finally: exception(ArgumentNullException), exception: NullReferenceException] "1" | semmle.label | successor | -| Finally.cs:161:39:161:47 | [finally: exception(ArgumentNullException), exception: OutOfMemoryException] access to property Message | Finally.cs:161:52:161:54 | [finally: exception(ArgumentNullException), exception: OutOfMemoryException] "1" | semmle.label | successor | | Finally.cs:161:39:161:47 | [finally: exception(Exception), exception: Exception] access to property Message | Finally.cs:161:52:161:54 | [finally: exception(Exception), exception: Exception] "1" | semmle.label | successor | | Finally.cs:161:39:161:47 | [finally: exception(Exception), exception: NullReferenceException] access to property Message | Finally.cs:161:52:161:54 | [finally: exception(Exception), exception: NullReferenceException] "1" | semmle.label | successor | -| Finally.cs:161:39:161:47 | [finally: exception(Exception), exception: OutOfMemoryException] access to property Message | Finally.cs:161:52:161:54 | [finally: exception(Exception), exception: OutOfMemoryException] "1" | semmle.label | successor | | Finally.cs:161:39:161:54 | [exception: Exception] ... == ... | Finally.cs:162:13:164:13 | {...} | semmle.label | true | | Finally.cs:161:39:161:54 | [exception: Exception] ... == ... | Finally.cs:165:13:168:13 | catch {...} | semmle.label | false | | Finally.cs:161:39:161:54 | [exception: NullReferenceException] ... == ... | Finally.cs:162:13:164:13 | {...} | semmle.label | true | | Finally.cs:161:39:161:54 | [exception: NullReferenceException] ... == ... | Finally.cs:165:13:168:13 | catch {...} | semmle.label | false | -| Finally.cs:161:39:161:54 | [exception: OutOfMemoryException] ... == ... | Finally.cs:162:13:164:13 | {...} | semmle.label | true | -| Finally.cs:161:39:161:54 | [exception: OutOfMemoryException] ... == ... | Finally.cs:165:13:168:13 | catch {...} | semmle.label | false | | Finally.cs:161:39:161:54 | [finally: exception(ArgumentNullException), exception: Exception] ... == ... | Finally.cs:162:13:164:13 | [finally: exception(ArgumentNullException)] {...} | semmle.label | true | | Finally.cs:161:39:161:54 | [finally: exception(ArgumentNullException), exception: Exception] ... == ... | Finally.cs:165:13:168:13 | [finally: exception(ArgumentNullException)] catch {...} | semmle.label | false | | Finally.cs:161:39:161:54 | [finally: exception(ArgumentNullException), exception: NullReferenceException] ... == ... | Finally.cs:162:13:164:13 | [finally: exception(ArgumentNullException)] {...} | semmle.label | true | | Finally.cs:161:39:161:54 | [finally: exception(ArgumentNullException), exception: NullReferenceException] ... == ... | Finally.cs:165:13:168:13 | [finally: exception(ArgumentNullException)] catch {...} | semmle.label | false | -| Finally.cs:161:39:161:54 | [finally: exception(ArgumentNullException), exception: OutOfMemoryException] ... == ... | Finally.cs:162:13:164:13 | [finally: exception(ArgumentNullException)] {...} | semmle.label | true | -| Finally.cs:161:39:161:54 | [finally: exception(ArgumentNullException), exception: OutOfMemoryException] ... == ... | Finally.cs:165:13:168:13 | [finally: exception(ArgumentNullException)] catch {...} | semmle.label | false | | Finally.cs:161:39:161:54 | [finally: exception(Exception), exception: Exception] ... == ... | Finally.cs:162:13:164:13 | [finally: exception(Exception)] {...} | semmle.label | true | | Finally.cs:161:39:161:54 | [finally: exception(Exception), exception: Exception] ... == ... | Finally.cs:165:13:168:13 | [finally: exception(Exception)] catch {...} | semmle.label | false | | Finally.cs:161:39:161:54 | [finally: exception(Exception), exception: NullReferenceException] ... == ... | Finally.cs:162:13:164:13 | [finally: exception(Exception)] {...} | semmle.label | true | | Finally.cs:161:39:161:54 | [finally: exception(Exception), exception: NullReferenceException] ... == ... | Finally.cs:165:13:168:13 | [finally: exception(Exception)] catch {...} | semmle.label | false | -| Finally.cs:161:39:161:54 | [finally: exception(Exception), exception: OutOfMemoryException] ... == ... | Finally.cs:162:13:164:13 | [finally: exception(Exception)] {...} | semmle.label | true | -| Finally.cs:161:39:161:54 | [finally: exception(Exception), exception: OutOfMemoryException] ... == ... | Finally.cs:165:13:168:13 | [finally: exception(Exception)] catch {...} | semmle.label | false | | Finally.cs:161:52:161:54 | [exception: Exception] "1" | Finally.cs:161:39:161:54 | [exception: Exception] ... == ... | semmle.label | successor | | Finally.cs:161:52:161:54 | [exception: NullReferenceException] "1" | Finally.cs:161:39:161:54 | [exception: NullReferenceException] ... == ... | semmle.label | successor | -| Finally.cs:161:52:161:54 | [exception: OutOfMemoryException] "1" | Finally.cs:161:39:161:54 | [exception: OutOfMemoryException] ... == ... | semmle.label | successor | | Finally.cs:161:52:161:54 | [finally: exception(ArgumentNullException), exception: Exception] "1" | Finally.cs:161:39:161:54 | [finally: exception(ArgumentNullException), exception: Exception] ... == ... | semmle.label | successor | | Finally.cs:161:52:161:54 | [finally: exception(ArgumentNullException), exception: NullReferenceException] "1" | Finally.cs:161:39:161:54 | [finally: exception(ArgumentNullException), exception: NullReferenceException] ... == ... | semmle.label | successor | -| Finally.cs:161:52:161:54 | [finally: exception(ArgumentNullException), exception: OutOfMemoryException] "1" | Finally.cs:161:39:161:54 | [finally: exception(ArgumentNullException), exception: OutOfMemoryException] ... == ... | semmle.label | successor | | Finally.cs:161:52:161:54 | [finally: exception(Exception), exception: Exception] "1" | Finally.cs:161:39:161:54 | [finally: exception(Exception), exception: Exception] ... == ... | semmle.label | successor | | Finally.cs:161:52:161:54 | [finally: exception(Exception), exception: NullReferenceException] "1" | Finally.cs:161:39:161:54 | [finally: exception(Exception), exception: NullReferenceException] ... == ... | semmle.label | successor | -| Finally.cs:161:52:161:54 | [finally: exception(Exception), exception: OutOfMemoryException] "1" | Finally.cs:161:39:161:54 | [finally: exception(Exception), exception: OutOfMemoryException] ... == ... | semmle.label | successor | | Finally.cs:162:13:164:13 | [finally: exception(ArgumentNullException)] {...} | Finally.cs:163:17:163:43 | [finally: exception(ArgumentNullException)] ...; | semmle.label | successor | | Finally.cs:162:13:164:13 | [finally: exception(Exception)] {...} | Finally.cs:163:17:163:43 | [finally: exception(Exception)] ...; | semmle.label | successor | | Finally.cs:162:13:164:13 | {...} | Finally.cs:163:17:163:43 | ...; | semmle.label | successor | @@ -2525,67 +2487,67 @@ | Finally.cs:205:21:205:22 | [finally: exception(ExceptionA)] access to parameter b2 | Finally.cs:208:13:210:13 | [finally: exception(ExceptionA)] {...} | semmle.label | false | | Finally.cs:205:21:205:22 | access to parameter b2 | Finally.cs:205:31:205:46 | object creation of type ExceptionB | semmle.label | true | | Finally.cs:205:21:205:22 | access to parameter b2 | Finally.cs:208:13:210:13 | {...} | semmle.label | false | -| Finally.cs:205:25:205:47 | [finally: exception(Exception)] throw ...; | Finally.cs:208:13:210:13 | [finally: exception(Exception), finally(2): exception(ExceptionB)] {...} | semmle.label | exception(ExceptionB) | -| Finally.cs:205:25:205:47 | [finally: exception(ExceptionA)] throw ...; | Finally.cs:208:13:210:13 | [finally: exception(ExceptionA), finally(2): exception(ExceptionB)] {...} | semmle.label | exception(ExceptionB) | -| Finally.cs:205:25:205:47 | throw ...; | Finally.cs:208:13:210:13 | [finally(2): exception(ExceptionB)] {...} | semmle.label | exception(ExceptionB) | +| Finally.cs:205:25:205:47 | [finally: exception(Exception)] throw ...; | Finally.cs:208:13:210:13 | [finally: exception(Exception), finally(1): exception(ExceptionB)] {...} | semmle.label | exception(ExceptionB) | +| Finally.cs:205:25:205:47 | [finally: exception(ExceptionA)] throw ...; | Finally.cs:208:13:210:13 | [finally: exception(ExceptionA), finally(1): exception(ExceptionB)] {...} | semmle.label | exception(ExceptionB) | +| Finally.cs:205:25:205:47 | throw ...; | Finally.cs:208:13:210:13 | [finally(1): exception(ExceptionB)] {...} | semmle.label | exception(ExceptionB) | | Finally.cs:205:31:205:46 | [finally: exception(Exception)] object creation of type ExceptionB | Finally.cs:205:25:205:47 | [finally: exception(Exception)] throw ...; | semmle.label | successor | -| Finally.cs:205:31:205:46 | [finally: exception(Exception)] object creation of type ExceptionB | Finally.cs:208:13:210:13 | [finally: exception(Exception), finally(2): exception(Exception)] {...} | semmle.label | exception(Exception) | +| Finally.cs:205:31:205:46 | [finally: exception(Exception)] object creation of type ExceptionB | Finally.cs:208:13:210:13 | [finally: exception(Exception), finally(1): exception(Exception)] {...} | semmle.label | exception(Exception) | | Finally.cs:205:31:205:46 | [finally: exception(ExceptionA)] object creation of type ExceptionB | Finally.cs:205:25:205:47 | [finally: exception(ExceptionA)] throw ...; | semmle.label | successor | -| Finally.cs:205:31:205:46 | [finally: exception(ExceptionA)] object creation of type ExceptionB | Finally.cs:208:13:210:13 | [finally: exception(ExceptionA), finally(2): exception(Exception)] {...} | semmle.label | exception(Exception) | +| Finally.cs:205:31:205:46 | [finally: exception(ExceptionA)] object creation of type ExceptionB | Finally.cs:208:13:210:13 | [finally: exception(ExceptionA), finally(1): exception(Exception)] {...} | semmle.label | exception(Exception) | | Finally.cs:205:31:205:46 | object creation of type ExceptionB | Finally.cs:205:25:205:47 | throw ...; | semmle.label | successor | -| Finally.cs:205:31:205:46 | object creation of type ExceptionB | Finally.cs:208:13:210:13 | [finally(2): exception(Exception)] {...} | semmle.label | exception(Exception) | -| Finally.cs:208:13:210:13 | [finally(2): exception(Exception)] {...} | Finally.cs:209:17:209:47 | [finally(2): exception(Exception)] if (...) ... | semmle.label | successor | -| Finally.cs:208:13:210:13 | [finally(2): exception(ExceptionB)] {...} | Finally.cs:209:17:209:47 | [finally(2): exception(ExceptionB)] if (...) ... | semmle.label | successor | -| Finally.cs:208:13:210:13 | [finally: exception(Exception), finally(2): exception(Exception)] {...} | Finally.cs:209:17:209:47 | [finally: exception(Exception), finally(2): exception(Exception)] if (...) ... | semmle.label | successor | -| Finally.cs:208:13:210:13 | [finally: exception(Exception), finally(2): exception(ExceptionB)] {...} | Finally.cs:209:17:209:47 | [finally: exception(Exception), finally(2): exception(ExceptionB)] if (...) ... | semmle.label | successor | +| Finally.cs:205:31:205:46 | object creation of type ExceptionB | Finally.cs:208:13:210:13 | [finally(1): exception(Exception)] {...} | semmle.label | exception(Exception) | +| Finally.cs:208:13:210:13 | [finally(1): exception(Exception)] {...} | Finally.cs:209:17:209:47 | [finally(1): exception(Exception)] if (...) ... | semmle.label | successor | +| Finally.cs:208:13:210:13 | [finally(1): exception(ExceptionB)] {...} | Finally.cs:209:17:209:47 | [finally(1): exception(ExceptionB)] if (...) ... | semmle.label | successor | +| Finally.cs:208:13:210:13 | [finally: exception(Exception), finally(1): exception(Exception)] {...} | Finally.cs:209:17:209:47 | [finally: exception(Exception), finally(1): exception(Exception)] if (...) ... | semmle.label | successor | +| Finally.cs:208:13:210:13 | [finally: exception(Exception), finally(1): exception(ExceptionB)] {...} | Finally.cs:209:17:209:47 | [finally: exception(Exception), finally(1): exception(ExceptionB)] if (...) ... | semmle.label | successor | | Finally.cs:208:13:210:13 | [finally: exception(Exception)] {...} | Finally.cs:209:17:209:47 | [finally: exception(Exception)] if (...) ... | semmle.label | successor | -| Finally.cs:208:13:210:13 | [finally: exception(ExceptionA), finally(2): exception(Exception)] {...} | Finally.cs:209:17:209:47 | [finally: exception(ExceptionA), finally(2): exception(Exception)] if (...) ... | semmle.label | successor | -| Finally.cs:208:13:210:13 | [finally: exception(ExceptionA), finally(2): exception(ExceptionB)] {...} | Finally.cs:209:17:209:47 | [finally: exception(ExceptionA), finally(2): exception(ExceptionB)] if (...) ... | semmle.label | successor | +| Finally.cs:208:13:210:13 | [finally: exception(ExceptionA), finally(1): exception(Exception)] {...} | Finally.cs:209:17:209:47 | [finally: exception(ExceptionA), finally(1): exception(Exception)] if (...) ... | semmle.label | successor | +| Finally.cs:208:13:210:13 | [finally: exception(ExceptionA), finally(1): exception(ExceptionB)] {...} | Finally.cs:209:17:209:47 | [finally: exception(ExceptionA), finally(1): exception(ExceptionB)] if (...) ... | semmle.label | successor | | Finally.cs:208:13:210:13 | [finally: exception(ExceptionA)] {...} | Finally.cs:209:17:209:47 | [finally: exception(ExceptionA)] if (...) ... | semmle.label | successor | | Finally.cs:208:13:210:13 | {...} | Finally.cs:209:17:209:47 | if (...) ... | semmle.label | successor | -| Finally.cs:209:17:209:47 | [finally(2): exception(Exception)] if (...) ... | Finally.cs:209:21:209:22 | [finally(2): exception(Exception)] access to parameter b3 | semmle.label | successor | -| Finally.cs:209:17:209:47 | [finally(2): exception(ExceptionB)] if (...) ... | Finally.cs:209:21:209:22 | [finally(2): exception(ExceptionB)] access to parameter b3 | semmle.label | successor | -| Finally.cs:209:17:209:47 | [finally: exception(Exception), finally(2): exception(Exception)] if (...) ... | Finally.cs:209:21:209:22 | [finally: exception(Exception), finally(2): exception(Exception)] access to parameter b3 | semmle.label | successor | -| Finally.cs:209:17:209:47 | [finally: exception(Exception), finally(2): exception(ExceptionB)] if (...) ... | Finally.cs:209:21:209:22 | [finally: exception(Exception), finally(2): exception(ExceptionB)] access to parameter b3 | semmle.label | successor | +| Finally.cs:209:17:209:47 | [finally(1): exception(Exception)] if (...) ... | Finally.cs:209:21:209:22 | [finally(1): exception(Exception)] access to parameter b3 | semmle.label | successor | +| Finally.cs:209:17:209:47 | [finally(1): exception(ExceptionB)] if (...) ... | Finally.cs:209:21:209:22 | [finally(1): exception(ExceptionB)] access to parameter b3 | semmle.label | successor | +| Finally.cs:209:17:209:47 | [finally: exception(Exception), finally(1): exception(Exception)] if (...) ... | Finally.cs:209:21:209:22 | [finally: exception(Exception), finally(1): exception(Exception)] access to parameter b3 | semmle.label | successor | +| Finally.cs:209:17:209:47 | [finally: exception(Exception), finally(1): exception(ExceptionB)] if (...) ... | Finally.cs:209:21:209:22 | [finally: exception(Exception), finally(1): exception(ExceptionB)] access to parameter b3 | semmle.label | successor | | Finally.cs:209:17:209:47 | [finally: exception(Exception)] if (...) ... | Finally.cs:209:21:209:22 | [finally: exception(Exception)] access to parameter b3 | semmle.label | successor | -| Finally.cs:209:17:209:47 | [finally: exception(ExceptionA), finally(2): exception(Exception)] if (...) ... | Finally.cs:209:21:209:22 | [finally: exception(ExceptionA), finally(2): exception(Exception)] access to parameter b3 | semmle.label | successor | -| Finally.cs:209:17:209:47 | [finally: exception(ExceptionA), finally(2): exception(ExceptionB)] if (...) ... | Finally.cs:209:21:209:22 | [finally: exception(ExceptionA), finally(2): exception(ExceptionB)] access to parameter b3 | semmle.label | successor | +| Finally.cs:209:17:209:47 | [finally: exception(ExceptionA), finally(1): exception(Exception)] if (...) ... | Finally.cs:209:21:209:22 | [finally: exception(ExceptionA), finally(1): exception(Exception)] access to parameter b3 | semmle.label | successor | +| Finally.cs:209:17:209:47 | [finally: exception(ExceptionA), finally(1): exception(ExceptionB)] if (...) ... | Finally.cs:209:21:209:22 | [finally: exception(ExceptionA), finally(1): exception(ExceptionB)] access to parameter b3 | semmle.label | successor | | Finally.cs:209:17:209:47 | [finally: exception(ExceptionA)] if (...) ... | Finally.cs:209:21:209:22 | [finally: exception(ExceptionA)] access to parameter b3 | semmle.label | successor | | Finally.cs:209:17:209:47 | if (...) ... | Finally.cs:209:21:209:22 | access to parameter b3 | semmle.label | successor | -| Finally.cs:209:21:209:22 | [finally(2): exception(Exception)] access to parameter b3 | Finally.cs:195:10:195:12 | exit M10 (abnormal) | semmle.label | exception(Exception) | -| Finally.cs:209:21:209:22 | [finally(2): exception(Exception)] access to parameter b3 | Finally.cs:209:31:209:46 | [finally(2): exception(Exception)] object creation of type ExceptionC | semmle.label | true | -| Finally.cs:209:21:209:22 | [finally(2): exception(ExceptionB)] access to parameter b3 | Finally.cs:195:10:195:12 | exit M10 (abnormal) | semmle.label | exception(ExceptionB) | -| Finally.cs:209:21:209:22 | [finally(2): exception(ExceptionB)] access to parameter b3 | Finally.cs:209:31:209:46 | [finally(2): exception(ExceptionB)] object creation of type ExceptionC | semmle.label | true | -| Finally.cs:209:21:209:22 | [finally: exception(Exception), finally(2): exception(Exception)] access to parameter b3 | Finally.cs:195:10:195:12 | exit M10 (abnormal) | semmle.label | exception(Exception) | -| Finally.cs:209:21:209:22 | [finally: exception(Exception), finally(2): exception(Exception)] access to parameter b3 | Finally.cs:209:31:209:46 | [finally: exception(Exception), finally(2): exception(Exception)] object creation of type ExceptionC | semmle.label | true | -| Finally.cs:209:21:209:22 | [finally: exception(Exception), finally(2): exception(ExceptionB)] access to parameter b3 | Finally.cs:195:10:195:12 | exit M10 (abnormal) | semmle.label | exception(ExceptionB) | -| Finally.cs:209:21:209:22 | [finally: exception(Exception), finally(2): exception(ExceptionB)] access to parameter b3 | Finally.cs:209:31:209:46 | [finally: exception(Exception), finally(2): exception(ExceptionB)] object creation of type ExceptionC | semmle.label | true | +| Finally.cs:209:21:209:22 | [finally(1): exception(Exception)] access to parameter b3 | Finally.cs:195:10:195:12 | exit M10 (abnormal) | semmle.label | exception(Exception) | +| Finally.cs:209:21:209:22 | [finally(1): exception(Exception)] access to parameter b3 | Finally.cs:209:31:209:46 | [finally(1): exception(Exception)] object creation of type ExceptionC | semmle.label | true | +| Finally.cs:209:21:209:22 | [finally(1): exception(ExceptionB)] access to parameter b3 | Finally.cs:195:10:195:12 | exit M10 (abnormal) | semmle.label | exception(ExceptionB) | +| Finally.cs:209:21:209:22 | [finally(1): exception(ExceptionB)] access to parameter b3 | Finally.cs:209:31:209:46 | [finally(1): exception(ExceptionB)] object creation of type ExceptionC | semmle.label | true | +| Finally.cs:209:21:209:22 | [finally: exception(Exception), finally(1): exception(Exception)] access to parameter b3 | Finally.cs:195:10:195:12 | exit M10 (abnormal) | semmle.label | exception(Exception) | +| Finally.cs:209:21:209:22 | [finally: exception(Exception), finally(1): exception(Exception)] access to parameter b3 | Finally.cs:209:31:209:46 | [finally: exception(Exception), finally(1): exception(Exception)] object creation of type ExceptionC | semmle.label | true | +| Finally.cs:209:21:209:22 | [finally: exception(Exception), finally(1): exception(ExceptionB)] access to parameter b3 | Finally.cs:195:10:195:12 | exit M10 (abnormal) | semmle.label | exception(ExceptionB) | +| Finally.cs:209:21:209:22 | [finally: exception(Exception), finally(1): exception(ExceptionB)] access to parameter b3 | Finally.cs:209:31:209:46 | [finally: exception(Exception), finally(1): exception(ExceptionB)] object creation of type ExceptionC | semmle.label | true | | Finally.cs:209:21:209:22 | [finally: exception(Exception)] access to parameter b3 | Finally.cs:209:31:209:46 | [finally: exception(Exception)] object creation of type ExceptionC | semmle.label | true | | Finally.cs:209:21:209:22 | [finally: exception(Exception)] access to parameter b3 | Finally.cs:211:13:211:29 | [finally: exception(Exception)] ...; | semmle.label | false | -| Finally.cs:209:21:209:22 | [finally: exception(ExceptionA), finally(2): exception(Exception)] access to parameter b3 | Finally.cs:195:10:195:12 | exit M10 (abnormal) | semmle.label | exception(Exception) | -| Finally.cs:209:21:209:22 | [finally: exception(ExceptionA), finally(2): exception(Exception)] access to parameter b3 | Finally.cs:209:31:209:46 | [finally: exception(ExceptionA), finally(2): exception(Exception)] object creation of type ExceptionC | semmle.label | true | -| Finally.cs:209:21:209:22 | [finally: exception(ExceptionA), finally(2): exception(ExceptionB)] access to parameter b3 | Finally.cs:195:10:195:12 | exit M10 (abnormal) | semmle.label | exception(ExceptionB) | -| Finally.cs:209:21:209:22 | [finally: exception(ExceptionA), finally(2): exception(ExceptionB)] access to parameter b3 | Finally.cs:209:31:209:46 | [finally: exception(ExceptionA), finally(2): exception(ExceptionB)] object creation of type ExceptionC | semmle.label | true | +| Finally.cs:209:21:209:22 | [finally: exception(ExceptionA), finally(1): exception(Exception)] access to parameter b3 | Finally.cs:195:10:195:12 | exit M10 (abnormal) | semmle.label | exception(Exception) | +| Finally.cs:209:21:209:22 | [finally: exception(ExceptionA), finally(1): exception(Exception)] access to parameter b3 | Finally.cs:209:31:209:46 | [finally: exception(ExceptionA), finally(1): exception(Exception)] object creation of type ExceptionC | semmle.label | true | +| Finally.cs:209:21:209:22 | [finally: exception(ExceptionA), finally(1): exception(ExceptionB)] access to parameter b3 | Finally.cs:195:10:195:12 | exit M10 (abnormal) | semmle.label | exception(ExceptionB) | +| Finally.cs:209:21:209:22 | [finally: exception(ExceptionA), finally(1): exception(ExceptionB)] access to parameter b3 | Finally.cs:209:31:209:46 | [finally: exception(ExceptionA), finally(1): exception(ExceptionB)] object creation of type ExceptionC | semmle.label | true | | Finally.cs:209:21:209:22 | [finally: exception(ExceptionA)] access to parameter b3 | Finally.cs:209:31:209:46 | [finally: exception(ExceptionA)] object creation of type ExceptionC | semmle.label | true | | Finally.cs:209:21:209:22 | [finally: exception(ExceptionA)] access to parameter b3 | Finally.cs:211:13:211:29 | [finally: exception(ExceptionA)] ...; | semmle.label | false | | Finally.cs:209:21:209:22 | access to parameter b3 | Finally.cs:209:31:209:46 | object creation of type ExceptionC | semmle.label | true | | Finally.cs:209:21:209:22 | access to parameter b3 | Finally.cs:211:13:211:29 | ...; | semmle.label | false | -| Finally.cs:209:25:209:47 | [finally(2): exception(Exception)] throw ...; | Finally.cs:195:10:195:12 | exit M10 (abnormal) | semmle.label | exception(ExceptionC) | -| Finally.cs:209:25:209:47 | [finally(2): exception(ExceptionB)] throw ...; | Finally.cs:195:10:195:12 | exit M10 (abnormal) | semmle.label | exception(ExceptionC) | -| Finally.cs:209:25:209:47 | [finally: exception(Exception), finally(2): exception(Exception)] throw ...; | Finally.cs:195:10:195:12 | exit M10 (abnormal) | semmle.label | exception(ExceptionC) | -| Finally.cs:209:25:209:47 | [finally: exception(Exception), finally(2): exception(ExceptionB)] throw ...; | Finally.cs:195:10:195:12 | exit M10 (abnormal) | semmle.label | exception(ExceptionC) | +| Finally.cs:209:25:209:47 | [finally(1): exception(Exception)] throw ...; | Finally.cs:195:10:195:12 | exit M10 (abnormal) | semmle.label | exception(ExceptionC) | +| Finally.cs:209:25:209:47 | [finally(1): exception(ExceptionB)] throw ...; | Finally.cs:195:10:195:12 | exit M10 (abnormal) | semmle.label | exception(ExceptionC) | +| Finally.cs:209:25:209:47 | [finally: exception(Exception), finally(1): exception(Exception)] throw ...; | Finally.cs:195:10:195:12 | exit M10 (abnormal) | semmle.label | exception(ExceptionC) | +| Finally.cs:209:25:209:47 | [finally: exception(Exception), finally(1): exception(ExceptionB)] throw ...; | Finally.cs:195:10:195:12 | exit M10 (abnormal) | semmle.label | exception(ExceptionC) | | Finally.cs:209:25:209:47 | [finally: exception(Exception)] throw ...; | Finally.cs:195:10:195:12 | exit M10 (abnormal) | semmle.label | exception(ExceptionC) | -| Finally.cs:209:25:209:47 | [finally: exception(ExceptionA), finally(2): exception(Exception)] throw ...; | Finally.cs:195:10:195:12 | exit M10 (abnormal) | semmle.label | exception(ExceptionC) | -| Finally.cs:209:25:209:47 | [finally: exception(ExceptionA), finally(2): exception(ExceptionB)] throw ...; | Finally.cs:195:10:195:12 | exit M10 (abnormal) | semmle.label | exception(ExceptionC) | +| Finally.cs:209:25:209:47 | [finally: exception(ExceptionA), finally(1): exception(Exception)] throw ...; | Finally.cs:195:10:195:12 | exit M10 (abnormal) | semmle.label | exception(ExceptionC) | +| Finally.cs:209:25:209:47 | [finally: exception(ExceptionA), finally(1): exception(ExceptionB)] throw ...; | Finally.cs:195:10:195:12 | exit M10 (abnormal) | semmle.label | exception(ExceptionC) | | Finally.cs:209:25:209:47 | [finally: exception(ExceptionA)] throw ...; | Finally.cs:195:10:195:12 | exit M10 (abnormal) | semmle.label | exception(ExceptionC) | | Finally.cs:209:25:209:47 | throw ...; | Finally.cs:195:10:195:12 | exit M10 (abnormal) | semmle.label | exception(ExceptionC) | -| Finally.cs:209:31:209:46 | [finally(2): exception(Exception)] object creation of type ExceptionC | Finally.cs:209:25:209:47 | [finally(2): exception(Exception)] throw ...; | semmle.label | successor | -| Finally.cs:209:31:209:46 | [finally(2): exception(ExceptionB)] object creation of type ExceptionC | Finally.cs:209:25:209:47 | [finally(2): exception(ExceptionB)] throw ...; | semmle.label | successor | -| Finally.cs:209:31:209:46 | [finally: exception(Exception), finally(2): exception(Exception)] object creation of type ExceptionC | Finally.cs:209:25:209:47 | [finally: exception(Exception), finally(2): exception(Exception)] throw ...; | semmle.label | successor | -| Finally.cs:209:31:209:46 | [finally: exception(Exception), finally(2): exception(ExceptionB)] object creation of type ExceptionC | Finally.cs:209:25:209:47 | [finally: exception(Exception), finally(2): exception(ExceptionB)] throw ...; | semmle.label | successor | +| Finally.cs:209:31:209:46 | [finally(1): exception(Exception)] object creation of type ExceptionC | Finally.cs:209:25:209:47 | [finally(1): exception(Exception)] throw ...; | semmle.label | successor | +| Finally.cs:209:31:209:46 | [finally(1): exception(ExceptionB)] object creation of type ExceptionC | Finally.cs:209:25:209:47 | [finally(1): exception(ExceptionB)] throw ...; | semmle.label | successor | +| Finally.cs:209:31:209:46 | [finally: exception(Exception), finally(1): exception(Exception)] object creation of type ExceptionC | Finally.cs:209:25:209:47 | [finally: exception(Exception), finally(1): exception(Exception)] throw ...; | semmle.label | successor | +| Finally.cs:209:31:209:46 | [finally: exception(Exception), finally(1): exception(ExceptionB)] object creation of type ExceptionC | Finally.cs:209:25:209:47 | [finally: exception(Exception), finally(1): exception(ExceptionB)] throw ...; | semmle.label | successor | | Finally.cs:209:31:209:46 | [finally: exception(Exception)] object creation of type ExceptionC | Finally.cs:209:25:209:47 | [finally: exception(Exception)] throw ...; | semmle.label | successor | -| Finally.cs:209:31:209:46 | [finally: exception(ExceptionA), finally(2): exception(Exception)] object creation of type ExceptionC | Finally.cs:209:25:209:47 | [finally: exception(ExceptionA), finally(2): exception(Exception)] throw ...; | semmle.label | successor | -| Finally.cs:209:31:209:46 | [finally: exception(ExceptionA), finally(2): exception(ExceptionB)] object creation of type ExceptionC | Finally.cs:209:25:209:47 | [finally: exception(ExceptionA), finally(2): exception(ExceptionB)] throw ...; | semmle.label | successor | +| Finally.cs:209:31:209:46 | [finally: exception(ExceptionA), finally(1): exception(Exception)] object creation of type ExceptionC | Finally.cs:209:25:209:47 | [finally: exception(ExceptionA), finally(1): exception(Exception)] throw ...; | semmle.label | successor | +| Finally.cs:209:31:209:46 | [finally: exception(ExceptionA), finally(1): exception(ExceptionB)] object creation of type ExceptionC | Finally.cs:209:25:209:47 | [finally: exception(ExceptionA), finally(1): exception(ExceptionB)] throw ...; | semmle.label | successor | | Finally.cs:209:31:209:46 | [finally: exception(ExceptionA)] object creation of type ExceptionC | Finally.cs:209:25:209:47 | [finally: exception(ExceptionA)] throw ...; | semmle.label | successor | | Finally.cs:209:31:209:46 | object creation of type ExceptionC | Finally.cs:209:25:209:47 | throw ...; | semmle.label | successor | | Finally.cs:211:13:211:16 | [finally: exception(Exception)] this access | Finally.cs:211:26:211:28 | [finally: exception(Exception)] "0" | semmle.label | successor | @@ -2613,7 +2575,6 @@ | Finally.cs:220:13:220:36 | call to method WriteLine | Finally.cs:227:9:229:9 | {...} | semmle.label | successor | | Finally.cs:220:13:220:37 | ...; | Finally.cs:220:31:220:35 | "Try" | semmle.label | successor | | Finally.cs:220:31:220:35 | "Try" | Finally.cs:220:13:220:36 | call to method WriteLine | semmle.label | successor | -| Finally.cs:220:31:220:35 | "Try" | Finally.cs:222:9:225:9 | catch {...} | semmle.label | exception(OutOfMemoryException) | | Finally.cs:222:9:225:9 | catch {...} | Finally.cs:223:9:225:9 | {...} | semmle.label | successor | | Finally.cs:223:9:225:9 | {...} | Finally.cs:224:13:224:39 | ...; | semmle.label | successor | | Finally.cs:224:13:224:38 | call to method WriteLine | Finally.cs:227:9:229:9 | {...} | semmle.label | successor | @@ -2626,6 +2587,130 @@ | Finally.cs:230:9:230:33 | call to method WriteLine | Finally.cs:216:10:216:12 | exit M11 (normal) | semmle.label | successor | | Finally.cs:230:9:230:34 | ...; | Finally.cs:230:27:230:32 | "Done" | semmle.label | successor | | Finally.cs:230:27:230:32 | "Done" | Finally.cs:230:9:230:33 | call to method WriteLine | semmle.label | successor | +| Finally.cs:233:10:233:12 | enter M12 | Finally.cs:234:5:261:5 | {...} | semmle.label | successor | +| Finally.cs:233:10:233:12 | exit M12 (abnormal) | Finally.cs:233:10:233:12 | exit M12 | semmle.label | successor | +| Finally.cs:233:10:233:12 | exit M12 (normal) | Finally.cs:233:10:233:12 | exit M12 | semmle.label | successor | +| Finally.cs:234:5:261:5 | {...} | Finally.cs:235:9:259:9 | try {...} ... | semmle.label | successor | +| Finally.cs:235:9:259:9 | try {...} ... | Finally.cs:236:9:255:9 | {...} | semmle.label | successor | +| Finally.cs:236:9:255:9 | {...} | Finally.cs:237:13:253:13 | try {...} ... | semmle.label | successor | +| Finally.cs:237:13:253:13 | try {...} ... | Finally.cs:238:13:241:13 | {...} | semmle.label | successor | +| Finally.cs:238:13:241:13 | {...} | Finally.cs:239:17:240:43 | if (...) ... | semmle.label | successor | +| Finally.cs:239:17:240:43 | if (...) ... | Finally.cs:239:21:239:22 | access to parameter b1 | semmle.label | successor | +| Finally.cs:239:21:239:22 | access to parameter b1 | Finally.cs:240:27:240:42 | object creation of type ExceptionA | semmle.label | true | +| Finally.cs:239:21:239:22 | access to parameter b1 | Finally.cs:243:13:253:13 | {...} | semmle.label | false | +| Finally.cs:240:21:240:43 | throw ...; | Finally.cs:243:13:253:13 | [finally: exception(ExceptionA)] {...} | semmle.label | exception(ExceptionA) | +| Finally.cs:240:27:240:42 | object creation of type ExceptionA | Finally.cs:240:21:240:43 | throw ...; | semmle.label | successor | +| Finally.cs:240:27:240:42 | object creation of type ExceptionA | Finally.cs:243:13:253:13 | [finally: exception(Exception)] {...} | semmle.label | exception(Exception) | +| Finally.cs:243:13:253:13 | [finally: exception(Exception)] {...} | Finally.cs:244:17:252:17 | [finally: exception(Exception)] try {...} ... | semmle.label | successor | +| Finally.cs:243:13:253:13 | [finally: exception(ExceptionA)] {...} | Finally.cs:244:17:252:17 | [finally: exception(ExceptionA)] try {...} ... | semmle.label | successor | +| Finally.cs:243:13:253:13 | {...} | Finally.cs:244:17:252:17 | try {...} ... | semmle.label | successor | +| Finally.cs:244:17:252:17 | [finally: exception(Exception)] try {...} ... | Finally.cs:245:17:248:17 | [finally: exception(Exception)] {...} | semmle.label | successor | +| Finally.cs:244:17:252:17 | [finally: exception(ExceptionA)] try {...} ... | Finally.cs:245:17:248:17 | [finally: exception(ExceptionA)] {...} | semmle.label | successor | +| Finally.cs:244:17:252:17 | try {...} ... | Finally.cs:245:17:248:17 | {...} | semmle.label | successor | +| Finally.cs:245:17:248:17 | [finally: exception(Exception)] {...} | Finally.cs:246:21:247:47 | [finally: exception(Exception)] if (...) ... | semmle.label | successor | +| Finally.cs:245:17:248:17 | [finally: exception(ExceptionA)] {...} | Finally.cs:246:21:247:47 | [finally: exception(ExceptionA)] if (...) ... | semmle.label | successor | +| Finally.cs:245:17:248:17 | {...} | Finally.cs:246:21:247:47 | if (...) ... | semmle.label | successor | +| Finally.cs:246:21:247:47 | [finally: exception(Exception)] if (...) ... | Finally.cs:246:25:246:26 | [finally: exception(Exception)] access to parameter b2 | semmle.label | successor | +| Finally.cs:246:21:247:47 | [finally: exception(ExceptionA)] if (...) ... | Finally.cs:246:25:246:26 | [finally: exception(ExceptionA)] access to parameter b2 | semmle.label | successor | +| Finally.cs:246:21:247:47 | if (...) ... | Finally.cs:246:25:246:26 | access to parameter b2 | semmle.label | successor | +| Finally.cs:246:25:246:26 | [finally: exception(Exception)] access to parameter b2 | Finally.cs:247:31:247:46 | [finally: exception(Exception)] object creation of type ExceptionA | semmle.label | true | +| Finally.cs:246:25:246:26 | [finally: exception(Exception)] access to parameter b2 | Finally.cs:250:17:252:17 | [finally: exception(Exception)] {...} | semmle.label | false | +| Finally.cs:246:25:246:26 | [finally: exception(ExceptionA)] access to parameter b2 | Finally.cs:247:31:247:46 | [finally: exception(ExceptionA)] object creation of type ExceptionA | semmle.label | true | +| Finally.cs:246:25:246:26 | [finally: exception(ExceptionA)] access to parameter b2 | Finally.cs:250:17:252:17 | [finally: exception(ExceptionA)] {...} | semmle.label | false | +| Finally.cs:246:25:246:26 | access to parameter b2 | Finally.cs:247:31:247:46 | object creation of type ExceptionA | semmle.label | true | +| Finally.cs:246:25:246:26 | access to parameter b2 | Finally.cs:250:17:252:17 | {...} | semmle.label | false | +| Finally.cs:247:25:247:47 | [finally: exception(Exception)] throw ...; | Finally.cs:250:17:252:17 | [finally: exception(Exception), finally(1): exception(ExceptionA)] {...} | semmle.label | exception(ExceptionA) | +| Finally.cs:247:25:247:47 | [finally: exception(ExceptionA)] throw ...; | Finally.cs:250:17:252:17 | [finally: exception(ExceptionA), finally(1): exception(ExceptionA)] {...} | semmle.label | exception(ExceptionA) | +| Finally.cs:247:25:247:47 | throw ...; | Finally.cs:250:17:252:17 | [finally(1): exception(ExceptionA)] {...} | semmle.label | exception(ExceptionA) | +| Finally.cs:247:31:247:46 | [finally: exception(Exception)] object creation of type ExceptionA | Finally.cs:247:25:247:47 | [finally: exception(Exception)] throw ...; | semmle.label | successor | +| Finally.cs:247:31:247:46 | [finally: exception(Exception)] object creation of type ExceptionA | Finally.cs:250:17:252:17 | [finally: exception(Exception), finally(1): exception(Exception)] {...} | semmle.label | exception(Exception) | +| Finally.cs:247:31:247:46 | [finally: exception(ExceptionA)] object creation of type ExceptionA | Finally.cs:247:25:247:47 | [finally: exception(ExceptionA)] throw ...; | semmle.label | successor | +| Finally.cs:247:31:247:46 | [finally: exception(ExceptionA)] object creation of type ExceptionA | Finally.cs:250:17:252:17 | [finally: exception(ExceptionA), finally(1): exception(Exception)] {...} | semmle.label | exception(Exception) | +| Finally.cs:247:31:247:46 | object creation of type ExceptionA | Finally.cs:247:25:247:47 | throw ...; | semmle.label | successor | +| Finally.cs:247:31:247:46 | object creation of type ExceptionA | Finally.cs:250:17:252:17 | [finally(1): exception(Exception)] {...} | semmle.label | exception(Exception) | +| Finally.cs:250:17:252:17 | [finally(1): exception(Exception)] {...} | Finally.cs:251:21:251:55 | [finally(1): exception(Exception)] ...; | semmle.label | successor | +| Finally.cs:250:17:252:17 | [finally(1): exception(ExceptionA)] {...} | Finally.cs:251:21:251:55 | [finally(1): exception(ExceptionA)] ...; | semmle.label | successor | +| Finally.cs:250:17:252:17 | [finally: exception(Exception), finally(1): exception(Exception)] {...} | Finally.cs:251:21:251:55 | [finally: exception(Exception), finally(1): exception(Exception)] ...; | semmle.label | successor | +| Finally.cs:250:17:252:17 | [finally: exception(Exception), finally(1): exception(ExceptionA)] {...} | Finally.cs:251:21:251:55 | [finally: exception(Exception), finally(1): exception(ExceptionA)] ...; | semmle.label | successor | +| Finally.cs:250:17:252:17 | [finally: exception(Exception)] {...} | Finally.cs:251:21:251:55 | [finally: exception(Exception)] ...; | semmle.label | successor | +| Finally.cs:250:17:252:17 | [finally: exception(ExceptionA), finally(1): exception(Exception)] {...} | Finally.cs:251:21:251:55 | [finally: exception(ExceptionA), finally(1): exception(Exception)] ...; | semmle.label | successor | +| Finally.cs:250:17:252:17 | [finally: exception(ExceptionA), finally(1): exception(ExceptionA)] {...} | Finally.cs:251:21:251:55 | [finally: exception(ExceptionA), finally(1): exception(ExceptionA)] ...; | semmle.label | successor | +| Finally.cs:250:17:252:17 | [finally: exception(ExceptionA)] {...} | Finally.cs:251:21:251:55 | [finally: exception(ExceptionA)] ...; | semmle.label | successor | +| Finally.cs:250:17:252:17 | {...} | Finally.cs:251:21:251:55 | ...; | semmle.label | successor | +| Finally.cs:251:21:251:54 | [finally(1): exception(Exception)] call to method WriteLine | Finally.cs:257:9:259:9 | [finally: exception(Exception)] {...} | semmle.label | exception(Exception) | +| Finally.cs:251:21:251:54 | [finally(1): exception(ExceptionA)] call to method WriteLine | Finally.cs:257:9:259:9 | [finally: exception(ExceptionA)] {...} | semmle.label | exception(ExceptionA) | +| Finally.cs:251:21:251:54 | [finally: exception(Exception), finally(1): exception(Exception)] call to method WriteLine | Finally.cs:257:9:259:9 | [finally: exception(Exception)] {...} | semmle.label | exception(Exception) | +| Finally.cs:251:21:251:54 | [finally: exception(Exception), finally(1): exception(ExceptionA)] call to method WriteLine | Finally.cs:257:9:259:9 | [finally: exception(ExceptionA)] {...} | semmle.label | exception(ExceptionA) | +| Finally.cs:251:21:251:54 | [finally: exception(Exception)] call to method WriteLine | Finally.cs:257:9:259:9 | [finally: exception(Exception)] {...} | semmle.label | exception(Exception) | +| Finally.cs:251:21:251:54 | [finally: exception(ExceptionA), finally(1): exception(Exception)] call to method WriteLine | Finally.cs:257:9:259:9 | [finally: exception(Exception)] {...} | semmle.label | exception(Exception) | +| Finally.cs:251:21:251:54 | [finally: exception(ExceptionA), finally(1): exception(ExceptionA)] call to method WriteLine | Finally.cs:257:9:259:9 | [finally: exception(ExceptionA)] {...} | semmle.label | exception(ExceptionA) | +| Finally.cs:251:21:251:54 | [finally: exception(ExceptionA)] call to method WriteLine | Finally.cs:257:9:259:9 | [finally: exception(ExceptionA)] {...} | semmle.label | exception(ExceptionA) | +| Finally.cs:251:21:251:54 | call to method WriteLine | Finally.cs:254:13:254:45 | ...; | semmle.label | successor | +| Finally.cs:251:21:251:55 | ...; | Finally.cs:251:39:251:53 | "Inner finally" | semmle.label | successor | +| Finally.cs:251:21:251:55 | [finally(1): exception(Exception)] ...; | Finally.cs:251:39:251:53 | [finally(1): exception(Exception)] "Inner finally" | semmle.label | successor | +| Finally.cs:251:21:251:55 | [finally(1): exception(ExceptionA)] ...; | Finally.cs:251:39:251:53 | [finally(1): exception(ExceptionA)] "Inner finally" | semmle.label | successor | +| Finally.cs:251:21:251:55 | [finally: exception(Exception), finally(1): exception(Exception)] ...; | Finally.cs:251:39:251:53 | [finally: exception(Exception), finally(1): exception(Exception)] "Inner finally" | semmle.label | successor | +| Finally.cs:251:21:251:55 | [finally: exception(Exception), finally(1): exception(ExceptionA)] ...; | Finally.cs:251:39:251:53 | [finally: exception(Exception), finally(1): exception(ExceptionA)] "Inner finally" | semmle.label | successor | +| Finally.cs:251:21:251:55 | [finally: exception(Exception)] ...; | Finally.cs:251:39:251:53 | [finally: exception(Exception)] "Inner finally" | semmle.label | successor | +| Finally.cs:251:21:251:55 | [finally: exception(ExceptionA), finally(1): exception(Exception)] ...; | Finally.cs:251:39:251:53 | [finally: exception(ExceptionA), finally(1): exception(Exception)] "Inner finally" | semmle.label | successor | +| Finally.cs:251:21:251:55 | [finally: exception(ExceptionA), finally(1): exception(ExceptionA)] ...; | Finally.cs:251:39:251:53 | [finally: exception(ExceptionA), finally(1): exception(ExceptionA)] "Inner finally" | semmle.label | successor | +| Finally.cs:251:21:251:55 | [finally: exception(ExceptionA)] ...; | Finally.cs:251:39:251:53 | [finally: exception(ExceptionA)] "Inner finally" | semmle.label | successor | +| Finally.cs:251:39:251:53 | "Inner finally" | Finally.cs:251:21:251:54 | call to method WriteLine | semmle.label | successor | +| Finally.cs:251:39:251:53 | [finally(1): exception(Exception)] "Inner finally" | Finally.cs:251:21:251:54 | [finally(1): exception(Exception)] call to method WriteLine | semmle.label | successor | +| Finally.cs:251:39:251:53 | [finally(1): exception(ExceptionA)] "Inner finally" | Finally.cs:251:21:251:54 | [finally(1): exception(ExceptionA)] call to method WriteLine | semmle.label | successor | +| Finally.cs:251:39:251:53 | [finally: exception(Exception), finally(1): exception(Exception)] "Inner finally" | Finally.cs:251:21:251:54 | [finally: exception(Exception), finally(1): exception(Exception)] call to method WriteLine | semmle.label | successor | +| Finally.cs:251:39:251:53 | [finally: exception(Exception), finally(1): exception(ExceptionA)] "Inner finally" | Finally.cs:251:21:251:54 | [finally: exception(Exception), finally(1): exception(ExceptionA)] call to method WriteLine | semmle.label | successor | +| Finally.cs:251:39:251:53 | [finally: exception(Exception)] "Inner finally" | Finally.cs:251:21:251:54 | [finally: exception(Exception)] call to method WriteLine | semmle.label | successor | +| Finally.cs:251:39:251:53 | [finally: exception(ExceptionA), finally(1): exception(Exception)] "Inner finally" | Finally.cs:251:21:251:54 | [finally: exception(ExceptionA), finally(1): exception(Exception)] call to method WriteLine | semmle.label | successor | +| Finally.cs:251:39:251:53 | [finally: exception(ExceptionA), finally(1): exception(ExceptionA)] "Inner finally" | Finally.cs:251:21:251:54 | [finally: exception(ExceptionA), finally(1): exception(ExceptionA)] call to method WriteLine | semmle.label | successor | +| Finally.cs:251:39:251:53 | [finally: exception(ExceptionA)] "Inner finally" | Finally.cs:251:21:251:54 | [finally: exception(ExceptionA)] call to method WriteLine | semmle.label | successor | +| Finally.cs:254:13:254:44 | call to method WriteLine | Finally.cs:257:9:259:9 | [finally: exception(Exception)] {...} | semmle.label | exception(Exception) | +| Finally.cs:254:13:254:44 | call to method WriteLine | Finally.cs:257:9:259:9 | {...} | semmle.label | successor | +| Finally.cs:254:13:254:45 | ...; | Finally.cs:254:31:254:43 | "Mid finally" | semmle.label | successor | +| Finally.cs:254:31:254:43 | "Mid finally" | Finally.cs:254:13:254:44 | call to method WriteLine | semmle.label | successor | +| Finally.cs:257:9:259:9 | [finally: exception(Exception)] {...} | Finally.cs:258:13:258:47 | [finally: exception(Exception)] ...; | semmle.label | successor | +| Finally.cs:257:9:259:9 | [finally: exception(ExceptionA)] {...} | Finally.cs:258:13:258:47 | [finally: exception(ExceptionA)] ...; | semmle.label | successor | +| Finally.cs:257:9:259:9 | {...} | Finally.cs:258:13:258:47 | ...; | semmle.label | successor | +| Finally.cs:258:13:258:46 | [finally: exception(Exception)] call to method WriteLine | Finally.cs:233:10:233:12 | exit M12 (abnormal) | semmle.label | exception(Exception) | +| Finally.cs:258:13:258:46 | [finally: exception(ExceptionA)] call to method WriteLine | Finally.cs:233:10:233:12 | exit M12 (abnormal) | semmle.label | exception(ExceptionA) | +| Finally.cs:258:13:258:46 | call to method WriteLine | Finally.cs:260:9:260:34 | ...; | semmle.label | successor | +| Finally.cs:258:13:258:47 | ...; | Finally.cs:258:31:258:45 | "Outer finally" | semmle.label | successor | +| Finally.cs:258:13:258:47 | [finally: exception(Exception)] ...; | Finally.cs:258:31:258:45 | [finally: exception(Exception)] "Outer finally" | semmle.label | successor | +| Finally.cs:258:13:258:47 | [finally: exception(ExceptionA)] ...; | Finally.cs:258:31:258:45 | [finally: exception(ExceptionA)] "Outer finally" | semmle.label | successor | +| Finally.cs:258:31:258:45 | "Outer finally" | Finally.cs:258:13:258:46 | call to method WriteLine | semmle.label | successor | +| Finally.cs:258:31:258:45 | [finally: exception(Exception)] "Outer finally" | Finally.cs:258:13:258:46 | [finally: exception(Exception)] call to method WriteLine | semmle.label | successor | +| Finally.cs:258:31:258:45 | [finally: exception(ExceptionA)] "Outer finally" | Finally.cs:258:13:258:46 | [finally: exception(ExceptionA)] call to method WriteLine | semmle.label | successor | +| Finally.cs:260:9:260:33 | call to method WriteLine | Finally.cs:233:10:233:12 | exit M12 (normal) | semmle.label | successor | +| Finally.cs:260:9:260:34 | ...; | Finally.cs:260:27:260:32 | "Done" | semmle.label | successor | +| Finally.cs:260:27:260:32 | "Done" | Finally.cs:260:9:260:33 | call to method WriteLine | semmle.label | successor | +| Finally.cs:263:10:263:12 | enter M13 | Finally.cs:264:5:274:5 | {...} | semmle.label | successor | +| Finally.cs:263:10:263:12 | exit M13 (abnormal) | Finally.cs:263:10:263:12 | exit M13 | semmle.label | successor | +| Finally.cs:263:10:263:12 | exit M13 (normal) | Finally.cs:263:10:263:12 | exit M13 | semmle.label | successor | +| Finally.cs:264:5:274:5 | {...} | Finally.cs:265:9:273:9 | try {...} ... | semmle.label | successor | +| Finally.cs:265:9:273:9 | try {...} ... | Finally.cs:266:9:268:9 | {...} | semmle.label | successor | +| Finally.cs:266:9:268:9 | {...} | Finally.cs:267:13:267:35 | ...; | semmle.label | successor | +| Finally.cs:267:13:267:34 | call to method WriteLine | Finally.cs:270:9:273:9 | [finally: exception(Exception)] {...} | semmle.label | exception(Exception) | +| Finally.cs:267:13:267:34 | call to method WriteLine | Finally.cs:270:9:273:9 | {...} | semmle.label | successor | +| Finally.cs:267:13:267:35 | ...; | Finally.cs:267:31:267:33 | "1" | semmle.label | successor | +| Finally.cs:267:31:267:33 | "1" | Finally.cs:267:13:267:34 | call to method WriteLine | semmle.label | successor | +| Finally.cs:270:9:273:9 | [finally: exception(Exception)] {...} | Finally.cs:271:13:271:35 | [finally: exception(Exception)] ...; | semmle.label | successor | +| Finally.cs:270:9:273:9 | {...} | Finally.cs:271:13:271:35 | ...; | semmle.label | successor | +| Finally.cs:271:13:271:34 | [finally: exception(Exception)] call to method WriteLine | Finally.cs:272:13:272:19 | [finally: exception(Exception)] ...; | semmle.label | successor | +| Finally.cs:271:13:271:34 | call to method WriteLine | Finally.cs:272:13:272:19 | ...; | semmle.label | successor | +| Finally.cs:271:13:271:35 | ...; | Finally.cs:271:31:271:33 | "3" | semmle.label | successor | +| Finally.cs:271:13:271:35 | [finally: exception(Exception)] ...; | Finally.cs:271:31:271:33 | [finally: exception(Exception)] "3" | semmle.label | successor | +| Finally.cs:271:31:271:33 | "3" | Finally.cs:271:13:271:34 | call to method WriteLine | semmle.label | successor | +| Finally.cs:271:31:271:33 | [finally: exception(Exception)] "3" | Finally.cs:271:13:271:34 | [finally: exception(Exception)] call to method WriteLine | semmle.label | successor | +| Finally.cs:272:13:272:13 | [finally: exception(Exception)] access to parameter i | Finally.cs:272:18:272:18 | [finally: exception(Exception)] 3 | semmle.label | successor | +| Finally.cs:272:13:272:13 | access to parameter i | Finally.cs:272:18:272:18 | 3 | semmle.label | successor | +| Finally.cs:272:13:272:18 | ... + ... | Finally.cs:272:13:272:18 | ... = ... | semmle.label | successor | +| Finally.cs:272:13:272:18 | ... = ... | Finally.cs:263:10:263:12 | exit M13 (normal) | semmle.label | successor | +| Finally.cs:272:13:272:18 | [finally: exception(Exception)] ... + ... | Finally.cs:272:13:272:18 | [finally: exception(Exception)] ... = ... | semmle.label | successor | +| Finally.cs:272:13:272:18 | [finally: exception(Exception)] ... = ... | Finally.cs:263:10:263:12 | exit M13 (abnormal) | semmle.label | exception(Exception) | +| Finally.cs:272:13:272:19 | ...; | Finally.cs:272:13:272:13 | access to parameter i | semmle.label | successor | +| Finally.cs:272:13:272:19 | [finally: exception(Exception)] ...; | Finally.cs:272:13:272:13 | [finally: exception(Exception)] access to parameter i | semmle.label | successor | +| Finally.cs:272:18:272:18 | 3 | Finally.cs:272:13:272:18 | ... + ... | semmle.label | successor | +| Finally.cs:272:18:272:18 | [finally: exception(Exception)] 3 | Finally.cs:272:13:272:18 | [finally: exception(Exception)] ... + ... | semmle.label | successor | | Foreach.cs:6:10:6:11 | enter M1 | Foreach.cs:7:5:10:5 | {...} | semmle.label | successor | | Foreach.cs:6:10:6:11 | exit M1 (normal) | Foreach.cs:6:10:6:11 | exit M1 | semmle.label | successor | | Foreach.cs:7:5:10:5 | {...} | Foreach.cs:8:29:8:32 | access to parameter args | semmle.label | successor | @@ -3438,17 +3523,18 @@ | NullCoalescing.cs:17:13:17:19 | (...) ... | NullCoalescing.cs:17:13:17:24 | ... ?? ... | semmle.label | non-null | | NullCoalescing.cs:17:13:17:24 | ... ?? ... | NullCoalescing.cs:17:9:17:24 | ... = ... | semmle.label | successor | | NullCoalescing.cs:17:19:17:19 | access to parameter i | NullCoalescing.cs:17:13:17:19 | (...) ... | semmle.label | successor | -| Patterns.cs:5:10:5:13 | enter Test | Patterns.cs:6:5:43:5 | {...} | semmle.label | successor | -| Patterns.cs:5:10:5:13 | exit Test (normal) | Patterns.cs:5:10:5:13 | exit Test | semmle.label | successor | +| Patterns.cs:5:10:5:11 | enter M1 | Patterns.cs:6:5:43:5 | {...} | semmle.label | successor | +| Patterns.cs:5:10:5:11 | exit M1 (normal) | Patterns.cs:5:10:5:11 | exit M1 | semmle.label | successor | | Patterns.cs:6:5:43:5 | {...} | Patterns.cs:7:9:7:24 | ... ...; | semmle.label | successor | | Patterns.cs:7:9:7:24 | ... ...; | Patterns.cs:7:20:7:23 | null | semmle.label | successor | | Patterns.cs:7:16:7:23 | Object o = ... | Patterns.cs:8:9:18:9 | if (...) ... | semmle.label | successor | | Patterns.cs:7:20:7:23 | null | Patterns.cs:7:16:7:23 | Object o = ... | semmle.label | successor | | Patterns.cs:8:9:18:9 | if (...) ... | Patterns.cs:8:13:8:13 | access to local variable o | semmle.label | successor | | Patterns.cs:8:13:8:13 | access to local variable o | Patterns.cs:8:18:8:23 | Int32 i1 | semmle.label | successor | -| Patterns.cs:8:13:8:23 | ... is ... | Patterns.cs:9:9:11:9 | {...} | semmle.label | true | -| Patterns.cs:8:13:8:23 | ... is ... | Patterns.cs:12:14:18:9 | if (...) ... | semmle.label | false | -| Patterns.cs:8:18:8:23 | Int32 i1 | Patterns.cs:8:13:8:23 | ... is ... | semmle.label | successor | +| Patterns.cs:8:13:8:23 | [false] ... is ... | Patterns.cs:12:14:18:9 | if (...) ... | semmle.label | false | +| Patterns.cs:8:13:8:23 | [true] ... is ... | Patterns.cs:9:9:11:9 | {...} | semmle.label | true | +| Patterns.cs:8:18:8:23 | Int32 i1 | Patterns.cs:8:13:8:23 | [false] ... is ... | semmle.label | no-match | +| Patterns.cs:8:18:8:23 | Int32 i1 | Patterns.cs:8:13:8:23 | [true] ... is ... | semmle.label | match | | Patterns.cs:9:9:11:9 | {...} | Patterns.cs:10:13:10:43 | ...; | semmle.label | successor | | Patterns.cs:10:13:10:42 | call to method WriteLine | Patterns.cs:20:9:38:9 | switch (...) {...} | semmle.label | successor | | Patterns.cs:10:13:10:43 | ...; | Patterns.cs:10:33:10:36 | "int " | semmle.label | successor | @@ -3457,9 +3543,10 @@ | Patterns.cs:10:38:10:39 | access to local variable i1 | Patterns.cs:10:31:10:41 | $"..." | semmle.label | successor | | Patterns.cs:12:14:18:9 | if (...) ... | Patterns.cs:12:18:12:18 | access to local variable o | semmle.label | successor | | Patterns.cs:12:18:12:18 | access to local variable o | Patterns.cs:12:23:12:31 | String s1 | semmle.label | successor | -| Patterns.cs:12:18:12:31 | ... is ... | Patterns.cs:13:9:15:9 | {...} | semmle.label | true | -| Patterns.cs:12:18:12:31 | ... is ... | Patterns.cs:16:14:18:9 | if (...) ... | semmle.label | false | -| Patterns.cs:12:23:12:31 | String s1 | Patterns.cs:12:18:12:31 | ... is ... | semmle.label | successor | +| Patterns.cs:12:18:12:31 | [false] ... is ... | Patterns.cs:16:14:18:9 | if (...) ... | semmle.label | false | +| Patterns.cs:12:18:12:31 | [true] ... is ... | Patterns.cs:13:9:15:9 | {...} | semmle.label | true | +| Patterns.cs:12:23:12:31 | String s1 | Patterns.cs:12:18:12:31 | [false] ... is ... | semmle.label | no-match | +| Patterns.cs:12:23:12:31 | String s1 | Patterns.cs:12:18:12:31 | [true] ... is ... | semmle.label | match | | Patterns.cs:13:9:15:9 | {...} | Patterns.cs:14:13:14:46 | ...; | semmle.label | successor | | Patterns.cs:14:13:14:45 | call to method WriteLine | Patterns.cs:20:9:38:9 | switch (...) {...} | semmle.label | successor | | Patterns.cs:14:13:14:46 | ...; | Patterns.cs:14:33:14:39 | "string " | semmle.label | successor | @@ -3468,9 +3555,10 @@ | Patterns.cs:14:41:14:42 | access to local variable s1 | Patterns.cs:14:31:14:44 | $"..." | semmle.label | successor | | Patterns.cs:16:14:18:9 | if (...) ... | Patterns.cs:16:18:16:18 | access to local variable o | semmle.label | successor | | Patterns.cs:16:18:16:18 | access to local variable o | Patterns.cs:16:23:16:28 | Object v1 | semmle.label | successor | -| Patterns.cs:16:18:16:28 | ... is ... | Patterns.cs:17:9:18:9 | {...} | semmle.label | true | -| Patterns.cs:16:18:16:28 | ... is ... | Patterns.cs:20:9:38:9 | switch (...) {...} | semmle.label | false | -| Patterns.cs:16:23:16:28 | Object v1 | Patterns.cs:16:18:16:28 | ... is ... | semmle.label | successor | +| Patterns.cs:16:18:16:28 | [false] ... is ... | Patterns.cs:20:9:38:9 | switch (...) {...} | semmle.label | false | +| Patterns.cs:16:18:16:28 | [true] ... is ... | Patterns.cs:17:9:18:9 | {...} | semmle.label | true | +| Patterns.cs:16:23:16:28 | Object v1 | Patterns.cs:16:18:16:28 | [false] ... is ... | semmle.label | no-match | +| Patterns.cs:16:23:16:28 | Object v1 | Patterns.cs:16:18:16:28 | [true] ... is ... | semmle.label | match | | Patterns.cs:17:9:18:9 | {...} | Patterns.cs:20:9:38:9 | switch (...) {...} | semmle.label | successor | | Patterns.cs:20:9:38:9 | switch (...) {...} | Patterns.cs:20:17:20:17 | access to local variable o | semmle.label | successor | | Patterns.cs:20:17:20:17 | access to local variable o | Patterns.cs:22:13:22:23 | case ...: | semmle.label | successor | @@ -3519,7 +3607,143 @@ | Patterns.cs:36:35:36:50 | "Something else" | Patterns.cs:36:17:36:51 | call to method WriteLine | semmle.label | successor | | Patterns.cs:37:17:37:22 | break; | Patterns.cs:40:9:42:9 | switch (...) {...} | semmle.label | break | | Patterns.cs:40:9:42:9 | switch (...) {...} | Patterns.cs:40:17:40:17 | access to local variable o | semmle.label | successor | -| Patterns.cs:40:17:40:17 | access to local variable o | Patterns.cs:5:10:5:13 | exit Test (normal) | semmle.label | successor | +| Patterns.cs:40:17:40:17 | access to local variable o | Patterns.cs:5:10:5:11 | exit M1 (normal) | semmle.label | successor | +| Patterns.cs:47:24:47:25 | enter M2 | Patterns.cs:48:9:48:9 | access to parameter c | semmle.label | successor | +| Patterns.cs:47:24:47:25 | exit M2 (normal) | Patterns.cs:47:24:47:25 | exit M2 | semmle.label | successor | +| Patterns.cs:48:9:48:9 | access to parameter c | Patterns.cs:48:18:48:20 | a | semmle.label | successor | +| Patterns.cs:48:9:48:20 | ... is ... | Patterns.cs:47:24:47:25 | exit M2 (normal) | semmle.label | successor | +| Patterns.cs:48:14:48:20 | not ... | Patterns.cs:48:9:48:20 | ... is ... | semmle.label | successor | +| Patterns.cs:48:18:48:20 | a | Patterns.cs:48:14:48:20 | not ... | semmle.label | successor | +| Patterns.cs:50:24:50:25 | enter M3 | Patterns.cs:51:9:51:9 | access to parameter c | semmle.label | successor | +| Patterns.cs:50:24:50:25 | exit M3 (normal) | Patterns.cs:50:24:50:25 | exit M3 | semmle.label | successor | +| Patterns.cs:51:9:51:9 | access to parameter c | Patterns.cs:51:18:51:21 | null | semmle.label | successor | +| Patterns.cs:51:9:51:21 | [false] ... is ... | Patterns.cs:51:34:51:34 | access to parameter c | semmle.label | false | +| Patterns.cs:51:9:51:21 | [true] ... is ... | Patterns.cs:51:25:51:25 | access to parameter c | semmle.label | true | +| Patterns.cs:51:9:51:39 | ... ? ... : ... | Patterns.cs:50:24:50:25 | exit M3 (normal) | semmle.label | successor | +| Patterns.cs:51:14:51:21 | [match] not ... | Patterns.cs:51:9:51:21 | [true] ... is ... | semmle.label | match | +| Patterns.cs:51:14:51:21 | [no-match] not ... | Patterns.cs:51:9:51:21 | [false] ... is ... | semmle.label | no-match | +| Patterns.cs:51:18:51:21 | null | Patterns.cs:51:14:51:21 | [match] not ... | semmle.label | no-match | +| Patterns.cs:51:18:51:21 | null | Patterns.cs:51:14:51:21 | [no-match] not ... | semmle.label | match | +| Patterns.cs:51:25:51:25 | access to parameter c | Patterns.cs:51:30:51:30 | 1 | semmle.label | successor | +| Patterns.cs:51:25:51:30 | ... is ... | Patterns.cs:51:9:51:39 | ... ? ... : ... | semmle.label | successor | +| Patterns.cs:51:30:51:30 | 1 | Patterns.cs:51:25:51:30 | ... is ... | semmle.label | successor | +| Patterns.cs:51:34:51:34 | access to parameter c | Patterns.cs:51:39:51:39 | 2 | semmle.label | successor | +| Patterns.cs:51:34:51:39 | ... is ... | Patterns.cs:51:9:51:39 | ... ? ... : ... | semmle.label | successor | +| Patterns.cs:51:39:51:39 | 2 | Patterns.cs:51:34:51:39 | ... is ... | semmle.label | successor | +| Patterns.cs:53:24:53:25 | enter M4 | Patterns.cs:54:9:54:9 | access to parameter c | semmle.label | successor | +| Patterns.cs:53:24:53:25 | exit M4 (normal) | Patterns.cs:53:24:53:25 | exit M4 | semmle.label | successor | +| Patterns.cs:54:9:54:9 | access to parameter c | Patterns.cs:54:18:54:37 | Patterns u | semmle.label | successor | +| Patterns.cs:54:9:54:37 | ... is ... | Patterns.cs:53:24:53:25 | exit M4 (normal) | semmle.label | successor | +| Patterns.cs:54:14:54:37 | not ... | Patterns.cs:54:9:54:37 | ... is ... | semmle.label | successor | +| Patterns.cs:54:18:54:37 | Patterns u | Patterns.cs:54:18:54:37 | { ... } | semmle.label | no-match | +| Patterns.cs:54:18:54:37 | Patterns u | Patterns.cs:54:33:54:33 | 1 | semmle.label | match | +| Patterns.cs:54:18:54:37 | { ... } | Patterns.cs:54:14:54:37 | not ... | semmle.label | successor | +| Patterns.cs:54:27:54:35 | [match] { ... } | Patterns.cs:54:18:54:37 | { ... } | semmle.label | match | +| Patterns.cs:54:27:54:35 | [no-match] { ... } | Patterns.cs:54:18:54:37 | { ... } | semmle.label | no-match | +| Patterns.cs:54:33:54:33 | 1 | Patterns.cs:54:27:54:35 | [match] { ... } | semmle.label | match | +| Patterns.cs:54:33:54:33 | 1 | Patterns.cs:54:27:54:35 | [no-match] { ... } | semmle.label | no-match | +| Patterns.cs:56:26:56:27 | enter M5 | Patterns.cs:57:5:63:5 | {...} | semmle.label | successor | +| Patterns.cs:56:26:56:27 | exit M5 (normal) | Patterns.cs:56:26:56:27 | exit M5 | semmle.label | successor | +| Patterns.cs:57:5:63:5 | {...} | Patterns.cs:58:16:58:16 | access to parameter i | semmle.label | successor | +| Patterns.cs:58:9:62:10 | return ...; | Patterns.cs:56:26:56:27 | exit M5 (normal) | semmle.label | return | +| Patterns.cs:58:16:58:16 | access to parameter i | Patterns.cs:60:17:60:17 | 1 | semmle.label | successor | +| Patterns.cs:58:16:62:9 | ... switch { ... } | Patterns.cs:58:9:62:10 | return ...; | semmle.label | successor | +| Patterns.cs:60:13:60:17 | [match] not ... | Patterns.cs:60:22:60:28 | "not 1" | semmle.label | match | +| Patterns.cs:60:13:60:17 | [no-match] not ... | Patterns.cs:61:13:61:13 | _ | semmle.label | no-match | +| Patterns.cs:60:13:60:28 | ... => ... | Patterns.cs:58:16:62:9 | ... switch { ... } | semmle.label | successor | +| Patterns.cs:60:17:60:17 | 1 | Patterns.cs:60:13:60:17 | [match] not ... | semmle.label | no-match | +| Patterns.cs:60:17:60:17 | 1 | Patterns.cs:60:13:60:17 | [no-match] not ... | semmle.label | match | +| Patterns.cs:60:22:60:28 | "not 1" | Patterns.cs:60:13:60:28 | ... => ... | semmle.label | successor | +| Patterns.cs:61:13:61:13 | _ | Patterns.cs:61:18:61:24 | "other" | semmle.label | match | +| Patterns.cs:61:13:61:24 | ... => ... | Patterns.cs:58:16:62:9 | ... switch { ... } | semmle.label | successor | +| Patterns.cs:61:18:61:24 | "other" | Patterns.cs:61:13:61:24 | ... => ... | semmle.label | successor | +| Patterns.cs:65:26:65:27 | enter M6 | Patterns.cs:66:5:72:5 | {...} | semmle.label | successor | +| Patterns.cs:65:26:65:27 | exit M6 (normal) | Patterns.cs:65:26:65:27 | exit M6 | semmle.label | successor | +| Patterns.cs:66:5:72:5 | {...} | Patterns.cs:67:16:67:16 | 2 | semmle.label | successor | +| Patterns.cs:67:9:71:10 | return ...; | Patterns.cs:65:26:65:27 | exit M6 (normal) | semmle.label | return | +| Patterns.cs:67:16:67:16 | 2 | Patterns.cs:69:17:69:17 | 2 | semmle.label | successor | +| Patterns.cs:67:16:71:9 | ... switch { ... } | Patterns.cs:67:9:71:10 | return ...; | semmle.label | successor | +| Patterns.cs:69:13:69:17 | [no-match] not ... | Patterns.cs:70:13:70:13 | 2 | semmle.label | no-match | +| Patterns.cs:69:17:69:17 | 2 | Patterns.cs:69:13:69:17 | [no-match] not ... | semmle.label | match | +| Patterns.cs:70:13:70:13 | 2 | Patterns.cs:70:18:70:27 | "possible" | semmle.label | match | +| Patterns.cs:70:13:70:27 | ... => ... | Patterns.cs:67:16:71:9 | ... switch { ... } | semmle.label | successor | +| Patterns.cs:70:18:70:27 | "possible" | Patterns.cs:70:13:70:27 | ... => ... | semmle.label | successor | +| Patterns.cs:74:26:74:27 | enter M7 | Patterns.cs:75:5:83:5 | {...} | semmle.label | successor | +| Patterns.cs:74:26:74:27 | exit M7 (normal) | Patterns.cs:74:26:74:27 | exit M7 | semmle.label | successor | +| Patterns.cs:75:5:83:5 | {...} | Patterns.cs:76:16:76:16 | access to parameter i | semmle.label | successor | +| Patterns.cs:76:9:82:10 | return ...; | Patterns.cs:74:26:74:27 | exit M7 (normal) | semmle.label | return | +| Patterns.cs:76:16:76:16 | access to parameter i | Patterns.cs:78:15:78:15 | 1 | semmle.label | successor | +| Patterns.cs:76:16:82:9 | ... switch { ... } | Patterns.cs:76:9:82:10 | return ...; | semmle.label | successor | +| Patterns.cs:78:13:78:15 | > ... | Patterns.cs:78:20:78:24 | "> 1" | semmle.label | match | +| Patterns.cs:78:13:78:15 | > ... | Patterns.cs:79:15:79:15 | 0 | semmle.label | no-match | +| Patterns.cs:78:13:78:24 | ... => ... | Patterns.cs:76:16:82:9 | ... switch { ... } | semmle.label | successor | +| Patterns.cs:78:15:78:15 | 1 | Patterns.cs:78:13:78:15 | > ... | semmle.label | successor | +| Patterns.cs:78:20:78:24 | "> 1" | Patterns.cs:78:13:78:24 | ... => ... | semmle.label | successor | +| Patterns.cs:79:13:79:15 | < ... | Patterns.cs:79:20:79:24 | "< 0" | semmle.label | match | +| Patterns.cs:79:13:79:15 | < ... | Patterns.cs:80:13:80:13 | 1 | semmle.label | no-match | +| Patterns.cs:79:13:79:24 | ... => ... | Patterns.cs:76:16:82:9 | ... switch { ... } | semmle.label | successor | +| Patterns.cs:79:15:79:15 | 0 | Patterns.cs:79:13:79:15 | < ... | semmle.label | successor | +| Patterns.cs:79:20:79:24 | "< 0" | Patterns.cs:79:13:79:24 | ... => ... | semmle.label | successor | +| Patterns.cs:80:13:80:13 | 1 | Patterns.cs:80:18:80:20 | "1" | semmle.label | match | +| Patterns.cs:80:13:80:13 | 1 | Patterns.cs:81:13:81:13 | _ | semmle.label | no-match | +| Patterns.cs:80:13:80:20 | ... => ... | Patterns.cs:76:16:82:9 | ... switch { ... } | semmle.label | successor | +| Patterns.cs:80:18:80:20 | "1" | Patterns.cs:80:13:80:20 | ... => ... | semmle.label | successor | +| Patterns.cs:81:13:81:13 | _ | Patterns.cs:81:18:81:20 | "0" | semmle.label | match | +| Patterns.cs:81:13:81:20 | ... => ... | Patterns.cs:76:16:82:9 | ... switch { ... } | semmle.label | successor | +| Patterns.cs:81:18:81:20 | "0" | Patterns.cs:81:13:81:20 | ... => ... | semmle.label | successor | +| Patterns.cs:85:26:85:27 | enter M8 | Patterns.cs:85:39:85:39 | access to parameter i | semmle.label | successor | +| Patterns.cs:85:26:85:27 | exit M8 (normal) | Patterns.cs:85:26:85:27 | exit M8 | semmle.label | successor | +| Patterns.cs:85:39:85:39 | access to parameter i | Patterns.cs:85:44:85:44 | 1 | semmle.label | successor | +| Patterns.cs:85:39:85:53 | [false] ... is ... | Patterns.cs:85:67:85:69 | "2" | semmle.label | false | +| Patterns.cs:85:39:85:53 | [true] ... is ... | Patterns.cs:85:57:85:63 | "not 2" | semmle.label | true | +| Patterns.cs:85:39:85:69 | ... ? ... : ... | Patterns.cs:85:26:85:27 | exit M8 (normal) | semmle.label | successor | +| Patterns.cs:85:44:85:44 | 1 | Patterns.cs:85:44:85:53 | [match] ... or ... | semmle.label | match | +| Patterns.cs:85:44:85:44 | 1 | Patterns.cs:85:53:85:53 | 2 | semmle.label | no-match | +| Patterns.cs:85:44:85:53 | [match] ... or ... | Patterns.cs:85:39:85:53 | [true] ... is ... | semmle.label | match | +| Patterns.cs:85:44:85:53 | [no-match] ... or ... | Patterns.cs:85:39:85:53 | [false] ... is ... | semmle.label | no-match | +| Patterns.cs:85:49:85:53 | [match] not ... | Patterns.cs:85:44:85:53 | [match] ... or ... | semmle.label | match | +| Patterns.cs:85:49:85:53 | [no-match] not ... | Patterns.cs:85:44:85:53 | [no-match] ... or ... | semmle.label | no-match | +| Patterns.cs:85:53:85:53 | 2 | Patterns.cs:85:49:85:53 | [match] not ... | semmle.label | no-match | +| Patterns.cs:85:53:85:53 | 2 | Patterns.cs:85:49:85:53 | [no-match] not ... | semmle.label | match | +| Patterns.cs:85:57:85:63 | "not 2" | Patterns.cs:85:39:85:69 | ... ? ... : ... | semmle.label | successor | +| Patterns.cs:85:67:85:69 | "2" | Patterns.cs:85:39:85:69 | ... ? ... : ... | semmle.label | successor | +| Patterns.cs:87:26:87:27 | enter M9 | Patterns.cs:87:39:87:39 | access to parameter i | semmle.label | successor | +| Patterns.cs:87:26:87:27 | exit M9 (normal) | Patterns.cs:87:26:87:27 | exit M9 | semmle.label | successor | +| Patterns.cs:87:39:87:39 | access to parameter i | Patterns.cs:87:44:87:44 | 1 | semmle.label | successor | +| Patterns.cs:87:39:87:54 | [false] ... is ... | Patterns.cs:87:64:87:70 | "not 1" | semmle.label | false | +| Patterns.cs:87:39:87:54 | [true] ... is ... | Patterns.cs:87:58:87:60 | "1" | semmle.label | true | +| Patterns.cs:87:39:87:70 | ... ? ... : ... | Patterns.cs:87:26:87:27 | exit M9 (normal) | semmle.label | successor | +| Patterns.cs:87:44:87:44 | 1 | Patterns.cs:87:44:87:54 | [no-match] ... and ... | semmle.label | no-match | +| Patterns.cs:87:44:87:44 | 1 | Patterns.cs:87:54:87:54 | 2 | semmle.label | match | +| Patterns.cs:87:44:87:54 | [match] ... and ... | Patterns.cs:87:39:87:54 | [true] ... is ... | semmle.label | match | +| Patterns.cs:87:44:87:54 | [no-match] ... and ... | Patterns.cs:87:39:87:54 | [false] ... is ... | semmle.label | no-match | +| Patterns.cs:87:50:87:54 | [match] not ... | Patterns.cs:87:44:87:54 | [match] ... and ... | semmle.label | match | +| Patterns.cs:87:50:87:54 | [no-match] not ... | Patterns.cs:87:44:87:54 | [no-match] ... and ... | semmle.label | no-match | +| Patterns.cs:87:54:87:54 | 2 | Patterns.cs:87:50:87:54 | [match] not ... | semmle.label | no-match | +| Patterns.cs:87:54:87:54 | 2 | Patterns.cs:87:50:87:54 | [no-match] not ... | semmle.label | match | +| Patterns.cs:87:58:87:60 | "1" | Patterns.cs:87:39:87:70 | ... ? ... : ... | semmle.label | successor | +| Patterns.cs:87:64:87:70 | "not 1" | Patterns.cs:87:39:87:70 | ... ? ... : ... | semmle.label | successor | +| Patterns.cs:93:17:93:19 | enter M10 | Patterns.cs:94:5:99:5 | {...} | semmle.label | successor | +| Patterns.cs:93:17:93:19 | exit M10 (normal) | Patterns.cs:93:17:93:19 | exit M10 | semmle.label | successor | +| Patterns.cs:94:5:99:5 | {...} | Patterns.cs:95:9:98:9 | if (...) ... | semmle.label | successor | +| Patterns.cs:95:9:98:9 | if (...) ... | Patterns.cs:95:13:95:16 | this access | semmle.label | successor | +| Patterns.cs:95:13:95:16 | this access | Patterns.cs:95:29:95:31 | access to constant A | semmle.label | successor | +| Patterns.cs:95:13:95:40 | [false] ... is ... | Patterns.cs:93:17:93:19 | exit M10 (normal) | semmle.label | false | +| Patterns.cs:95:13:95:40 | [true] ... is ... | Patterns.cs:96:9:98:9 | {...} | semmle.label | true | +| Patterns.cs:95:21:95:40 | [match] { ... } | Patterns.cs:95:13:95:40 | [true] ... is ... | semmle.label | match | +| Patterns.cs:95:21:95:40 | [match] { ... } | Patterns.cs:95:21:95:40 | [match] { ... } | semmle.label | match | +| Patterns.cs:95:21:95:40 | [no-match] { ... } | Patterns.cs:95:13:95:40 | [false] ... is ... | semmle.label | no-match | +| Patterns.cs:95:21:95:40 | [no-match] { ... } | Patterns.cs:95:21:95:40 | [no-match] { ... } | semmle.label | no-match | +| Patterns.cs:95:29:95:31 | access to constant A | Patterns.cs:95:29:95:38 | [match] ... or ... | semmle.label | match | +| Patterns.cs:95:29:95:31 | access to constant A | Patterns.cs:95:36:95:38 | access to constant B | semmle.label | no-match | +| Patterns.cs:95:29:95:38 | [match] ... or ... | Patterns.cs:95:21:95:40 | [match] { ... } | semmle.label | match | +| Patterns.cs:95:29:95:38 | [no-match] ... or ... | Patterns.cs:95:21:95:40 | [no-match] { ... } | semmle.label | no-match | +| Patterns.cs:95:36:95:38 | access to constant B | Patterns.cs:95:29:95:38 | [match] ... or ... | semmle.label | match | +| Patterns.cs:95:36:95:38 | access to constant B | Patterns.cs:95:29:95:38 | [no-match] ... or ... | semmle.label | no-match | +| Patterns.cs:96:9:98:9 | {...} | Patterns.cs:97:13:97:39 | ...; | semmle.label | successor | +| Patterns.cs:97:13:97:38 | call to method WriteLine | Patterns.cs:93:17:93:19 | exit M10 (normal) | semmle.label | successor | +| Patterns.cs:97:13:97:39 | ...; | Patterns.cs:97:31:97:37 | "not C" | semmle.label | successor | +| Patterns.cs:97:31:97:37 | "not C" | Patterns.cs:97:13:97:38 | call to method WriteLine | semmle.label | successor | | PostDominance.cs:5:10:5:11 | enter M1 | PostDominance.cs:6:5:8:5 | {...} | semmle.label | successor | | PostDominance.cs:5:10:5:11 | exit M1 (normal) | PostDominance.cs:5:10:5:11 | exit M1 | semmle.label | successor | | PostDominance.cs:6:5:8:5 | {...} | PostDominance.cs:7:9:7:29 | ...; | semmle.label | successor | @@ -3531,9 +3755,10 @@ | PostDominance.cs:11:5:15:5 | {...} | PostDominance.cs:12:9:13:19 | if (...) ... | semmle.label | successor | | PostDominance.cs:12:9:13:19 | if (...) ... | PostDominance.cs:12:13:12:13 | access to parameter s | semmle.label | successor | | PostDominance.cs:12:13:12:13 | access to parameter s | PostDominance.cs:12:18:12:21 | null | semmle.label | successor | -| PostDominance.cs:12:13:12:21 | ... is ... | PostDominance.cs:13:13:13:19 | return ...; | semmle.label | true | -| PostDominance.cs:12:13:12:21 | ... is ... | PostDominance.cs:14:9:14:29 | ...; | semmle.label | false | -| PostDominance.cs:12:18:12:21 | null | PostDominance.cs:12:13:12:21 | ... is ... | semmle.label | successor | +| PostDominance.cs:12:13:12:21 | [false] ... is ... | PostDominance.cs:14:9:14:29 | ...; | semmle.label | false | +| PostDominance.cs:12:13:12:21 | [true] ... is ... | PostDominance.cs:13:13:13:19 | return ...; | semmle.label | true | +| PostDominance.cs:12:18:12:21 | null | PostDominance.cs:12:13:12:21 | [false] ... is ... | semmle.label | no-match | +| PostDominance.cs:12:18:12:21 | null | PostDominance.cs:12:13:12:21 | [true] ... is ... | semmle.label | match | | PostDominance.cs:13:13:13:19 | return ...; | PostDominance.cs:10:10:10:11 | exit M2 (normal) | semmle.label | return | | PostDominance.cs:14:9:14:28 | call to method WriteLine | PostDominance.cs:10:10:10:11 | exit M2 (normal) | semmle.label | successor | | PostDominance.cs:14:9:14:29 | ...; | PostDominance.cs:14:27:14:27 | access to parameter s | semmle.label | successor | @@ -3544,9 +3769,10 @@ | PostDominance.cs:18:5:22:5 | {...} | PostDominance.cs:19:9:20:55 | if (...) ... | semmle.label | successor | | PostDominance.cs:19:9:20:55 | if (...) ... | PostDominance.cs:19:13:19:13 | access to parameter s | semmle.label | successor | | PostDominance.cs:19:13:19:13 | access to parameter s | PostDominance.cs:19:18:19:21 | null | semmle.label | successor | -| PostDominance.cs:19:13:19:21 | ... is ... | PostDominance.cs:20:45:20:53 | nameof(...) | semmle.label | true | -| PostDominance.cs:19:13:19:21 | ... is ... | PostDominance.cs:21:9:21:29 | ...; | semmle.label | false | -| PostDominance.cs:19:18:19:21 | null | PostDominance.cs:19:13:19:21 | ... is ... | semmle.label | successor | +| PostDominance.cs:19:13:19:21 | [false] ... is ... | PostDominance.cs:21:9:21:29 | ...; | semmle.label | false | +| PostDominance.cs:19:13:19:21 | [true] ... is ... | PostDominance.cs:20:45:20:53 | nameof(...) | semmle.label | true | +| PostDominance.cs:19:18:19:21 | null | PostDominance.cs:19:13:19:21 | [false] ... is ... | semmle.label | no-match | +| PostDominance.cs:19:18:19:21 | null | PostDominance.cs:19:13:19:21 | [true] ... is ... | semmle.label | match | | PostDominance.cs:20:13:20:55 | throw ...; | PostDominance.cs:17:10:17:11 | exit M3 (abnormal) | semmle.label | exception(ArgumentNullException) | | PostDominance.cs:20:19:20:54 | object creation of type ArgumentNullException | PostDominance.cs:20:13:20:55 | throw ...; | semmle.label | successor | | PostDominance.cs:20:45:20:53 | nameof(...) | PostDominance.cs:20:19:20:54 | object creation of type ArgumentNullException | semmle.label | successor | @@ -3923,9 +4149,10 @@ | TypeAccesses.cs:6:13:6:23 | ... as ... | TypeAccesses.cs:6:9:6:23 | ... = ... | semmle.label | successor | | TypeAccesses.cs:7:9:7:25 | if (...) ... | TypeAccesses.cs:7:13:7:13 | access to parameter o | semmle.label | successor | | TypeAccesses.cs:7:13:7:13 | access to parameter o | TypeAccesses.cs:7:18:7:22 | Int32 j | semmle.label | successor | -| TypeAccesses.cs:7:13:7:22 | ... is ... | TypeAccesses.cs:7:25:7:25 | ; | semmle.label | true | -| TypeAccesses.cs:7:13:7:22 | ... is ... | TypeAccesses.cs:8:9:8:28 | ... ...; | semmle.label | false | -| TypeAccesses.cs:7:18:7:22 | Int32 j | TypeAccesses.cs:7:13:7:22 | ... is ... | semmle.label | successor | +| TypeAccesses.cs:7:13:7:22 | [false] ... is ... | TypeAccesses.cs:8:9:8:28 | ... ...; | semmle.label | false | +| TypeAccesses.cs:7:13:7:22 | [true] ... is ... | TypeAccesses.cs:7:25:7:25 | ; | semmle.label | true | +| TypeAccesses.cs:7:18:7:22 | Int32 j | TypeAccesses.cs:7:13:7:22 | [false] ... is ... | semmle.label | no-match | +| TypeAccesses.cs:7:18:7:22 | Int32 j | TypeAccesses.cs:7:13:7:22 | [true] ... is ... | semmle.label | match | | TypeAccesses.cs:7:25:7:25 | ; | TypeAccesses.cs:8:9:8:28 | ... ...; | semmle.label | successor | | TypeAccesses.cs:8:9:8:28 | ... ...; | TypeAccesses.cs:8:17:8:27 | typeof(...) | semmle.label | successor | | TypeAccesses.cs:8:13:8:27 | Type t = ... | TypeAccesses.cs:3:10:3:10 | exit M (normal) | semmle.label | successor | diff --git a/csharp/ql/test/library-tests/controlflow/graph/Nodes.expected b/csharp/ql/test/library-tests/controlflow/graph/Nodes.expected index 2dbbf608e5a..9085e248d03 100644 --- a/csharp/ql/test/library-tests/controlflow/graph/Nodes.expected +++ b/csharp/ql/test/library-tests/controlflow/graph/Nodes.expected @@ -619,13 +619,9 @@ finallyNode | CompileTimeOperators.cs:37:13:37:41 | [finally: goto(End)] ...; | CompileTimeOperators.cs:30:9:38:9 | try {...} ... | | CompileTimeOperators.cs:37:31:37:39 | [finally: goto(End)] "Finally" | CompileTimeOperators.cs:30:9:38:9 | try {...} ... | | Finally.cs:14:9:16:9 | [finally: exception(Exception)] {...} | Finally.cs:9:9:16:9 | try {...} ... | -| Finally.cs:14:9:16:9 | [finally: exception(OutOfMemoryException)] {...} | Finally.cs:9:9:16:9 | try {...} ... | | Finally.cs:15:13:15:40 | [finally: exception(Exception)] call to method WriteLine | Finally.cs:9:9:16:9 | try {...} ... | -| Finally.cs:15:13:15:40 | [finally: exception(OutOfMemoryException)] call to method WriteLine | Finally.cs:9:9:16:9 | try {...} ... | | Finally.cs:15:13:15:41 | [finally: exception(Exception)] ...; | Finally.cs:9:9:16:9 | try {...} ... | -| Finally.cs:15:13:15:41 | [finally: exception(OutOfMemoryException)] ...; | Finally.cs:9:9:16:9 | try {...} ... | | Finally.cs:15:31:15:39 | [finally: exception(Exception)] "Finally" | Finally.cs:9:9:16:9 | try {...} ... | -| Finally.cs:15:31:15:39 | [finally: exception(OutOfMemoryException)] "Finally" | Finally.cs:9:9:16:9 | try {...} ... | | Finally.cs:37:13:39:13 | [finally: exception(ArgumentException)] {...} | Finally.cs:32:13:39:13 | try {...} ... | | Finally.cs:38:17:38:44 | [finally: exception(ArgumentException)] throw ...; | Finally.cs:32:13:39:13 | try {...} ... | | Finally.cs:38:23:38:43 | [finally: exception(ArgumentException)] object creation of type Exception | Finally.cs:32:13:39:13 | try {...} ... | @@ -644,19 +640,15 @@ finallyNode | Finally.cs:50:31:50:39 | [finally: return] "Finally" | Finally.cs:21:9:51:9 | try {...} ... | | Finally.cs:69:9:71:9 | [finally: exception(Exception)] {...} | Finally.cs:56:9:71:9 | try {...} ... | | Finally.cs:69:9:71:9 | [finally: exception(IOException)] {...} | Finally.cs:56:9:71:9 | try {...} ... | -| Finally.cs:69:9:71:9 | [finally: exception(OutOfMemoryException)] {...} | Finally.cs:56:9:71:9 | try {...} ... | | Finally.cs:69:9:71:9 | [finally: return] {...} | Finally.cs:56:9:71:9 | try {...} ... | | Finally.cs:70:13:70:40 | [finally: exception(Exception)] call to method WriteLine | Finally.cs:56:9:71:9 | try {...} ... | | Finally.cs:70:13:70:40 | [finally: exception(IOException)] call to method WriteLine | Finally.cs:56:9:71:9 | try {...} ... | -| Finally.cs:70:13:70:40 | [finally: exception(OutOfMemoryException)] call to method WriteLine | Finally.cs:56:9:71:9 | try {...} ... | | Finally.cs:70:13:70:40 | [finally: return] call to method WriteLine | Finally.cs:56:9:71:9 | try {...} ... | | Finally.cs:70:13:70:41 | [finally: exception(Exception)] ...; | Finally.cs:56:9:71:9 | try {...} ... | | Finally.cs:70:13:70:41 | [finally: exception(IOException)] ...; | Finally.cs:56:9:71:9 | try {...} ... | -| Finally.cs:70:13:70:41 | [finally: exception(OutOfMemoryException)] ...; | Finally.cs:56:9:71:9 | try {...} ... | | Finally.cs:70:13:70:41 | [finally: return] ...; | Finally.cs:56:9:71:9 | try {...} ... | | Finally.cs:70:31:70:39 | [finally: exception(Exception)] "Finally" | Finally.cs:56:9:71:9 | try {...} ... | | Finally.cs:70:31:70:39 | [finally: exception(IOException)] "Finally" | Finally.cs:56:9:71:9 | try {...} ... | -| Finally.cs:70:31:70:39 | [finally: exception(OutOfMemoryException)] "Finally" | Finally.cs:56:9:71:9 | try {...} ... | | Finally.cs:70:31:70:39 | [finally: return] "Finally" | Finally.cs:56:9:71:9 | try {...} ... | | Finally.cs:89:13:99:13 | [finally: break] {...} | Finally.cs:79:13:99:13 | try {...} ... | | Finally.cs:89:13:99:13 | [finally: continue] {...} | Finally.cs:79:13:99:13 | try {...} ... | @@ -685,33 +677,33 @@ finallyNode | Finally.cs:93:31:93:45 | [finally: break] object creation of type Exception | Finally.cs:79:13:99:13 | try {...} ... | | Finally.cs:93:31:93:45 | [finally: continue] object creation of type Exception | Finally.cs:79:13:99:13 | try {...} ... | | Finally.cs:93:31:93:45 | [finally: return] object creation of type Exception | Finally.cs:79:13:99:13 | try {...} ... | -| Finally.cs:96:17:98:17 | [finally(2): exception(Exception)] {...} | Finally.cs:90:17:98:17 | try {...} ... | -| Finally.cs:96:17:98:17 | [finally: break, finally(2): exception(Exception)] {...} | Finally.cs:90:17:98:17 | try {...} ... | +| Finally.cs:96:17:98:17 | [finally(1): exception(Exception)] {...} | Finally.cs:90:17:98:17 | try {...} ... | +| Finally.cs:96:17:98:17 | [finally: break, finally(1): exception(Exception)] {...} | Finally.cs:90:17:98:17 | try {...} ... | | Finally.cs:96:17:98:17 | [finally: break] {...} | Finally.cs:90:17:98:17 | try {...} ... | -| Finally.cs:96:17:98:17 | [finally: continue, finally(2): exception(Exception)] {...} | Finally.cs:90:17:98:17 | try {...} ... | +| Finally.cs:96:17:98:17 | [finally: continue, finally(1): exception(Exception)] {...} | Finally.cs:90:17:98:17 | try {...} ... | | Finally.cs:96:17:98:17 | [finally: continue] {...} | Finally.cs:90:17:98:17 | try {...} ... | -| Finally.cs:96:17:98:17 | [finally: return, finally(2): exception(Exception)] {...} | Finally.cs:90:17:98:17 | try {...} ... | +| Finally.cs:96:17:98:17 | [finally: return, finally(1): exception(Exception)] {...} | Finally.cs:90:17:98:17 | try {...} ... | | Finally.cs:96:17:98:17 | [finally: return] {...} | Finally.cs:90:17:98:17 | try {...} ... | -| Finally.cs:97:21:97:21 | [finally(2): exception(Exception)] access to local variable i | Finally.cs:90:17:98:17 | try {...} ... | -| Finally.cs:97:21:97:21 | [finally: break, finally(2): exception(Exception)] access to local variable i | Finally.cs:90:17:98:17 | try {...} ... | +| Finally.cs:97:21:97:21 | [finally(1): exception(Exception)] access to local variable i | Finally.cs:90:17:98:17 | try {...} ... | +| Finally.cs:97:21:97:21 | [finally: break, finally(1): exception(Exception)] access to local variable i | Finally.cs:90:17:98:17 | try {...} ... | | Finally.cs:97:21:97:21 | [finally: break] access to local variable i | Finally.cs:90:17:98:17 | try {...} ... | -| Finally.cs:97:21:97:21 | [finally: continue, finally(2): exception(Exception)] access to local variable i | Finally.cs:90:17:98:17 | try {...} ... | +| Finally.cs:97:21:97:21 | [finally: continue, finally(1): exception(Exception)] access to local variable i | Finally.cs:90:17:98:17 | try {...} ... | | Finally.cs:97:21:97:21 | [finally: continue] access to local variable i | Finally.cs:90:17:98:17 | try {...} ... | -| Finally.cs:97:21:97:21 | [finally: return, finally(2): exception(Exception)] access to local variable i | Finally.cs:90:17:98:17 | try {...} ... | +| Finally.cs:97:21:97:21 | [finally: return, finally(1): exception(Exception)] access to local variable i | Finally.cs:90:17:98:17 | try {...} ... | | Finally.cs:97:21:97:21 | [finally: return] access to local variable i | Finally.cs:90:17:98:17 | try {...} ... | -| Finally.cs:97:21:97:23 | [finally(2): exception(Exception)] ...-- | Finally.cs:90:17:98:17 | try {...} ... | -| Finally.cs:97:21:97:23 | [finally: break, finally(2): exception(Exception)] ...-- | Finally.cs:90:17:98:17 | try {...} ... | +| Finally.cs:97:21:97:23 | [finally(1): exception(Exception)] ...-- | Finally.cs:90:17:98:17 | try {...} ... | +| Finally.cs:97:21:97:23 | [finally: break, finally(1): exception(Exception)] ...-- | Finally.cs:90:17:98:17 | try {...} ... | | Finally.cs:97:21:97:23 | [finally: break] ...-- | Finally.cs:90:17:98:17 | try {...} ... | -| Finally.cs:97:21:97:23 | [finally: continue, finally(2): exception(Exception)] ...-- | Finally.cs:90:17:98:17 | try {...} ... | +| Finally.cs:97:21:97:23 | [finally: continue, finally(1): exception(Exception)] ...-- | Finally.cs:90:17:98:17 | try {...} ... | | Finally.cs:97:21:97:23 | [finally: continue] ...-- | Finally.cs:90:17:98:17 | try {...} ... | -| Finally.cs:97:21:97:23 | [finally: return, finally(2): exception(Exception)] ...-- | Finally.cs:90:17:98:17 | try {...} ... | +| Finally.cs:97:21:97:23 | [finally: return, finally(1): exception(Exception)] ...-- | Finally.cs:90:17:98:17 | try {...} ... | | Finally.cs:97:21:97:23 | [finally: return] ...-- | Finally.cs:90:17:98:17 | try {...} ... | -| Finally.cs:97:21:97:24 | [finally(2): exception(Exception)] ...; | Finally.cs:90:17:98:17 | try {...} ... | -| Finally.cs:97:21:97:24 | [finally: break, finally(2): exception(Exception)] ...; | Finally.cs:90:17:98:17 | try {...} ... | +| Finally.cs:97:21:97:24 | [finally(1): exception(Exception)] ...; | Finally.cs:90:17:98:17 | try {...} ... | +| Finally.cs:97:21:97:24 | [finally: break, finally(1): exception(Exception)] ...; | Finally.cs:90:17:98:17 | try {...} ... | | Finally.cs:97:21:97:24 | [finally: break] ...; | Finally.cs:90:17:98:17 | try {...} ... | -| Finally.cs:97:21:97:24 | [finally: continue, finally(2): exception(Exception)] ...; | Finally.cs:90:17:98:17 | try {...} ... | +| Finally.cs:97:21:97:24 | [finally: continue, finally(1): exception(Exception)] ...; | Finally.cs:90:17:98:17 | try {...} ... | | Finally.cs:97:21:97:24 | [finally: continue] ...; | Finally.cs:90:17:98:17 | try {...} ... | -| Finally.cs:97:21:97:24 | [finally: return, finally(2): exception(Exception)] ...; | Finally.cs:90:17:98:17 | try {...} ... | +| Finally.cs:97:21:97:24 | [finally: return, finally(1): exception(Exception)] ...; | Finally.cs:90:17:98:17 | try {...} ... | | Finally.cs:97:21:97:24 | [finally: return] ...; | Finally.cs:90:17:98:17 | try {...} ... | | Finally.cs:113:9:118:9 | [finally: exception(Exception)] {...} | Finally.cs:105:9:118:9 | try {...} ... | | Finally.cs:113:9:118:9 | [finally: exception(NullReferenceException)] {...} | Finally.cs:105:9:118:9 | try {...} ... | @@ -802,13 +794,9 @@ finallyNode | Finally.cs:117:35:117:35 | [finally: exception(OutOfMemoryException)] 1 | Finally.cs:105:9:118:9 | try {...} ... | | Finally.cs:117:35:117:35 | [finally: return] 1 | Finally.cs:105:9:118:9 | try {...} ... | | Finally.cs:140:9:143:9 | [finally: exception(Exception)] {...} | Finally.cs:135:9:143:9 | try {...} ... | -| Finally.cs:140:9:143:9 | [finally: exception(OutOfMemoryException)] {...} | Finally.cs:135:9:143:9 | try {...} ... | | Finally.cs:141:13:141:44 | [finally: exception(Exception)] throw ...; | Finally.cs:135:9:143:9 | try {...} ... | -| Finally.cs:141:13:141:44 | [finally: exception(OutOfMemoryException)] throw ...; | Finally.cs:135:9:143:9 | try {...} ... | | Finally.cs:141:19:141:43 | [finally: exception(Exception)] object creation of type ArgumentException | Finally.cs:135:9:143:9 | try {...} ... | -| Finally.cs:141:19:141:43 | [finally: exception(OutOfMemoryException)] object creation of type ArgumentException | Finally.cs:135:9:143:9 | try {...} ... | | Finally.cs:141:41:141:42 | [finally: exception(Exception)] "" | Finally.cs:135:9:143:9 | try {...} ... | -| Finally.cs:141:41:141:42 | [finally: exception(OutOfMemoryException)] "" | Finally.cs:135:9:143:9 | try {...} ... | | Finally.cs:155:9:169:9 | [finally: exception(ArgumentNullException)] {...} | Finally.cs:149:9:169:9 | try {...} ... | | Finally.cs:155:9:169:9 | [finally: exception(Exception)] {...} | Finally.cs:149:9:169:9 | try {...} ... | | Finally.cs:156:13:168:13 | [finally: exception(ArgumentNullException)] try {...} ... | Finally.cs:149:9:169:9 | try {...} ... | @@ -833,40 +821,28 @@ finallyNode | Finally.cs:159:41:159:43 | [finally: exception(Exception)] "1" | Finally.cs:149:9:169:9 | try {...} ... | | Finally.cs:161:13:164:13 | [finally: exception(ArgumentNullException), exception: Exception] catch (...) {...} | Finally.cs:149:9:169:9 | try {...} ... | | Finally.cs:161:13:164:13 | [finally: exception(ArgumentNullException), exception: NullReferenceException] catch (...) {...} | Finally.cs:149:9:169:9 | try {...} ... | -| Finally.cs:161:13:164:13 | [finally: exception(ArgumentNullException), exception: OutOfMemoryException] catch (...) {...} | Finally.cs:149:9:169:9 | try {...} ... | | Finally.cs:161:13:164:13 | [finally: exception(Exception), exception: Exception] catch (...) {...} | Finally.cs:149:9:169:9 | try {...} ... | | Finally.cs:161:13:164:13 | [finally: exception(Exception), exception: NullReferenceException] catch (...) {...} | Finally.cs:149:9:169:9 | try {...} ... | -| Finally.cs:161:13:164:13 | [finally: exception(Exception), exception: OutOfMemoryException] catch (...) {...} | Finally.cs:149:9:169:9 | try {...} ... | | Finally.cs:161:30:161:30 | [finally: exception(ArgumentNullException), exception: Exception] Exception e | Finally.cs:149:9:169:9 | try {...} ... | | Finally.cs:161:30:161:30 | [finally: exception(ArgumentNullException), exception: NullReferenceException] Exception e | Finally.cs:149:9:169:9 | try {...} ... | -| Finally.cs:161:30:161:30 | [finally: exception(ArgumentNullException), exception: OutOfMemoryException] Exception e | Finally.cs:149:9:169:9 | try {...} ... | | Finally.cs:161:30:161:30 | [finally: exception(Exception), exception: Exception] Exception e | Finally.cs:149:9:169:9 | try {...} ... | | Finally.cs:161:30:161:30 | [finally: exception(Exception), exception: NullReferenceException] Exception e | Finally.cs:149:9:169:9 | try {...} ... | -| Finally.cs:161:30:161:30 | [finally: exception(Exception), exception: OutOfMemoryException] Exception e | Finally.cs:149:9:169:9 | try {...} ... | | Finally.cs:161:39:161:39 | [finally: exception(ArgumentNullException), exception: Exception] access to local variable e | Finally.cs:149:9:169:9 | try {...} ... | | Finally.cs:161:39:161:39 | [finally: exception(ArgumentNullException), exception: NullReferenceException] access to local variable e | Finally.cs:149:9:169:9 | try {...} ... | -| Finally.cs:161:39:161:39 | [finally: exception(ArgumentNullException), exception: OutOfMemoryException] access to local variable e | Finally.cs:149:9:169:9 | try {...} ... | | Finally.cs:161:39:161:39 | [finally: exception(Exception), exception: Exception] access to local variable e | Finally.cs:149:9:169:9 | try {...} ... | | Finally.cs:161:39:161:39 | [finally: exception(Exception), exception: NullReferenceException] access to local variable e | Finally.cs:149:9:169:9 | try {...} ... | -| Finally.cs:161:39:161:39 | [finally: exception(Exception), exception: OutOfMemoryException] access to local variable e | Finally.cs:149:9:169:9 | try {...} ... | | Finally.cs:161:39:161:47 | [finally: exception(ArgumentNullException), exception: Exception] access to property Message | Finally.cs:149:9:169:9 | try {...} ... | | Finally.cs:161:39:161:47 | [finally: exception(ArgumentNullException), exception: NullReferenceException] access to property Message | Finally.cs:149:9:169:9 | try {...} ... | -| Finally.cs:161:39:161:47 | [finally: exception(ArgumentNullException), exception: OutOfMemoryException] access to property Message | Finally.cs:149:9:169:9 | try {...} ... | | Finally.cs:161:39:161:47 | [finally: exception(Exception), exception: Exception] access to property Message | Finally.cs:149:9:169:9 | try {...} ... | | Finally.cs:161:39:161:47 | [finally: exception(Exception), exception: NullReferenceException] access to property Message | Finally.cs:149:9:169:9 | try {...} ... | -| Finally.cs:161:39:161:47 | [finally: exception(Exception), exception: OutOfMemoryException] access to property Message | Finally.cs:149:9:169:9 | try {...} ... | | Finally.cs:161:39:161:54 | [finally: exception(ArgumentNullException), exception: Exception] ... == ... | Finally.cs:149:9:169:9 | try {...} ... | | Finally.cs:161:39:161:54 | [finally: exception(ArgumentNullException), exception: NullReferenceException] ... == ... | Finally.cs:149:9:169:9 | try {...} ... | -| Finally.cs:161:39:161:54 | [finally: exception(ArgumentNullException), exception: OutOfMemoryException] ... == ... | Finally.cs:149:9:169:9 | try {...} ... | | Finally.cs:161:39:161:54 | [finally: exception(Exception), exception: Exception] ... == ... | Finally.cs:149:9:169:9 | try {...} ... | | Finally.cs:161:39:161:54 | [finally: exception(Exception), exception: NullReferenceException] ... == ... | Finally.cs:149:9:169:9 | try {...} ... | -| Finally.cs:161:39:161:54 | [finally: exception(Exception), exception: OutOfMemoryException] ... == ... | Finally.cs:149:9:169:9 | try {...} ... | | Finally.cs:161:52:161:54 | [finally: exception(ArgumentNullException), exception: Exception] "1" | Finally.cs:149:9:169:9 | try {...} ... | | Finally.cs:161:52:161:54 | [finally: exception(ArgumentNullException), exception: NullReferenceException] "1" | Finally.cs:149:9:169:9 | try {...} ... | -| Finally.cs:161:52:161:54 | [finally: exception(ArgumentNullException), exception: OutOfMemoryException] "1" | Finally.cs:149:9:169:9 | try {...} ... | | Finally.cs:161:52:161:54 | [finally: exception(Exception), exception: Exception] "1" | Finally.cs:149:9:169:9 | try {...} ... | | Finally.cs:161:52:161:54 | [finally: exception(Exception), exception: NullReferenceException] "1" | Finally.cs:149:9:169:9 | try {...} ... | -| Finally.cs:161:52:161:54 | [finally: exception(Exception), exception: OutOfMemoryException] "1" | Finally.cs:149:9:169:9 | try {...} ... | | Finally.cs:162:13:164:13 | [finally: exception(ArgumentNullException)] {...} | Finally.cs:149:9:169:9 | try {...} ... | | Finally.cs:162:13:164:13 | [finally: exception(Exception)] {...} | Finally.cs:149:9:169:9 | try {...} ... | | Finally.cs:163:17:163:42 | [finally: exception(ArgumentNullException)] call to method WriteLine | Finally.cs:149:9:169:9 | try {...} ... | @@ -935,45 +911,45 @@ finallyNode | Finally.cs:205:25:205:47 | [finally: exception(ExceptionA)] throw ...; | Finally.cs:197:9:212:9 | try {...} ... | | Finally.cs:205:31:205:46 | [finally: exception(Exception)] object creation of type ExceptionB | Finally.cs:197:9:212:9 | try {...} ... | | Finally.cs:205:31:205:46 | [finally: exception(ExceptionA)] object creation of type ExceptionB | Finally.cs:197:9:212:9 | try {...} ... | -| Finally.cs:208:13:210:13 | [finally(2): exception(Exception)] {...} | Finally.cs:203:13:210:13 | try {...} ... | -| Finally.cs:208:13:210:13 | [finally(2): exception(ExceptionB)] {...} | Finally.cs:203:13:210:13 | try {...} ... | -| Finally.cs:208:13:210:13 | [finally: exception(Exception), finally(2): exception(Exception)] {...} | Finally.cs:203:13:210:13 | try {...} ... | -| Finally.cs:208:13:210:13 | [finally: exception(Exception), finally(2): exception(ExceptionB)] {...} | Finally.cs:203:13:210:13 | try {...} ... | +| Finally.cs:208:13:210:13 | [finally(1): exception(Exception)] {...} | Finally.cs:203:13:210:13 | try {...} ... | +| Finally.cs:208:13:210:13 | [finally(1): exception(ExceptionB)] {...} | Finally.cs:203:13:210:13 | try {...} ... | +| Finally.cs:208:13:210:13 | [finally: exception(Exception), finally(1): exception(Exception)] {...} | Finally.cs:203:13:210:13 | try {...} ... | +| Finally.cs:208:13:210:13 | [finally: exception(Exception), finally(1): exception(ExceptionB)] {...} | Finally.cs:203:13:210:13 | try {...} ... | | Finally.cs:208:13:210:13 | [finally: exception(Exception)] {...} | Finally.cs:203:13:210:13 | try {...} ... | -| Finally.cs:208:13:210:13 | [finally: exception(ExceptionA), finally(2): exception(Exception)] {...} | Finally.cs:203:13:210:13 | try {...} ... | -| Finally.cs:208:13:210:13 | [finally: exception(ExceptionA), finally(2): exception(ExceptionB)] {...} | Finally.cs:203:13:210:13 | try {...} ... | +| Finally.cs:208:13:210:13 | [finally: exception(ExceptionA), finally(1): exception(Exception)] {...} | Finally.cs:203:13:210:13 | try {...} ... | +| Finally.cs:208:13:210:13 | [finally: exception(ExceptionA), finally(1): exception(ExceptionB)] {...} | Finally.cs:203:13:210:13 | try {...} ... | | Finally.cs:208:13:210:13 | [finally: exception(ExceptionA)] {...} | Finally.cs:203:13:210:13 | try {...} ... | -| Finally.cs:209:17:209:47 | [finally(2): exception(Exception)] if (...) ... | Finally.cs:203:13:210:13 | try {...} ... | -| Finally.cs:209:17:209:47 | [finally(2): exception(ExceptionB)] if (...) ... | Finally.cs:203:13:210:13 | try {...} ... | -| Finally.cs:209:17:209:47 | [finally: exception(Exception), finally(2): exception(Exception)] if (...) ... | Finally.cs:203:13:210:13 | try {...} ... | -| Finally.cs:209:17:209:47 | [finally: exception(Exception), finally(2): exception(ExceptionB)] if (...) ... | Finally.cs:203:13:210:13 | try {...} ... | +| Finally.cs:209:17:209:47 | [finally(1): exception(Exception)] if (...) ... | Finally.cs:203:13:210:13 | try {...} ... | +| Finally.cs:209:17:209:47 | [finally(1): exception(ExceptionB)] if (...) ... | Finally.cs:203:13:210:13 | try {...} ... | +| Finally.cs:209:17:209:47 | [finally: exception(Exception), finally(1): exception(Exception)] if (...) ... | Finally.cs:203:13:210:13 | try {...} ... | +| Finally.cs:209:17:209:47 | [finally: exception(Exception), finally(1): exception(ExceptionB)] if (...) ... | Finally.cs:203:13:210:13 | try {...} ... | | Finally.cs:209:17:209:47 | [finally: exception(Exception)] if (...) ... | Finally.cs:203:13:210:13 | try {...} ... | -| Finally.cs:209:17:209:47 | [finally: exception(ExceptionA), finally(2): exception(Exception)] if (...) ... | Finally.cs:203:13:210:13 | try {...} ... | -| Finally.cs:209:17:209:47 | [finally: exception(ExceptionA), finally(2): exception(ExceptionB)] if (...) ... | Finally.cs:203:13:210:13 | try {...} ... | +| Finally.cs:209:17:209:47 | [finally: exception(ExceptionA), finally(1): exception(Exception)] if (...) ... | Finally.cs:203:13:210:13 | try {...} ... | +| Finally.cs:209:17:209:47 | [finally: exception(ExceptionA), finally(1): exception(ExceptionB)] if (...) ... | Finally.cs:203:13:210:13 | try {...} ... | | Finally.cs:209:17:209:47 | [finally: exception(ExceptionA)] if (...) ... | Finally.cs:203:13:210:13 | try {...} ... | -| Finally.cs:209:21:209:22 | [finally(2): exception(Exception)] access to parameter b3 | Finally.cs:203:13:210:13 | try {...} ... | -| Finally.cs:209:21:209:22 | [finally(2): exception(ExceptionB)] access to parameter b3 | Finally.cs:203:13:210:13 | try {...} ... | -| Finally.cs:209:21:209:22 | [finally: exception(Exception), finally(2): exception(Exception)] access to parameter b3 | Finally.cs:203:13:210:13 | try {...} ... | -| Finally.cs:209:21:209:22 | [finally: exception(Exception), finally(2): exception(ExceptionB)] access to parameter b3 | Finally.cs:203:13:210:13 | try {...} ... | +| Finally.cs:209:21:209:22 | [finally(1): exception(Exception)] access to parameter b3 | Finally.cs:203:13:210:13 | try {...} ... | +| Finally.cs:209:21:209:22 | [finally(1): exception(ExceptionB)] access to parameter b3 | Finally.cs:203:13:210:13 | try {...} ... | +| Finally.cs:209:21:209:22 | [finally: exception(Exception), finally(1): exception(Exception)] access to parameter b3 | Finally.cs:203:13:210:13 | try {...} ... | +| Finally.cs:209:21:209:22 | [finally: exception(Exception), finally(1): exception(ExceptionB)] access to parameter b3 | Finally.cs:203:13:210:13 | try {...} ... | | Finally.cs:209:21:209:22 | [finally: exception(Exception)] access to parameter b3 | Finally.cs:203:13:210:13 | try {...} ... | -| Finally.cs:209:21:209:22 | [finally: exception(ExceptionA), finally(2): exception(Exception)] access to parameter b3 | Finally.cs:203:13:210:13 | try {...} ... | -| Finally.cs:209:21:209:22 | [finally: exception(ExceptionA), finally(2): exception(ExceptionB)] access to parameter b3 | Finally.cs:203:13:210:13 | try {...} ... | +| Finally.cs:209:21:209:22 | [finally: exception(ExceptionA), finally(1): exception(Exception)] access to parameter b3 | Finally.cs:203:13:210:13 | try {...} ... | +| Finally.cs:209:21:209:22 | [finally: exception(ExceptionA), finally(1): exception(ExceptionB)] access to parameter b3 | Finally.cs:203:13:210:13 | try {...} ... | | Finally.cs:209:21:209:22 | [finally: exception(ExceptionA)] access to parameter b3 | Finally.cs:203:13:210:13 | try {...} ... | -| Finally.cs:209:25:209:47 | [finally(2): exception(Exception)] throw ...; | Finally.cs:203:13:210:13 | try {...} ... | -| Finally.cs:209:25:209:47 | [finally(2): exception(ExceptionB)] throw ...; | Finally.cs:203:13:210:13 | try {...} ... | -| Finally.cs:209:25:209:47 | [finally: exception(Exception), finally(2): exception(Exception)] throw ...; | Finally.cs:203:13:210:13 | try {...} ... | -| Finally.cs:209:25:209:47 | [finally: exception(Exception), finally(2): exception(ExceptionB)] throw ...; | Finally.cs:203:13:210:13 | try {...} ... | +| Finally.cs:209:25:209:47 | [finally(1): exception(Exception)] throw ...; | Finally.cs:203:13:210:13 | try {...} ... | +| Finally.cs:209:25:209:47 | [finally(1): exception(ExceptionB)] throw ...; | Finally.cs:203:13:210:13 | try {...} ... | +| Finally.cs:209:25:209:47 | [finally: exception(Exception), finally(1): exception(Exception)] throw ...; | Finally.cs:203:13:210:13 | try {...} ... | +| Finally.cs:209:25:209:47 | [finally: exception(Exception), finally(1): exception(ExceptionB)] throw ...; | Finally.cs:203:13:210:13 | try {...} ... | | Finally.cs:209:25:209:47 | [finally: exception(Exception)] throw ...; | Finally.cs:203:13:210:13 | try {...} ... | -| Finally.cs:209:25:209:47 | [finally: exception(ExceptionA), finally(2): exception(Exception)] throw ...; | Finally.cs:203:13:210:13 | try {...} ... | -| Finally.cs:209:25:209:47 | [finally: exception(ExceptionA), finally(2): exception(ExceptionB)] throw ...; | Finally.cs:203:13:210:13 | try {...} ... | +| Finally.cs:209:25:209:47 | [finally: exception(ExceptionA), finally(1): exception(Exception)] throw ...; | Finally.cs:203:13:210:13 | try {...} ... | +| Finally.cs:209:25:209:47 | [finally: exception(ExceptionA), finally(1): exception(ExceptionB)] throw ...; | Finally.cs:203:13:210:13 | try {...} ... | | Finally.cs:209:25:209:47 | [finally: exception(ExceptionA)] throw ...; | Finally.cs:203:13:210:13 | try {...} ... | -| Finally.cs:209:31:209:46 | [finally(2): exception(Exception)] object creation of type ExceptionC | Finally.cs:203:13:210:13 | try {...} ... | -| Finally.cs:209:31:209:46 | [finally(2): exception(ExceptionB)] object creation of type ExceptionC | Finally.cs:203:13:210:13 | try {...} ... | -| Finally.cs:209:31:209:46 | [finally: exception(Exception), finally(2): exception(Exception)] object creation of type ExceptionC | Finally.cs:203:13:210:13 | try {...} ... | -| Finally.cs:209:31:209:46 | [finally: exception(Exception), finally(2): exception(ExceptionB)] object creation of type ExceptionC | Finally.cs:203:13:210:13 | try {...} ... | +| Finally.cs:209:31:209:46 | [finally(1): exception(Exception)] object creation of type ExceptionC | Finally.cs:203:13:210:13 | try {...} ... | +| Finally.cs:209:31:209:46 | [finally(1): exception(ExceptionB)] object creation of type ExceptionC | Finally.cs:203:13:210:13 | try {...} ... | +| Finally.cs:209:31:209:46 | [finally: exception(Exception), finally(1): exception(Exception)] object creation of type ExceptionC | Finally.cs:203:13:210:13 | try {...} ... | +| Finally.cs:209:31:209:46 | [finally: exception(Exception), finally(1): exception(ExceptionB)] object creation of type ExceptionC | Finally.cs:203:13:210:13 | try {...} ... | | Finally.cs:209:31:209:46 | [finally: exception(Exception)] object creation of type ExceptionC | Finally.cs:203:13:210:13 | try {...} ... | -| Finally.cs:209:31:209:46 | [finally: exception(ExceptionA), finally(2): exception(Exception)] object creation of type ExceptionC | Finally.cs:203:13:210:13 | try {...} ... | -| Finally.cs:209:31:209:46 | [finally: exception(ExceptionA), finally(2): exception(ExceptionB)] object creation of type ExceptionC | Finally.cs:203:13:210:13 | try {...} ... | +| Finally.cs:209:31:209:46 | [finally: exception(ExceptionA), finally(1): exception(Exception)] object creation of type ExceptionC | Finally.cs:203:13:210:13 | try {...} ... | +| Finally.cs:209:31:209:46 | [finally: exception(ExceptionA), finally(1): exception(ExceptionB)] object creation of type ExceptionC | Finally.cs:203:13:210:13 | try {...} ... | | Finally.cs:209:31:209:46 | [finally: exception(ExceptionA)] object creation of type ExceptionC | Finally.cs:203:13:210:13 | try {...} ... | | Finally.cs:211:13:211:16 | [finally: exception(Exception)] this access | Finally.cs:197:9:212:9 | try {...} ... | | Finally.cs:211:13:211:16 | [finally: exception(ExceptionA)] this access | Finally.cs:197:9:212:9 | try {...} ... | @@ -983,6 +959,69 @@ finallyNode | Finally.cs:211:13:211:29 | [finally: exception(ExceptionA)] ...; | Finally.cs:197:9:212:9 | try {...} ... | | Finally.cs:211:26:211:28 | [finally: exception(Exception)] "0" | Finally.cs:197:9:212:9 | try {...} ... | | Finally.cs:211:26:211:28 | [finally: exception(ExceptionA)] "0" | Finally.cs:197:9:212:9 | try {...} ... | +| Finally.cs:243:13:253:13 | [finally: exception(Exception)] {...} | Finally.cs:237:13:253:13 | try {...} ... | +| Finally.cs:243:13:253:13 | [finally: exception(ExceptionA)] {...} | Finally.cs:237:13:253:13 | try {...} ... | +| Finally.cs:244:17:252:17 | [finally: exception(Exception)] try {...} ... | Finally.cs:237:13:253:13 | try {...} ... | +| Finally.cs:244:17:252:17 | [finally: exception(ExceptionA)] try {...} ... | Finally.cs:237:13:253:13 | try {...} ... | +| Finally.cs:245:17:248:17 | [finally: exception(Exception)] {...} | Finally.cs:237:13:253:13 | try {...} ... | +| Finally.cs:245:17:248:17 | [finally: exception(ExceptionA)] {...} | Finally.cs:237:13:253:13 | try {...} ... | +| Finally.cs:246:21:247:47 | [finally: exception(Exception)] if (...) ... | Finally.cs:237:13:253:13 | try {...} ... | +| Finally.cs:246:21:247:47 | [finally: exception(ExceptionA)] if (...) ... | Finally.cs:237:13:253:13 | try {...} ... | +| Finally.cs:246:25:246:26 | [finally: exception(Exception)] access to parameter b2 | Finally.cs:237:13:253:13 | try {...} ... | +| Finally.cs:246:25:246:26 | [finally: exception(ExceptionA)] access to parameter b2 | Finally.cs:237:13:253:13 | try {...} ... | +| Finally.cs:247:25:247:47 | [finally: exception(Exception)] throw ...; | Finally.cs:237:13:253:13 | try {...} ... | +| Finally.cs:247:25:247:47 | [finally: exception(ExceptionA)] throw ...; | Finally.cs:237:13:253:13 | try {...} ... | +| Finally.cs:247:31:247:46 | [finally: exception(Exception)] object creation of type ExceptionA | Finally.cs:237:13:253:13 | try {...} ... | +| Finally.cs:247:31:247:46 | [finally: exception(ExceptionA)] object creation of type ExceptionA | Finally.cs:237:13:253:13 | try {...} ... | +| Finally.cs:250:17:252:17 | [finally(1): exception(Exception)] {...} | Finally.cs:244:17:252:17 | try {...} ... | +| Finally.cs:250:17:252:17 | [finally(1): exception(ExceptionA)] {...} | Finally.cs:244:17:252:17 | try {...} ... | +| Finally.cs:250:17:252:17 | [finally: exception(Exception), finally(1): exception(Exception)] {...} | Finally.cs:244:17:252:17 | try {...} ... | +| Finally.cs:250:17:252:17 | [finally: exception(Exception), finally(1): exception(ExceptionA)] {...} | Finally.cs:244:17:252:17 | try {...} ... | +| Finally.cs:250:17:252:17 | [finally: exception(Exception)] {...} | Finally.cs:244:17:252:17 | try {...} ... | +| Finally.cs:250:17:252:17 | [finally: exception(ExceptionA), finally(1): exception(Exception)] {...} | Finally.cs:244:17:252:17 | try {...} ... | +| Finally.cs:250:17:252:17 | [finally: exception(ExceptionA), finally(1): exception(ExceptionA)] {...} | Finally.cs:244:17:252:17 | try {...} ... | +| Finally.cs:250:17:252:17 | [finally: exception(ExceptionA)] {...} | Finally.cs:244:17:252:17 | try {...} ... | +| Finally.cs:251:21:251:54 | [finally(1): exception(Exception)] call to method WriteLine | Finally.cs:244:17:252:17 | try {...} ... | +| Finally.cs:251:21:251:54 | [finally(1): exception(ExceptionA)] call to method WriteLine | Finally.cs:244:17:252:17 | try {...} ... | +| Finally.cs:251:21:251:54 | [finally: exception(Exception), finally(1): exception(Exception)] call to method WriteLine | Finally.cs:244:17:252:17 | try {...} ... | +| Finally.cs:251:21:251:54 | [finally: exception(Exception), finally(1): exception(ExceptionA)] call to method WriteLine | Finally.cs:244:17:252:17 | try {...} ... | +| Finally.cs:251:21:251:54 | [finally: exception(Exception)] call to method WriteLine | Finally.cs:244:17:252:17 | try {...} ... | +| Finally.cs:251:21:251:54 | [finally: exception(ExceptionA), finally(1): exception(Exception)] call to method WriteLine | Finally.cs:244:17:252:17 | try {...} ... | +| Finally.cs:251:21:251:54 | [finally: exception(ExceptionA), finally(1): exception(ExceptionA)] call to method WriteLine | Finally.cs:244:17:252:17 | try {...} ... | +| Finally.cs:251:21:251:54 | [finally: exception(ExceptionA)] call to method WriteLine | Finally.cs:244:17:252:17 | try {...} ... | +| Finally.cs:251:21:251:55 | [finally(1): exception(Exception)] ...; | Finally.cs:244:17:252:17 | try {...} ... | +| Finally.cs:251:21:251:55 | [finally(1): exception(ExceptionA)] ...; | Finally.cs:244:17:252:17 | try {...} ... | +| Finally.cs:251:21:251:55 | [finally: exception(Exception), finally(1): exception(Exception)] ...; | Finally.cs:244:17:252:17 | try {...} ... | +| Finally.cs:251:21:251:55 | [finally: exception(Exception), finally(1): exception(ExceptionA)] ...; | Finally.cs:244:17:252:17 | try {...} ... | +| Finally.cs:251:21:251:55 | [finally: exception(Exception)] ...; | Finally.cs:244:17:252:17 | try {...} ... | +| Finally.cs:251:21:251:55 | [finally: exception(ExceptionA), finally(1): exception(Exception)] ...; | Finally.cs:244:17:252:17 | try {...} ... | +| Finally.cs:251:21:251:55 | [finally: exception(ExceptionA), finally(1): exception(ExceptionA)] ...; | Finally.cs:244:17:252:17 | try {...} ... | +| Finally.cs:251:21:251:55 | [finally: exception(ExceptionA)] ...; | Finally.cs:244:17:252:17 | try {...} ... | +| Finally.cs:251:39:251:53 | [finally(1): exception(Exception)] "Inner finally" | Finally.cs:244:17:252:17 | try {...} ... | +| Finally.cs:251:39:251:53 | [finally(1): exception(ExceptionA)] "Inner finally" | Finally.cs:244:17:252:17 | try {...} ... | +| Finally.cs:251:39:251:53 | [finally: exception(Exception), finally(1): exception(Exception)] "Inner finally" | Finally.cs:244:17:252:17 | try {...} ... | +| Finally.cs:251:39:251:53 | [finally: exception(Exception), finally(1): exception(ExceptionA)] "Inner finally" | Finally.cs:244:17:252:17 | try {...} ... | +| Finally.cs:251:39:251:53 | [finally: exception(Exception)] "Inner finally" | Finally.cs:244:17:252:17 | try {...} ... | +| Finally.cs:251:39:251:53 | [finally: exception(ExceptionA), finally(1): exception(Exception)] "Inner finally" | Finally.cs:244:17:252:17 | try {...} ... | +| Finally.cs:251:39:251:53 | [finally: exception(ExceptionA), finally(1): exception(ExceptionA)] "Inner finally" | Finally.cs:244:17:252:17 | try {...} ... | +| Finally.cs:251:39:251:53 | [finally: exception(ExceptionA)] "Inner finally" | Finally.cs:244:17:252:17 | try {...} ... | +| Finally.cs:257:9:259:9 | [finally: exception(Exception)] {...} | Finally.cs:235:9:259:9 | try {...} ... | +| Finally.cs:257:9:259:9 | [finally: exception(ExceptionA)] {...} | Finally.cs:235:9:259:9 | try {...} ... | +| Finally.cs:258:13:258:46 | [finally: exception(Exception)] call to method WriteLine | Finally.cs:235:9:259:9 | try {...} ... | +| Finally.cs:258:13:258:46 | [finally: exception(ExceptionA)] call to method WriteLine | Finally.cs:235:9:259:9 | try {...} ... | +| Finally.cs:258:13:258:47 | [finally: exception(Exception)] ...; | Finally.cs:235:9:259:9 | try {...} ... | +| Finally.cs:258:13:258:47 | [finally: exception(ExceptionA)] ...; | Finally.cs:235:9:259:9 | try {...} ... | +| Finally.cs:258:31:258:45 | [finally: exception(Exception)] "Outer finally" | Finally.cs:235:9:259:9 | try {...} ... | +| Finally.cs:258:31:258:45 | [finally: exception(ExceptionA)] "Outer finally" | Finally.cs:235:9:259:9 | try {...} ... | +| Finally.cs:270:9:273:9 | [finally: exception(Exception)] {...} | Finally.cs:265:9:273:9 | try {...} ... | +| Finally.cs:271:13:271:34 | [finally: exception(Exception)] call to method WriteLine | Finally.cs:265:9:273:9 | try {...} ... | +| Finally.cs:271:13:271:35 | [finally: exception(Exception)] ...; | Finally.cs:265:9:273:9 | try {...} ... | +| Finally.cs:271:31:271:33 | [finally: exception(Exception)] "3" | Finally.cs:265:9:273:9 | try {...} ... | +| Finally.cs:272:13:272:13 | [finally: exception(Exception)] access to parameter i | Finally.cs:265:9:273:9 | try {...} ... | +| Finally.cs:272:13:272:18 | [finally: exception(Exception)] ... + ... | Finally.cs:265:9:273:9 | try {...} ... | +| Finally.cs:272:13:272:18 | [finally: exception(Exception)] ... = ... | Finally.cs:265:9:273:9 | try {...} ... | +| Finally.cs:272:13:272:19 | [finally: exception(Exception)] ...; | Finally.cs:265:9:273:9 | try {...} ... | +| Finally.cs:272:18:272:18 | [finally: exception(Exception)] 3 | Finally.cs:265:9:273:9 | try {...} ... | | cflow.cs:274:9:276:9 | [finally: return] {...} | cflow.cs:268:9:276:9 | try {...} ... | | cflow.cs:275:13:275:41 | [finally: return] call to method WriteLine | cflow.cs:268:9:276:9 | try {...} ... | | cflow.cs:275:13:275:42 | [finally: return] ...; | cflow.cs:268:9:276:9 | try {...} ... | @@ -1053,27 +1092,28 @@ entryPoint | Conditions.cs:113:10:113:11 | M9 | Conditions.cs:114:5:124:5 | {...} | | Conditions.cs:129:10:129:12 | M10 | Conditions.cs:130:5:141:5 | {...} | | Conditions.cs:143:10:143:12 | M11 | Conditions.cs:144:5:150:5 | {...} | -| ExitMethods.cs:7:10:7:11 | M1 | ExitMethods.cs:8:5:11:5 | {...} | -| ExitMethods.cs:13:10:13:11 | M2 | ExitMethods.cs:14:5:17:5 | {...} | -| ExitMethods.cs:19:10:19:11 | M3 | ExitMethods.cs:20:5:23:5 | {...} | -| ExitMethods.cs:25:10:25:11 | M4 | ExitMethods.cs:26:5:29:5 | {...} | -| ExitMethods.cs:31:10:31:11 | M5 | ExitMethods.cs:32:5:35:5 | {...} | -| ExitMethods.cs:37:10:37:11 | M6 | ExitMethods.cs:38:5:51:5 | {...} | -| ExitMethods.cs:53:10:53:11 | M7 | ExitMethods.cs:54:5:57:5 | {...} | -| ExitMethods.cs:59:10:59:11 | M8 | ExitMethods.cs:60:5:63:5 | {...} | -| ExitMethods.cs:65:17:65:26 | ErrorMaybe | ExitMethods.cs:66:5:69:5 | {...} | -| ExitMethods.cs:71:17:71:27 | ErrorAlways | ExitMethods.cs:72:5:77:5 | {...} | -| ExitMethods.cs:79:17:79:28 | ErrorAlways2 | ExitMethods.cs:80:5:82:5 | {...} | -| ExitMethods.cs:84:17:84:28 | ErrorAlways3 | ExitMethods.cs:84:41:84:55 | object creation of type Exception | -| ExitMethods.cs:86:10:86:13 | Exit | ExitMethods.cs:87:5:89:5 | {...} | -| ExitMethods.cs:91:10:91:18 | ExitInTry | ExitMethods.cs:92:5:102:5 | {...} | -| ExitMethods.cs:104:10:104:24 | ApplicationExit | ExitMethods.cs:105:5:107:5 | {...} | -| ExitMethods.cs:109:13:109:21 | ThrowExpr | ExitMethods.cs:110:5:112:5 | {...} | -| ExitMethods.cs:114:16:114:34 | ExtensionMethodCall | ExitMethods.cs:115:5:117:5 | {...} | -| ExitMethods.cs:119:17:119:32 | FailingAssertion | ExitMethods.cs:120:5:123:5 | {...} | -| ExitMethods.cs:125:17:125:33 | FailingAssertion2 | ExitMethods.cs:126:5:129:5 | {...} | -| ExitMethods.cs:131:10:131:20 | AssertFalse | ExitMethods.cs:131:48:131:48 | access to parameter b | -| ExitMethods.cs:133:17:133:33 | FailingAssertion3 | ExitMethods.cs:134:5:137:5 | {...} | +| ExitMethods.cs:8:10:8:11 | M1 | ExitMethods.cs:9:5:12:5 | {...} | +| ExitMethods.cs:14:10:14:11 | M2 | ExitMethods.cs:15:5:18:5 | {...} | +| ExitMethods.cs:20:10:20:11 | M3 | ExitMethods.cs:21:5:24:5 | {...} | +| ExitMethods.cs:26:10:26:11 | M4 | ExitMethods.cs:27:5:30:5 | {...} | +| ExitMethods.cs:32:10:32:11 | M5 | ExitMethods.cs:33:5:36:5 | {...} | +| ExitMethods.cs:38:10:38:11 | M6 | ExitMethods.cs:39:5:52:5 | {...} | +| ExitMethods.cs:54:10:54:11 | M7 | ExitMethods.cs:55:5:58:5 | {...} | +| ExitMethods.cs:60:10:60:11 | M8 | ExitMethods.cs:61:5:64:5 | {...} | +| ExitMethods.cs:66:17:66:26 | ErrorMaybe | ExitMethods.cs:67:5:70:5 | {...} | +| ExitMethods.cs:72:17:72:27 | ErrorAlways | ExitMethods.cs:73:5:78:5 | {...} | +| ExitMethods.cs:80:17:80:28 | ErrorAlways2 | ExitMethods.cs:81:5:83:5 | {...} | +| ExitMethods.cs:85:17:85:28 | ErrorAlways3 | ExitMethods.cs:85:41:85:55 | object creation of type Exception | +| ExitMethods.cs:87:10:87:13 | Exit | ExitMethods.cs:88:5:90:5 | {...} | +| ExitMethods.cs:92:10:92:18 | ExitInTry | ExitMethods.cs:93:5:103:5 | {...} | +| ExitMethods.cs:105:10:105:24 | ApplicationExit | ExitMethods.cs:106:5:108:5 | {...} | +| ExitMethods.cs:110:13:110:21 | ThrowExpr | ExitMethods.cs:111:5:113:5 | {...} | +| ExitMethods.cs:115:16:115:34 | ExtensionMethodCall | ExitMethods.cs:116:5:118:5 | {...} | +| ExitMethods.cs:120:17:120:32 | FailingAssertion | ExitMethods.cs:121:5:124:5 | {...} | +| ExitMethods.cs:126:17:126:33 | FailingAssertion2 | ExitMethods.cs:127:5:130:5 | {...} | +| ExitMethods.cs:132:10:132:20 | AssertFalse | ExitMethods.cs:132:48:132:48 | access to parameter b | +| ExitMethods.cs:134:17:134:33 | FailingAssertion3 | ExitMethods.cs:135:5:138:5 | {...} | +| ExitMethods.cs:140:17:140:42 | ExceptionDispatchInfoThrow | ExitMethods.cs:141:5:147:5 | {...} | | Extensions.cs:5:23:5:29 | ToInt32 | Extensions.cs:6:5:8:5 | {...} | | Extensions.cs:10:24:10:29 | ToBool | Extensions.cs:11:5:13:5 | {...} | | Extensions.cs:15:23:15:33 | CallToInt32 | Extensions.cs:15:48:15:50 | "0" | @@ -1089,6 +1129,8 @@ entryPoint | Finally.cs:176:10:176:11 | M9 | Finally.cs:177:5:193:5 | {...} | | Finally.cs:195:10:195:12 | M10 | Finally.cs:196:5:214:5 | {...} | | Finally.cs:216:10:216:12 | M11 | Finally.cs:217:5:231:5 | {...} | +| Finally.cs:233:10:233:12 | M12 | Finally.cs:234:5:261:5 | {...} | +| Finally.cs:263:10:263:12 | M13 | Finally.cs:264:5:274:5 | {...} | | Foreach.cs:6:10:6:11 | M1 | Foreach.cs:7:5:10:5 | {...} | | Foreach.cs:12:10:12:11 | M2 | Foreach.cs:13:5:16:5 | {...} | | Foreach.cs:18:10:18:11 | M3 | Foreach.cs:19:5:22:5 | {...} | @@ -1177,7 +1219,16 @@ entryPoint | NullCoalescing.cs:9:12:9:13 | M4 | NullCoalescing.cs:9:37:9:37 | access to parameter b | | NullCoalescing.cs:11:9:11:10 | M5 | NullCoalescing.cs:11:44:11:45 | access to parameter b1 | | NullCoalescing.cs:13:10:13:11 | M6 | NullCoalescing.cs:14:5:18:5 | {...} | -| Patterns.cs:5:10:5:13 | Test | Patterns.cs:6:5:43:5 | {...} | +| Patterns.cs:5:10:5:11 | M1 | Patterns.cs:6:5:43:5 | {...} | +| Patterns.cs:47:24:47:25 | M2 | Patterns.cs:48:9:48:9 | access to parameter c | +| Patterns.cs:50:24:50:25 | M3 | Patterns.cs:51:9:51:9 | access to parameter c | +| Patterns.cs:53:24:53:25 | M4 | Patterns.cs:54:9:54:9 | access to parameter c | +| Patterns.cs:56:26:56:27 | M5 | Patterns.cs:57:5:63:5 | {...} | +| Patterns.cs:65:26:65:27 | M6 | Patterns.cs:66:5:72:5 | {...} | +| Patterns.cs:74:26:74:27 | M7 | Patterns.cs:75:5:83:5 | {...} | +| Patterns.cs:85:26:85:27 | M8 | Patterns.cs:85:39:85:39 | access to parameter i | +| Patterns.cs:87:26:87:27 | M9 | Patterns.cs:87:39:87:39 | access to parameter i | +| Patterns.cs:93:17:93:19 | M10 | Patterns.cs:94:5:99:5 | {...} | | PostDominance.cs:5:10:5:11 | M1 | PostDominance.cs:6:5:8:5 | {...} | | PostDominance.cs:10:10:10:11 | M2 | PostDominance.cs:11:5:15:5 | {...} | | PostDominance.cs:17:10:17:11 | M3 | PostDominance.cs:18:5:22:5 | {...} | diff --git a/csharp/ql/test/library-tests/controlflow/graph/Nodes.ql b/csharp/ql/test/library-tests/controlflow/graph/Nodes.ql index 9ffd6f48cba..b391aaa3259 100644 --- a/csharp/ql/test/library-tests/controlflow/graph/Nodes.ql +++ b/csharp/ql/test/library-tests/controlflow/graph/Nodes.ql @@ -16,9 +16,7 @@ class MyFinallySplitControlFlowNode extends ElementNode { ) } - TryStmt getTryStmt() { - this.getElement() = Splitting::FinallySplitting::getAFinallyDescendant(result) - } + Statements::TryStmtTree getTryStmt() { this.getElement() = result.getAFinallyDescendant() } } query predicate finallyNode(MyFinallySplitControlFlowNode f, TryStmt try) { try = f.getTryStmt() } diff --git a/csharp/ql/test/library-tests/controlflow/graph/Patterns.cs b/csharp/ql/test/library-tests/controlflow/graph/Patterns.cs index 70bf7e29063..72d17592b74 100644 --- a/csharp/ql/test/library-tests/controlflow/graph/Patterns.cs +++ b/csharp/ql/test/library-tests/controlflow/graph/Patterns.cs @@ -2,7 +2,7 @@ using System; class Patterns { - void Test() + void M1() { object o = null; if (o is int i1) @@ -41,4 +41,60 @@ class Patterns { } } + + public int P1 { get; set; } + + public static bool M2(char c) => + c is not 'a'; + + public static bool M3(object c) => + c is not null ? c is 1 : c is 2; + + public static bool M4(object c) => + c is not Patterns { P1: 1 } u; + + public static string M5(int i) + { + return i switch + { + not 1 => "not 1", + _ => "other" + }; + } + + public static string M6() + { + return 2 switch + { + not 2 => "impossible", + 2 => "possible" + }; + } + + public static string M7(int i) + { + return i switch + { + > 1 => "> 1", + < 0 => "< 0", + 1 => "1", + _ => "0" + }; + } + + public static string M8(int i) => i is 1 or not 2 ? "not 2" : "2"; + + public static string M9(int i) => i is 1 and not 2 ? "1" : "not 1"; + + public E Prop { get; set; } + + public enum E { A, B, C } + + public void M10() + { + if (this is { Prop: E.A or E.B }) + { + Console.WriteLine("not C"); + } + } } diff --git a/csharp/ql/test/library-tests/controlflow/guards/AbstractValue.expected b/csharp/ql/test/library-tests/controlflow/guards/AbstractValue.expected index 1dd7f2c4da4..2303633e4f4 100644 --- a/csharp/ql/test/library-tests/controlflow/guards/AbstractValue.expected +++ b/csharp/ql/test/library-tests/controlflow/guards/AbstractValue.expected @@ -370,6 +370,7 @@ abstractValue | non-null | Guards.cs:341:31:341:32 | "" | | non-null | Guards.cs:343:13:343:19 | access to type Console | | non-null | Guards.cs:343:31:343:31 | access to local variable s | +| non-null | Guards.cs:349:13:349:13 | access to parameter o | | non-null | Splitting.cs:13:17:13:17 | access to parameter o | | non-null | Splitting.cs:23:24:23:24 | access to parameter o | | non-null | Splitting.cs:33:24:33:25 | "" | diff --git a/csharp/ql/test/library-tests/controlflow/guards/BooleanGuardedExpr.expected b/csharp/ql/test/library-tests/controlflow/guards/BooleanGuardedExpr.expected index f87600ebed5..120e3e2c5ce 100644 --- a/csharp/ql/test/library-tests/controlflow/guards/BooleanGuardedExpr.expected +++ b/csharp/ql/test/library-tests/controlflow/guards/BooleanGuardedExpr.expected @@ -103,6 +103,7 @@ | Guards.cs:342:27:342:27 | access to parameter b | Guards.cs:341:20:341:20 | access to parameter b | Guards.cs:341:20:341:20 | access to parameter b | false | | Guards.cs:343:31:343:31 | access to local variable s | Guards.cs:342:13:342:21 | ... != ... | Guards.cs:342:13:342:13 | access to local variable s | true | | Guards.cs:343:31:343:31 | access to local variable s | Guards.cs:342:13:342:27 | ... && ... | Guards.cs:342:13:342:13 | access to local variable s | true | +| Guards.cs:349:13:349:13 | access to parameter o | Guards.cs:348:13:348:25 | ... is ... | Guards.cs:348:13:348:13 | access to parameter o | true | | Splitting.cs:13:17:13:17 | access to parameter o | Splitting.cs:12:17:12:25 | ... != ... | Splitting.cs:12:17:12:17 | access to parameter o | true | | Splitting.cs:23:24:23:24 | access to parameter o | Splitting.cs:22:17:22:25 | ... != ... | Splitting.cs:22:17:22:17 | access to parameter o | true | | Splitting.cs:25:13:25:13 | access to parameter o | Splitting.cs:22:17:22:25 | ... != ... | Splitting.cs:22:17:22:17 | access to parameter o | false | diff --git a/csharp/ql/test/library-tests/controlflow/guards/ExtractorOptions.cs b/csharp/ql/test/library-tests/controlflow/guards/ExtractorOptions.cs index 5b68aaea481..3353234761a 100644 --- a/csharp/ql/test/library-tests/controlflow/guards/ExtractorOptions.cs +++ b/csharp/ql/test/library-tests/controlflow/guards/ExtractorOptions.cs @@ -1,2 +1,2 @@ -// semmle-extractor-options: --cil /langversion:8.0 +// semmle-extractor-options: --cil #nullable enable diff --git a/csharp/ql/test/library-tests/controlflow/guards/GuardedControlFlowNode.expected b/csharp/ql/test/library-tests/controlflow/guards/GuardedControlFlowNode.expected index 8f0a09d0389..3db5997056c 100644 --- a/csharp/ql/test/library-tests/controlflow/guards/GuardedControlFlowNode.expected +++ b/csharp/ql/test/library-tests/controlflow/guards/GuardedControlFlowNode.expected @@ -242,6 +242,8 @@ | Guards.cs:343:31:343:31 | access to local variable s | Guards.cs:342:13:342:13 | access to local variable s | Guards.cs:342:13:342:13 | access to local variable s | non-null | | Guards.cs:343:31:343:31 | access to local variable s | Guards.cs:342:13:342:21 | ... != ... | Guards.cs:342:13:342:13 | access to local variable s | true | | Guards.cs:343:31:343:31 | access to local variable s | Guards.cs:342:13:342:27 | ... && ... | Guards.cs:342:13:342:13 | access to local variable s | true | +| Guards.cs:349:13:349:13 | access to parameter o | Guards.cs:348:13:348:13 | access to parameter o | Guards.cs:348:13:348:13 | access to parameter o | non-null | +| Guards.cs:349:13:349:13 | access to parameter o | Guards.cs:348:13:348:25 | ... is ... | Guards.cs:348:13:348:13 | access to parameter o | true | | Splitting.cs:13:17:13:17 | [b (line 9): true] access to parameter o | Splitting.cs:12:17:12:17 | access to parameter o | Splitting.cs:12:17:12:17 | access to parameter o | non-null | | Splitting.cs:13:17:13:17 | [b (line 9): true] access to parameter o | Splitting.cs:12:17:12:25 | ... != ... | Splitting.cs:12:17:12:17 | access to parameter o | true | | Splitting.cs:14:13:14:13 | [b (line 9): false] access to parameter b | Splitting.cs:11:13:11:13 | access to parameter b | Splitting.cs:11:13:11:13 | access to parameter b | false | diff --git a/csharp/ql/test/library-tests/controlflow/guards/GuardedExpr.expected b/csharp/ql/test/library-tests/controlflow/guards/GuardedExpr.expected index 05537dcf8d9..aad97097f21 100644 --- a/csharp/ql/test/library-tests/controlflow/guards/GuardedExpr.expected +++ b/csharp/ql/test/library-tests/controlflow/guards/GuardedExpr.expected @@ -223,6 +223,8 @@ | Guards.cs:343:31:343:31 | access to local variable s | Guards.cs:342:13:342:13 | access to local variable s | Guards.cs:342:13:342:13 | access to local variable s | non-null | | Guards.cs:343:31:343:31 | access to local variable s | Guards.cs:342:13:342:21 | ... != ... | Guards.cs:342:13:342:13 | access to local variable s | true | | Guards.cs:343:31:343:31 | access to local variable s | Guards.cs:342:13:342:27 | ... && ... | Guards.cs:342:13:342:13 | access to local variable s | true | +| Guards.cs:349:13:349:13 | access to parameter o | Guards.cs:348:13:348:13 | access to parameter o | Guards.cs:348:13:348:13 | access to parameter o | non-null | +| Guards.cs:349:13:349:13 | access to parameter o | Guards.cs:348:13:348:25 | ... is ... | Guards.cs:348:13:348:13 | access to parameter o | true | | Splitting.cs:13:17:13:17 | access to parameter o | Splitting.cs:12:17:12:17 | access to parameter o | Splitting.cs:12:17:12:17 | access to parameter o | non-null | | Splitting.cs:13:17:13:17 | access to parameter o | Splitting.cs:12:17:12:25 | ... != ... | Splitting.cs:12:17:12:17 | access to parameter o | true | | Splitting.cs:23:24:23:24 | access to parameter o | Splitting.cs:22:17:22:17 | access to parameter o | Splitting.cs:22:17:22:17 | access to parameter o | non-null | diff --git a/csharp/ql/test/library-tests/controlflow/guards/Guards.cs b/csharp/ql/test/library-tests/controlflow/guards/Guards.cs index 0c4563b3c9f..3e1008b1971 100644 --- a/csharp/ql/test/library-tests/controlflow/guards/Guards.cs +++ b/csharp/ql/test/library-tests/controlflow/guards/Guards.cs @@ -342,5 +342,11 @@ public class Guards if (s != null && !b) Console.WriteLine(s.Length); // null guarded } + + void M29(object? o) + { + if (o is not null) + o.ToString(); // null guarded + } } diff --git a/csharp/ql/test/library-tests/controlflow/guards/Implications.expected b/csharp/ql/test/library-tests/controlflow/guards/Implications.expected index 00e09ccfbda..ee5a0bb7017 100644 --- a/csharp/ql/test/library-tests/controlflow/guards/Implications.expected +++ b/csharp/ql/test/library-tests/controlflow/guards/Implications.expected @@ -442,6 +442,7 @@ | Guards.cs:342:26:342:27 | !... | true | Guards.cs:342:27:342:27 | access to parameter b | false | | Guards.cs:343:31:343:31 | access to local variable s | non-null | Guards.cs:341:20:341:32 | ... ? ... : ... | non-null | | Guards.cs:343:31:343:31 | access to local variable s | null | Guards.cs:341:20:341:32 | ... ? ... : ... | null | +| Guards.cs:348:13:348:25 | ... is ... | true | Guards.cs:348:13:348:13 | access to parameter o | non-null | | Splitting.cs:12:17:12:25 | ... != ... | false | Splitting.cs:12:17:12:17 | access to parameter o | null | | Splitting.cs:12:17:12:25 | ... != ... | true | Splitting.cs:12:17:12:17 | access to parameter o | non-null | | Splitting.cs:22:17:22:25 | ... != ... | false | Splitting.cs:22:17:22:17 | access to parameter o | null | diff --git a/csharp/ql/test/library-tests/controlflow/guards/NullGuardedExpr.expected b/csharp/ql/test/library-tests/controlflow/guards/NullGuardedExpr.expected index eea5a4dadd3..fa21b5cb312 100644 --- a/csharp/ql/test/library-tests/controlflow/guards/NullGuardedExpr.expected +++ b/csharp/ql/test/library-tests/controlflow/guards/NullGuardedExpr.expected @@ -46,6 +46,7 @@ | Guards.cs:283:17:283:17 | access to parameter o | | Guards.cs:287:17:287:17 | access to parameter o | | Guards.cs:343:31:343:31 | access to local variable s | +| Guards.cs:349:13:349:13 | access to parameter o | | Splitting.cs:13:17:13:17 | access to parameter o | | Splitting.cs:23:24:23:24 | access to parameter o | | Splitting.cs:35:13:35:13 | access to parameter o | diff --git a/csharp/ql/test/library-tests/csharp6/PrintAst.expected b/csharp/ql/test/library-tests/csharp6/PrintAst.expected index 5655f862738..675f15a5c45 100644 --- a/csharp/ql/test/library-tests/csharp6/PrintAst.expected +++ b/csharp/ql/test/library-tests/csharp6/PrintAst.expected @@ -141,7 +141,7 @@ csharp6.cs: # 57| -1: [TypeMention] Dictionary<Int32, String> # 57| 1: [TypeMention] int # 57| 2: [TypeMention] string -# 58| 6: [IndexerProperty] DictionaryProperty +# 58| 6: [Property] DictionaryProperty # 58| -1: [TypeMention] Dictionary<Int32, String> # 58| 1: [TypeMention] int # 58| 2: [TypeMention] string diff --git a/csharp/ql/test/library-tests/csharp7/IsFlow.expected b/csharp/ql/test/library-tests/csharp7/IsFlow.expected index f61853bd4de..18b1fa2615f 100644 --- a/csharp/ql/test/library-tests/csharp7/IsFlow.expected +++ b/csharp/ql/test/library-tests/csharp7/IsFlow.expected @@ -16,9 +16,10 @@ | CSharp7.cs:256:18:256:20 | "x" | CSharp7.cs:256:27:256:27 | access to local variable o | semmle.label | match | | CSharp7.cs:256:18:256:20 | "x" | CSharp7.cs:259:13:259:36 | case ...: | semmle.label | no-match | | CSharp7.cs:256:27:256:27 | access to local variable o | CSharp7.cs:256:32:256:40 | String s4 | semmle.label | successor | -| CSharp7.cs:256:27:256:40 | ... is ... | CSharp7.cs:257:17:257:45 | ...; | semmle.label | true | -| CSharp7.cs:256:27:256:40 | ... is ... | CSharp7.cs:259:13:259:36 | case ...: | semmle.label | false | -| CSharp7.cs:256:32:256:40 | String s4 | CSharp7.cs:256:27:256:40 | ... is ... | semmle.label | successor | +| CSharp7.cs:256:27:256:40 | [false] ... is ... | CSharp7.cs:259:13:259:36 | case ...: | semmle.label | false | +| CSharp7.cs:256:27:256:40 | [true] ... is ... | CSharp7.cs:257:17:257:45 | ...; | semmle.label | true | +| CSharp7.cs:256:32:256:40 | String s4 | CSharp7.cs:256:27:256:40 | [false] ... is ... | semmle.label | no-match | +| CSharp7.cs:256:32:256:40 | String s4 | CSharp7.cs:256:27:256:40 | [true] ... is ... | semmle.label | match | | CSharp7.cs:257:17:257:44 | call to method WriteLine | CSharp7.cs:258:17:258:22 | break; | semmle.label | successor | | CSharp7.cs:257:17:257:45 | ...; | CSharp7.cs:257:37:257:38 | "x " | semmle.label | successor | | CSharp7.cs:257:35:257:43 | $"..." | CSharp7.cs:257:17:257:44 | call to method WriteLine | semmle.label | successor | diff --git a/csharp/ql/test/library-tests/csharp7/LocalTaintFlow.expected b/csharp/ql/test/library-tests/csharp7/LocalTaintFlow.expected index acce87f5c60..590c31f4510 100644 --- a/csharp/ql/test/library-tests/csharp7/LocalTaintFlow.expected +++ b/csharp/ql/test/library-tests/csharp7/LocalTaintFlow.expected @@ -1,9 +1,11 @@ +| CSharp7.cs:7:7:7:14 | this | CSharp7.cs:9:9:9:9 | this access | | CSharp7.cs:9:9:9:9 | [post] this access | CSharp7.cs:10:9:10:9 | this access | | CSharp7.cs:9:9:9:9 | this access | CSharp7.cs:10:9:10:9 | this access | | CSharp7.cs:10:9:10:9 | [post] this access | CSharp7.cs:11:9:11:9 | this access | | CSharp7.cs:10:9:10:9 | this access | CSharp7.cs:11:9:11:9 | this access | | CSharp7.cs:16:9:16:13 | [post] this access | CSharp7.cs:25:39:25:43 | this access | | CSharp7.cs:16:9:16:13 | this access | CSharp7.cs:25:39:25:43 | this access | +| CSharp7.cs:17:9:17:11 | SSA entry def(this.field) | CSharp7.cs:17:18:17:22 | access to field field | | CSharp7.cs:17:9:17:11 | this | CSharp7.cs:17:18:17:22 | this access | | CSharp7.cs:21:9:21:11 | this | CSharp7.cs:21:16:21:20 | this access | | CSharp7.cs:22:9:22:11 | this | CSharp7.cs:22:16:22:20 | this access | @@ -67,6 +69,7 @@ | CSharp7.cs:84:23:84:23 | 2 | CSharp7.cs:84:16:84:24 | (..., ...) | | CSharp7.cs:87:10:87:18 | this | CSharp7.cs:92:18:92:28 | this access | | CSharp7.cs:89:13:89:34 | SSA def(t1) | CSharp7.cs:90:28:90:29 | access to local variable t1 | +| CSharp7.cs:89:13:89:34 | SSA qualifier def(t1.Item1) | CSharp7.cs:92:20:92:27 | access to field Item1 | | CSharp7.cs:89:18:89:34 | (..., ...) | CSharp7.cs:89:13:89:34 | SSA def(t1) | | CSharp7.cs:89:19:89:27 | "tainted" | CSharp7.cs:89:18:89:34 | (..., ...) | | CSharp7.cs:89:30:89:33 | "X2" | CSharp7.cs:89:18:89:34 | (..., ...) | @@ -100,6 +103,7 @@ | CSharp7.cs:112:31:112:32 | access to local variable m2 | CSharp7.cs:112:26:112:33 | (..., ...) | | CSharp7.cs:114:9:114:67 | SSA def(m9) | CSharp7.cs:115:19:115:20 | access to local variable m9 | | CSharp7.cs:114:38:114:67 | SSA def(m2) | CSharp7.cs:118:9:118:10 | access to local variable m2 | +| CSharp7.cs:114:38:114:67 | SSA qualifier def(m2.Item1) | CSharp7.cs:119:19:119:26 | access to field Item1 | | CSharp7.cs:114:49:114:67 | (..., ...) | CSharp7.cs:114:38:114:67 | ... = ... | | CSharp7.cs:114:50:114:58 | "DefUse2" | CSharp7.cs:114:49:114:67 | (..., ...) | | CSharp7.cs:114:61:114:66 | (..., ...) | CSharp7.cs:114:38:114:67 | SSA def(m2) | @@ -190,8 +194,9 @@ | CSharp7.cs:235:13:235:13 | access to local variable o | CSharp7.cs:235:18:235:23 | SSA def(i1) | | CSharp7.cs:235:13:235:13 | access to local variable o | CSharp7.cs:239:18:239:18 | access to local variable o | | CSharp7.cs:235:13:235:13 | access to local variable o | CSharp7.cs:250:17:250:17 | access to local variable o | -| CSharp7.cs:235:13:235:23 | ... is ... | CSharp7.cs:235:13:235:33 | [false] ... && ... | -| CSharp7.cs:235:13:235:23 | ... is ... | CSharp7.cs:235:13:235:33 | [true] ... && ... | +| CSharp7.cs:235:13:235:23 | [false] ... is ... | CSharp7.cs:235:13:235:33 | [false] ... && ... | +| CSharp7.cs:235:13:235:23 | [true] ... is ... | CSharp7.cs:235:13:235:33 | [false] ... && ... | +| CSharp7.cs:235:13:235:23 | [true] ... is ... | CSharp7.cs:235:13:235:33 | [true] ... && ... | | CSharp7.cs:235:18:235:23 | SSA def(i1) | CSharp7.cs:235:28:235:29 | access to local variable i1 | | CSharp7.cs:235:28:235:29 | access to local variable i1 | CSharp7.cs:235:28:235:33 | ... > ... | | CSharp7.cs:235:28:235:29 | access to local variable i1 | CSharp7.cs:237:38:237:39 | access to local variable i1 | @@ -248,7 +253,7 @@ | CSharp7.cs:299:25:299:30 | ... < ... | CSharp7.cs:299:25:299:44 | [true] ... && ... | | CSharp7.cs:299:35:299:35 | access to local variable x | CSharp7.cs:299:40:299:44 | SSA def(y) | | CSharp7.cs:299:35:299:35 | access to local variable x | CSharp7.cs:299:49:299:49 | access to local variable x | -| CSharp7.cs:299:35:299:44 | ... is ... | CSharp7.cs:299:25:299:44 | [false] ... && ... | -| CSharp7.cs:299:35:299:44 | ... is ... | CSharp7.cs:299:25:299:44 | [true] ... && ... | +| CSharp7.cs:299:35:299:44 | [false] ... is ... | CSharp7.cs:299:25:299:44 | [false] ... && ... | +| CSharp7.cs:299:35:299:44 | [true] ... is ... | CSharp7.cs:299:25:299:44 | [true] ... && ... | | CSharp7.cs:299:40:299:44 | SSA def(y) | CSharp7.cs:301:31:301:31 | access to local variable y | | CSharp7.cs:299:47:299:49 | SSA def(x) | CSharp7.cs:299:25:299:25 | SSA phi(x) | diff --git a/csharp/ql/test/library-tests/csharp8/PrintAst.expected b/csharp/ql/test/library-tests/csharp8/PrintAst.expected index b392bec6dc7..d38d183151d 100644 --- a/csharp/ql/test/library-tests/csharp8/PrintAst.expected +++ b/csharp/ql/test/library-tests/csharp8/PrintAst.expected @@ -74,10 +74,10 @@ AsyncStreams.cs: # 42| 1: [TypeMention] bool DefaultInterfaceMethods.cs: # 3| [Interface] IPerson -# 5| 4: [IndexerProperty] Name +# 5| 4: [Property] Name # 5| -1: [TypeMention] string # 5| 3: [Getter] get_Name -# 7| 5: [IndexerProperty] Greeting +# 7| 5: [Property] Greeting # 7| -1: [TypeMention] string # 9| 3: [Getter] get_Greeting # 9| 4: [StringLiteral] "Hello" @@ -95,7 +95,7 @@ DefaultInterfaceMethods.cs: # 13| 0: [PropertyCall] access to property Greeting # 13| 1: [StringLiteral] " " # 13| 1: [ParameterAccess] access to parameter name -# 15| 7: [IndexerProperty] GreetingString +# 15| 7: [Property] GreetingString # 15| -1: [TypeMention] string # 15| 3: [Getter] get_GreetingString # 15| 4: [MethodCall] call to method Greet @@ -105,11 +105,11 @@ DefaultInterfaceMethods.cs: # 20| [Class] Person #-----| 3: (Base types) # 20| 1: [TypeMention] IPerson -# 22| 5: [IndexerProperty] Name +# 22| 5: [Property] Name # 22| -1: [TypeMention] string # 22| 3: [Getter] get_Name # 22| 4: [StringLiteral] "Petra" -# 24| 6: [IndexerProperty] Greeting +# 24| 6: [Property] Greeting # 24| -1: [TypeMention] IPerson # 24| -1: [TypeMention] string # 24| 3: [Getter] get_Greeting @@ -141,11 +141,11 @@ NullableRefTypes.cs: # 9| -1: [TypeMention] MyClass # 10| 6: [Field] B # 10| -1: [TypeMention] MyClass -# 13| 7: [IndexerProperty] C +# 13| 7: [Property] C # 13| -1: [TypeMention] MyClass # 13| 3: [Getter] get_C # 13| 4: [NullLiteral] null -# 14| 8: [IndexerProperty] D +# 14| 8: [Property] D # 14| -1: [TypeMention] MyClass # 14| 3: [Getter] get_D # 14| 4: [ThisAccess] this access @@ -417,7 +417,7 @@ NullableRefTypes.cs: # 110| 0: [NullLiteral] null # 112| 12: [Field] Property # 112| -1: [TypeMention] MyClass -# 113| 13: [IndexerProperty] RefProperty +# 113| 13: [Property] RefProperty # 113| -1: [TypeMention] MyClass # 113| 3: [Getter] get_RefProperty # 113| 4: [RefExpr] ref ... @@ -502,7 +502,7 @@ NullableRefTypes.cs: # 154| [Class] DisabledNullability # 156| 5: [Field] f1 # 156| -1: [TypeMention] MyClass -# 157| 6: [IndexerProperty] P +# 157| 6: [Property] P # 157| -1: [TypeMention] MyClass # 157| 3: [Getter] get_P # 157| 4: [ObjectCreation] object creation of type MyClass @@ -754,8 +754,8 @@ patterns.cs: # 13| 0: [IsExpr] ... is ... # 13| 0: [LocalVariableAccess] access to local variable o # 13| 1: [RecursivePatternExpr] { ... } -# 13| 0: [LocalVariableDeclExpr] MyStruct s -# 13| 1: [TypeAccess] access to type MyStruct +# 13| 0: [VariablePatternExpr] MyStruct s +# 13| 1: [TypeAccessPatternExpr] access to type MyStruct # 13| 0: [TypeMention] MyStruct # 13| 3: [PropertyPatternExpr] { ... } # 13| 0: [LabeledPatternExpr,VariablePatternExpr] Int32 x @@ -772,14 +772,14 @@ patterns.cs: # 17| 0: [IsExpr] ... is ... # 17| 0: [LocalVariableAccess] access to local variable o # 17| 1: [RecursivePatternExpr] { ... } -# 17| 0: [LocalVariableDeclExpr] Object p +# 17| 0: [VariablePatternExpr] Object p # 17| 3: [PropertyPatternExpr] { ... } # 18| 1: [BlockStmt] {...} # 22| 4: [IfStmt] if (...) ... # 22| 0: [IsExpr] ... is ... # 22| 0: [LocalVariableAccess] access to local variable o # 22| 1: [RecursivePatternExpr] { ... } -# 22| 1: [TypeAccess] access to type MyStruct +# 22| 1: [TypeAccessPatternExpr] access to type MyStruct # 22| 0: [TypeMention] MyStruct # 22| 3: [PropertyPatternExpr] { ... } # 22| 0: [ConstantPatternExpr,IntLiteral,LabeledPatternExpr] 12 @@ -791,13 +791,13 @@ patterns.cs: # 27| 0: [IsExpr] ... is ... # 27| 0: [LocalVariableAccess] access to local variable o # 27| 1: [RecursivePatternExpr] { ... } -# 27| 1: [TypeAccess] access to type MyStruct +# 27| 1: [TypeAccessPatternExpr] access to type MyStruct # 27| 0: [TypeMention] MyStruct # 27| 3: [PropertyPatternExpr] { ... } # 27| 0: [ConstantPatternExpr,IntLiteral,LabeledPatternExpr] 12 # 27| 1: [LabeledPatternExpr,RecursivePatternExpr] { ... } -# 27| 0: [LocalVariableDeclExpr] MyStruct ms -# 27| 1: [TypeAccess] access to type MyStruct +# 27| 0: [VariablePatternExpr] MyStruct ms +# 27| 1: [TypeAccessPatternExpr] access to type MyStruct # 27| 0: [TypeMention] MyStruct # 27| 3: [PropertyPatternExpr] { ... } # 27| 0: [DiscardPatternExpr,LabeledPatternExpr] _ @@ -847,7 +847,7 @@ patterns.cs: # 46| 0: [LocalVariableAccess] access to local variable s # 48| 0: [CaseStmt] case ...: # 48| 0: [RecursivePatternExpr] { ... } -# 48| 1: [TypeAccess] access to type MyStruct +# 48| 1: [TypeAccessPatternExpr] access to type MyStruct # 48| 0: [TypeMention] MyStruct # 48| 3: [PropertyPatternExpr] { ... } # 48| 0: [LabeledPatternExpr,VariablePatternExpr] Int32 x @@ -863,8 +863,8 @@ patterns.cs: # 50| 2: [BreakStmt] break; # 51| 3: [CaseStmt] case ...: # 51| 0: [RecursivePatternExpr] { ... } -# 51| 0: [LocalVariableDeclExpr] MyStruct ms -# 51| 1: [TypeAccess] access to type MyStruct +# 51| 0: [VariablePatternExpr] MyStruct ms +# 51| 1: [TypeAccessPatternExpr] access to type MyStruct # 51| 0: [TypeMention] MyStruct # 51| 3: [PropertyPatternExpr] { ... } # 51| 0: [ConstantPatternExpr,IntLiteral,LabeledPatternExpr] 10 @@ -905,7 +905,7 @@ patterns.cs: # 65| 0: [LocalVariableAccess] access to local variable s # 67| 0: [CaseStmt] case ...: # 67| 0: [RecursivePatternExpr] { ... } -# 67| 1: [TypeAccess] access to type MyStruct +# 67| 1: [TypeAccessPatternExpr] access to type MyStruct # 67| 0: [TypeMention] MyStruct # 67| 3: [PropertyPatternExpr] { ... } # 67| 0: [LabeledPatternExpr,VariablePatternExpr] Int32 x @@ -921,8 +921,8 @@ patterns.cs: # 69| 2: [BreakStmt] break; # 70| 3: [CaseStmt] case ...: # 70| 0: [RecursivePatternExpr] { ... } -# 70| 0: [LocalVariableDeclExpr] MyStruct ms -# 70| 1: [TypeAccess] access to type MyStruct +# 70| 0: [VariablePatternExpr] MyStruct ms +# 70| 1: [TypeAccessPatternExpr] access to type MyStruct # 70| 0: [TypeMention] MyStruct # 70| 3: [PropertyPatternExpr] { ... } # 70| 0: [ConstantPatternExpr,IntLiteral,LabeledPatternExpr] 10 @@ -1098,7 +1098,7 @@ patterns.cs: # 126| -1: [LocalVariableAccess] access to local variable s # 128| 0: [SwitchCaseExpr] ... => ... # 128| 0: [RecursivePatternExpr] { ... } -# 128| 1: [TypeAccess] access to type MyStruct +# 128| 1: [TypeAccessPatternExpr] access to type MyStruct # 128| 0: [TypeMention] MyStruct # 128| 3: [PropertyPatternExpr] { ... } # 128| 0: [LabeledPatternExpr,VariablePatternExpr] Int32 x @@ -1109,8 +1109,8 @@ patterns.cs: # 128| 2: [IntLiteral] 0 # 129| 1: [SwitchCaseExpr] ... => ... # 129| 0: [RecursivePatternExpr] { ... } -# 129| 0: [LocalVariableDeclExpr] MyStruct ms -# 129| 1: [TypeAccess] access to type MyStruct +# 129| 0: [VariablePatternExpr] MyStruct ms +# 129| 1: [TypeAccessPatternExpr] access to type MyStruct # 129| 0: [TypeMention] MyStruct # 129| 3: [PropertyPatternExpr] { ... } # 129| 0: [ConstantPatternExpr,IntLiteral,LabeledPatternExpr] 10 @@ -1155,7 +1155,7 @@ patterns.cs: # 141| 2: [IntLiteral] 5 # 142| 4: [SwitchCaseExpr] ... => ... # 142| 0: [RecursivePatternExpr] { ... } -# 142| 1: [TypeAccess] access to type MyStruct +# 142| 1: [TypeAccessPatternExpr] access to type MyStruct # 142| 0: [TypeMention] MyStruct # 142| 3: [PropertyPatternExpr] { ... } # 142| 0: [ConstantPatternExpr,IntLiteral,LabeledPatternExpr] 10 diff --git a/csharp/ql/test/library-tests/csharp8/ispatternflow.expected b/csharp/ql/test/library-tests/csharp8/ispatternflow.expected index 31e52472bde..553f416cd96 100644 --- a/csharp/ql/test/library-tests/csharp8/ispatternflow.expected +++ b/csharp/ql/test/library-tests/csharp8/ispatternflow.expected @@ -10,22 +10,27 @@ | patterns.cs:7:39:7:39 | 2 | patterns.cs:7:35:7:39 | ... = ... | semmle.label | successor | | patterns.cs:9:9:11:9 | if (...) ... | patterns.cs:9:13:9:13 | access to local variable o | semmle.label | successor | | patterns.cs:9:13:9:13 | access to local variable o | patterns.cs:9:18:9:29 | MyStruct ms1 | semmle.label | successor | -| patterns.cs:9:13:9:29 | ... is ... | patterns.cs:10:9:11:9 | {...} | semmle.label | true | -| patterns.cs:9:13:9:29 | ... is ... | patterns.cs:13:9:15:9 | if (...) ... | semmle.label | false | -| patterns.cs:9:18:9:29 | MyStruct ms1 | patterns.cs:9:13:9:29 | ... is ... | semmle.label | successor | +| patterns.cs:9:13:9:29 | [false] ... is ... | patterns.cs:13:9:15:9 | if (...) ... | semmle.label | false | +| patterns.cs:9:13:9:29 | [true] ... is ... | patterns.cs:10:9:11:9 | {...} | semmle.label | true | +| patterns.cs:9:18:9:29 | MyStruct ms1 | patterns.cs:9:13:9:29 | [false] ... is ... | semmle.label | no-match | +| patterns.cs:9:18:9:29 | MyStruct ms1 | patterns.cs:9:13:9:29 | [true] ... is ... | semmle.label | match | | patterns.cs:10:9:11:9 | {...} | patterns.cs:13:9:15:9 | if (...) ... | semmle.label | successor | | patterns.cs:13:9:15:9 | if (...) ... | patterns.cs:13:13:13:13 | access to local variable o | semmle.label | successor | | patterns.cs:13:13:13:13 | access to local variable o | patterns.cs:13:18:13:40 | MyStruct s | semmle.label | successor | -| patterns.cs:13:13:13:40 | ... is ... | patterns.cs:13:13:13:47 | [false] ... && ... | semmle.label | false | -| patterns.cs:13:13:13:40 | ... is ... | patterns.cs:13:45:13:45 | access to local variable x | semmle.label | true | +| patterns.cs:13:13:13:40 | [false] ... is ... | patterns.cs:13:13:13:47 | [false] ... && ... | semmle.label | false | +| patterns.cs:13:13:13:40 | [true] ... is ... | patterns.cs:13:45:13:45 | access to local variable x | semmle.label | true | | patterns.cs:13:13:13:47 | [false] ... && ... | patterns.cs:13:13:13:56 | [false] ... && ... | semmle.label | false | | patterns.cs:13:13:13:47 | [true] ... && ... | patterns.cs:13:52:13:52 | access to local variable s | semmle.label | true | | patterns.cs:13:13:13:56 | [false] ... && ... | patterns.cs:17:9:19:9 | if (...) ... | semmle.label | false | | patterns.cs:13:13:13:56 | [true] ... && ... | patterns.cs:14:9:15:9 | {...} | semmle.label | true | -| patterns.cs:13:18:13:40 | MyStruct s | patterns.cs:13:32:13:36 | Int32 x | semmle.label | successor | -| patterns.cs:13:18:13:40 | { ... } | patterns.cs:13:13:13:40 | ... is ... | semmle.label | successor | -| patterns.cs:13:27:13:38 | { ... } | patterns.cs:13:18:13:40 | { ... } | semmle.label | successor | -| patterns.cs:13:32:13:36 | Int32 x | patterns.cs:13:27:13:38 | { ... } | semmle.label | successor | +| patterns.cs:13:18:13:40 | MyStruct s | patterns.cs:13:18:13:40 | [no-match] { ... } | semmle.label | no-match | +| patterns.cs:13:18:13:40 | MyStruct s | patterns.cs:13:32:13:36 | Int32 x | semmle.label | match | +| patterns.cs:13:18:13:40 | [match] { ... } | patterns.cs:13:13:13:40 | [true] ... is ... | semmle.label | match | +| patterns.cs:13:18:13:40 | [no-match] { ... } | patterns.cs:13:13:13:40 | [false] ... is ... | semmle.label | no-match | +| patterns.cs:13:27:13:38 | [match] { ... } | patterns.cs:13:18:13:40 | [match] { ... } | semmle.label | match | +| patterns.cs:13:27:13:38 | [no-match] { ... } | patterns.cs:13:18:13:40 | [no-match] { ... } | semmle.label | no-match | +| patterns.cs:13:32:13:36 | Int32 x | patterns.cs:13:27:13:38 | [match] { ... } | semmle.label | match | +| patterns.cs:13:32:13:36 | Int32 x | patterns.cs:13:27:13:38 | [no-match] { ... } | semmle.label | no-match | | patterns.cs:13:45:13:45 | access to local variable x | patterns.cs:13:47:13:47 | 4 | semmle.label | successor | | patterns.cs:13:45:13:47 | ... < ... | patterns.cs:13:13:13:47 | [false] ... && ... | semmle.label | false | | patterns.cs:13:45:13:47 | ... < ... | patterns.cs:13:13:13:47 | [true] ... && ... | semmle.label | true | @@ -38,32 +43,50 @@ | patterns.cs:14:9:15:9 | {...} | patterns.cs:17:9:19:9 | if (...) ... | semmle.label | successor | | patterns.cs:17:9:19:9 | if (...) ... | patterns.cs:17:13:17:13 | access to local variable o | semmle.label | successor | | patterns.cs:17:13:17:13 | access to local variable o | patterns.cs:17:18:17:21 | Object p | semmle.label | successor | -| patterns.cs:17:13:17:21 | ... is ... | patterns.cs:18:9:19:9 | {...} | semmle.label | true | -| patterns.cs:17:13:17:21 | ... is ... | patterns.cs:22:9:24:9 | if (...) ... | semmle.label | false | -| patterns.cs:17:18:17:19 | { ... } | patterns.cs:17:18:17:21 | { ... } | semmle.label | successor | -| patterns.cs:17:18:17:21 | Object p | patterns.cs:17:18:17:19 | { ... } | semmle.label | successor | -| patterns.cs:17:18:17:21 | { ... } | patterns.cs:17:13:17:21 | ... is ... | semmle.label | successor | +| patterns.cs:17:13:17:21 | [false] ... is ... | patterns.cs:22:9:24:9 | if (...) ... | semmle.label | false | +| patterns.cs:17:13:17:21 | [true] ... is ... | patterns.cs:18:9:19:9 | {...} | semmle.label | true | +| patterns.cs:17:18:17:19 | { ... } | patterns.cs:17:18:17:21 | [match] { ... } | semmle.label | match | +| patterns.cs:17:18:17:19 | { ... } | patterns.cs:17:18:17:21 | [no-match] { ... } | semmle.label | no-match | +| patterns.cs:17:18:17:21 | Object p | patterns.cs:17:18:17:19 | { ... } | semmle.label | match | +| patterns.cs:17:18:17:21 | Object p | patterns.cs:17:18:17:21 | [no-match] { ... } | semmle.label | no-match | +| patterns.cs:17:18:17:21 | [match] { ... } | patterns.cs:17:13:17:21 | [true] ... is ... | semmle.label | match | +| patterns.cs:17:18:17:21 | [no-match] { ... } | patterns.cs:17:13:17:21 | [false] ... is ... | semmle.label | no-match | | patterns.cs:18:9:19:9 | {...} | patterns.cs:22:9:24:9 | if (...) ... | semmle.label | successor | | patterns.cs:22:9:24:9 | if (...) ... | patterns.cs:22:13:22:13 | access to local variable o | semmle.label | successor | -| patterns.cs:22:13:22:13 | access to local variable o | patterns.cs:22:31:22:32 | 12 | semmle.label | successor | -| patterns.cs:22:13:22:53 | ... is ... | patterns.cs:23:9:24:9 | {...} | semmle.label | true | -| patterns.cs:22:13:22:53 | ... is ... | patterns.cs:27:9:29:9 | if (...) ... | semmle.label | false | -| patterns.cs:22:18:22:53 | { ... } | patterns.cs:22:13:22:53 | ... is ... | semmle.label | successor | -| patterns.cs:22:27:22:53 | { ... } | patterns.cs:22:18:22:53 | { ... } | semmle.label | successor | -| patterns.cs:22:31:22:32 | 12 | patterns.cs:22:42:22:49 | Int32 subX | semmle.label | successor | -| patterns.cs:22:38:22:51 | { ... } | patterns.cs:22:27:22:53 | { ... } | semmle.label | successor | -| patterns.cs:22:38:22:51 | { ... } | patterns.cs:22:38:22:51 | { ... } | semmle.label | successor | -| patterns.cs:22:42:22:49 | Int32 subX | patterns.cs:22:38:22:51 | { ... } | semmle.label | successor | +| patterns.cs:22:13:22:13 | access to local variable o | patterns.cs:22:18:22:25 | access to type MyStruct | semmle.label | successor | +| patterns.cs:22:13:22:53 | [false] ... is ... | patterns.cs:27:9:29:9 | if (...) ... | semmle.label | false | +| patterns.cs:22:13:22:53 | [true] ... is ... | patterns.cs:23:9:24:9 | {...} | semmle.label | true | +| patterns.cs:22:18:22:25 | access to type MyStruct | patterns.cs:22:18:22:53 | [no-match] { ... } | semmle.label | no-match | +| patterns.cs:22:18:22:25 | access to type MyStruct | patterns.cs:22:31:22:32 | 12 | semmle.label | match | +| patterns.cs:22:18:22:53 | [match] { ... } | patterns.cs:22:13:22:53 | [true] ... is ... | semmle.label | match | +| patterns.cs:22:18:22:53 | [no-match] { ... } | patterns.cs:22:13:22:53 | [false] ... is ... | semmle.label | no-match | +| patterns.cs:22:27:22:53 | [match] { ... } | patterns.cs:22:18:22:53 | [match] { ... } | semmle.label | match | +| patterns.cs:22:27:22:53 | [no-match] { ... } | patterns.cs:22:18:22:53 | [no-match] { ... } | semmle.label | no-match | +| patterns.cs:22:31:22:32 | 12 | patterns.cs:22:27:22:53 | [no-match] { ... } | semmle.label | no-match | +| patterns.cs:22:31:22:32 | 12 | patterns.cs:22:42:22:49 | Int32 subX | semmle.label | match | +| patterns.cs:22:38:22:51 | [match] { ... } | patterns.cs:22:27:22:53 | [match] { ... } | semmle.label | match | +| patterns.cs:22:38:22:51 | [match] { ... } | patterns.cs:22:38:22:51 | [match] { ... } | semmle.label | match | +| patterns.cs:22:38:22:51 | [no-match] { ... } | patterns.cs:22:27:22:53 | [no-match] { ... } | semmle.label | no-match | +| patterns.cs:22:38:22:51 | [no-match] { ... } | patterns.cs:22:38:22:51 | [no-match] { ... } | semmle.label | no-match | +| patterns.cs:22:42:22:49 | Int32 subX | patterns.cs:22:38:22:51 | [match] { ... } | semmle.label | match | +| patterns.cs:22:42:22:49 | Int32 subX | patterns.cs:22:38:22:51 | [no-match] { ... } | semmle.label | no-match | | patterns.cs:23:9:24:9 | {...} | patterns.cs:27:9:29:9 | if (...) ... | semmle.label | successor | | patterns.cs:27:9:29:9 | if (...) ... | patterns.cs:27:13:27:13 | access to local variable o | semmle.label | successor | -| patterns.cs:27:13:27:13 | access to local variable o | patterns.cs:27:31:27:32 | 12 | semmle.label | successor | -| patterns.cs:27:13:27:58 | ... is ... | patterns.cs:5:10:5:19 | exit IsPatterns (normal) | semmle.label | false | -| patterns.cs:27:13:27:58 | ... is ... | patterns.cs:28:9:29:9 | {...} | semmle.label | true | -| patterns.cs:27:18:27:58 | { ... } | patterns.cs:27:13:27:58 | ... is ... | semmle.label | successor | -| patterns.cs:27:27:27:58 | { ... } | patterns.cs:27:18:27:58 | { ... } | semmle.label | successor | -| patterns.cs:27:31:27:32 | 12 | patterns.cs:27:38:27:56 | MyStruct ms | semmle.label | successor | -| patterns.cs:27:38:27:56 | MyStruct ms | patterns.cs:27:51:27:51 | _ | semmle.label | successor | -| patterns.cs:27:38:27:56 | { ... } | patterns.cs:27:27:27:58 | { ... } | semmle.label | successor | -| patterns.cs:27:47:27:53 | { ... } | patterns.cs:27:38:27:56 | { ... } | semmle.label | successor | -| patterns.cs:27:51:27:51 | _ | patterns.cs:27:47:27:53 | { ... } | semmle.label | successor | +| patterns.cs:27:13:27:13 | access to local variable o | patterns.cs:27:18:27:25 | access to type MyStruct | semmle.label | successor | +| patterns.cs:27:13:27:58 | [false] ... is ... | patterns.cs:5:10:5:19 | exit IsPatterns (normal) | semmle.label | false | +| patterns.cs:27:13:27:58 | [true] ... is ... | patterns.cs:28:9:29:9 | {...} | semmle.label | true | +| patterns.cs:27:18:27:25 | access to type MyStruct | patterns.cs:27:18:27:58 | [no-match] { ... } | semmle.label | no-match | +| patterns.cs:27:18:27:25 | access to type MyStruct | patterns.cs:27:31:27:32 | 12 | semmle.label | match | +| patterns.cs:27:18:27:58 | [match] { ... } | patterns.cs:27:13:27:58 | [true] ... is ... | semmle.label | match | +| patterns.cs:27:18:27:58 | [no-match] { ... } | patterns.cs:27:13:27:58 | [false] ... is ... | semmle.label | no-match | +| patterns.cs:27:27:27:58 | [match] { ... } | patterns.cs:27:18:27:58 | [match] { ... } | semmle.label | match | +| patterns.cs:27:27:27:58 | [no-match] { ... } | patterns.cs:27:18:27:58 | [no-match] { ... } | semmle.label | no-match | +| patterns.cs:27:31:27:32 | 12 | patterns.cs:27:27:27:58 | [no-match] { ... } | semmle.label | no-match | +| patterns.cs:27:31:27:32 | 12 | patterns.cs:27:38:27:56 | MyStruct ms | semmle.label | match | +| patterns.cs:27:38:27:56 | MyStruct ms | patterns.cs:27:38:27:56 | [no-match] { ... } | semmle.label | no-match | +| patterns.cs:27:38:27:56 | MyStruct ms | patterns.cs:27:51:27:51 | _ | semmle.label | match | +| patterns.cs:27:38:27:56 | [match] { ... } | patterns.cs:27:27:27:58 | [match] { ... } | semmle.label | match | +| patterns.cs:27:38:27:56 | [no-match] { ... } | patterns.cs:27:27:27:58 | [no-match] { ... } | semmle.label | no-match | +| patterns.cs:27:47:27:53 | [match] { ... } | patterns.cs:27:38:27:56 | [match] { ... } | semmle.label | match | +| patterns.cs:27:51:27:51 | _ | patterns.cs:27:47:27:53 | [match] { ... } | semmle.label | match | | patterns.cs:28:9:29:9 | {...} | patterns.cs:5:10:5:19 | exit IsPatterns (normal) | semmle.label | successor | diff --git a/csharp/ql/test/library-tests/csharp8/switchexprcontrolflow.expected b/csharp/ql/test/library-tests/csharp8/switchexprcontrolflow.expected index 53132fa80cf..b8a976a78a6 100644 --- a/csharp/ql/test/library-tests/csharp8/switchexprcontrolflow.expected +++ b/csharp/ql/test/library-tests/csharp8/switchexprcontrolflow.expected @@ -27,59 +27,76 @@ | patterns.cs:108:9:112:10 | ...; | patterns.cs:108:14:108:15 | Int32 x1 | semmle.label | successor | | patterns.cs:108:14:108:15 | Int32 x1 | patterns.cs:108:18:108:19 | Int32 y1 | semmle.label | successor | | patterns.cs:108:18:108:19 | Int32 y1 | patterns.cs:108:9:108:20 | (..., ...) | semmle.label | successor | -| patterns.cs:108:24:108:31 | (..., ...) | patterns.cs:110:14:110:14 | 0 | semmle.label | successor | +| patterns.cs:108:24:108:31 | (..., ...) | patterns.cs:110:13:110:17 | ( ... ) | semmle.label | successor | | patterns.cs:108:24:112:9 | ... switch { ... } | patterns.cs:108:9:112:9 | ... = ... | semmle.label | successor | | patterns.cs:108:25:108:26 | access to local variable x0 | patterns.cs:108:29:108:30 | access to local variable y0 | semmle.label | successor | | patterns.cs:108:29:108:30 | access to local variable y0 | patterns.cs:108:24:108:31 | (..., ...) | semmle.label | successor | -| patterns.cs:110:13:110:17 | ( ... ) | patterns.cs:110:13:110:17 | { ... } | semmle.label | successor | -| patterns.cs:110:13:110:17 | { ... } | patterns.cs:110:23:110:23 | 1 | semmle.label | match | -| patterns.cs:110:13:110:17 | { ... } | patterns.cs:111:14:111:14 | 1 | semmle.label | no-match | +| patterns.cs:110:13:110:17 | ( ... ) | patterns.cs:110:13:110:17 | [no-match] { ... } | semmle.label | no-match | +| patterns.cs:110:13:110:17 | ( ... ) | patterns.cs:110:14:110:14 | 0 | semmle.label | match | +| patterns.cs:110:13:110:17 | [match] { ... } | patterns.cs:110:23:110:23 | 1 | semmle.label | match | +| patterns.cs:110:13:110:17 | [no-match] { ... } | patterns.cs:111:13:111:17 | ( ... ) | semmle.label | no-match | | patterns.cs:110:13:110:26 | ... => ... | patterns.cs:108:24:112:9 | ... switch { ... } | semmle.label | successor | -| patterns.cs:110:14:110:14 | 0 | patterns.cs:110:16:110:16 | 1 | semmle.label | successor | -| patterns.cs:110:16:110:16 | 1 | patterns.cs:110:13:110:17 | ( ... ) | semmle.label | successor | +| patterns.cs:110:14:110:14 | 0 | patterns.cs:110:13:110:17 | [no-match] { ... } | semmle.label | no-match | +| patterns.cs:110:14:110:14 | 0 | patterns.cs:110:16:110:16 | 1 | semmle.label | match | +| patterns.cs:110:16:110:16 | 1 | patterns.cs:110:13:110:17 | [match] { ... } | semmle.label | match | +| patterns.cs:110:16:110:16 | 1 | patterns.cs:110:13:110:17 | [no-match] { ... } | semmle.label | no-match | | patterns.cs:110:22:110:26 | (..., ...) | patterns.cs:110:13:110:26 | ... => ... | semmle.label | successor | | patterns.cs:110:23:110:23 | 1 | patterns.cs:110:25:110:25 | 0 | semmle.label | successor | | patterns.cs:110:25:110:25 | 0 | patterns.cs:110:22:110:26 | (..., ...) | semmle.label | successor | -| patterns.cs:111:13:111:17 | ( ... ) | patterns.cs:111:13:111:17 | { ... } | semmle.label | successor | -| patterns.cs:111:13:111:17 | { ... } | patterns.cs:98:10:98:20 | exit Expressions (abnormal) | semmle.label | exception(InvalidOperationException) | -| patterns.cs:111:13:111:17 | { ... } | patterns.cs:111:23:111:23 | 0 | semmle.label | match | +| patterns.cs:111:13:111:17 | ( ... ) | patterns.cs:111:13:111:17 | [no-match] { ... } | semmle.label | no-match | +| patterns.cs:111:13:111:17 | ( ... ) | patterns.cs:111:14:111:14 | 1 | semmle.label | match | +| patterns.cs:111:13:111:17 | [match] { ... } | patterns.cs:98:10:98:20 | exit Expressions (abnormal) | semmle.label | exception(InvalidOperationException) | +| patterns.cs:111:13:111:17 | [match] { ... } | patterns.cs:111:23:111:23 | 0 | semmle.label | match | +| patterns.cs:111:13:111:17 | [no-match] { ... } | patterns.cs:98:10:98:20 | exit Expressions (abnormal) | semmle.label | exception(InvalidOperationException) | | patterns.cs:111:13:111:26 | ... => ... | patterns.cs:108:24:112:9 | ... switch { ... } | semmle.label | successor | -| patterns.cs:111:14:111:14 | 1 | patterns.cs:111:16:111:16 | 0 | semmle.label | successor | -| patterns.cs:111:16:111:16 | 0 | patterns.cs:111:13:111:17 | ( ... ) | semmle.label | successor | +| patterns.cs:111:14:111:14 | 1 | patterns.cs:111:13:111:17 | [no-match] { ... } | semmle.label | no-match | +| patterns.cs:111:14:111:14 | 1 | patterns.cs:111:16:111:16 | 0 | semmle.label | match | +| patterns.cs:111:16:111:16 | 0 | patterns.cs:111:13:111:17 | [match] { ... } | semmle.label | match | +| patterns.cs:111:16:111:16 | 0 | patterns.cs:111:13:111:17 | [no-match] { ... } | semmle.label | no-match | | patterns.cs:111:22:111:26 | (..., ...) | patterns.cs:111:13:111:26 | ... => ... | semmle.label | successor | | patterns.cs:111:23:111:23 | 0 | patterns.cs:111:25:111:25 | 1 | semmle.label | successor | | patterns.cs:111:25:111:25 | 1 | patterns.cs:111:22:111:26 | (..., ...) | semmle.label | successor | | patterns.cs:115:9:115:16 | (..., ...) | patterns.cs:115:21:115:22 | access to local variable x0 | semmle.label | successor | | patterns.cs:115:9:120:9 | ... = ... | patterns.cs:98:10:98:20 | exit Expressions (normal) | semmle.label | successor | | patterns.cs:115:9:120:10 | ...; | patterns.cs:115:9:115:16 | (..., ...) | semmle.label | successor | -| patterns.cs:115:20:115:27 | (..., ...) | patterns.cs:117:14:117:14 | 0 | semmle.label | successor | +| patterns.cs:115:20:115:27 | (..., ...) | patterns.cs:117:13:117:22 | ( ... ) | semmle.label | successor | | patterns.cs:115:20:120:9 | ... switch { ... } | patterns.cs:115:9:120:9 | ... = ... | semmle.label | successor | | patterns.cs:115:21:115:22 | access to local variable x0 | patterns.cs:115:25:115:26 | access to local variable y0 | semmle.label | successor | | patterns.cs:115:25:115:26 | access to local variable y0 | patterns.cs:115:20:115:27 | (..., ...) | semmle.label | successor | -| patterns.cs:117:13:117:22 | ( ... ) | patterns.cs:117:13:117:22 | { ... } | semmle.label | successor | -| patterns.cs:117:13:117:22 | { ... } | patterns.cs:117:28:117:29 | access to local variable y2 | semmle.label | match | -| patterns.cs:117:13:117:22 | { ... } | patterns.cs:118:14:118:19 | Int32 x2 | semmle.label | no-match | +| patterns.cs:117:13:117:22 | ( ... ) | patterns.cs:117:13:117:22 | [no-match] { ... } | semmle.label | no-match | +| patterns.cs:117:13:117:22 | ( ... ) | patterns.cs:117:14:117:14 | 0 | semmle.label | match | +| patterns.cs:117:13:117:22 | [match] { ... } | patterns.cs:117:28:117:29 | access to local variable y2 | semmle.label | match | +| patterns.cs:117:13:117:22 | [no-match] { ... } | patterns.cs:118:13:118:23 | ( ... ) | semmle.label | no-match | | patterns.cs:117:13:117:33 | ... => ... | patterns.cs:115:20:120:9 | ... switch { ... } | semmle.label | successor | -| patterns.cs:117:14:117:14 | 0 | patterns.cs:117:16:117:21 | Int32 y2 | semmle.label | successor | -| patterns.cs:117:16:117:21 | Int32 y2 | patterns.cs:117:13:117:22 | ( ... ) | semmle.label | successor | +| patterns.cs:117:14:117:14 | 0 | patterns.cs:117:13:117:22 | [no-match] { ... } | semmle.label | no-match | +| patterns.cs:117:14:117:14 | 0 | patterns.cs:117:16:117:21 | Int32 y2 | semmle.label | match | +| patterns.cs:117:16:117:21 | Int32 y2 | patterns.cs:117:13:117:22 | [match] { ... } | semmle.label | match | +| patterns.cs:117:16:117:21 | Int32 y2 | patterns.cs:117:13:117:22 | [no-match] { ... } | semmle.label | no-match | | patterns.cs:117:27:117:33 | (..., ...) | patterns.cs:117:13:117:33 | ... => ... | semmle.label | successor | | patterns.cs:117:28:117:29 | access to local variable y2 | patterns.cs:117:32:117:32 | 0 | semmle.label | successor | | patterns.cs:117:32:117:32 | 0 | patterns.cs:117:27:117:33 | (..., ...) | semmle.label | successor | -| patterns.cs:118:13:118:23 | ( ... ) | patterns.cs:118:13:118:23 | { ... } | semmle.label | successor | -| patterns.cs:118:13:118:23 | { ... } | patterns.cs:118:29:118:29 | 0 | semmle.label | match | -| patterns.cs:118:13:118:23 | { ... } | patterns.cs:119:14:119:19 | Int32 x2 | semmle.label | no-match | +| patterns.cs:118:13:118:23 | ( ... ) | patterns.cs:118:13:118:23 | [no-match] { ... } | semmle.label | no-match | +| patterns.cs:118:13:118:23 | ( ... ) | patterns.cs:118:14:118:19 | Int32 x2 | semmle.label | match | +| patterns.cs:118:13:118:23 | [match] { ... } | patterns.cs:118:29:118:29 | 0 | semmle.label | match | +| patterns.cs:118:13:118:23 | [no-match] { ... } | patterns.cs:119:13:119:28 | ( ... ) | semmle.label | no-match | | patterns.cs:118:13:118:34 | ... => ... | patterns.cs:115:20:120:9 | ... switch { ... } | semmle.label | successor | -| patterns.cs:118:14:118:19 | Int32 x2 | patterns.cs:118:22:118:22 | 0 | semmle.label | successor | -| patterns.cs:118:22:118:22 | 0 | patterns.cs:118:13:118:23 | ( ... ) | semmle.label | successor | +| patterns.cs:118:14:118:19 | Int32 x2 | patterns.cs:118:13:118:23 | [no-match] { ... } | semmle.label | no-match | +| patterns.cs:118:14:118:19 | Int32 x2 | patterns.cs:118:22:118:22 | 0 | semmle.label | match | +| patterns.cs:118:22:118:22 | 0 | patterns.cs:118:13:118:23 | [match] { ... } | semmle.label | match | +| patterns.cs:118:22:118:22 | 0 | patterns.cs:118:13:118:23 | [no-match] { ... } | semmle.label | no-match | | patterns.cs:118:28:118:34 | (..., ...) | patterns.cs:118:13:118:34 | ... => ... | semmle.label | successor | | patterns.cs:118:29:118:29 | 0 | patterns.cs:118:32:118:33 | access to local variable x2 | semmle.label | successor | | patterns.cs:118:32:118:33 | access to local variable x2 | patterns.cs:118:28:118:34 | (..., ...) | semmle.label | successor | -| patterns.cs:119:13:119:28 | ( ... ) | patterns.cs:119:13:119:28 | { ... } | semmle.label | successor | -| patterns.cs:119:13:119:28 | { ... } | patterns.cs:98:10:98:20 | exit Expressions (abnormal) | semmle.label | exception(InvalidOperationException) | -| patterns.cs:119:13:119:28 | { ... } | patterns.cs:119:34:119:34 | 0 | semmle.label | match | +| patterns.cs:119:13:119:28 | ( ... ) | patterns.cs:119:13:119:28 | [no-match] { ... } | semmle.label | no-match | +| patterns.cs:119:13:119:28 | ( ... ) | patterns.cs:119:14:119:19 | Int32 x2 | semmle.label | match | +| patterns.cs:119:13:119:28 | [match] { ... } | patterns.cs:98:10:98:20 | exit Expressions (abnormal) | semmle.label | exception(InvalidOperationException) | +| patterns.cs:119:13:119:28 | [match] { ... } | patterns.cs:119:34:119:34 | 0 | semmle.label | match | +| patterns.cs:119:13:119:28 | [no-match] { ... } | patterns.cs:98:10:98:20 | exit Expressions (abnormal) | semmle.label | exception(InvalidOperationException) | | patterns.cs:119:13:119:38 | ... => ... | patterns.cs:115:20:120:9 | ... switch { ... } | semmle.label | successor | -| patterns.cs:119:14:119:19 | Int32 x2 | patterns.cs:119:22:119:27 | Int32 y2 | semmle.label | successor | -| patterns.cs:119:22:119:27 | Int32 y2 | patterns.cs:119:13:119:28 | ( ... ) | semmle.label | successor | +| patterns.cs:119:14:119:19 | Int32 x2 | patterns.cs:119:13:119:28 | [no-match] { ... } | semmle.label | no-match | +| patterns.cs:119:14:119:19 | Int32 x2 | patterns.cs:119:22:119:27 | Int32 y2 | semmle.label | match | +| patterns.cs:119:22:119:27 | Int32 y2 | patterns.cs:119:13:119:28 | [match] { ... } | semmle.label | match | +| patterns.cs:119:22:119:27 | Int32 y2 | patterns.cs:119:13:119:28 | [no-match] { ... } | semmle.label | no-match | | patterns.cs:119:33:119:38 | (..., ...) | patterns.cs:119:13:119:38 | ... => ... | semmle.label | successor | | patterns.cs:119:34:119:34 | 0 | patterns.cs:119:37:119:37 | 0 | semmle.label | successor | | patterns.cs:119:37:119:37 | 0 | patterns.cs:119:33:119:38 | (..., ...) | semmle.label | successor | @@ -95,31 +112,41 @@ | patterns.cs:125:36:125:36 | 0 | patterns.cs:125:32:125:36 | ... = ... | semmle.label | successor | | patterns.cs:126:9:132:10 | ... ...; | patterns.cs:126:17:126:17 | access to local variable s | semmle.label | successor | | patterns.cs:126:13:132:9 | Int32 r = ... | patterns.cs:134:9:148:9 | try {...} ... | semmle.label | successor | -| patterns.cs:126:17:126:17 | access to local variable s | patterns.cs:128:27:128:31 | Int32 x | semmle.label | successor | +| patterns.cs:126:17:126:17 | access to local variable s | patterns.cs:128:13:128:20 | access to type MyStruct | semmle.label | successor | | patterns.cs:126:17:132:9 | ... switch { ... } | patterns.cs:126:13:132:9 | Int32 r = ... | semmle.label | successor | -| patterns.cs:128:13:128:33 | { ... } | patterns.cs:128:40:128:40 | access to local variable x | semmle.label | match | -| patterns.cs:128:13:128:33 | { ... } | patterns.cs:129:13:129:33 | MyStruct ms | semmle.label | no-match | +| patterns.cs:128:13:128:20 | access to type MyStruct | patterns.cs:128:13:128:33 | [no-match] { ... } | semmle.label | no-match | +| patterns.cs:128:13:128:20 | access to type MyStruct | patterns.cs:128:27:128:31 | Int32 x | semmle.label | match | +| patterns.cs:128:13:128:33 | [match] { ... } | patterns.cs:128:40:128:40 | access to local variable x | semmle.label | match | +| patterns.cs:128:13:128:33 | [no-match] { ... } | patterns.cs:129:13:129:33 | MyStruct ms | semmle.label | no-match | | patterns.cs:128:13:128:49 | ... => ... | patterns.cs:126:17:132:9 | ... switch { ... } | semmle.label | successor | -| patterns.cs:128:22:128:33 | { ... } | patterns.cs:128:13:128:33 | { ... } | semmle.label | successor | -| patterns.cs:128:27:128:31 | Int32 x | patterns.cs:128:22:128:33 | { ... } | semmle.label | successor | +| patterns.cs:128:22:128:33 | [match] { ... } | patterns.cs:128:13:128:33 | [match] { ... } | semmle.label | match | +| patterns.cs:128:22:128:33 | [no-match] { ... } | patterns.cs:128:13:128:33 | [no-match] { ... } | semmle.label | no-match | +| patterns.cs:128:27:128:31 | Int32 x | patterns.cs:128:22:128:33 | [match] { ... } | semmle.label | match | +| patterns.cs:128:27:128:31 | Int32 x | patterns.cs:128:22:128:33 | [no-match] { ... } | semmle.label | no-match | | patterns.cs:128:40:128:40 | access to local variable x | patterns.cs:128:44:128:44 | 2 | semmle.label | successor | | patterns.cs:128:40:128:44 | ... > ... | patterns.cs:128:49:128:49 | 0 | semmle.label | true | | patterns.cs:128:40:128:44 | ... > ... | patterns.cs:129:13:129:33 | MyStruct ms | semmle.label | false | | patterns.cs:128:44:128:44 | 2 | patterns.cs:128:40:128:44 | ... > ... | semmle.label | successor | | patterns.cs:128:49:128:49 | 0 | patterns.cs:128:13:128:49 | ... => ... | semmle.label | successor | -| patterns.cs:129:13:129:33 | MyStruct ms | patterns.cs:129:27:129:28 | 10 | semmle.label | successor | -| patterns.cs:129:13:129:33 | { ... } | patterns.cs:129:38:129:38 | 1 | semmle.label | match | -| patterns.cs:129:13:129:33 | { ... } | patterns.cs:130:14:130:14 | 1 | semmle.label | no-match | +| patterns.cs:129:13:129:33 | MyStruct ms | patterns.cs:129:13:129:33 | [no-match] { ... } | semmle.label | no-match | +| patterns.cs:129:13:129:33 | MyStruct ms | patterns.cs:129:27:129:28 | 10 | semmle.label | match | +| patterns.cs:129:13:129:33 | [match] { ... } | patterns.cs:129:38:129:38 | 1 | semmle.label | match | +| patterns.cs:129:13:129:33 | [no-match] { ... } | patterns.cs:130:13:130:18 | ( ... ) | semmle.label | no-match | | patterns.cs:129:13:129:38 | ... => ... | patterns.cs:126:17:132:9 | ... switch { ... } | semmle.label | successor | -| patterns.cs:129:22:129:30 | { ... } | patterns.cs:129:13:129:33 | { ... } | semmle.label | successor | -| patterns.cs:129:27:129:28 | 10 | patterns.cs:129:22:129:30 | { ... } | semmle.label | successor | +| patterns.cs:129:22:129:30 | [match] { ... } | patterns.cs:129:13:129:33 | [match] { ... } | semmle.label | match | +| patterns.cs:129:22:129:30 | [no-match] { ... } | patterns.cs:129:13:129:33 | [no-match] { ... } | semmle.label | no-match | +| patterns.cs:129:27:129:28 | 10 | patterns.cs:129:22:129:30 | [match] { ... } | semmle.label | match | +| patterns.cs:129:27:129:28 | 10 | patterns.cs:129:22:129:30 | [no-match] { ... } | semmle.label | no-match | | patterns.cs:129:38:129:38 | 1 | patterns.cs:129:13:129:38 | ... => ... | semmle.label | successor | -| patterns.cs:130:13:130:18 | ( ... ) | patterns.cs:130:13:130:18 | { ... } | semmle.label | successor | -| patterns.cs:130:13:130:18 | { ... } | patterns.cs:130:23:130:23 | 2 | semmle.label | match | -| patterns.cs:130:13:130:18 | { ... } | patterns.cs:131:18:131:18 | Int32 x | semmle.label | no-match | +| patterns.cs:130:13:130:18 | ( ... ) | patterns.cs:130:13:130:18 | [no-match] { ... } | semmle.label | no-match | +| patterns.cs:130:13:130:18 | ( ... ) | patterns.cs:130:14:130:14 | 1 | semmle.label | match | +| patterns.cs:130:13:130:18 | [match] { ... } | patterns.cs:130:23:130:23 | 2 | semmle.label | match | +| patterns.cs:130:13:130:18 | [no-match] { ... } | patterns.cs:131:18:131:18 | Int32 x | semmle.label | no-match | | patterns.cs:130:13:130:23 | ... => ... | patterns.cs:126:17:132:9 | ... switch { ... } | semmle.label | successor | -| patterns.cs:130:14:130:14 | 1 | patterns.cs:130:17:130:17 | 2 | semmle.label | successor | -| patterns.cs:130:17:130:17 | 2 | patterns.cs:130:13:130:18 | ( ... ) | semmle.label | successor | +| patterns.cs:130:14:130:14 | 1 | patterns.cs:130:13:130:18 | [no-match] { ... } | semmle.label | no-match | +| patterns.cs:130:14:130:14 | 1 | patterns.cs:130:17:130:17 | 2 | semmle.label | match | +| patterns.cs:130:17:130:17 | 2 | patterns.cs:130:13:130:18 | [match] { ... } | semmle.label | match | +| patterns.cs:130:17:130:17 | 2 | patterns.cs:130:13:130:18 | [no-match] { ... } | semmle.label | no-match | | patterns.cs:130:23:130:23 | 2 | patterns.cs:130:13:130:23 | ... => ... | semmle.label | successor | | patterns.cs:131:13:131:22 | (..., ...) | patterns.cs:123:10:123:21 | exit Expressions2 (abnormal) | semmle.label | exception(InvalidOperationException) | | patterns.cs:131:13:131:22 | (..., ...) | patterns.cs:131:27:131:27 | 3 | semmle.label | match | @@ -146,20 +173,27 @@ | patterns.cs:140:17:140:24 | Object y | patterns.cs:141:17:141:22 | access to type String | semmle.label | no-match | | patterns.cs:140:17:140:42 | ... => ... | patterns.cs:136:17:143:13 | ... switch { ... } | semmle.label | successor | | patterns.cs:140:31:140:31 | access to local variable y | patterns.cs:140:36:140:37 | { ... } | semmle.label | successor | -| patterns.cs:140:31:140:37 | ... is ... | patterns.cs:140:42:140:42 | 4 | semmle.label | true | -| patterns.cs:140:31:140:37 | ... is ... | patterns.cs:141:17:141:22 | access to type String | semmle.label | false | -| patterns.cs:140:36:140:37 | { ... } | patterns.cs:140:31:140:37 | ... is ... | semmle.label | successor | -| patterns.cs:140:36:140:37 | { ... } | patterns.cs:140:36:140:37 | { ... } | semmle.label | successor | +| patterns.cs:140:31:140:37 | [false] ... is ... | patterns.cs:141:17:141:22 | access to type String | semmle.label | false | +| patterns.cs:140:31:140:37 | [true] ... is ... | patterns.cs:140:42:140:42 | 4 | semmle.label | true | +| patterns.cs:140:36:140:37 | [match] { ... } | patterns.cs:140:31:140:37 | [true] ... is ... | semmle.label | match | +| patterns.cs:140:36:140:37 | [no-match] { ... } | patterns.cs:140:31:140:37 | [false] ... is ... | semmle.label | no-match | +| patterns.cs:140:36:140:37 | { ... } | patterns.cs:140:36:140:37 | [match] { ... } | semmle.label | match | +| patterns.cs:140:36:140:37 | { ... } | patterns.cs:140:36:140:37 | [no-match] { ... } | semmle.label | no-match | | patterns.cs:140:42:140:42 | 4 | patterns.cs:140:17:140:42 | ... => ... | semmle.label | successor | | patterns.cs:141:17:141:22 | access to type String | patterns.cs:141:29:141:29 | 5 | semmle.label | match | -| patterns.cs:141:17:141:22 | access to type String | patterns.cs:142:31:142:32 | 10 | semmle.label | no-match | +| patterns.cs:141:17:141:22 | access to type String | patterns.cs:142:17:142:24 | access to type MyStruct | semmle.label | no-match | | patterns.cs:141:17:141:29 | ... => ... | patterns.cs:136:17:143:13 | ... switch { ... } | semmle.label | successor | | patterns.cs:141:29:141:29 | 5 | patterns.cs:141:17:141:29 | ... => ... | semmle.label | successor | -| patterns.cs:142:17:142:36 | { ... } | patterns.cs:142:41:142:41 | 6 | semmle.label | match | -| patterns.cs:142:17:142:36 | { ... } | patterns.cs:145:9:148:9 | [exception: InvalidOperationException] catch (...) {...} | semmle.label | exception(InvalidOperationException) | +| patterns.cs:142:17:142:24 | access to type MyStruct | patterns.cs:142:17:142:36 | [no-match] { ... } | semmle.label | no-match | +| patterns.cs:142:17:142:24 | access to type MyStruct | patterns.cs:142:31:142:32 | 10 | semmle.label | match | +| patterns.cs:142:17:142:36 | [match] { ... } | patterns.cs:142:41:142:41 | 6 | semmle.label | match | +| patterns.cs:142:17:142:36 | [match] { ... } | patterns.cs:145:9:148:9 | [exception: InvalidOperationException] catch (...) {...} | semmle.label | exception(InvalidOperationException) | +| patterns.cs:142:17:142:36 | [no-match] { ... } | patterns.cs:145:9:148:9 | [exception: InvalidOperationException] catch (...) {...} | semmle.label | exception(InvalidOperationException) | | patterns.cs:142:17:142:41 | ... => ... | patterns.cs:136:17:143:13 | ... switch { ... } | semmle.label | successor | -| patterns.cs:142:26:142:34 | { ... } | patterns.cs:142:17:142:36 | { ... } | semmle.label | successor | -| patterns.cs:142:31:142:32 | 10 | patterns.cs:142:26:142:34 | { ... } | semmle.label | successor | +| patterns.cs:142:26:142:34 | [match] { ... } | patterns.cs:142:17:142:36 | [match] { ... } | semmle.label | match | +| patterns.cs:142:26:142:34 | [no-match] { ... } | patterns.cs:142:17:142:36 | [no-match] { ... } | semmle.label | no-match | +| patterns.cs:142:31:142:32 | 10 | patterns.cs:142:26:142:34 | [match] { ... } | semmle.label | match | +| patterns.cs:142:31:142:32 | 10 | patterns.cs:142:26:142:34 | [no-match] { ... } | semmle.label | no-match | | patterns.cs:142:41:142:41 | 6 | patterns.cs:142:17:142:41 | ... => ... | semmle.label | successor | | patterns.cs:145:9:148:9 | [exception: ArgumentException] catch (...) {...} | patterns.cs:123:10:123:21 | exit Expressions2 (abnormal) | semmle.label | exception(ArgumentException) | | patterns.cs:145:9:148:9 | [exception: Exception] catch (...) {...} | patterns.cs:123:10:123:21 | exit Expressions2 (abnormal) | semmle.label | exception(Exception) | diff --git a/csharp/ql/test/library-tests/csharp8/switchstmtctrlflow.expected b/csharp/ql/test/library-tests/csharp8/switchstmtctrlflow.expected index 2c5f491b138..64e16c2d7cf 100644 --- a/csharp/ql/test/library-tests/csharp8/switchstmtctrlflow.expected +++ b/csharp/ql/test/library-tests/csharp8/switchstmtctrlflow.expected @@ -35,11 +35,15 @@ | patterns.cs:43:17:43:22 | break; | patterns.cs:46:9:63:9 | switch (...) {...} | semmle.label | break | | patterns.cs:46:9:63:9 | switch (...) {...} | patterns.cs:46:17:46:17 | access to local variable s | semmle.label | successor | | patterns.cs:46:17:46:17 | access to local variable s | patterns.cs:48:13:48:50 | case ...: | semmle.label | successor | -| patterns.cs:48:13:48:50 | case ...: | patterns.cs:48:32:48:36 | Int32 x | semmle.label | successor | -| patterns.cs:48:18:48:38 | { ... } | patterns.cs:48:45:48:45 | access to local variable x | semmle.label | match | -| patterns.cs:48:18:48:38 | { ... } | patterns.cs:51:13:51:39 | case ...: | semmle.label | no-match | -| patterns.cs:48:27:48:38 | { ... } | patterns.cs:48:18:48:38 | { ... } | semmle.label | successor | -| patterns.cs:48:32:48:36 | Int32 x | patterns.cs:48:27:48:38 | { ... } | semmle.label | successor | +| patterns.cs:48:13:48:50 | case ...: | patterns.cs:48:18:48:25 | access to type MyStruct | semmle.label | successor | +| patterns.cs:48:18:48:25 | access to type MyStruct | patterns.cs:48:18:48:38 | [no-match] { ... } | semmle.label | no-match | +| patterns.cs:48:18:48:25 | access to type MyStruct | patterns.cs:48:32:48:36 | Int32 x | semmle.label | match | +| patterns.cs:48:18:48:38 | [match] { ... } | patterns.cs:48:45:48:45 | access to local variable x | semmle.label | match | +| patterns.cs:48:18:48:38 | [no-match] { ... } | patterns.cs:51:13:51:39 | case ...: | semmle.label | no-match | +| patterns.cs:48:27:48:38 | [match] { ... } | patterns.cs:48:18:48:38 | [match] { ... } | semmle.label | match | +| patterns.cs:48:27:48:38 | [no-match] { ... } | patterns.cs:48:18:48:38 | [no-match] { ... } | semmle.label | no-match | +| patterns.cs:48:32:48:36 | Int32 x | patterns.cs:48:27:48:38 | [match] { ... } | semmle.label | match | +| patterns.cs:48:32:48:36 | Int32 x | patterns.cs:48:27:48:38 | [no-match] { ... } | semmle.label | no-match | | patterns.cs:48:45:48:45 | access to local variable x | patterns.cs:48:49:48:49 | 2 | semmle.label | successor | | patterns.cs:48:45:48:49 | ... > ... | patterns.cs:49:17:49:37 | ...; | semmle.label | true | | patterns.cs:48:45:48:49 | ... > ... | patterns.cs:51:13:51:39 | case ...: | semmle.label | false | @@ -49,20 +53,25 @@ | patterns.cs:49:35:49:35 | access to local variable x | patterns.cs:49:17:49:36 | call to method WriteLine | semmle.label | successor | | patterns.cs:50:17:50:22 | break; | patterns.cs:65:9:73:9 | switch (...) {...} | semmle.label | break | | patterns.cs:51:13:51:39 | case ...: | patterns.cs:51:18:51:38 | MyStruct ms | semmle.label | successor | -| patterns.cs:51:18:51:38 | MyStruct ms | patterns.cs:51:32:51:33 | 10 | semmle.label | successor | -| patterns.cs:51:18:51:38 | { ... } | patterns.cs:52:17:52:56 | ...; | semmle.label | match | -| patterns.cs:51:18:51:38 | { ... } | patterns.cs:54:13:54:43 | case ...: | semmle.label | no-match | -| patterns.cs:51:27:51:35 | { ... } | patterns.cs:51:18:51:38 | { ... } | semmle.label | successor | -| patterns.cs:51:32:51:33 | 10 | patterns.cs:51:27:51:35 | { ... } | semmle.label | successor | +| patterns.cs:51:18:51:38 | MyStruct ms | patterns.cs:51:18:51:38 | [no-match] { ... } | semmle.label | no-match | +| patterns.cs:51:18:51:38 | MyStruct ms | patterns.cs:51:32:51:33 | 10 | semmle.label | match | +| patterns.cs:51:18:51:38 | [match] { ... } | patterns.cs:52:17:52:56 | ...; | semmle.label | match | +| patterns.cs:51:18:51:38 | [no-match] { ... } | patterns.cs:54:13:54:43 | case ...: | semmle.label | no-match | +| patterns.cs:51:27:51:35 | [match] { ... } | patterns.cs:51:18:51:38 | [match] { ... } | semmle.label | match | +| patterns.cs:51:27:51:35 | [no-match] { ... } | patterns.cs:51:18:51:38 | [no-match] { ... } | semmle.label | no-match | +| patterns.cs:51:32:51:33 | 10 | patterns.cs:51:27:51:35 | [match] { ... } | semmle.label | match | +| patterns.cs:51:32:51:33 | 10 | patterns.cs:51:27:51:35 | [no-match] { ... } | semmle.label | no-match | | patterns.cs:52:17:52:55 | call to method WriteLine | patterns.cs:53:17:53:22 | break; | semmle.label | successor | | patterns.cs:52:17:52:56 | ...; | patterns.cs:52:35:52:54 | "Hit the breakpoint" | semmle.label | successor | | patterns.cs:52:35:52:54 | "Hit the breakpoint" | patterns.cs:52:17:52:55 | call to method WriteLine | semmle.label | successor | | patterns.cs:53:17:53:22 | break; | patterns.cs:65:9:73:9 | switch (...) {...} | semmle.label | break | | patterns.cs:54:13:54:43 | case ...: | patterns.cs:54:23:54:28 | Int32 x2 | semmle.label | successor | -| patterns.cs:54:18:54:30 | { ... } | patterns.cs:54:18:54:30 | { ... } | semmle.label | successor | -| patterns.cs:54:18:54:30 | { ... } | patterns.cs:54:37:54:38 | access to local variable x2 | semmle.label | match | -| patterns.cs:54:18:54:30 | { ... } | patterns.cs:57:13:57:24 | case ...: | semmle.label | no-match | -| patterns.cs:54:23:54:28 | Int32 x2 | patterns.cs:54:18:54:30 | { ... } | semmle.label | successor | +| patterns.cs:54:18:54:30 | [match] { ... } | patterns.cs:54:18:54:30 | [match] { ... } | semmle.label | match | +| patterns.cs:54:18:54:30 | [match] { ... } | patterns.cs:54:37:54:38 | access to local variable x2 | semmle.label | match | +| patterns.cs:54:18:54:30 | [no-match] { ... } | patterns.cs:54:18:54:30 | [no-match] { ... } | semmle.label | no-match | +| patterns.cs:54:18:54:30 | [no-match] { ... } | patterns.cs:57:13:57:24 | case ...: | semmle.label | no-match | +| patterns.cs:54:23:54:28 | Int32 x2 | patterns.cs:54:18:54:30 | [match] { ... } | semmle.label | match | +| patterns.cs:54:23:54:28 | Int32 x2 | patterns.cs:54:18:54:30 | [no-match] { ... } | semmle.label | no-match | | patterns.cs:54:37:54:38 | access to local variable x2 | patterns.cs:54:42:54:42 | 2 | semmle.label | successor | | patterns.cs:54:37:54:42 | ... > ... | patterns.cs:55:17:55:38 | ...; | semmle.label | true | | patterns.cs:54:37:54:42 | ... > ... | patterns.cs:57:13:57:24 | case ...: | semmle.label | false | @@ -71,12 +80,15 @@ | patterns.cs:55:17:55:38 | ...; | patterns.cs:55:35:55:36 | access to local variable x2 | semmle.label | successor | | patterns.cs:55:35:55:36 | access to local variable x2 | patterns.cs:55:17:55:37 | call to method WriteLine | semmle.label | successor | | patterns.cs:56:17:56:22 | break; | patterns.cs:65:9:73:9 | switch (...) {...} | semmle.label | break | -| patterns.cs:57:13:57:24 | case ...: | patterns.cs:57:19:57:19 | 1 | semmle.label | successor | -| patterns.cs:57:18:57:23 | ( ... ) | patterns.cs:57:18:57:23 | { ... } | semmle.label | successor | -| patterns.cs:57:18:57:23 | { ... } | patterns.cs:58:17:58:22 | break; | semmle.label | match | -| patterns.cs:57:18:57:23 | { ... } | patterns.cs:59:13:59:28 | case ...: | semmle.label | no-match | -| patterns.cs:57:19:57:19 | 1 | patterns.cs:57:22:57:22 | 2 | semmle.label | successor | -| patterns.cs:57:22:57:22 | 2 | patterns.cs:57:18:57:23 | ( ... ) | semmle.label | successor | +| patterns.cs:57:13:57:24 | case ...: | patterns.cs:57:18:57:23 | ( ... ) | semmle.label | successor | +| patterns.cs:57:18:57:23 | ( ... ) | patterns.cs:57:18:57:23 | [no-match] { ... } | semmle.label | no-match | +| patterns.cs:57:18:57:23 | ( ... ) | patterns.cs:57:19:57:19 | 1 | semmle.label | match | +| patterns.cs:57:18:57:23 | [match] { ... } | patterns.cs:58:17:58:22 | break; | semmle.label | match | +| patterns.cs:57:18:57:23 | [no-match] { ... } | patterns.cs:59:13:59:28 | case ...: | semmle.label | no-match | +| patterns.cs:57:19:57:19 | 1 | patterns.cs:57:18:57:23 | [no-match] { ... } | semmle.label | no-match | +| patterns.cs:57:19:57:19 | 1 | patterns.cs:57:22:57:22 | 2 | semmle.label | match | +| patterns.cs:57:22:57:22 | 2 | patterns.cs:57:18:57:23 | [match] { ... } | semmle.label | match | +| patterns.cs:57:22:57:22 | 2 | patterns.cs:57:18:57:23 | [no-match] { ... } | semmle.label | no-match | | patterns.cs:58:17:58:22 | break; | patterns.cs:65:9:73:9 | switch (...) {...} | semmle.label | break | | patterns.cs:59:13:59:28 | case ...: | patterns.cs:59:23:59:23 | Int32 x | semmle.label | successor | | patterns.cs:59:18:59:27 | (..., ...) | patterns.cs:60:17:60:22 | break; | semmle.label | match | @@ -88,11 +100,15 @@ | patterns.cs:62:17:62:22 | break; | patterns.cs:65:9:73:9 | switch (...) {...} | semmle.label | break | | patterns.cs:65:9:73:9 | switch (...) {...} | patterns.cs:65:17:65:17 | access to local variable s | semmle.label | successor | | patterns.cs:65:17:65:17 | access to local variable s | patterns.cs:67:13:67:50 | case ...: | semmle.label | successor | -| patterns.cs:67:13:67:50 | case ...: | patterns.cs:67:32:67:36 | Int32 x | semmle.label | successor | -| patterns.cs:67:18:67:38 | { ... } | patterns.cs:67:45:67:45 | access to local variable x | semmle.label | match | -| patterns.cs:67:18:67:38 | { ... } | patterns.cs:70:13:70:51 | case ...: | semmle.label | no-match | -| patterns.cs:67:27:67:38 | { ... } | patterns.cs:67:18:67:38 | { ... } | semmle.label | successor | -| patterns.cs:67:32:67:36 | Int32 x | patterns.cs:67:27:67:38 | { ... } | semmle.label | successor | +| patterns.cs:67:13:67:50 | case ...: | patterns.cs:67:18:67:25 | access to type MyStruct | semmle.label | successor | +| patterns.cs:67:18:67:25 | access to type MyStruct | patterns.cs:67:18:67:38 | [no-match] { ... } | semmle.label | no-match | +| patterns.cs:67:18:67:25 | access to type MyStruct | patterns.cs:67:32:67:36 | Int32 x | semmle.label | match | +| patterns.cs:67:18:67:38 | [match] { ... } | patterns.cs:67:45:67:45 | access to local variable x | semmle.label | match | +| patterns.cs:67:18:67:38 | [no-match] { ... } | patterns.cs:70:13:70:51 | case ...: | semmle.label | no-match | +| patterns.cs:67:27:67:38 | [match] { ... } | patterns.cs:67:18:67:38 | [match] { ... } | semmle.label | match | +| patterns.cs:67:27:67:38 | [no-match] { ... } | patterns.cs:67:18:67:38 | [no-match] { ... } | semmle.label | no-match | +| patterns.cs:67:32:67:36 | Int32 x | patterns.cs:67:27:67:38 | [match] { ... } | semmle.label | match | +| patterns.cs:67:32:67:36 | Int32 x | patterns.cs:67:27:67:38 | [no-match] { ... } | semmle.label | no-match | | patterns.cs:67:45:67:45 | access to local variable x | patterns.cs:67:49:67:49 | 2 | semmle.label | successor | | patterns.cs:67:45:67:49 | ... > ... | patterns.cs:68:17:68:37 | ...; | semmle.label | true | | patterns.cs:67:45:67:49 | ... > ... | patterns.cs:70:13:70:51 | case ...: | semmle.label | false | @@ -102,11 +118,14 @@ | patterns.cs:68:35:68:35 | access to local variable x | patterns.cs:68:17:68:36 | call to method WriteLine | semmle.label | successor | | patterns.cs:69:17:69:22 | break; | patterns.cs:76:9:84:9 | switch (...) {...} | semmle.label | break | | patterns.cs:70:13:70:51 | case ...: | patterns.cs:70:18:70:38 | MyStruct ms | semmle.label | successor | -| patterns.cs:70:18:70:38 | MyStruct ms | patterns.cs:70:32:70:33 | 10 | semmle.label | successor | -| patterns.cs:70:18:70:38 | { ... } | patterns.cs:70:45:70:45 | access to local variable s | semmle.label | match | -| patterns.cs:70:18:70:38 | { ... } | patterns.cs:76:9:84:9 | switch (...) {...} | semmle.label | no-match | -| patterns.cs:70:27:70:35 | { ... } | patterns.cs:70:18:70:38 | { ... } | semmle.label | successor | -| patterns.cs:70:32:70:33 | 10 | patterns.cs:70:27:70:35 | { ... } | semmle.label | successor | +| patterns.cs:70:18:70:38 | MyStruct ms | patterns.cs:70:18:70:38 | [no-match] { ... } | semmle.label | no-match | +| patterns.cs:70:18:70:38 | MyStruct ms | patterns.cs:70:32:70:33 | 10 | semmle.label | match | +| patterns.cs:70:18:70:38 | [match] { ... } | patterns.cs:70:45:70:45 | access to local variable s | semmle.label | match | +| patterns.cs:70:18:70:38 | [no-match] { ... } | patterns.cs:76:9:84:9 | switch (...) {...} | semmle.label | no-match | +| patterns.cs:70:27:70:35 | [match] { ... } | patterns.cs:70:18:70:38 | [match] { ... } | semmle.label | match | +| patterns.cs:70:27:70:35 | [no-match] { ... } | patterns.cs:70:18:70:38 | [no-match] { ... } | semmle.label | no-match | +| patterns.cs:70:32:70:33 | 10 | patterns.cs:70:27:70:35 | [match] { ... } | semmle.label | match | +| patterns.cs:70:32:70:33 | 10 | patterns.cs:70:27:70:35 | [no-match] { ... } | semmle.label | no-match | | patterns.cs:70:45:70:45 | access to local variable s | patterns.cs:70:45:70:47 | access to field X | semmle.label | successor | | patterns.cs:70:45:70:47 | access to field X | patterns.cs:70:50:70:50 | 0 | semmle.label | successor | | patterns.cs:70:45:70:50 | ... == ... | patterns.cs:71:17:71:56 | ...; | semmle.label | true | @@ -118,12 +137,15 @@ | patterns.cs:72:17:72:22 | break; | patterns.cs:76:9:84:9 | switch (...) {...} | semmle.label | break | | patterns.cs:76:9:84:9 | switch (...) {...} | patterns.cs:76:17:76:28 | object creation of type Object | semmle.label | successor | | patterns.cs:76:17:76:28 | object creation of type Object | patterns.cs:78:13:78:43 | case ...: | semmle.label | successor | -| patterns.cs:78:13:78:43 | case ...: | patterns.cs:78:19:78:23 | Int32 x | semmle.label | successor | -| patterns.cs:78:18:78:33 | ( ... ) | patterns.cs:78:18:78:33 | { ... } | semmle.label | successor | -| patterns.cs:78:18:78:33 | { ... } | patterns.cs:78:40:78:40 | access to local variable x | semmle.label | match | -| patterns.cs:78:18:78:33 | { ... } | patterns.cs:80:13:80:20 | case ...: | semmle.label | no-match | -| patterns.cs:78:19:78:23 | Int32 x | patterns.cs:78:26:78:32 | Single y | semmle.label | successor | -| patterns.cs:78:26:78:32 | Single y | patterns.cs:78:18:78:33 | ( ... ) | semmle.label | successor | +| patterns.cs:78:13:78:43 | case ...: | patterns.cs:78:18:78:33 | ( ... ) | semmle.label | successor | +| patterns.cs:78:18:78:33 | ( ... ) | patterns.cs:78:18:78:33 | [no-match] { ... } | semmle.label | no-match | +| patterns.cs:78:18:78:33 | ( ... ) | patterns.cs:78:19:78:23 | Int32 x | semmle.label | match | +| patterns.cs:78:18:78:33 | [match] { ... } | patterns.cs:78:40:78:40 | access to local variable x | semmle.label | match | +| patterns.cs:78:18:78:33 | [no-match] { ... } | patterns.cs:80:13:80:20 | case ...: | semmle.label | no-match | +| patterns.cs:78:19:78:23 | Int32 x | patterns.cs:78:18:78:33 | [no-match] { ... } | semmle.label | no-match | +| patterns.cs:78:19:78:23 | Int32 x | patterns.cs:78:26:78:32 | Single y | semmle.label | match | +| patterns.cs:78:26:78:32 | Single y | patterns.cs:78:18:78:33 | [match] { ... } | semmle.label | match | +| patterns.cs:78:26:78:32 | Single y | patterns.cs:78:18:78:33 | [no-match] { ... } | semmle.label | no-match | | patterns.cs:78:40:78:40 | (...) ... | patterns.cs:78:42:78:42 | access to local variable y | semmle.label | successor | | patterns.cs:78:40:78:40 | access to local variable x | patterns.cs:78:40:78:40 | (...) ... | semmle.label | successor | | patterns.cs:78:40:78:42 | ... < ... | patterns.cs:79:17:79:22 | break; | semmle.label | true | @@ -131,41 +153,48 @@ | patterns.cs:78:42:78:42 | access to local variable y | patterns.cs:78:40:78:42 | ... < ... | semmle.label | successor | | patterns.cs:79:17:79:22 | break; | patterns.cs:86:9:89:9 | switch (...) {...} | semmle.label | break | | patterns.cs:80:13:80:20 | case ...: | patterns.cs:80:18:80:19 | ( ... ) | semmle.label | successor | -| patterns.cs:80:18:80:19 | ( ... ) | patterns.cs:80:18:80:19 | { ... } | semmle.label | successor | -| patterns.cs:80:18:80:19 | { ... } | patterns.cs:81:17:81:22 | break; | semmle.label | match | -| patterns.cs:80:18:80:19 | { ... } | patterns.cs:82:13:82:20 | case ...: | semmle.label | no-match | -| patterns.cs:81:17:81:22 | break; | patterns.cs:86:9:89:9 | switch (...) {...} | semmle.label | break | +| patterns.cs:80:18:80:19 | ( ... ) | patterns.cs:80:18:80:19 | [no-match] { ... } | semmle.label | no-match | +| patterns.cs:80:18:80:19 | [no-match] { ... } | patterns.cs:82:13:82:20 | case ...: | semmle.label | no-match | | patterns.cs:82:13:82:20 | case ...: | patterns.cs:82:18:82:19 | { ... } | semmle.label | successor | -| patterns.cs:82:18:82:19 | { ... } | patterns.cs:82:18:82:19 | { ... } | semmle.label | successor | -| patterns.cs:82:18:82:19 | { ... } | patterns.cs:83:17:83:22 | break; | semmle.label | match | -| patterns.cs:82:18:82:19 | { ... } | patterns.cs:86:9:89:9 | switch (...) {...} | semmle.label | no-match | +| patterns.cs:82:18:82:19 | [match] { ... } | patterns.cs:83:17:83:22 | break; | semmle.label | match | +| patterns.cs:82:18:82:19 | [no-match] { ... } | patterns.cs:86:9:89:9 | switch (...) {...} | semmle.label | no-match | +| patterns.cs:82:18:82:19 | { ... } | patterns.cs:82:18:82:19 | [match] { ... } | semmle.label | match | +| patterns.cs:82:18:82:19 | { ... } | patterns.cs:82:18:82:19 | [no-match] { ... } | semmle.label | no-match | | patterns.cs:83:17:83:22 | break; | patterns.cs:86:9:89:9 | switch (...) {...} | semmle.label | break | | patterns.cs:86:9:89:9 | switch (...) {...} | patterns.cs:86:16:86:16 | 1 | semmle.label | successor | | patterns.cs:86:15:86:19 | (..., ...) | patterns.cs:88:13:88:24 | case ...: | semmle.label | successor | | patterns.cs:86:16:86:16 | 1 | patterns.cs:86:18:86:18 | 2 | semmle.label | successor | | patterns.cs:86:18:86:18 | 2 | patterns.cs:86:15:86:19 | (..., ...) | semmle.label | successor | -| patterns.cs:88:13:88:24 | case ...: | patterns.cs:88:19:88:19 | 1 | semmle.label | successor | -| patterns.cs:88:18:88:23 | ( ... ) | patterns.cs:88:18:88:23 | { ... } | semmle.label | successor | -| patterns.cs:88:18:88:23 | { ... } | patterns.cs:88:26:88:31 | break; | semmle.label | match | -| patterns.cs:88:18:88:23 | { ... } | patterns.cs:91:9:95:9 | switch (...) {...} | semmle.label | no-match | -| patterns.cs:88:19:88:19 | 1 | patterns.cs:88:22:88:22 | 2 | semmle.label | successor | -| patterns.cs:88:22:88:22 | 2 | patterns.cs:88:18:88:23 | ( ... ) | semmle.label | successor | +| patterns.cs:88:13:88:24 | case ...: | patterns.cs:88:18:88:23 | ( ... ) | semmle.label | successor | +| patterns.cs:88:18:88:23 | ( ... ) | patterns.cs:88:18:88:23 | [no-match] { ... } | semmle.label | no-match | +| patterns.cs:88:18:88:23 | ( ... ) | patterns.cs:88:19:88:19 | 1 | semmle.label | match | +| patterns.cs:88:18:88:23 | [match] { ... } | patterns.cs:88:26:88:31 | break; | semmle.label | match | +| patterns.cs:88:18:88:23 | [no-match] { ... } | patterns.cs:91:9:95:9 | switch (...) {...} | semmle.label | no-match | +| patterns.cs:88:19:88:19 | 1 | patterns.cs:88:18:88:23 | [no-match] { ... } | semmle.label | no-match | +| patterns.cs:88:19:88:19 | 1 | patterns.cs:88:22:88:22 | 2 | semmle.label | match | +| patterns.cs:88:22:88:22 | 2 | patterns.cs:88:18:88:23 | [match] { ... } | semmle.label | match | +| patterns.cs:88:22:88:22 | 2 | patterns.cs:88:18:88:23 | [no-match] { ... } | semmle.label | no-match | | patterns.cs:88:26:88:31 | break; | patterns.cs:91:9:95:9 | switch (...) {...} | semmle.label | break | | patterns.cs:91:9:95:9 | switch (...) {...} | patterns.cs:91:17:91:17 | 1 | semmle.label | successor | | patterns.cs:91:16:91:20 | (..., ...) | patterns.cs:93:13:93:28 | case ...: | semmle.label | successor | | patterns.cs:91:17:91:17 | 1 | patterns.cs:91:19:91:19 | 2 | semmle.label | successor | | patterns.cs:91:19:91:19 | 2 | patterns.cs:91:16:91:20 | (..., ...) | semmle.label | successor | -| patterns.cs:93:13:93:28 | case ...: | patterns.cs:93:19:93:19 | 1 | semmle.label | successor | -| patterns.cs:93:18:93:27 | ( ... ) | patterns.cs:93:18:93:27 | { ... } | semmle.label | successor | -| patterns.cs:93:18:93:27 | { ... } | patterns.cs:93:30:93:35 | break; | semmle.label | match | -| patterns.cs:93:18:93:27 | { ... } | patterns.cs:94:13:94:24 | case ...: | semmle.label | no-match | -| patterns.cs:93:19:93:19 | 1 | patterns.cs:93:22:93:26 | Int32 x | semmle.label | successor | -| patterns.cs:93:22:93:26 | Int32 x | patterns.cs:93:18:93:27 | ( ... ) | semmle.label | successor | +| patterns.cs:93:13:93:28 | case ...: | patterns.cs:93:18:93:27 | ( ... ) | semmle.label | successor | +| patterns.cs:93:18:93:27 | ( ... ) | patterns.cs:93:18:93:27 | [no-match] { ... } | semmle.label | no-match | +| patterns.cs:93:18:93:27 | ( ... ) | patterns.cs:93:19:93:19 | 1 | semmle.label | match | +| patterns.cs:93:18:93:27 | [match] { ... } | patterns.cs:93:30:93:35 | break; | semmle.label | match | +| patterns.cs:93:18:93:27 | [no-match] { ... } | patterns.cs:94:13:94:24 | case ...: | semmle.label | no-match | +| patterns.cs:93:19:93:19 | 1 | patterns.cs:93:18:93:27 | [no-match] { ... } | semmle.label | no-match | +| patterns.cs:93:19:93:19 | 1 | patterns.cs:93:22:93:26 | Int32 x | semmle.label | match | +| patterns.cs:93:22:93:26 | Int32 x | patterns.cs:93:18:93:27 | [match] { ... } | semmle.label | match | +| patterns.cs:93:22:93:26 | Int32 x | patterns.cs:93:18:93:27 | [no-match] { ... } | semmle.label | no-match | | patterns.cs:93:30:93:35 | break; | patterns.cs:32:10:32:25 | exit SwitchStatements (normal) | semmle.label | break | -| patterns.cs:94:13:94:24 | case ...: | patterns.cs:94:19:94:19 | 2 | semmle.label | successor | -| patterns.cs:94:18:94:23 | ( ... ) | patterns.cs:94:18:94:23 | { ... } | semmle.label | successor | -| patterns.cs:94:18:94:23 | { ... } | patterns.cs:32:10:32:25 | exit SwitchStatements (normal) | semmle.label | no-match | -| patterns.cs:94:18:94:23 | { ... } | patterns.cs:94:26:94:31 | break; | semmle.label | match | -| patterns.cs:94:19:94:19 | 2 | patterns.cs:94:22:94:22 | _ | semmle.label | successor | -| patterns.cs:94:22:94:22 | _ | patterns.cs:94:18:94:23 | ( ... ) | semmle.label | successor | +| patterns.cs:94:13:94:24 | case ...: | patterns.cs:94:18:94:23 | ( ... ) | semmle.label | successor | +| patterns.cs:94:18:94:23 | ( ... ) | patterns.cs:94:18:94:23 | [no-match] { ... } | semmle.label | no-match | +| patterns.cs:94:18:94:23 | ( ... ) | patterns.cs:94:19:94:19 | 2 | semmle.label | match | +| patterns.cs:94:18:94:23 | [match] { ... } | patterns.cs:94:26:94:31 | break; | semmle.label | match | +| patterns.cs:94:18:94:23 | [no-match] { ... } | patterns.cs:32:10:32:25 | exit SwitchStatements (normal) | semmle.label | no-match | +| patterns.cs:94:19:94:19 | 2 | patterns.cs:94:18:94:23 | [no-match] { ... } | semmle.label | no-match | +| patterns.cs:94:19:94:19 | 2 | patterns.cs:94:22:94:22 | _ | semmle.label | match | +| patterns.cs:94:22:94:22 | _ | patterns.cs:94:18:94:23 | [match] { ... } | semmle.label | match | | patterns.cs:94:26:94:31 | break; | patterns.cs:32:10:32:25 | exit SwitchStatements (normal) | semmle.label | break | diff --git a/csharp/ql/test/library-tests/csharp9/AnonymousObjectCreation.cs b/csharp/ql/test/library-tests/csharp9/AnonymousObjectCreation.cs new file mode 100644 index 00000000000..da10c241883 --- /dev/null +++ b/csharp/ql/test/library-tests/csharp9/AnonymousObjectCreation.cs @@ -0,0 +1,27 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +public class AnonObj +{ + private List<AnonObj> l = new(); + + public int Prop1 { get; set; } + + public AnonObj M1(AnonObj t) + { + this.M1(new() { Prop1 = 1 }); + return new(); + } + + delegate void D(int x); + + void M2(int x) { } + + D GetM() { return new(M2); } + + void MethodAdd() + { + List<int> list = new();// { 1, 2, 3 }; todo: the initializer causes an extraction error + } +} \ No newline at end of file diff --git a/csharp/ql/test/library-tests/csharp9/AnonymousObjectCreation.expected b/csharp/ql/test/library-tests/csharp9/AnonymousObjectCreation.expected new file mode 100644 index 00000000000..4e1357facb7 --- /dev/null +++ b/csharp/ql/test/library-tests/csharp9/AnonymousObjectCreation.expected @@ -0,0 +1,7 @@ +implicitlyTypedObjectCreation +| AnonymousObjectCreation.cs:7:31:7:35 | object creation of type List<AnonObj> | +| AnonymousObjectCreation.cs:13:17:13:35 | object creation of type AnonObj | +| AnonymousObjectCreation.cs:14:16:14:20 | object creation of type AnonObj | +| AnonymousObjectCreation.cs:25:26:25:30 | object creation of type List<Int32> | +implicitlyTypedDelegateCreation +| AnonymousObjectCreation.cs:21:23:21:29 | delegate creation of type D | diff --git a/csharp/ql/test/library-tests/csharp9/AnonymousObjectCreation.ql b/csharp/ql/test/library-tests/csharp9/AnonymousObjectCreation.ql new file mode 100644 index 00000000000..835e9c9dca5 --- /dev/null +++ b/csharp/ql/test/library-tests/csharp9/AnonymousObjectCreation.ql @@ -0,0 +1,9 @@ +import csharp + +query predicate implicitlyTypedObjectCreation(ObjectCreation creation) { + creation.isImplicitlyTyped() +} + +query predicate implicitlyTypedDelegateCreation(ExplicitDelegateCreation creation) { + creation.isImplicitlyTyped() +} diff --git a/csharp/ql/test/library-tests/csharp9/BinaryPattern.cs b/csharp/ql/test/library-tests/csharp9/BinaryPattern.cs new file mode 100644 index 00000000000..45570ed9695 --- /dev/null +++ b/csharp/ql/test/library-tests/csharp9/BinaryPattern.cs @@ -0,0 +1,22 @@ +using System; + +public class BinaryPattern +{ + public int P1 { get; set; } + + public static bool M1(char c) => + c is 'a' or 'b'; + public static bool M2(object c) => + c is object o and BinaryPattern { P1: 1 } u; + public static bool M3(object c) => + c is object o and BinaryPattern u; + + public static string M4(int i) + { + return i switch + { + 1 or 2 => "1 or 2", + _ => "other" + }; + } +} \ No newline at end of file diff --git a/csharp/ql/test/library-tests/csharp9/ForeachExtension.cs b/csharp/ql/test/library-tests/csharp9/ForeachExtension.cs new file mode 100644 index 00000000000..6e2af21e323 --- /dev/null +++ b/csharp/ql/test/library-tests/csharp9/ForeachExtension.cs @@ -0,0 +1,48 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +static class Extensions +{ + public static IEnumerator<T> GetEnumerator<T>(this IEnumerator<T> enumerator) => enumerator; + public static IAsyncEnumerator<T> GetAsyncEnumerator<T>(this IAsyncEnumerator<T> enumerator) => enumerator; + public static IEnumerator<int> GetEnumerator(this int count) + { + for (int i = 0; i < count; i++) + { + yield return i; + } + } +} + +class Program +{ + async Task Main() + { + IEnumerator<int> enumerator1 = Enumerable.Range(0, 10).GetEnumerator(); + foreach (var item in enumerator1) + { + } + + IAsyncEnumerator<int> enumerator2 = GetAsyncEnumerator(); + await foreach (var item in enumerator2) + { + } + + foreach (var item in 42) + { + } + + foreach (var i in new int[] { 1, 2, 3 }) // not extension + { + } + } + + static async IAsyncEnumerator<int> GetAsyncEnumerator() + { + yield return 0; + await Task.Delay(1); + yield return 1; + } +} diff --git a/csharp/ql/test/library-tests/csharp9/FunctionPointer.cs b/csharp/ql/test/library-tests/csharp9/FunctionPointer.cs new file mode 100644 index 00000000000..3c51dcc1744 --- /dev/null +++ b/csharp/ql/test/library-tests/csharp9/FunctionPointer.cs @@ -0,0 +1,52 @@ +using System; + + + +public class FnPointer +{ + public unsafe static class Program + { + static delegate*<int> pointer = &M0; + + public static int M0() + { + return 0; + } + + static void M1(delegate*<ref int, out object?, ref readonly int> f) + { + int i = 42; + int j = f(ref i, out object? o); + } + + static void M2<T>(delegate* unmanaged[Stdcall/*, StdcallSuppressGCTransition*/]<ref int, out object?, T, void> f) where T : new() + { + int i = 42; + f(ref i, out object? o, new T()); + } + + static void M3(delegate* managed<ref int, out object?, in int, ref int> f) + { + int i = 42; + ref int j = ref f(ref i, out object? o, in i); + } + + static void M4<T>(delegate*<T, int> f) where T : new() + { + int j = f(new T()); + } + + static void M5(delegate*<B, A> f, delegate*<A, B> ff) + { + M5(ff, ff); // implicit conversion due to implicit reference conversion + } + + static void M6(delegate*<int*, void*> f, delegate*<void*, int*> ff) + { + M6(ff, ff); // implicit conversion due to implicit pointer conversion + } + + class A { } + class B : A { } + } +} \ No newline at end of file diff --git a/csharp/ql/test/library-tests/csharp9/FunctionPointer.expected b/csharp/ql/test/library-tests/csharp9/FunctionPointer.expected new file mode 100644 index 00000000000..d39e7d7d2af --- /dev/null +++ b/csharp/ql/test/library-tests/csharp9/FunctionPointer.expected @@ -0,0 +1,33 @@ +type +| file://:0:0:0:0 | delegate* default<A,B> | B | DefaultCallingConvention | +| file://:0:0:0:0 | delegate* default<B,A> | A | DefaultCallingConvention | +| file://:0:0:0:0 | delegate* default<Int32 ref,Object out,Int32 in,Int32 ref> | ref int | DefaultCallingConvention | +| file://:0:0:0:0 | delegate* default<Int32 ref,Object out,Int32 ref readonly> | readonly int | DefaultCallingConvention | +| file://:0:0:0:0 | delegate* default<Int32*,Void*> | Void* | DefaultCallingConvention | +| file://:0:0:0:0 | delegate* default<Int32> | int | DefaultCallingConvention | +| file://:0:0:0:0 | delegate* default<T,Int32> | int | DefaultCallingConvention | +| file://:0:0:0:0 | delegate* default<Void*,Int32*> | int* | DefaultCallingConvention | +| file://:0:0:0:0 | delegate* stdcall<Int32 ref,Object out,T,Void> | Void | StdCallCallingConvention | +unmanagedCallingConvention +parameter +| file://:0:0:0:0 | delegate* default<A,B> | 0 | file://:0:0:0:0 | | A | +| file://:0:0:0:0 | delegate* default<B,A> | 0 | file://:0:0:0:0 | | B | +| file://:0:0:0:0 | delegate* default<Int32 ref,Object out,Int32 in,Int32 ref> | 0 | file://:0:0:0:0 | | ref int! | +| file://:0:0:0:0 | delegate* default<Int32 ref,Object out,Int32 in,Int32 ref> | 1 | file://:0:0:0:0 | `1 | out object? | +| file://:0:0:0:0 | delegate* default<Int32 ref,Object out,Int32 in,Int32 ref> | 2 | file://:0:0:0:0 | `2 | readonly int! | +| file://:0:0:0:0 | delegate* default<Int32 ref,Object out,Int32 ref readonly> | 0 | file://:0:0:0:0 | | ref int! | +| file://:0:0:0:0 | delegate* default<Int32 ref,Object out,Int32 ref readonly> | 1 | file://:0:0:0:0 | `1 | out object? | +| file://:0:0:0:0 | delegate* default<Int32*,Void*> | 0 | file://:0:0:0:0 | | int*! | +| file://:0:0:0:0 | delegate* default<T,Int32> | 0 | file://:0:0:0:0 | | T | +| file://:0:0:0:0 | delegate* default<Void*,Int32*> | 0 | file://:0:0:0:0 | | Void*! | +| file://:0:0:0:0 | delegate* stdcall<Int32 ref,Object out,T,Void> | 0 | file://:0:0:0:0 | | ref int! | +| file://:0:0:0:0 | delegate* stdcall<Int32 ref,Object out,T,Void> | 1 | file://:0:0:0:0 | `1 | out object? | +| file://:0:0:0:0 | delegate* stdcall<Int32 ref,Object out,T,Void> | 2 | file://:0:0:0:0 | `2 | T | +invocation +| FunctionPointer.cs:19:21:19:43 | function pointer call | +| FunctionPointer.cs:25:13:25:44 | function pointer call | +| FunctionPointer.cs:31:29:31:57 | function pointer call | +| FunctionPointer.cs:36:21:36:30 | function pointer call | +casts +| FunctionPointer.cs:41:16:41:17 | (...) ... | file://:0:0:0:0 | delegate* default<A,B> | file://:0:0:0:0 | delegate* default<B,A> | +| FunctionPointer.cs:46:16:46:17 | (...) ... | file://:0:0:0:0 | delegate* default<Void*,Int32*> | file://:0:0:0:0 | delegate* default<Int32*,Void*> | diff --git a/csharp/ql/test/library-tests/csharp9/FunctionPointer.ql b/csharp/ql/test/library-tests/csharp9/FunctionPointer.ql new file mode 100644 index 00000000000..25f0254ef45 --- /dev/null +++ b/csharp/ql/test/library-tests/csharp9/FunctionPointer.ql @@ -0,0 +1,20 @@ +import csharp + +query predicate type(FunctionPointerType fpt, string returnType, string callingConvention) { + fpt.getAnnotatedReturnType().toString() = returnType and + fpt.getCallingConvention().toString() = callingConvention +} + +query predicate unmanagedCallingConvention(FunctionPointerType fpt, int i, string callingConvention) { + fpt.getUnmanagedCallingConvention(i).toString() = callingConvention +} + +query predicate parameter(FunctionPointerType fpt, int i, Parameter p, string t) { + fpt.getParameter(i) = p and p.getAnnotatedType().toString() = t +} + +query predicate invocation(FunctionPointerCall fpc) { any() } + +query predicate casts(ImplicitCast cast, FunctionPointerType fromType, FunctionPointerType toType) { + cast.getSourceType() = fromType and cast.getTargetType() = toType +} diff --git a/csharp/ql/test/library-tests/csharp9/GlobalStmt.cs b/csharp/ql/test/library-tests/csharp9/GlobalStmt.cs new file mode 100644 index 00000000000..6b8958d7fbd --- /dev/null +++ b/csharp/ql/test/library-tests/csharp9/GlobalStmt.cs @@ -0,0 +1,25 @@ +/* + Global statements are not allowed in 'library' target. + + semmle-extractor-options: --standalone +*/ + +using System; + +[assembly: Attr] // not a global stmt + +Console.WriteLine("1"); +Console.WriteLine("2"); +M(); + +void M() +{ +} + +public class Attr : Attribute +{ + void M1() + { + Console.WriteLine("3"); + } +} \ No newline at end of file diff --git a/csharp/ql/test/library-tests/csharp9/InitOnlyProperty.cs b/csharp/ql/test/library-tests/csharp9/InitOnlyProperty.cs new file mode 100644 index 00000000000..e5a27113566 --- /dev/null +++ b/csharp/ql/test/library-tests/csharp9/InitOnlyProperty.cs @@ -0,0 +1,37 @@ +using System; + +public class Base +{ + public int Prop0 { get { return 1; } init { Prop1 = value; } } + public virtual int Prop1 { get; init; } + public virtual int Prop2 { get; set; } + +} + +public class Derived : Base +{ + public override int Prop1 { get; init; } + public int Prop2 + { + get { return 0; } + init + { + System.Console.WriteLine(value); + Prop1 = value; + Prop0 = value; + } + } +} + +public class C1 +{ + public void M1() + { + var d = new Derived + { + Prop1 = 1, + Prop2 = 2, + Prop0 = 0 + }; + } +} \ No newline at end of file diff --git a/csharp/ql/test/library-tests/csharp9/IsExternalInit.cs b/csharp/ql/test/library-tests/csharp9/IsExternalInit.cs new file mode 100644 index 00000000000..354491fdec2 --- /dev/null +++ b/csharp/ql/test/library-tests/csharp9/IsExternalInit.cs @@ -0,0 +1,7 @@ +using System; +using System.Text; + +namespace System.Runtime.CompilerServices +{ + public class IsExternalInit { } +} diff --git a/csharp/ql/test/library-tests/csharp9/LocalFunctions.expected b/csharp/ql/test/library-tests/csharp9/LocalFunctions.expected index fd746b2a58b..c57ece05e59 100644 --- a/csharp/ql/test/library-tests/csharp9/LocalFunctions.expected +++ b/csharp/ql/test/library-tests/csharp9/LocalFunctions.expected @@ -1,6 +1,7 @@ noBody | LocalFunction.cs:16:9:16:41 | localExtern | localFunctionModifier +| GlobalStmt.cs:15:1:17:1 | M | private | | LambdaModifier.cs:8:9:8:36 | m | private | | LocalFunction.cs:9:9:12:9 | mul | async | | LocalFunction.cs:9:9:12:9 | mul | private | diff --git a/csharp/ql/test/library-tests/csharp9/PrintAst.expected b/csharp/ql/test/library-tests/csharp9/PrintAst.expected index 42a0fad8d14..e09c7067139 100644 --- a/csharp/ql/test/library-tests/csharp9/PrintAst.expected +++ b/csharp/ql/test/library-tests/csharp9/PrintAst.expected @@ -1,3 +1,122 @@ +AnonymousObjectCreation.cs: +# 5| [Class] AnonObj +# 7| 5: [Field] l +# 7| -1: [TypeMention] List<AnonObj> +# 7| 1: [TypeMention] AnonObj +# 7| 1: [AssignExpr] ... = ... +# 7| 0: [FieldAccess] access to field l +# 7| 1: [ObjectCreation] object creation of type List<AnonObj> +# 9| 6: [Property] Prop1 +# 9| -1: [TypeMention] int +# 9| 3: [Getter] get_Prop1 +# 9| 4: [Setter] set_Prop1 +#-----| 2: (Parameters) +# 9| 0: [Parameter] value +# 11| 7: [Method] M1 +# 11| -1: [TypeMention] AnonObj +#-----| 2: (Parameters) +# 11| 0: [Parameter] t +# 11| -1: [TypeMention] AnonObj +# 12| 4: [BlockStmt] {...} +# 13| 0: [ExprStmt] ...; +# 13| 0: [MethodCall] call to method M1 +# 13| -1: [ThisAccess] this access +# 13| 0: [ObjectCreation] object creation of type AnonObj +# 13| -1: [ObjectInitializer] { ..., ... } +# 13| 0: [MemberInitializer] ... = ... +# 13| 0: [PropertyCall] access to property Prop1 +# 13| 1: [IntLiteral] 1 +# 14| 1: [ReturnStmt] return ...; +# 14| 0: [ObjectCreation] object creation of type AnonObj +# 17| 8: [DelegateType] D +#-----| 2: (Parameters) +# 17| 0: [Parameter] x +# 17| -1: [TypeMention] int +# 19| 9: [Method] M2 +# 19| -1: [TypeMention] Void +#-----| 2: (Parameters) +# 19| 0: [Parameter] x +# 19| -1: [TypeMention] int +# 19| 4: [BlockStmt] {...} +# 21| 10: [Method] GetM +# 21| -1: [TypeMention] D +# 21| 4: [BlockStmt] {...} +# 21| 0: [ReturnStmt] return ...; +# 21| 0: [ExplicitDelegateCreation] delegate creation of type D +# 21| 0: [ImplicitDelegateCreation] delegate creation of type D +# 21| 0: [MethodAccess] access to method M2 +# 23| 11: [Method] MethodAdd +# 23| -1: [TypeMention] Void +# 24| 4: [BlockStmt] {...} +# 25| 0: [LocalVariableDeclStmt] ... ...; +# 25| 0: [LocalVariableDeclAndInitExpr] List<Int32> list = ... +# 25| -1: [TypeMention] List<Int32> +# 25| 1: [TypeMention] int +# 25| 0: [LocalVariableAccess] access to local variable list +# 25| 1: [ObjectCreation] object creation of type List<Int32> +BinaryPattern.cs: +# 3| [Class] BinaryPattern +# 5| 5: [Property] P1 +# 5| -1: [TypeMention] int +# 5| 3: [Getter] get_P1 +# 5| 4: [Setter] set_P1 +#-----| 2: (Parameters) +# 5| 0: [Parameter] value +# 7| 6: [Method] M1 +# 7| -1: [TypeMention] bool +#-----| 2: (Parameters) +# 7| 0: [Parameter] c +# 7| -1: [TypeMention] char +# 8| 4: [IsExpr] ... is ... +# 8| 0: [ParameterAccess] access to parameter c +# 8| 1: [OrPatternExpr] ... or ... +# 8| 0: [CharLiteral,ConstantPatternExpr] a +# 8| 1: [CharLiteral,ConstantPatternExpr] b +# 9| 7: [Method] M2 +# 9| -1: [TypeMention] bool +#-----| 2: (Parameters) +# 9| 0: [Parameter] c +# 9| -1: [TypeMention] object +# 10| 4: [IsExpr] ... is ... +# 10| 0: [ParameterAccess] access to parameter c +# 10| 1: [AndPatternExpr] ... and ... +# 10| 0: [VariablePatternExpr] Object o +# 10| 0: [TypeMention] object +# 10| 1: [RecursivePatternExpr] { ... } +# 10| 0: [VariablePatternExpr] BinaryPattern u +# 10| 1: [TypeAccessPatternExpr] access to type BinaryPattern +# 10| 0: [TypeMention] BinaryPattern +# 10| 3: [PropertyPatternExpr] { ... } +# 10| 0: [ConstantPatternExpr,IntLiteral,LabeledPatternExpr] 1 +# 11| 8: [Method] M3 +# 11| -1: [TypeMention] bool +#-----| 2: (Parameters) +# 11| 0: [Parameter] c +# 11| -1: [TypeMention] object +# 12| 4: [IsExpr] ... is ... +# 12| 0: [ParameterAccess] access to parameter c +# 12| 1: [AndPatternExpr] ... and ... +# 12| 0: [VariablePatternExpr] Object o +# 12| 0: [TypeMention] object +# 12| 1: [VariablePatternExpr] BinaryPattern u +# 12| 0: [TypeMention] BinaryPattern +# 14| 9: [Method] M4 +# 14| -1: [TypeMention] string +#-----| 2: (Parameters) +# 14| 0: [Parameter] i +# 14| -1: [TypeMention] int +# 15| 4: [BlockStmt] {...} +# 16| 0: [ReturnStmt] return ...; +# 16| 0: [SwitchExpr] ... switch { ... } +# 16| -1: [ParameterAccess] access to parameter i +# 18| 0: [SwitchCaseExpr] ... => ... +# 18| 0: [OrPatternExpr] ... or ... +# 18| 0: [ConstantPatternExpr,IntLiteral] 1 +# 18| 1: [ConstantPatternExpr,IntLiteral] 2 +# 18| 2: [StringLiteral] "1 or 2" +# 19| 1: [SwitchCaseExpr] ... => ... +# 19| 0: [DiscardPatternExpr] _ +# 19| 2: [StringLiteral] "other" Discard.cs: # 3| [Class] Discard # 5| 5: [Method] M1 @@ -47,6 +166,345 @@ Discard.cs: # 10| 4: [BlockStmt] {...} # 10| 0: [ReturnStmt] return ...; # 10| 0: [IntLiteral] 0 +ForeachExtension.cs: +# 6| [Class] Extensions +# 8| 4: [ExtensionMethod] GetEnumerator +# 8| -1: [TypeMention] IEnumerator<T> +# 8| 1: [TypeMention] T +#-----| 1: (Type parameters) +# 8| 0: [TypeParameter] T +#-----| 2: (Parameters) +# 8| 0: [Parameter] enumerator +# 8| -1: [TypeMention] IEnumerator<T> +# 8| 1: [TypeMention] T +# 8| 4: [ParameterAccess] access to parameter enumerator +# 9| 6: [ExtensionMethod] GetAsyncEnumerator +# 9| -1: [TypeMention] IAsyncEnumerator<T> +# 9| 1: [TypeMention] T +#-----| 1: (Type parameters) +# 9| 0: [TypeParameter] T +#-----| 2: (Parameters) +# 9| 0: [Parameter] enumerator +# 9| -1: [TypeMention] IAsyncEnumerator<T> +# 9| 1: [TypeMention] T +# 9| 4: [ParameterAccess] access to parameter enumerator +# 10| 8: [ExtensionMethod] GetEnumerator +# 10| -1: [TypeMention] IEnumerator<Int32> +# 10| 1: [TypeMention] int +#-----| 2: (Parameters) +# 10| 0: [Parameter] count +# 10| -1: [TypeMention] int +# 11| 4: [BlockStmt] {...} +# 12| 0: [ForStmt] for (...;...;...) ... +# 12| -1: [LocalVariableDeclAndInitExpr] Int32 i = ... +# 12| -1: [TypeMention] int +# 12| 0: [LocalVariableAccess] access to local variable i +# 12| 1: [IntLiteral] 0 +# 12| 0: [LTExpr] ... < ... +# 12| 0: [LocalVariableAccess] access to local variable i +# 12| 1: [ParameterAccess] access to parameter count +# 12| 1: [PostIncrExpr] ...++ +# 12| 0: [LocalVariableAccess] access to local variable i +# 13| 2: [BlockStmt] {...} +# 14| 0: [YieldReturnStmt] yield return ...; +# 14| 0: [LocalVariableAccess] access to local variable i +# 19| [Class] Program +# 21| 5: [Method] Main +# 21| -1: [TypeMention] Task +# 22| 4: [BlockStmt] {...} +# 23| 0: [LocalVariableDeclStmt] ... ...; +# 23| 0: [LocalVariableDeclAndInitExpr] IEnumerator<Int32> enumerator1 = ... +# 23| -1: [TypeMention] IEnumerator<Int32> +# 23| 1: [TypeMention] int +# 23| 0: [LocalVariableAccess] access to local variable enumerator1 +# 23| 1: [MethodCall] call to method GetEnumerator +# 23| -1: [MethodCall] call to method Range +# 23| -1: [TypeAccess] access to type Enumerable +# 23| 0: [TypeMention] Enumerable +# 23| 0: [IntLiteral] 0 +# 23| 1: [IntLiteral] 10 +# 24| 1: [ForeachStmt] foreach (... ... in ...) ... +# 24| 0: [LocalVariableDeclExpr] Int32 item +# 24| 0: [TypeMention] int +# 24| 1: [LocalVariableAccess] access to local variable enumerator1 +# 25| 2: [BlockStmt] {...} +# 28| 2: [LocalVariableDeclStmt] ... ...; +# 28| 0: [LocalVariableDeclAndInitExpr] IAsyncEnumerator<Int32> enumerator2 = ... +# 28| -1: [TypeMention] IAsyncEnumerator<Int32> +# 28| 1: [TypeMention] int +# 28| 0: [LocalVariableAccess] access to local variable enumerator2 +# 28| 1: [MethodCall] call to method GetAsyncEnumerator +# 29| 3: [ForeachStmt] foreach (... ... in ...) ... +# 29| 0: [LocalVariableDeclExpr] Int32 item +# 29| 0: [TypeMention] int +# 29| 1: [LocalVariableAccess] access to local variable enumerator2 +# 30| 2: [BlockStmt] {...} +# 33| 4: [ForeachStmt] foreach (... ... in ...) ... +# 33| 0: [LocalVariableDeclExpr] Int32 item +# 33| 0: [TypeMention] int +# 33| 1: [IntLiteral] 42 +# 34| 2: [BlockStmt] {...} +# 37| 5: [ForeachStmt] foreach (... ... in ...) ... +# 37| 0: [LocalVariableDeclExpr] Int32 i +# 37| 0: [TypeMention] int +# 37| 1: [ArrayCreation] array creation of type Int32[] +# 37| -2: [TypeMention] Int32[] +# 37| 1: [TypeMention] int +# 37| -1: [ArrayInitializer] { ..., ... } +# 37| 0: [IntLiteral] 1 +# 37| 1: [IntLiteral] 2 +# 37| 2: [IntLiteral] 3 +# 38| 2: [BlockStmt] {...} +# 42| 6: [Method] GetAsyncEnumerator +# 42| -1: [TypeMention] IAsyncEnumerator<Int32> +# 42| 1: [TypeMention] int +# 43| 4: [BlockStmt] {...} +# 44| 0: [YieldReturnStmt] yield return ...; +# 44| 0: [IntLiteral] 0 +# 45| 1: [ExprStmt] ...; +# 45| 0: [AwaitExpr] await ... +# 45| 0: [MethodCall] call to method Delay +# 45| -1: [TypeAccess] access to type Task +# 45| 0: [TypeMention] Task +# 45| 0: [IntLiteral] 1 +# 46| 2: [YieldReturnStmt] yield return ...; +# 46| 0: [IntLiteral] 1 +FunctionPointer.cs: +# 5| [Class] FnPointer +# 7| 5: [Class] Program +# 9| 5: [Field] pointer +# 9| -1: [TypeMention] delegate* default<Int32> +# 9| 1: [AssignExpr] ... = ... +# 9| 0: [FieldAccess] access to field pointer +# 9| 1: [AddressOfExpr] &... +# 9| 0: [MethodAccess] access to method M0 +# 11| 6: [Method] M0 +# 11| -1: [TypeMention] int +# 12| 4: [BlockStmt] {...} +# 13| 0: [ReturnStmt] return ...; +# 13| 0: [IntLiteral] 0 +# 16| 7: [Method] M1 +# 16| -1: [TypeMention] Void +#-----| 2: (Parameters) +# 16| 0: [Parameter] f +# 16| -1: [TypeMention] delegate* default<Int32 ref,Object out,Int32 ref readonly> +# 17| 4: [BlockStmt] {...} +# 18| 0: [LocalVariableDeclStmt] ... ...; +# 18| 0: [LocalVariableDeclAndInitExpr] Int32 i = ... +# 18| -1: [TypeMention] int +# 18| 0: [LocalVariableAccess] access to local variable i +# 18| 1: [IntLiteral] 42 +# 19| 1: [LocalVariableDeclStmt] ... ...; +# 19| 0: [LocalVariableDeclAndInitExpr] Int32 j = ... +# 19| -1: [TypeMention] int +# 19| 0: [LocalVariableAccess] access to local variable j +# 19| 1: [FunctionPointerCall] function pointer call +# 19| -1: [ParameterAccess] access to parameter f +# 19| 0: [LocalVariableAccess] access to local variable i +# 19| 1: [LocalVariableAccess,LocalVariableDeclExpr] Object o +# 22| 8: [Method] M2 +# 22| -1: [TypeMention] Void +#-----| 1: (Type parameters) +# 22| 0: [TypeParameter] T +#-----| 2: (Parameters) +# 22| 0: [Parameter] f +# 22| -1: [TypeMention] delegate* stdcall<Int32 ref,Object out,T,Void> +# 23| 4: [BlockStmt] {...} +# 24| 0: [LocalVariableDeclStmt] ... ...; +# 24| 0: [LocalVariableDeclAndInitExpr] Int32 i = ... +# 24| -1: [TypeMention] int +# 24| 0: [LocalVariableAccess] access to local variable i +# 24| 1: [IntLiteral] 42 +# 25| 1: [ExprStmt] ...; +# 25| 0: [FunctionPointerCall] function pointer call +# 25| -1: [ParameterAccess] access to parameter f +# 25| 0: [LocalVariableAccess] access to local variable i +# 25| 1: [LocalVariableAccess,LocalVariableDeclExpr] Object o +# 25| 2: [ObjectCreation] object creation of type T +# 25| 0: [TypeMention] T +# 28| 9: [Method] M3 +# 28| -1: [TypeMention] Void +#-----| 2: (Parameters) +# 28| 0: [Parameter] f +# 28| -1: [TypeMention] delegate* default<Int32 ref,Object out,Int32 in,Int32 ref> +# 29| 4: [BlockStmt] {...} +# 30| 0: [LocalVariableDeclStmt] ... ...; +# 30| 0: [LocalVariableDeclAndInitExpr] Int32 i = ... +# 30| -1: [TypeMention] int +# 30| 0: [LocalVariableAccess] access to local variable i +# 30| 1: [IntLiteral] 42 +# 31| 1: [LocalVariableDeclStmt] ... ...; +# 31| 0: [LocalVariableDeclAndInitExpr] Int32 j = ... +# 31| -1: [TypeMention] null +# 31| 0: [LocalVariableAccess] access to local variable j +# 31| 1: [RefExpr] ref ... +# 31| 0: [FunctionPointerCall] function pointer call +# 31| -1: [ParameterAccess] access to parameter f +# 31| 0: [LocalVariableAccess] access to local variable i +# 31| 1: [LocalVariableAccess,LocalVariableDeclExpr] Object o +# 31| 2: [LocalVariableAccess] access to local variable i +# 34| 10: [Method] M4 +# 34| -1: [TypeMention] Void +#-----| 1: (Type parameters) +# 34| 0: [TypeParameter] T +#-----| 2: (Parameters) +# 34| 0: [Parameter] f +# 34| -1: [TypeMention] delegate* default<T,Int32> +# 35| 4: [BlockStmt] {...} +# 36| 0: [LocalVariableDeclStmt] ... ...; +# 36| 0: [LocalVariableDeclAndInitExpr] Int32 j = ... +# 36| -1: [TypeMention] int +# 36| 0: [LocalVariableAccess] access to local variable j +# 36| 1: [FunctionPointerCall] function pointer call +# 36| -1: [ParameterAccess] access to parameter f +# 36| 0: [ObjectCreation] object creation of type T +# 36| 0: [TypeMention] T +# 39| 11: [Method] M5 +# 39| -1: [TypeMention] Void +#-----| 2: (Parameters) +# 39| 0: [Parameter] f +# 39| -1: [TypeMention] delegate* default<B,A> +# 39| 1: [Parameter] ff +# 39| -1: [TypeMention] delegate* default<A,B> +# 40| 4: [BlockStmt] {...} +# 41| 0: [ExprStmt] ...; +# 41| 0: [MethodCall] call to method M5 +# 41| 0: [CastExpr] (...) ... +# 41| 1: [ParameterAccess] access to parameter ff +# 41| 1: [ParameterAccess] access to parameter ff +# 44| 12: [Method] M6 +# 44| -1: [TypeMention] Void +#-----| 2: (Parameters) +# 44| 0: [Parameter] f +# 44| -1: [TypeMention] delegate* default<Int32*,Void*> +# 44| 1: [Parameter] ff +# 44| -1: [TypeMention] delegate* default<Void*,Int32*> +# 45| 4: [BlockStmt] {...} +# 46| 0: [ExprStmt] ...; +# 46| 0: [MethodCall] call to method M6 +# 46| 0: [CastExpr] (...) ... +# 46| 1: [ParameterAccess] access to parameter ff +# 46| 1: [ParameterAccess] access to parameter ff +# 49| 13: [Class] A +# 50| 14: [Class] B +#-----| 3: (Base types) +# 50| 0: [TypeMention] A +GlobalStmt.cs: +# 7| [Class] <Program>$ +# 7| 4: [Method] <Main>$ +#-----| 2: (Parameters) +# 1| 0: [Parameter] args +# 7| 4: [BlockStmt] {...} +# 11| 0: [ExprStmt] ...; +# 11| 0: [MethodCall] call to method WriteLine +# 11| -1: [TypeAccess] access to type Console +# 11| 0: [TypeMention] Console +# 11| 0: [StringLiteral] "1" +# 12| 1: [ExprStmt] ...; +# 12| 0: [MethodCall] call to method WriteLine +# 12| -1: [TypeAccess] access to type Console +# 12| 0: [TypeMention] Console +# 12| 0: [StringLiteral] "2" +# 13| 2: [ExprStmt] ...; +# 13| 0: [LocalFunctionCall] call to local function M +# 13| -1: [LocalFunctionAccess] access to local function M +# 15| 3: [LocalFunctionStmt] M(...) +# 15| 0: [LocalFunction] M +# 16| 4: [BlockStmt] {...} +# 19| [Class] Attr +#-----| 3: (Base types) +# 19| 0: [TypeMention] Attribute +# 21| 5: [Method] M1 +# 21| -1: [TypeMention] Void +# 22| 4: [BlockStmt] {...} +# 23| 0: [ExprStmt] ...; +# 23| 0: [MethodCall] call to method WriteLine +# 23| -1: [TypeAccess] access to type Console +# 23| 0: [TypeMention] Console +# 23| 0: [StringLiteral] "3" +InitOnlyProperty.cs: +# 3| [Class] Base +# 5| 5: [Property] Prop0 +# 5| -1: [TypeMention] int +# 5| 3: [Getter] get_Prop0 +# 5| 4: [BlockStmt] {...} +# 5| 0: [ReturnStmt] return ...; +# 5| 0: [IntLiteral] 1 +# 5| 4: [Setter] set_Prop0 +#-----| 2: (Parameters) +# 5| 0: [Parameter] value +# 5| 4: [BlockStmt] {...} +# 5| 0: [ExprStmt] ...; +# 5| 0: [AssignExpr] ... = ... +# 5| 0: [PropertyCall] access to property Prop1 +# 5| 1: [ParameterAccess] access to parameter value +# 6| 6: [Property] Prop1 +# 6| -1: [TypeMention] int +# 6| 3: [Getter] get_Prop1 +# 6| 4: [Setter] set_Prop1 +#-----| 2: (Parameters) +# 6| 0: [Parameter] value +# 7| 7: [Property] Prop2 +# 7| -1: [TypeMention] int +# 7| 3: [Getter] get_Prop2 +# 7| 4: [Setter] set_Prop2 +#-----| 2: (Parameters) +# 7| 0: [Parameter] value +# 11| [Class] Derived +#-----| 3: (Base types) +# 11| 0: [TypeMention] Base +# 13| 5: [Property] Prop1 +# 13| -1: [TypeMention] int +# 13| 3: [Getter] get_Prop1 +# 13| 4: [Setter] set_Prop1 +#-----| 2: (Parameters) +# 13| 0: [Parameter] value +# 14| 6: [Property] Prop2 +# 14| -1: [TypeMention] int +# 16| 3: [Getter] get_Prop2 +# 16| 4: [BlockStmt] {...} +# 16| 0: [ReturnStmt] return ...; +# 16| 0: [IntLiteral] 0 +# 17| 4: [Setter] set_Prop2 +#-----| 2: (Parameters) +# 17| 0: [Parameter] value +# 18| 4: [BlockStmt] {...} +# 19| 0: [ExprStmt] ...; +# 19| 0: [MethodCall] call to method WriteLine +# 19| -1: [TypeAccess] access to type Console +# 19| 0: [TypeMention] Console +# 19| 0: [ParameterAccess] access to parameter value +# 20| 1: [ExprStmt] ...; +# 20| 0: [AssignExpr] ... = ... +# 20| 0: [PropertyCall] access to property Prop1 +# 20| 1: [ParameterAccess] access to parameter value +# 21| 2: [ExprStmt] ...; +# 21| 0: [AssignExpr] ... = ... +# 21| 0: [PropertyCall] access to property Prop0 +# 21| 1: [ParameterAccess] access to parameter value +# 26| [Class] C1 +# 28| 5: [Method] M1 +# 28| -1: [TypeMention] Void +# 29| 4: [BlockStmt] {...} +# 30| 0: [LocalVariableDeclStmt] ... ...; +# 30| 0: [LocalVariableDeclAndInitExpr] Derived d = ... +# 30| -1: [TypeMention] Derived +# 30| 0: [LocalVariableAccess] access to local variable d +# 30| 1: [ObjectCreation] object creation of type Derived +# 30| -2: [TypeMention] Derived +# 31| -1: [ObjectInitializer] { ..., ... } +# 32| 0: [MemberInitializer] ... = ... +# 32| 0: [PropertyCall] access to property Prop1 +# 32| 1: [IntLiteral] 1 +# 33| 1: [MemberInitializer] ... = ... +# 33| 0: [PropertyCall] access to property Prop2 +# 33| 1: [IntLiteral] 2 +# 34| 2: [MemberInitializer] ... = ... +# 34| 0: [PropertyCall] access to property Prop0 +# 34| 1: [IntLiteral] 0 +IsExternalInit.cs: +# 4| [NamespaceDeclaration] namespace ... { ... } +# 6| 1: [Class] IsExternalInit LambdaModifier.cs: # 4| [Class] Class1 # 6| 5: [Method] M1 @@ -287,14 +745,14 @@ ParenthesizedPattern.cs: # 9| 0: [IsExpr] ... is ... # 9| 0: [ParameterAccess] access to parameter o # 9| 1: [RecursivePatternExpr] { ... } -# 9| 0: [LocalVariableDeclExpr] Object p1 +# 9| 0: [VariablePatternExpr] Object p1 # 9| 3: [PropertyPatternExpr] { ... } # 10| 1: [BlockStmt] {...} # 13| 1: [IfStmt] if (...) ... # 13| 0: [IsExpr] ... is ... # 13| 0: [ParameterAccess] access to parameter o # 13| 1: [RecursivePatternExpr] { ... } -# 13| 0: [LocalVariableDeclExpr] Object p2 +# 13| 0: [VariablePatternExpr] Object p2 # 13| 3: [PropertyPatternExpr] { ... } # 14| 1: [BlockStmt] {...} # 19| 6: [Method] M2 @@ -335,6 +793,345 @@ ParenthesizedPattern.cs: # 27| 0: [TypeAccessPatternExpr] access to type String # 27| 0: [TypeMention] string # 27| 2: [IntLiteral] 5 +Record.cs: +# 4| [Record] Person +# 4| 11: [NEOperator] != +#-----| 2: (Parameters) +# 4| 0: [Parameter] r1 +# 4| 1: [Parameter] r2 +# 4| 12: [EQOperator] == +#-----| 2: (Parameters) +# 4| 0: [Parameter] r1 +# 4| 1: [Parameter] r2 +# 4| 13: [Property] EqualityContract +# 4| 3: [Getter] get_EqualityContract +# 6| 14: [Property] LastName +# 6| -1: [TypeMention] string +# 6| 3: [Getter] get_LastName +# 7| 15: [Property] FirstName +# 7| -1: [TypeMention] string +# 7| 3: [Getter] get_FirstName +# 9| 16: [InstanceConstructor] Person +#-----| 2: (Parameters) +# 9| 0: [Parameter] first +# 9| -1: [TypeMention] string +# 9| 1: [Parameter] last +# 9| -1: [TypeMention] string +# 9| 4: [AssignExpr] ... = ... +# 9| 0: [TupleExpr] (..., ...) +# 9| 0: [PropertyCall] access to property FirstName +# 9| 1: [PropertyCall] access to property LastName +# 9| 1: [TupleExpr] (..., ...) +# 9| 0: [ParameterAccess] access to parameter first +# 9| 1: [ParameterAccess] access to parameter last +# 12| [Record] Teacher +# 12| 12: [NEOperator] != +#-----| 2: (Parameters) +# 12| 0: [Parameter] r1 +# 12| 1: [Parameter] r2 +# 12| 13: [EQOperator] == +#-----| 2: (Parameters) +# 12| 0: [Parameter] r1 +# 12| 1: [Parameter] r2 +# 12| 14: [Property] EqualityContract +# 12| 3: [Getter] get_EqualityContract +# 14| 15: [Property] Subject +# 14| -1: [TypeMention] string +# 14| 3: [Getter] get_Subject +# 16| 16: [InstanceConstructor] Teacher +#-----| 2: (Parameters) +# 16| 0: [Parameter] first +# 16| -1: [TypeMention] string +# 16| 1: [Parameter] last +# 16| -1: [TypeMention] string +# 16| 2: [Parameter] sub +# 16| -1: [TypeMention] string +# 17| 3: [ConstructorInitializer] call to constructor Person +# 17| 0: [ParameterAccess] access to parameter first +# 17| 1: [ParameterAccess] access to parameter last +# 17| 4: [AssignExpr] ... = ... +# 17| 0: [PropertyCall] access to property Subject +# 17| 1: [ParameterAccess] access to parameter sub +# 20| [Record] Student +# 20| 12: [NEOperator] != +#-----| 2: (Parameters) +# 20| 0: [Parameter] r1 +# 20| 1: [Parameter] r2 +# 20| 13: [EQOperator] == +#-----| 2: (Parameters) +# 20| 0: [Parameter] r1 +# 20| 1: [Parameter] r2 +# 20| 14: [Property] EqualityContract +# 20| 3: [Getter] get_EqualityContract +# 22| 15: [Property] Level +# 22| -1: [TypeMention] int +# 22| 3: [Getter] get_Level +# 24| 16: [InstanceConstructor] Student +#-----| 2: (Parameters) +# 24| 0: [Parameter] first +# 24| -1: [TypeMention] string +# 24| 1: [Parameter] last +# 24| -1: [TypeMention] string +# 24| 2: [Parameter] level +# 24| -1: [TypeMention] int +# 24| 3: [ConstructorInitializer] call to constructor Person +# 24| 0: [ParameterAccess] access to parameter first +# 24| 1: [ParameterAccess] access to parameter last +# 24| 4: [AssignExpr] ... = ... +# 24| 0: [PropertyCall] access to property Level +# 24| 1: [ParameterAccess] access to parameter level +# 27| [Record] Person1 +# 27| 12: [NEOperator] != +#-----| 2: (Parameters) +# 27| 0: [Parameter] r1 +# 27| 1: [Parameter] r2 +# 27| 13: [EQOperator] == +#-----| 2: (Parameters) +# 27| 0: [Parameter] r1 +# 27| 1: [Parameter] r2 +# 27| 14: [Property] EqualityContract +# 27| 3: [Getter] get_EqualityContract +# 27| 15: [InstanceConstructor] Person1 +#-----| 2: (Parameters) +# 27| 0: [Parameter] FirstName +# 27| -1: [TypeMention] string +# 27| 1: [Parameter] LastName +# 27| -1: [TypeMention] string +# 27| 16: [Property] FirstName +# 27| 3: [Getter] get_FirstName +# 27| 4: [Setter] set_FirstName +#-----| 2: (Parameters) +# 27| 0: [Parameter] value +# 27| 17: [Property] LastName +# 27| 3: [Getter] get_LastName +# 27| 4: [Setter] set_LastName +#-----| 2: (Parameters) +# 27| 0: [Parameter] value +# 29| [Record] Teacher1 +# 29| 13: [NEOperator] != +#-----| 2: (Parameters) +# 29| 0: [Parameter] r1 +# 29| 1: [Parameter] r2 +# 29| 14: [EQOperator] == +#-----| 2: (Parameters) +# 29| 0: [Parameter] r1 +# 29| 1: [Parameter] r2 +# 29| 15: [Property] EqualityContract +# 29| 3: [Getter] get_EqualityContract +# 29| 16: [InstanceConstructor] Teacher1 +#-----| 2: (Parameters) +# 29| 0: [Parameter] FirstName +# 29| -1: [TypeMention] string +# 29| 1: [Parameter] LastName +# 29| -1: [TypeMention] string +# 29| 2: [Parameter] Subject +# 29| -1: [TypeMention] string +# 29| 17: [Property] Subject +# 29| 3: [Getter] get_Subject +# 29| 4: [Setter] set_Subject +#-----| 2: (Parameters) +# 29| 0: [Parameter] value +# 32| [Record] Student1 +# 32| 13: [NEOperator] != +#-----| 2: (Parameters) +# 32| 0: [Parameter] r1 +# 32| 1: [Parameter] r2 +# 32| 14: [EQOperator] == +#-----| 2: (Parameters) +# 32| 0: [Parameter] r1 +# 32| 1: [Parameter] r2 +# 32| 15: [Property] EqualityContract +# 32| 3: [Getter] get_EqualityContract +# 32| 16: [InstanceConstructor] Student1 +#-----| 2: (Parameters) +# 32| 0: [Parameter] FirstName +# 32| -1: [TypeMention] string +# 32| 1: [Parameter] LastName +# 32| -1: [TypeMention] string +# 32| 2: [Parameter] Level +# 32| -1: [TypeMention] int +# 32| 17: [Property] Level +# 32| 3: [Getter] get_Level +# 32| 4: [Setter] set_Level +#-----| 2: (Parameters) +# 32| 0: [Parameter] value +# 35| [Record] Pet +# 35| 12: [NEOperator] != +#-----| 2: (Parameters) +# 35| 0: [Parameter] r1 +# 35| 1: [Parameter] r2 +# 35| 13: [EQOperator] == +#-----| 2: (Parameters) +# 35| 0: [Parameter] r1 +# 35| 1: [Parameter] r2 +# 35| 14: [Property] EqualityContract +# 35| 3: [Getter] get_EqualityContract +# 35| 15: [InstanceConstructor] Pet +#-----| 2: (Parameters) +# 35| 0: [Parameter] Name +# 35| -1: [TypeMention] string +# 35| 16: [Property] Name +# 35| 3: [Getter] get_Name +# 35| 4: [Setter] set_Name +#-----| 2: (Parameters) +# 35| 0: [Parameter] value +# 37| 17: [Method] ShredTheFurniture +# 37| -1: [TypeMention] Void +# 38| 4: [MethodCall] call to method WriteLine +# 38| -1: [TypeAccess] access to type Console +# 38| 0: [TypeMention] Console +# 38| 0: [StringLiteral] "Shredding furniture" +# 41| [Record] Dog +# 41| 12: [NEOperator] != +#-----| 2: (Parameters) +# 41| 0: [Parameter] r1 +# 41| 1: [Parameter] r2 +# 41| 13: [EQOperator] == +#-----| 2: (Parameters) +# 41| 0: [Parameter] r1 +# 41| 1: [Parameter] r2 +# 41| 14: [InstanceConstructor] Dog +#-----| 2: (Parameters) +# 41| 0: [Parameter] Name +# 41| -1: [TypeMention] string +# 41| 15: [Property] EqualityContract +# 41| 3: [Getter] get_EqualityContract +# 43| 16: [Method] WagTail +# 43| -1: [TypeMention] Void +# 44| 4: [MethodCall] call to method WriteLine +# 44| -1: [TypeAccess] access to type Console +# 44| 0: [TypeMention] Console +# 44| 0: [StringLiteral] "It's tail wagging time" +# 46| 17: [Method] ToString +# 46| -1: [TypeMention] string +# 47| 4: [BlockStmt] {...} +# 48| 0: [LocalVariableDeclStmt] ... ...; +# 48| 0: [LocalVariableDeclAndInitExpr] StringBuilder s = ... +# 48| -1: [TypeMention] StringBuilder +# 48| 0: [LocalVariableAccess] access to local variable s +# 48| 1: [ObjectCreation] object creation of type StringBuilder +# 48| 0: [TypeMention] StringBuilder +# 49| 1: [ExprStmt] ...; +# 49| 0: [MethodCall] call to method PrintMembers +# 49| -1: [BaseAccess] base access +# 49| 0: [LocalVariableAccess] access to local variable s +# 50| 2: [ReturnStmt] return ...; +# 50| 0: [InterpolatedStringExpr] $"..." +# 50| 0: [MethodCall] call to method ToString +# 50| -1: [LocalVariableAccess] access to local variable s +# 50| 1: [StringLiteral] " is a dog" +# 54| [Class] Record1 +# 56| 5: [Method] M1 +# 56| -1: [TypeMention] Void +# 57| 4: [BlockStmt] {...} +# 58| 0: [LocalVariableDeclStmt] ... ...; +# 58| 0: [LocalVariableDeclAndInitExpr] Person person = ... +# 58| -1: [TypeMention] Person +# 58| 0: [LocalVariableAccess] access to local variable person +# 58| 1: [ObjectCreation] object creation of type Person +# 58| -1: [TypeMention] Person +# 58| 0: [StringLiteral] "Bill" +# 58| 1: [StringLiteral] "Wagner" +# 59| 1: [LocalVariableDeclStmt] ... ...; +# 59| 0: [LocalVariableDeclAndInitExpr] Student student = ... +# 59| -1: [TypeMention] Student +# 59| 0: [LocalVariableAccess] access to local variable student +# 59| 1: [ObjectCreation] object creation of type Student +# 59| -1: [TypeMention] Student +# 59| 0: [StringLiteral] "Bill" +# 59| 1: [StringLiteral] "Wagner" +# 59| 2: [IntLiteral] 11 +# 61| 2: [ExprStmt] ...; +# 61| 0: [MethodCall] call to method WriteLine +# 61| -1: [TypeAccess] access to type Console +# 61| 0: [TypeMention] Console +# 61| 0: [OperatorCall] call to operator == +# 61| 0: [LocalVariableAccess] access to local variable student +# 61| 1: [LocalVariableAccess] access to local variable person +# 64| 6: [Method] M2 +# 64| -1: [TypeMention] Void +# 65| 4: [BlockStmt] {...} +# 66| 0: [LocalVariableDeclStmt] ... ...; +# 66| 0: [LocalVariableDeclAndInitExpr] Person1 person = ... +# 66| -1: [TypeMention] Person1 +# 66| 0: [LocalVariableAccess] access to local variable person +# 66| 1: [ObjectCreation] object creation of type Person1 +# 66| -1: [TypeMention] Person1 +# 66| 0: [StringLiteral] "Bill" +# 66| 1: [StringLiteral] "Wagner" +# 68| 1: [ExprStmt] ...; +# 68| 0: [AssignExpr] ... = ... +# 68| 0: [TupleExpr] (..., ...) +# 68| 0: [LocalVariableDeclExpr] String first +# 68| 1: [LocalVariableDeclExpr] String last +# 68| 1: [LocalVariableAccess] access to local variable person +# 69| 2: [ExprStmt] ...; +# 69| 0: [MethodCall] call to method WriteLine +# 69| -1: [TypeAccess] access to type Console +# 69| 0: [TypeMention] Console +# 69| 0: [LocalVariableAccess] access to local variable first +# 70| 3: [ExprStmt] ...; +# 70| 0: [MethodCall] call to method WriteLine +# 70| -1: [TypeAccess] access to type Console +# 70| 0: [TypeMention] Console +# 70| 0: [LocalVariableAccess] access to local variable last +RelationalPattern.cs: +# 3| [Class] RelationalPattern +# 5| 5: [Method] M1 +# 5| -1: [TypeMention] bool +#-----| 2: (Parameters) +# 5| 0: [Parameter] c +# 5| -1: [TypeMention] char +# 6| 4: [IsExpr] ... is ... +# 6| 0: [ParameterAccess] access to parameter c +# 6| 1: [GEPattern] >= ... +# 6| 0: [CharLiteral] a +# 7| 6: [Method] M2 +# 7| -1: [TypeMention] bool +#-----| 2: (Parameters) +# 7| 0: [Parameter] c +# 7| -1: [TypeMention] char +# 8| 4: [IsExpr] ... is ... +# 8| 0: [ParameterAccess] access to parameter c +# 8| 1: [GTPattern] > ... +# 8| 0: [CharLiteral] a +# 9| 7: [Method] M3 +# 9| -1: [TypeMention] bool +#-----| 2: (Parameters) +# 9| 0: [Parameter] c +# 9| -1: [TypeMention] char +# 10| 4: [IsExpr] ... is ... +# 10| 0: [ParameterAccess] access to parameter c +# 10| 1: [LEPattern] <= ... +# 10| 0: [CharLiteral] a +# 11| 8: [Method] M4 +# 11| -1: [TypeMention] bool +#-----| 2: (Parameters) +# 11| 0: [Parameter] c +# 11| -1: [TypeMention] char +# 12| 4: [IsExpr] ... is ... +# 12| 0: [ParameterAccess] access to parameter c +# 12| 1: [LTPattern] < ... +# 12| 0: [CharLiteral] a +# 14| 9: [Method] M5 +# 14| -1: [TypeMention] string +#-----| 2: (Parameters) +# 14| 0: [Parameter] i +# 14| -1: [TypeMention] int +# 15| 4: [BlockStmt] {...} +# 16| 0: [ReturnStmt] return ...; +# 16| 0: [SwitchExpr] ... switch { ... } +# 16| -1: [ParameterAccess] access to parameter i +# 18| 0: [SwitchCaseExpr] ... => ... +# 18| 0: [ConstantPatternExpr,IntLiteral] 1 +# 18| 2: [StringLiteral] "1" +# 19| 1: [SwitchCaseExpr] ... => ... +# 19| 0: [GTPattern] > ... +# 19| 0: [IntLiteral] 1 +# 19| 2: [StringLiteral] ">1" +# 20| 2: [SwitchCaseExpr] ... => ... +# 20| 0: [DiscardPatternExpr] _ +# 20| 2: [StringLiteral] "other" TargetType.cs: # 5| [Class] TargetType # 7| 5: [Method] M2 @@ -626,3 +1423,59 @@ TypePattern.cs: # 14| 0: [VariablePatternExpr] Object o # 14| 0: [TypeMention] object # 14| 2: [LocalVariableAccess] access to local variable o +UnaryPattern.cs: +# 3| [Class] UnaryPattern +# 5| 5: [Property] P1 +# 5| -1: [TypeMention] int +# 5| 3: [Getter] get_P1 +# 5| 4: [Setter] set_P1 +#-----| 2: (Parameters) +# 5| 0: [Parameter] value +# 7| 6: [Method] M1 +# 7| -1: [TypeMention] bool +#-----| 2: (Parameters) +# 7| 0: [Parameter] c +# 7| -1: [TypeMention] char +# 8| 4: [IsExpr] ... is ... +# 8| 0: [ParameterAccess] access to parameter c +# 8| 1: [NotPatternExpr] not ... +# 8| 0: [CharLiteral,ConstantPatternExpr] a +# 9| 7: [Method] M2 +# 9| -1: [TypeMention] bool +#-----| 2: (Parameters) +# 9| 0: [Parameter] c +# 9| -1: [TypeMention] object +# 10| 4: [IsExpr] ... is ... +# 10| 0: [ParameterAccess] access to parameter c +# 10| 1: [NotPatternExpr] not ... +# 10| 0: [ConstantPatternExpr,NullLiteral] null +# 11| 8: [Method] M3 +# 11| -1: [TypeMention] bool +#-----| 2: (Parameters) +# 11| 0: [Parameter] c +# 11| -1: [TypeMention] object +# 12| 4: [IsExpr] ... is ... +# 12| 0: [ParameterAccess] access to parameter c +# 12| 1: [NotPatternExpr] not ... +# 12| 0: [RecursivePatternExpr] { ... } +# 12| 0: [VariablePatternExpr] UnaryPattern u +# 12| 1: [TypeAccessPatternExpr] access to type UnaryPattern +# 12| 0: [TypeMention] UnaryPattern +# 12| 3: [PropertyPatternExpr] { ... } +# 12| 0: [ConstantPatternExpr,IntLiteral,LabeledPatternExpr] 1 +# 14| 9: [Method] M4 +# 14| -1: [TypeMention] string +#-----| 2: (Parameters) +# 14| 0: [Parameter] i +# 14| -1: [TypeMention] int +# 15| 4: [BlockStmt] {...} +# 16| 0: [ReturnStmt] return ...; +# 16| 0: [SwitchExpr] ... switch { ... } +# 16| -1: [ParameterAccess] access to parameter i +# 18| 0: [SwitchCaseExpr] ... => ... +# 18| 0: [NotPatternExpr] not ... +# 18| 0: [ConstantPatternExpr,IntLiteral] 1 +# 18| 2: [StringLiteral] "not 1" +# 19| 1: [SwitchCaseExpr] ... => ... +# 19| 0: [DiscardPatternExpr] _ +# 19| 2: [StringLiteral] "other" diff --git a/csharp/ql/test/library-tests/csharp9/Record.cs b/csharp/ql/test/library-tests/csharp9/Record.cs new file mode 100644 index 00000000000..45d1506c055 --- /dev/null +++ b/csharp/ql/test/library-tests/csharp9/Record.cs @@ -0,0 +1,72 @@ +using System; +using System.Text; + +public record Person +{ + public string LastName { get; } + public string FirstName { get; } + + public Person(string first, string last) => (FirstName, LastName) = (first, last); +} + +public record Teacher : Person +{ + public string Subject { get; } + + public Teacher(string first, string last, string sub) + : base(first, last) => Subject = sub; +} + +public sealed record Student : Person +{ + public int Level { get; } + + public Student(string first, string last, int level) : base(first, last) => Level = level; +} + +public record Person1(string FirstName, string LastName); + +public record Teacher1(string FirstName, string LastName, string Subject) + : Person1(FirstName, LastName); + +public sealed record Student1(string FirstName, string LastName, int Level) + : Person1(FirstName, LastName); + +public record Pet(string Name) +{ + public void ShredTheFurniture() => + Console.WriteLine("Shredding furniture"); +} + +public record Dog(string Name) : Pet(Name) +{ + public void WagTail() => + Console.WriteLine("It's tail wagging time"); + + public override string ToString() + { + var s = new StringBuilder(); + base.PrintMembers(s); + return $"{s.ToString()} is a dog"; + } +} + +public class Record1 +{ + public void M1() + { + var person = new Person("Bill", "Wagner"); + var student = new Student("Bill", "Wagner", 11); + + Console.WriteLine(student == person); + } + + public void M2() + { + var person = new Person1("Bill", "Wagner"); + + var (first, last) = person; + Console.WriteLine(first); + Console.WriteLine(last); + } +} diff --git a/csharp/ql/test/library-tests/csharp9/RelationalPattern.cs b/csharp/ql/test/library-tests/csharp9/RelationalPattern.cs new file mode 100644 index 00000000000..d21f5044507 --- /dev/null +++ b/csharp/ql/test/library-tests/csharp9/RelationalPattern.cs @@ -0,0 +1,23 @@ +using System; + +public class RelationalPattern +{ + public static bool M1(char c) => + c is >= 'a'; + public static bool M2(char c) => + c is > 'a'; + public static bool M3(char c) => + c is <= 'a'; + public static bool M4(char c) => + c is < 'a'; + + public static string M5(int i) + { + return i switch + { + 1 => "1", + >1 => ">1", + _ => "other" + }; + } +} \ No newline at end of file diff --git a/csharp/ql/test/library-tests/csharp9/UnaryPattern.cs b/csharp/ql/test/library-tests/csharp9/UnaryPattern.cs new file mode 100644 index 00000000000..5dfcb335bfb --- /dev/null +++ b/csharp/ql/test/library-tests/csharp9/UnaryPattern.cs @@ -0,0 +1,22 @@ +using System; + +public class UnaryPattern +{ + public int P1 { get; set; } + + public static bool M1(char c) => + c is not 'a'; + public static bool M2(object c) => + c is not null; + public static bool M3(object c) => + c is not UnaryPattern { P1: 1 } u; + + public static string M4(int i) + { + return i switch + { + not 1 => "not 1", + _ => "other" + }; + } +} \ No newline at end of file diff --git a/csharp/ql/test/library-tests/csharp9/binaryPattern.expected b/csharp/ql/test/library-tests/csharp9/binaryPattern.expected new file mode 100644 index 00000000000..6eabb4e314b --- /dev/null +++ b/csharp/ql/test/library-tests/csharp9/binaryPattern.expected @@ -0,0 +1,4 @@ +| BinaryPattern.cs:8:14:8:23 | ... or ... | BinaryPattern.cs:8:14:8:16 | a | BinaryPattern.cs:8:21:8:23 | b | +| BinaryPattern.cs:10:14:10:51 | ... and ... | BinaryPattern.cs:10:14:10:21 | Object o | BinaryPattern.cs:10:27:10:51 | { ... } | +| BinaryPattern.cs:12:14:12:41 | ... and ... | BinaryPattern.cs:12:14:12:21 | Object o | BinaryPattern.cs:12:27:12:41 | BinaryPattern u | +| BinaryPattern.cs:18:13:18:18 | ... or ... | BinaryPattern.cs:18:13:18:13 | 1 | BinaryPattern.cs:18:18:18:18 | 2 | diff --git a/csharp/ql/test/library-tests/csharp9/binaryPattern.ql b/csharp/ql/test/library-tests/csharp9/binaryPattern.ql new file mode 100644 index 00000000000..34ec78f2f8a --- /dev/null +++ b/csharp/ql/test/library-tests/csharp9/binaryPattern.ql @@ -0,0 +1,4 @@ +import csharp + +from BinaryPatternExpr pattern +select pattern, pattern.getLeftOperand(), pattern.getRightOperand() diff --git a/csharp/ql/test/library-tests/csharp9/foreach.expected b/csharp/ql/test/library-tests/csharp9/foreach.expected new file mode 100644 index 00000000000..39694665cb0 --- /dev/null +++ b/csharp/ql/test/library-tests/csharp9/foreach.expected @@ -0,0 +1,4 @@ +| ForeachExtension.cs:24:9:26:9 | foreach (... ... in ...) ... | Int32 | sync | Extensions | ForeachExtension.cs:8:34:8:49 | System.Collections.Generic.IEnumerator<Int32> | - | System.Collections.IEnumerator | - | +| ForeachExtension.cs:29:9:31:9 | foreach (... ... in ...) ... | Int32 | async | Extensions | ForeachExtension.cs:9:39:9:59 | System.Collections.Generic.IAsyncEnumerator<Int32> | - | System.Collections.Generic.IAsyncEnumerator<Int32> | - | +| ForeachExtension.cs:33:9:35:9 | foreach (... ... in ...) ... | Int32 | sync | Extensions | ForeachExtension.cs:10:36:10:48 | System.Collections.Generic.IEnumerator<Int32> | - | System.Collections.IEnumerator | - | +| ForeachExtension.cs:37:9:39:9 | foreach (... ... in ...) ... | Int32 | sync | System.Collections.IEnumerable | - | System.Collections.IEnumerator | - | System.Collections.IEnumerator | - | diff --git a/csharp/ql/test/library-tests/csharp9/foreach.ql b/csharp/ql/test/library-tests/csharp9/foreach.ql new file mode 100644 index 00000000000..38d431d762f --- /dev/null +++ b/csharp/ql/test/library-tests/csharp9/foreach.ql @@ -0,0 +1,15 @@ +import csharp + +private string getLocation(Member m) { + if m.fromSource() then result = m.getALocation().(SourceLocation).toString() else result = "-" +} + +private string getIsAsync(ForeachStmt f) { + if f.isAsync() then result = "async" else result = "sync" +} + +from ForeachStmt f +select f, f.getElementType().toString(), getIsAsync(f), + f.getGetEnumerator().getDeclaringType().getQualifiedName(), getLocation(f.getGetEnumerator()), + f.getCurrent().getDeclaringType().getQualifiedName(), getLocation(f.getCurrent()), + f.getMoveNext().getDeclaringType().getQualifiedName(), getLocation(f.getMoveNext()) diff --git a/csharp/ql/test/library-tests/csharp9/globalStmt.expected b/csharp/ql/test/library-tests/csharp9/globalStmt.expected new file mode 100644 index 00000000000..dc7ccea6ad1 --- /dev/null +++ b/csharp/ql/test/library-tests/csharp9/globalStmt.expected @@ -0,0 +1,10 @@ +global_stmt +| GlobalStmt.cs:11:1:11:23 | ...; | +| GlobalStmt.cs:12:1:12:23 | ...; | +| GlobalStmt.cs:13:1:13:4 | ...; | +| GlobalStmt.cs:15:1:17:1 | M(...) | +globalBlock +| GlobalStmt.cs:7:1:25:1 | {...} | GlobalStmt.cs:7:1:25:1 | <Main>$ | GlobalStmt.cs:1:1:1:0 | args | GlobalStmt.cs:7:1:25:1 | <Program>$ | +methods +| GlobalStmt.cs:7:1:25:1 | <Main>$ | entry | +| GlobalStmt.cs:21:8:21:9 | M1 | non-entry | diff --git a/csharp/ql/test/library-tests/csharp9/globalStmt.ql b/csharp/ql/test/library-tests/csharp9/globalStmt.ql new file mode 100644 index 00000000000..ff0ca8f661a --- /dev/null +++ b/csharp/ql/test/library-tests/csharp9/globalStmt.ql @@ -0,0 +1,16 @@ +import csharp +private import semmle.code.csharp.commons.Util + +query predicate global_stmt(Stmt stmt) { stmt.isGlobal() } + +query predicate globalBlock(BlockStmt block, Method m, Parameter p, Type t) { + block.isGlobalStatementContainer() and + block.getEnclosingCallable() = m and + m.getDeclaringType() = t and + m.getAParameter() = p +} + +query predicate methods(Method m, string entry) { + m.getFile().getStem() = "GlobalStmt" and + if m instanceof MainMethod then entry = "entry" else entry = "non-entry" +} diff --git a/csharp/ql/test/library-tests/csharp9/initOnlyProperty.expected b/csharp/ql/test/library-tests/csharp9/initOnlyProperty.expected new file mode 100644 index 00000000000..ca27ad80532 --- /dev/null +++ b/csharp/ql/test/library-tests/csharp9/initOnlyProperty.expected @@ -0,0 +1,13 @@ +| AnonymousObjectCreation.cs:9:29:9:31 | set_Prop1 | set | +| BinaryPattern.cs:5:26:5:28 | set_P1 | set | +| InitOnlyProperty.cs:5:42:5:45 | set_Prop0 | init | +| InitOnlyProperty.cs:6:37:6:40 | set_Prop1 | init | +| InitOnlyProperty.cs:7:37:7:39 | set_Prop2 | set | +| InitOnlyProperty.cs:13:38:13:41 | set_Prop1 | init | +| InitOnlyProperty.cs:17:9:17:12 | set_Prop2 | init | +| Record.cs:27:30:27:38 | set_FirstName | init | +| Record.cs:27:48:27:55 | set_LastName | init | +| Record.cs:29:66:29:72 | set_Subject | init | +| Record.cs:32:70:32:74 | set_Level | init | +| Record.cs:35:26:35:29 | set_Name | init | +| UnaryPattern.cs:5:26:5:28 | set_P1 | set | diff --git a/csharp/ql/test/library-tests/csharp9/initOnlyProperty.ql b/csharp/ql/test/library-tests/csharp9/initOnlyProperty.ql new file mode 100644 index 00000000000..ad9a797d9be --- /dev/null +++ b/csharp/ql/test/library-tests/csharp9/initOnlyProperty.ql @@ -0,0 +1,7 @@ +import csharp + +private string getType(Setter s) { if s.isInitOnly() then result = "init" else result = "set" } + +from Setter s +where s.fromSource() +select s, getType(s) diff --git a/csharp/ql/test/library-tests/csharp9/record.expected b/csharp/ql/test/library-tests/csharp9/record.expected new file mode 100644 index 00000000000..69d7abddb31 --- /dev/null +++ b/csharp/ql/test/library-tests/csharp9/record.expected @@ -0,0 +1,200 @@ +types +| Record.cs:4:1:10:1 | Person | IEquatable<Person> | +| Record.cs:12:1:18:1 | Teacher | IEquatable<Teacher> | +| Record.cs:20:1:25:1 | Student | IEquatable<Student> | +| Record.cs:27:1:27:57 | Person1 | IEquatable<Person1> | +| Record.cs:29:1:30:35 | Teacher1 | IEquatable<Teacher1> | +| Record.cs:32:1:33:35 | Student1 | IEquatable<Student1> | +| Record.cs:35:1:39:1 | Pet | IEquatable<Pet> | +| Record.cs:41:1:52:1 | Dog | IEquatable<Dog> | +members +| Record.cs:4:1:10:1 | Person | Person.!=(Person, Person) | Record.cs:4:15:4:20 | +| Record.cs:4:1:10:1 | Person | Person.<Clone>$() | no location | +| Record.cs:4:1:10:1 | Person | Person.==(Person, Person) | Record.cs:4:15:4:20 | +| Record.cs:4:1:10:1 | Person | Person.EqualityContract | Record.cs:4:15:4:20 | +| Record.cs:4:1:10:1 | Person | Person.Equals(Person) | no location | +| Record.cs:4:1:10:1 | Person | Person.Equals(object) | no location | +| Record.cs:4:1:10:1 | Person | Person.FirstName | Record.cs:7:19:7:27 | +| Record.cs:4:1:10:1 | Person | Person.GetHashCode() | no location | +| Record.cs:4:1:10:1 | Person | Person.LastName | Record.cs:6:19:6:26 | +| Record.cs:4:1:10:1 | Person | Person.Person(Person) | no location | +| Record.cs:4:1:10:1 | Person | Person.Person(string, string) | Record.cs:9:12:9:17 | +| Record.cs:4:1:10:1 | Person | Person.PrintMembers(StringBuilder) | no location | +| Record.cs:4:1:10:1 | Person | Person.ToString() | no location | +| Record.cs:4:1:10:1 | Person | System.Object.Equals(object, object) | no location | +| Record.cs:4:1:10:1 | Person | System.Object.GetType() | no location | +| Record.cs:4:1:10:1 | Person | System.Object.MemberwiseClone() | no location | +| Record.cs:4:1:10:1 | Person | System.Object.Object() | no location | +| Record.cs:4:1:10:1 | Person | System.Object.ReferenceEquals(object, object) | no location | +| Record.cs:4:1:10:1 | Person | System.Object.~Object() | no location | +| Record.cs:12:1:18:1 | Teacher | Person.!=(Person, Person) | Record.cs:4:15:4:20 | +| Record.cs:12:1:18:1 | Teacher | Person.==(Person, Person) | Record.cs:4:15:4:20 | +| Record.cs:12:1:18:1 | Teacher | Person.FirstName | Record.cs:7:19:7:27 | +| Record.cs:12:1:18:1 | Teacher | Person.LastName | Record.cs:6:19:6:26 | +| Record.cs:12:1:18:1 | Teacher | Person.Person(Person) | no location | +| Record.cs:12:1:18:1 | Teacher | Person.Person(string, string) | Record.cs:9:12:9:17 | +| Record.cs:12:1:18:1 | Teacher | System.Object.Equals(object, object) | no location | +| Record.cs:12:1:18:1 | Teacher | System.Object.GetType() | no location | +| Record.cs:12:1:18:1 | Teacher | System.Object.MemberwiseClone() | no location | +| Record.cs:12:1:18:1 | Teacher | System.Object.Object() | no location | +| Record.cs:12:1:18:1 | Teacher | System.Object.ReferenceEquals(object, object) | no location | +| Record.cs:12:1:18:1 | Teacher | System.Object.~Object() | no location | +| Record.cs:12:1:18:1 | Teacher | Teacher.!=(Teacher, Teacher) | Record.cs:12:15:12:21 | +| Record.cs:12:1:18:1 | Teacher | Teacher.<Clone>$() | no location | +| Record.cs:12:1:18:1 | Teacher | Teacher.==(Teacher, Teacher) | Record.cs:12:15:12:21 | +| Record.cs:12:1:18:1 | Teacher | Teacher.EqualityContract | Record.cs:12:15:12:21 | +| Record.cs:12:1:18:1 | Teacher | Teacher.Equals(Person) | no location | +| Record.cs:12:1:18:1 | Teacher | Teacher.Equals(Teacher) | no location | +| Record.cs:12:1:18:1 | Teacher | Teacher.Equals(object) | no location | +| Record.cs:12:1:18:1 | Teacher | Teacher.GetHashCode() | no location | +| Record.cs:12:1:18:1 | Teacher | Teacher.PrintMembers(StringBuilder) | no location | +| Record.cs:12:1:18:1 | Teacher | Teacher.Subject | Record.cs:14:19:14:25 | +| Record.cs:12:1:18:1 | Teacher | Teacher.Teacher(Teacher) | no location | +| Record.cs:12:1:18:1 | Teacher | Teacher.Teacher(string, string, string) | Record.cs:16:12:16:18 | +| Record.cs:12:1:18:1 | Teacher | Teacher.ToString() | no location | +| Record.cs:20:1:25:1 | Student | Person.!=(Person, Person) | Record.cs:4:15:4:20 | +| Record.cs:20:1:25:1 | Student | Person.==(Person, Person) | Record.cs:4:15:4:20 | +| Record.cs:20:1:25:1 | Student | Person.FirstName | Record.cs:7:19:7:27 | +| Record.cs:20:1:25:1 | Student | Person.LastName | Record.cs:6:19:6:26 | +| Record.cs:20:1:25:1 | Student | Person.Person(Person) | no location | +| Record.cs:20:1:25:1 | Student | Person.Person(string, string) | Record.cs:9:12:9:17 | +| Record.cs:20:1:25:1 | Student | Student.!=(Student, Student) | Record.cs:20:22:20:28 | +| Record.cs:20:1:25:1 | Student | Student.<Clone>$() | no location | +| Record.cs:20:1:25:1 | Student | Student.==(Student, Student) | Record.cs:20:22:20:28 | +| Record.cs:20:1:25:1 | Student | Student.EqualityContract | Record.cs:20:22:20:28 | +| Record.cs:20:1:25:1 | Student | Student.Equals(Person) | no location | +| Record.cs:20:1:25:1 | Student | Student.Equals(Student) | no location | +| Record.cs:20:1:25:1 | Student | Student.Equals(object) | no location | +| Record.cs:20:1:25:1 | Student | Student.GetHashCode() | no location | +| Record.cs:20:1:25:1 | Student | Student.Level | Record.cs:22:16:22:20 | +| Record.cs:20:1:25:1 | Student | Student.PrintMembers(StringBuilder) | no location | +| Record.cs:20:1:25:1 | Student | Student.Student(Student) | no location | +| Record.cs:20:1:25:1 | Student | Student.Student(string, string, int) | Record.cs:24:12:24:18 | +| Record.cs:20:1:25:1 | Student | Student.ToString() | no location | +| Record.cs:20:1:25:1 | Student | System.Object.Equals(object, object) | no location | +| Record.cs:20:1:25:1 | Student | System.Object.GetType() | no location | +| Record.cs:20:1:25:1 | Student | System.Object.MemberwiseClone() | no location | +| Record.cs:20:1:25:1 | Student | System.Object.Object() | no location | +| Record.cs:20:1:25:1 | Student | System.Object.ReferenceEquals(object, object) | no location | +| Record.cs:20:1:25:1 | Student | System.Object.~Object() | no location | +| Record.cs:27:1:27:57 | Person1 | Person1.!=(Person1, Person1) | Record.cs:27:15:27:21 | +| Record.cs:27:1:27:57 | Person1 | Person1.<Clone>$() | no location | +| Record.cs:27:1:27:57 | Person1 | Person1.==(Person1, Person1) | Record.cs:27:15:27:21 | +| Record.cs:27:1:27:57 | Person1 | Person1.Deconstruct(out string, out string) | no location | +| Record.cs:27:1:27:57 | Person1 | Person1.EqualityContract | Record.cs:27:15:27:21 | +| Record.cs:27:1:27:57 | Person1 | Person1.Equals(Person1) | no location | +| Record.cs:27:1:27:57 | Person1 | Person1.Equals(object) | no location | +| Record.cs:27:1:27:57 | Person1 | Person1.FirstName | Record.cs:27:30:27:38 | +| Record.cs:27:1:27:57 | Person1 | Person1.GetHashCode() | no location | +| Record.cs:27:1:27:57 | Person1 | Person1.LastName | Record.cs:27:48:27:55 | +| Record.cs:27:1:27:57 | Person1 | Person1.Person1(Person1) | no location | +| Record.cs:27:1:27:57 | Person1 | Person1.Person1(string, string) | Record.cs:27:15:27:21 | +| Record.cs:27:1:27:57 | Person1 | Person1.PrintMembers(StringBuilder) | no location | +| Record.cs:27:1:27:57 | Person1 | Person1.ToString() | no location | +| Record.cs:27:1:27:57 | Person1 | System.Object.Equals(object, object) | no location | +| Record.cs:27:1:27:57 | Person1 | System.Object.GetType() | no location | +| Record.cs:27:1:27:57 | Person1 | System.Object.MemberwiseClone() | no location | +| Record.cs:27:1:27:57 | Person1 | System.Object.Object() | no location | +| Record.cs:27:1:27:57 | Person1 | System.Object.ReferenceEquals(object, object) | no location | +| Record.cs:27:1:27:57 | Person1 | System.Object.~Object() | no location | +| Record.cs:29:1:30:35 | Teacher1 | Person1.!=(Person1, Person1) | Record.cs:27:15:27:21 | +| Record.cs:29:1:30:35 | Teacher1 | Person1.==(Person1, Person1) | Record.cs:27:15:27:21 | +| Record.cs:29:1:30:35 | Teacher1 | Person1.Deconstruct(out string, out string) | no location | +| Record.cs:29:1:30:35 | Teacher1 | Person1.FirstName | Record.cs:27:30:27:38 | +| Record.cs:29:1:30:35 | Teacher1 | Person1.LastName | Record.cs:27:48:27:55 | +| Record.cs:29:1:30:35 | Teacher1 | Person1.Person1(Person1) | no location | +| Record.cs:29:1:30:35 | Teacher1 | Person1.Person1(string, string) | Record.cs:27:15:27:21 | +| Record.cs:29:1:30:35 | Teacher1 | System.Object.Equals(object, object) | no location | +| Record.cs:29:1:30:35 | Teacher1 | System.Object.GetType() | no location | +| Record.cs:29:1:30:35 | Teacher1 | System.Object.MemberwiseClone() | no location | +| Record.cs:29:1:30:35 | Teacher1 | System.Object.Object() | no location | +| Record.cs:29:1:30:35 | Teacher1 | System.Object.ReferenceEquals(object, object) | no location | +| Record.cs:29:1:30:35 | Teacher1 | System.Object.~Object() | no location | +| Record.cs:29:1:30:35 | Teacher1 | Teacher1.!=(Teacher1, Teacher1) | Record.cs:29:15:29:22 | +| Record.cs:29:1:30:35 | Teacher1 | Teacher1.<Clone>$() | no location | +| Record.cs:29:1:30:35 | Teacher1 | Teacher1.==(Teacher1, Teacher1) | Record.cs:29:15:29:22 | +| Record.cs:29:1:30:35 | Teacher1 | Teacher1.Deconstruct(out string, out string, out string) | no location | +| Record.cs:29:1:30:35 | Teacher1 | Teacher1.EqualityContract | Record.cs:29:15:29:22 | +| Record.cs:29:1:30:35 | Teacher1 | Teacher1.Equals(Person1) | no location | +| Record.cs:29:1:30:35 | Teacher1 | Teacher1.Equals(Teacher1) | no location | +| Record.cs:29:1:30:35 | Teacher1 | Teacher1.Equals(object) | no location | +| Record.cs:29:1:30:35 | Teacher1 | Teacher1.GetHashCode() | no location | +| Record.cs:29:1:30:35 | Teacher1 | Teacher1.PrintMembers(StringBuilder) | no location | +| Record.cs:29:1:30:35 | Teacher1 | Teacher1.Subject | Record.cs:29:66:29:72 | +| Record.cs:29:1:30:35 | Teacher1 | Teacher1.Teacher1(Teacher1) | no location | +| Record.cs:29:1:30:35 | Teacher1 | Teacher1.Teacher1(string, string, string) | Record.cs:29:15:29:22 | +| Record.cs:29:1:30:35 | Teacher1 | Teacher1.ToString() | no location | +| Record.cs:32:1:33:35 | Student1 | Person1.!=(Person1, Person1) | Record.cs:27:15:27:21 | +| Record.cs:32:1:33:35 | Student1 | Person1.==(Person1, Person1) | Record.cs:27:15:27:21 | +| Record.cs:32:1:33:35 | Student1 | Person1.Deconstruct(out string, out string) | no location | +| Record.cs:32:1:33:35 | Student1 | Person1.FirstName | Record.cs:27:30:27:38 | +| Record.cs:32:1:33:35 | Student1 | Person1.LastName | Record.cs:27:48:27:55 | +| Record.cs:32:1:33:35 | Student1 | Person1.Person1(Person1) | no location | +| Record.cs:32:1:33:35 | Student1 | Person1.Person1(string, string) | Record.cs:27:15:27:21 | +| Record.cs:32:1:33:35 | Student1 | Student1.!=(Student1, Student1) | Record.cs:32:22:32:29 | +| Record.cs:32:1:33:35 | Student1 | Student1.<Clone>$() | no location | +| Record.cs:32:1:33:35 | Student1 | Student1.==(Student1, Student1) | Record.cs:32:22:32:29 | +| Record.cs:32:1:33:35 | Student1 | Student1.Deconstruct(out string, out string, out int) | no location | +| Record.cs:32:1:33:35 | Student1 | Student1.EqualityContract | Record.cs:32:22:32:29 | +| Record.cs:32:1:33:35 | Student1 | Student1.Equals(Person1) | no location | +| Record.cs:32:1:33:35 | Student1 | Student1.Equals(Student1) | no location | +| Record.cs:32:1:33:35 | Student1 | Student1.Equals(object) | no location | +| Record.cs:32:1:33:35 | Student1 | Student1.GetHashCode() | no location | +| Record.cs:32:1:33:35 | Student1 | Student1.Level | Record.cs:32:70:32:74 | +| Record.cs:32:1:33:35 | Student1 | Student1.PrintMembers(StringBuilder) | no location | +| Record.cs:32:1:33:35 | Student1 | Student1.Student1(Student1) | no location | +| Record.cs:32:1:33:35 | Student1 | Student1.Student1(string, string, int) | Record.cs:32:22:32:29 | +| Record.cs:32:1:33:35 | Student1 | Student1.ToString() | no location | +| Record.cs:32:1:33:35 | Student1 | System.Object.Equals(object, object) | no location | +| Record.cs:32:1:33:35 | Student1 | System.Object.GetType() | no location | +| Record.cs:32:1:33:35 | Student1 | System.Object.MemberwiseClone() | no location | +| Record.cs:32:1:33:35 | Student1 | System.Object.Object() | no location | +| Record.cs:32:1:33:35 | Student1 | System.Object.ReferenceEquals(object, object) | no location | +| Record.cs:32:1:33:35 | Student1 | System.Object.~Object() | no location | +| Record.cs:35:1:39:1 | Pet | Pet.!=(Pet, Pet) | Record.cs:35:15:35:17 | +| Record.cs:35:1:39:1 | Pet | Pet.<Clone>$() | no location | +| Record.cs:35:1:39:1 | Pet | Pet.==(Pet, Pet) | Record.cs:35:15:35:17 | +| Record.cs:35:1:39:1 | Pet | Pet.Deconstruct(out string) | no location | +| Record.cs:35:1:39:1 | Pet | Pet.EqualityContract | Record.cs:35:15:35:17 | +| Record.cs:35:1:39:1 | Pet | Pet.Equals(Pet) | no location | +| Record.cs:35:1:39:1 | Pet | Pet.Equals(object) | no location | +| Record.cs:35:1:39:1 | Pet | Pet.GetHashCode() | no location | +| Record.cs:35:1:39:1 | Pet | Pet.Name | Record.cs:35:26:35:29 | +| Record.cs:35:1:39:1 | Pet | Pet.Pet(Pet) | no location | +| Record.cs:35:1:39:1 | Pet | Pet.Pet(string) | Record.cs:35:15:35:17 | +| Record.cs:35:1:39:1 | Pet | Pet.PrintMembers(StringBuilder) | no location | +| Record.cs:35:1:39:1 | Pet | Pet.ShredTheFurniture() | Record.cs:37:17:37:33 | +| Record.cs:35:1:39:1 | Pet | Pet.ToString() | no location | +| Record.cs:35:1:39:1 | Pet | System.Object.Equals(object, object) | no location | +| Record.cs:35:1:39:1 | Pet | System.Object.GetType() | no location | +| Record.cs:35:1:39:1 | Pet | System.Object.MemberwiseClone() | no location | +| Record.cs:35:1:39:1 | Pet | System.Object.Object() | no location | +| Record.cs:35:1:39:1 | Pet | System.Object.ReferenceEquals(object, object) | no location | +| Record.cs:35:1:39:1 | Pet | System.Object.~Object() | no location | +| Record.cs:41:1:52:1 | Dog | Dog.!=(Dog, Dog) | Record.cs:41:15:41:17 | +| Record.cs:41:1:52:1 | Dog | Dog.<Clone>$() | no location | +| Record.cs:41:1:52:1 | Dog | Dog.==(Dog, Dog) | Record.cs:41:15:41:17 | +| Record.cs:41:1:52:1 | Dog | Dog.Deconstruct(out string) | no location | +| Record.cs:41:1:52:1 | Dog | Dog.Dog(Dog) | no location | +| Record.cs:41:1:52:1 | Dog | Dog.Dog(string) | Record.cs:41:15:41:17 | +| Record.cs:41:1:52:1 | Dog | Dog.EqualityContract | Record.cs:41:15:41:17 | +| Record.cs:41:1:52:1 | Dog | Dog.Equals(Dog) | no location | +| Record.cs:41:1:52:1 | Dog | Dog.Equals(Pet) | no location | +| Record.cs:41:1:52:1 | Dog | Dog.Equals(object) | no location | +| Record.cs:41:1:52:1 | Dog | Dog.GetHashCode() | no location | +| Record.cs:41:1:52:1 | Dog | Dog.PrintMembers(StringBuilder) | no location | +| Record.cs:41:1:52:1 | Dog | Dog.ToString() | Record.cs:46:28:46:35 | +| Record.cs:41:1:52:1 | Dog | Dog.WagTail() | Record.cs:43:17:43:23 | +| Record.cs:41:1:52:1 | Dog | Pet.!=(Pet, Pet) | Record.cs:35:15:35:17 | +| Record.cs:41:1:52:1 | Dog | Pet.==(Pet, Pet) | Record.cs:35:15:35:17 | +| Record.cs:41:1:52:1 | Dog | Pet.Deconstruct(out string) | no location | +| Record.cs:41:1:52:1 | Dog | Pet.Name | Record.cs:35:26:35:29 | +| Record.cs:41:1:52:1 | Dog | Pet.Pet(Pet) | no location | +| Record.cs:41:1:52:1 | Dog | Pet.Pet(string) | Record.cs:35:15:35:17 | +| Record.cs:41:1:52:1 | Dog | Pet.ShredTheFurniture() | Record.cs:37:17:37:33 | +| Record.cs:41:1:52:1 | Dog | System.Object.Equals(object, object) | no location | +| Record.cs:41:1:52:1 | Dog | System.Object.GetType() | no location | +| Record.cs:41:1:52:1 | Dog | System.Object.MemberwiseClone() | no location | +| Record.cs:41:1:52:1 | Dog | System.Object.Object() | no location | +| Record.cs:41:1:52:1 | Dog | System.Object.ReferenceEquals(object, object) | no location | +| Record.cs:41:1:52:1 | Dog | System.Object.~Object() | no location | diff --git a/csharp/ql/test/library-tests/csharp9/record.ql b/csharp/ql/test/library-tests/csharp9/record.ql new file mode 100644 index 00000000000..3c97ee1aa84 --- /dev/null +++ b/csharp/ql/test/library-tests/csharp9/record.ql @@ -0,0 +1,14 @@ +import csharp + +query predicate types(Record t, string i) { t.getABaseInterface().toStringWithTypes() = i } + +private string getMemberName(Member m) { + result = m.getDeclaringType().getQualifiedName() + "." + m.toStringWithTypes() +} + +query predicate members(Record t, string ms, string l) { + exists(Member m | t.hasMember(m) | + ms = getMemberName(m) and + if m.fromSource() then l = m.getLocation().toString() else l = "no location" + ) +} diff --git a/csharp/ql/test/library-tests/csharp9/relationalPattern.expected b/csharp/ql/test/library-tests/csharp9/relationalPattern.expected new file mode 100644 index 00000000000..43dca825928 --- /dev/null +++ b/csharp/ql/test/library-tests/csharp9/relationalPattern.expected @@ -0,0 +1,5 @@ +| RelationalPattern.cs:6:14:6:19 | >= ... | >= | +| RelationalPattern.cs:8:14:8:18 | > ... | > | +| RelationalPattern.cs:10:14:10:19 | <= ... | <= | +| RelationalPattern.cs:12:14:12:18 | < ... | < | +| RelationalPattern.cs:19:13:19:14 | > ... | > | diff --git a/csharp/ql/test/library-tests/csharp9/relationalPattern.ql b/csharp/ql/test/library-tests/csharp9/relationalPattern.ql new file mode 100644 index 00000000000..50618e5bb7d --- /dev/null +++ b/csharp/ql/test/library-tests/csharp9/relationalPattern.ql @@ -0,0 +1,4 @@ +import csharp + +from RelationalPatternExpr p +select p, p.getOperator() diff --git a/csharp/ql/test/library-tests/csharp9/typeParameterNullability.ql b/csharp/ql/test/library-tests/csharp9/typeParameterNullability.ql index 58d3bfb8fb9..d8a966e2ff2 100644 --- a/csharp/ql/test/library-tests/csharp9/typeParameterNullability.ql +++ b/csharp/ql/test/library-tests/csharp9/typeParameterNullability.ql @@ -1,17 +1,17 @@ import csharp query predicate refType(TypeParameter tp) { - tp.fromSource() and + tp.getFile().getStem() = "TypeParameterNullability" and tp.isRefType() } query predicate valueType(TypeParameter tp) { - tp.fromSource() and + tp.getFile().getStem() = "TypeParameterNullability" and tp.isValueType() } query predicate valueOrRefType(TypeParameter tp) { - tp.fromSource() and + tp.getFile().getStem() = "TypeParameterNullability" and not tp.isRefType() and not tp.isValueType() } diff --git a/csharp/ql/test/library-tests/csharp9/typePattern.expected b/csharp/ql/test/library-tests/csharp9/typePattern.expected index 91b8f2c1afc..158d7050af4 100644 --- a/csharp/ql/test/library-tests/csharp9/typePattern.expected +++ b/csharp/ql/test/library-tests/csharp9/typePattern.expected @@ -1,3 +1,10 @@ +| BinaryPattern.cs:10:14:10:21 | Object o | Object | +| BinaryPattern.cs:10:27:10:39 | access to type BinaryPattern | BinaryPattern | +| BinaryPattern.cs:10:27:10:51 | BinaryPattern u | BinaryPattern | +| BinaryPattern.cs:12:14:12:21 | Object o | Object | +| BinaryPattern.cs:12:27:12:41 | BinaryPattern u | BinaryPattern | +| ParenthesizedPattern.cs:9:18:9:22 | Object p1 | Object | +| ParenthesizedPattern.cs:13:19:13:23 | Object p2 | Object | | ParenthesizedPattern.cs:25:13:25:15 | T t | T | | ParenthesizedPattern.cs:26:14:26:22 | Object o1 | Object | | ParenthesizedPattern.cs:27:14:27:19 | access to type String | String | @@ -7,3 +14,5 @@ | TypePattern.cs:12:13:12:20 | Double d | Double | | TypePattern.cs:13:13:13:25 | access to type String | String | | TypePattern.cs:14:13:14:27 | Object o | Object | +| UnaryPattern.cs:12:18:12:29 | access to type UnaryPattern | UnaryPattern | +| UnaryPattern.cs:12:18:12:41 | UnaryPattern u | UnaryPattern | diff --git a/csharp/ql/test/library-tests/csharp9/unaryPattern.expected b/csharp/ql/test/library-tests/csharp9/unaryPattern.expected new file mode 100644 index 00000000000..7a6ecdebeae --- /dev/null +++ b/csharp/ql/test/library-tests/csharp9/unaryPattern.expected @@ -0,0 +1,4 @@ +| UnaryPattern.cs:8:14:8:20 | not ... | UnaryPattern.cs:8:18:8:20 | a | +| UnaryPattern.cs:10:14:10:21 | not ... | UnaryPattern.cs:10:18:10:21 | null | +| UnaryPattern.cs:12:14:12:41 | not ... | UnaryPattern.cs:12:18:12:41 | { ... } | +| UnaryPattern.cs:18:13:18:17 | not ... | UnaryPattern.cs:18:17:18:17 | 1 | diff --git a/csharp/ql/test/library-tests/csharp9/unaryPattern.ql b/csharp/ql/test/library-tests/csharp9/unaryPattern.ql new file mode 100644 index 00000000000..87b70067664 --- /dev/null +++ b/csharp/ql/test/library-tests/csharp9/unaryPattern.ql @@ -0,0 +1,4 @@ +import csharp + +from UnaryPatternExpr pattern +select pattern, pattern.getAChild() diff --git a/csharp/ql/test/library-tests/dataflow/defuse/useUseEquivalence.ql b/csharp/ql/test/library-tests/dataflow/defuse/useUseEquivalence.ql index b7997b85384..e09c3d15caa 100644 --- a/csharp/ql/test/library-tests/dataflow/defuse/useUseEquivalence.ql +++ b/csharp/ql/test/library-tests/dataflow/defuse/useUseEquivalence.ql @@ -28,20 +28,20 @@ private TLocalScopeVariableReadOrSsaDef getANextReadOrDef(TLocalScopeVariableRea or not exists(read.getANextRead()) and exists( - Ssa::Definition ssaDef, Ssa::PseudoDefinition pseudoDef, ControlFlow::Node cfn, - ControlFlow::BasicBlock bb, int i + Ssa::Definition ssaDef, Ssa::PhiNode phi, ControlFlow::Node cfn, ControlFlow::BasicBlock bb, + int i | ssaDef.getARead() = read | - pseudoDef.getAnInput() = ssaDef and - pseudoDef.definesAt(bb, i) and + phi.getAnInput() = ssaDef and + phi.definesAt(_, bb, i) and cfn = read.getAReachableElement().getAControlFlowNode() and ( cfn = bb.getNode(i) or cfn = bb.getFirstNode() and i < 0 ) and - result = TSsaDefinition(pseudoDef) + result = TSsaDefinition(phi) ) ) or @@ -49,9 +49,9 @@ private TLocalScopeVariableReadOrSsaDef getANextReadOrDef(TLocalScopeVariableRea result = TLocalScopeVariableRead(ssaDef.getAFirstRead()) or not exists(ssaDef.getAFirstRead()) and - exists(Ssa::PseudoDefinition pseudoDef | - pseudoDef.getAnInput() = ssaDef and - result = TSsaDefinition(pseudoDef) + exists(Ssa::PhiNode phi | + phi.getAnInput() = ssaDef and + result = TSsaDefinition(phi) ) ) } diff --git a/csharp/ql/test/library-tests/dataflow/delegates/DelegateFlow.cs b/csharp/ql/test/library-tests/dataflow/delegates/DelegateFlow.cs index 9479cca940d..59c1c924a80 100644 --- a/csharp/ql/test/library-tests/dataflow/delegates/DelegateFlow.cs +++ b/csharp/ql/test/library-tests/dataflow/delegates/DelegateFlow.cs @@ -4,11 +4,11 @@ class DelegateFlow { void M1(int i) { } - void M2(Action<int> a) + static void M2(Action<int> a) { a(0); a = _ => { }; - a(0); + a(1); } void M3() @@ -108,4 +108,20 @@ class DelegateFlow } public delegate void MyDelegate(); + + public unsafe void M16(delegate*<Action<int>, void> fnptr, Action<int> a) + { + fnptr(a); + } + + public unsafe void M17() + { + M16(&M2, (i) => { }); + } + + public unsafe void M18() + { + delegate*<Action<int>, void> fnptr = &M2; + fnptr((i) => { }); + } } diff --git a/csharp/ql/test/library-tests/dataflow/delegates/DelegateFlow.expected b/csharp/ql/test/library-tests/dataflow/delegates/DelegateFlow.expected index c8893ec9b0e..80ae0d0fe89 100644 --- a/csharp/ql/test/library-tests/dataflow/delegates/DelegateFlow.expected +++ b/csharp/ql/test/library-tests/dataflow/delegates/DelegateFlow.expected @@ -1,12 +1,14 @@ summaryDelegateCall -| file://:0:0:0:0 | [summary] valueFactory | DelegateFlow.cs:104:23:104:30 | (...) => ... | DelegateFlow.cs:105:23:105:23 | access to local variable f | -| file://:0:0:0:0 | [summary] valueFactory | DelegateFlow.cs:106:13:106:20 | (...) => ... | DelegateFlow.cs:107:23:107:23 | access to local variable f | +| file://:0:0:0:0 | valueFactory | DelegateFlow.cs:104:23:104:30 | (...) => ... | DelegateFlow.cs:105:23:105:23 | access to local variable f | +| file://:0:0:0:0 | valueFactory | DelegateFlow.cs:106:13:106:20 | (...) => ... | DelegateFlow.cs:107:23:107:23 | access to local variable f | delegateCall | DelegateFlow.cs:9:9:9:12 | delegate call | DelegateFlow.cs:5:10:5:11 | M1 | DelegateFlow.cs:17:12:17:13 | delegate creation of type Action<Int32> | | DelegateFlow.cs:9:9:9:12 | delegate call | DelegateFlow.cs:5:10:5:11 | M1 | DelegateFlow.cs:22:12:22:12 | access to parameter a | | DelegateFlow.cs:9:9:9:12 | delegate call | DelegateFlow.cs:16:12:16:19 | (...) => ... | DelegateFlow.cs:16:12:16:19 | (...) => ... | | DelegateFlow.cs:9:9:9:12 | delegate call | DelegateFlow.cs:27:12:27:19 | (...) => ... | DelegateFlow.cs:22:12:22:12 | access to parameter a | | DelegateFlow.cs:9:9:9:12 | delegate call | DelegateFlow.cs:98:9:98:37 | LocalFunction | DelegateFlow.cs:99:12:99:24 | delegate creation of type Action<Int32> | +| DelegateFlow.cs:9:9:9:12 | delegate call | DelegateFlow.cs:119:18:119:27 | (...) => ... | DelegateFlow.cs:114:15:114:15 | access to parameter a | +| DelegateFlow.cs:9:9:9:12 | delegate call | DelegateFlow.cs:125:15:125:24 | (...) => ... | DelegateFlow.cs:125:15:125:24 | (...) => ... | | DelegateFlow.cs:11:9:11:12 | delegate call | DelegateFlow.cs:10:13:10:20 | (...) => ... | file://:0:0:0:0 | <empty> | | DelegateFlow.cs:33:9:33:13 | delegate call | DelegateFlow.cs:38:12:38:25 | (...) => ... | DelegateFlow.cs:38:12:38:25 | (...) => ... | | DelegateFlow.cs:38:19:38:22 | delegate call | DelegateFlow.cs:5:10:5:11 | M1 | DelegateFlow.cs:33:12:33:12 | access to parameter a | diff --git a/csharp/ql/test/library-tests/dataflow/functionpointers/FunctionPointerFlow.cs b/csharp/ql/test/library-tests/dataflow/functionpointers/FunctionPointerFlow.cs new file mode 100644 index 00000000000..0ebbef4942d --- /dev/null +++ b/csharp/ql/test/library-tests/dataflow/functionpointers/FunctionPointerFlow.cs @@ -0,0 +1,83 @@ +using System; + +unsafe class FunctionPointerFlow +{ + public static void Log1(int i) { } + public static void Log2(int i) { } + public static void Log3(int i) { } + public static void Log4(int i) { } + public static void Log5(int i) { } + public static void Log6(int i) { } + + public static void M2(delegate*<int, void> a) + { + a(1); + a = &Log3; + a(2); + } + + public void M3() + { + M2(&Log1); + } + + public static void M4(delegate*<int, void> a) + { + M2(a); + } + + public void M5() + { + M4(&Log2); + } + + public delegate*<int, void> M6() + { + return &Log4; + } + + public void M7() + { + M6()(0); + } + + public void M8() + { + static void LocalFunction(int i) { }; + M2(&LocalFunction); + } + + private static delegate*<int, void> field = &Log5; + + public void M9() + { + field(1); + } + + public void M10(delegate*<delegate*<int, void>, void> aa, delegate*<int, void> a) + { + aa(a); + } + + public void M11() + { + M10(&M4, &Log6); + } + + public void M16(delegate*<Action<int>, void> aa, Action<int> a) + { + aa(a); + } + + public static void M17(Action<int> a) + { + a(0); + a = _ => { }; + a(0); + } + + public void M18() + { + M16(&M17, (i) => { }); + } +} diff --git a/csharp/ql/test/library-tests/dataflow/functionpointers/FunctionPointerFlow.expected b/csharp/ql/test/library-tests/dataflow/functionpointers/FunctionPointerFlow.expected new file mode 100644 index 00000000000..ad2bfb887c0 --- /dev/null +++ b/csharp/ql/test/library-tests/dataflow/functionpointers/FunctionPointerFlow.expected @@ -0,0 +1,9 @@ +| FunctionPointerFlow.cs:14:9:14:12 | function pointer call | FunctionPointerFlow.cs:5:24:5:27 | Log1 | FunctionPointerFlow.cs:21:12:21:16 | &... | +| FunctionPointerFlow.cs:14:9:14:12 | function pointer call | FunctionPointerFlow.cs:6:24:6:27 | Log2 | FunctionPointerFlow.cs:26:12:26:12 | access to parameter a | +| FunctionPointerFlow.cs:14:9:14:12 | function pointer call | FunctionPointerFlow.cs:10:24:10:27 | Log6 | FunctionPointerFlow.cs:26:12:26:12 | access to parameter a | +| FunctionPointerFlow.cs:14:9:14:12 | function pointer call | FunctionPointerFlow.cs:46:9:46:44 | LocalFunction | FunctionPointerFlow.cs:47:12:47:25 | &... | +| FunctionPointerFlow.cs:16:9:16:12 | function pointer call | FunctionPointerFlow.cs:7:24:7:27 | Log3 | file://:0:0:0:0 | <empty> | +| FunctionPointerFlow.cs:41:9:41:15 | function pointer call | FunctionPointerFlow.cs:8:24:8:27 | Log4 | file://:0:0:0:0 | <empty> | +| FunctionPointerFlow.cs:54:9:54:16 | function pointer call | FunctionPointerFlow.cs:9:24:9:27 | Log5 | file://:0:0:0:0 | <empty> | +| FunctionPointerFlow.cs:59:9:59:13 | function pointer call | FunctionPointerFlow.cs:24:24:24:25 | M4 | FunctionPointerFlow.cs:64:13:64:15 | &... | +| FunctionPointerFlow.cs:69:9:69:13 | function pointer call | FunctionPointerFlow.cs:72:24:72:26 | M17 | FunctionPointerFlow.cs:81:13:81:16 | &... | diff --git a/csharp/ql/test/library-tests/dataflow/functionpointers/FunctionPointerFlow.ql b/csharp/ql/test/library-tests/dataflow/functionpointers/FunctionPointerFlow.ql new file mode 100644 index 00000000000..3434d068329 --- /dev/null +++ b/csharp/ql/test/library-tests/dataflow/functionpointers/FunctionPointerFlow.ql @@ -0,0 +1,5 @@ +import csharp + +query predicate fptrCall(FunctionPointerCall fptrc, Callable c, CallContext::CallContext cc) { + c = fptrc.getARuntimeTarget(cc) +} diff --git a/csharp/ql/test/library-tests/dataflow/local/DataFlowStep.expected b/csharp/ql/test/library-tests/dataflow/local/DataFlowStep.expected index e54670f07fc..e6c0dd9beda 100644 --- a/csharp/ql/test/library-tests/dataflow/local/DataFlowStep.expected +++ b/csharp/ql/test/library-tests/dataflow/local/DataFlowStep.expected @@ -325,6 +325,8 @@ | LocalDataFlow.cs:243:9:243:17 | access to local variable nonSink10 | LocalDataFlow.cs:244:15:244:23 | access to local variable nonSink10 | | LocalDataFlow.cs:247:13:247:52 | SSA def(taintedDataContract) | LocalDataFlow.cs:248:22:248:40 | access to local variable taintedDataContract | | LocalDataFlow.cs:247:13:247:52 | SSA qualifier def(taintedDataContract.AList) | LocalDataFlow.cs:250:22:250:46 | access to property AList | +| LocalDataFlow.cs:247:13:247:52 | SSA qualifier def(taintedDataContract.AString) | LocalDataFlow.cs:248:22:248:48 | access to property AString | +| LocalDataFlow.cs:247:13:247:52 | SSA qualifier def(taintedDataContract.AnInt) | LocalDataFlow.cs:257:20:257:44 | access to property AnInt | | LocalDataFlow.cs:247:35:247:52 | object creation of type DataContract | LocalDataFlow.cs:247:13:247:52 | SSA def(taintedDataContract) | | LocalDataFlow.cs:248:13:248:48 | SSA def(sink53) | LocalDataFlow.cs:249:15:249:20 | access to local variable sink53 | | LocalDataFlow.cs:248:22:248:40 | [post] access to local variable taintedDataContract | LocalDataFlow.cs:250:22:250:40 | access to local variable taintedDataContract | @@ -337,6 +339,7 @@ | LocalDataFlow.cs:250:22:250:46 | access to property AList | LocalDataFlow.cs:259:20:259:44 | access to property AList | | LocalDataFlow.cs:250:22:250:57 | access to property AString | LocalDataFlow.cs:250:13:250:57 | SSA def(sink54) | | LocalDataFlow.cs:254:13:254:55 | SSA def(nonTaintedDataContract) | LocalDataFlow.cs:255:20:255:41 | access to local variable nonTaintedDataContract | +| LocalDataFlow.cs:254:13:254:55 | SSA qualifier def(nonTaintedDataContract.AString) | LocalDataFlow.cs:255:20:255:49 | access to property AString | | LocalDataFlow.cs:254:38:254:55 | object creation of type DataContract | LocalDataFlow.cs:254:13:254:55 | SSA def(nonTaintedDataContract) | | LocalDataFlow.cs:255:9:255:49 | SSA def(nonSink0) | LocalDataFlow.cs:256:15:256:22 | access to local variable nonSink0 | | LocalDataFlow.cs:255:20:255:49 | access to property AString | LocalDataFlow.cs:255:9:255:49 | SSA def(nonSink0) | @@ -347,10 +350,12 @@ | LocalDataFlow.cs:259:9:259:53 | SSA def(nonSink2) | LocalDataFlow.cs:260:15:260:22 | access to local variable nonSink2 | | LocalDataFlow.cs:259:20:259:53 | access to property AnInt | LocalDataFlow.cs:259:9:259:53 | SSA def(nonSink2) | | LocalDataFlow.cs:263:17:263:37 | SSA def(taintedTextBox) | LocalDataFlow.cs:264:22:264:35 | access to local variable taintedTextBox | +| LocalDataFlow.cs:263:17:263:37 | SSA qualifier def(taintedTextBox.Text) | LocalDataFlow.cs:264:22:264:40 | access to property Text | | LocalDataFlow.cs:263:34:263:37 | null | LocalDataFlow.cs:263:17:263:37 | SSA def(taintedTextBox) | | LocalDataFlow.cs:264:13:264:40 | SSA def(sink60) | LocalDataFlow.cs:265:15:265:20 | access to local variable sink60 | | LocalDataFlow.cs:264:22:264:40 | access to property Text | LocalDataFlow.cs:264:13:264:40 | SSA def(sink60) | | LocalDataFlow.cs:268:17:268:40 | SSA def(nonTaintedTextBox) | LocalDataFlow.cs:269:20:269:36 | access to local variable nonTaintedTextBox | +| LocalDataFlow.cs:268:17:268:40 | SSA qualifier def(nonTaintedTextBox.Text) | LocalDataFlow.cs:269:20:269:41 | access to property Text | | LocalDataFlow.cs:268:37:268:40 | null | LocalDataFlow.cs:268:17:268:40 | SSA def(nonTaintedTextBox) | | LocalDataFlow.cs:269:9:269:41 | SSA def(nonSink0) | LocalDataFlow.cs:270:15:270:22 | access to local variable nonSink0 | | LocalDataFlow.cs:269:20:269:41 | access to property Text | LocalDataFlow.cs:269:9:269:41 | SSA def(nonSink0) | @@ -396,6 +401,7 @@ | LocalDataFlow.cs:314:22:314:26 | access to local variable sink0 | LocalDataFlow.cs:314:22:314:38 | ... ?? ... | | LocalDataFlow.cs:314:22:314:38 | ... ?? ... | LocalDataFlow.cs:314:13:314:38 | SSA def(sink74) | | LocalDataFlow.cs:314:31:314:38 | access to local variable nonSink0 | LocalDataFlow.cs:314:22:314:38 | ... ?? ... | +| LocalDataFlow.cs:334:28:334:30 | SSA entry def(this.anInt) | LocalDataFlow.cs:334:41:334:45 | access to field anInt | | LocalDataFlow.cs:334:28:334:30 | this | LocalDataFlow.cs:334:41:334:45 | this access | | LocalDataFlow.cs:334:50:334:52 | this | LocalDataFlow.cs:334:56:334:60 | this access | | LocalDataFlow.cs:334:50:334:52 | value | LocalDataFlow.cs:334:64:334:68 | access to parameter value | @@ -408,6 +414,14 @@ | LocalDataFlow.cs:361:41:361:44 | args | LocalDataFlow.cs:363:29:363:32 | access to parameter args | | LocalDataFlow.cs:363:29:363:32 | [post] access to parameter args | LocalDataFlow.cs:364:27:364:30 | access to parameter args | | LocalDataFlow.cs:363:29:363:32 | access to parameter args | LocalDataFlow.cs:364:27:364:30 | access to parameter args | +| LocalDataFlow.cs:367:23:367:24 | b1 | LocalDataFlow.cs:371:13:371:14 | access to parameter b1 | +| LocalDataFlow.cs:367:32:367:33 | b2 | LocalDataFlow.cs:374:17:374:18 | access to parameter b2 | +| LocalDataFlow.cs:373:13:373:25 | SSA def(x) | LocalDataFlow.cs:376:35:376:35 | access to local variable x | +| LocalDataFlow.cs:373:13:373:25 | SSA def(x) | LocalDataFlow.cs:382:9:382:17 | SSA phi(x) | +| LocalDataFlow.cs:373:17:373:25 | "tainted" | LocalDataFlow.cs:373:13:373:25 | SSA def(x) | +| LocalDataFlow.cs:381:13:381:29 | SSA def(x) | LocalDataFlow.cs:382:9:382:17 | SSA phi(x) | +| LocalDataFlow.cs:381:17:381:29 | "not tainted" | LocalDataFlow.cs:381:13:381:29 | SSA def(x) | +| LocalDataFlow.cs:382:9:382:17 | SSA phi(x) | LocalDataFlow.cs:382:15:382:15 | access to local variable x | | SSA.cs:5:17:5:17 | SSA entry def(this.S) | SSA.cs:67:9:67:14 | access to field S | | SSA.cs:5:17:5:17 | this | SSA.cs:67:9:67:12 | this access | | SSA.cs:5:26:5:32 | tainted | SSA.cs:8:24:8:30 | access to parameter tainted | @@ -688,7 +702,6 @@ | SSA.cs:154:13:154:13 | access to parameter t | SSA.cs:154:13:154:13 | (...) ... | | SSA.cs:154:13:154:13 | access to parameter t | SSA.cs:155:25:155:25 | access to parameter t | | SSA.cs:155:25:155:25 | SSA def(t) | SSA.cs:152:17:152:28 | SSA phi(t) | -| SSA.cs:155:25:155:25 | access to parameter t | SSA.cs:152:17:152:28 | SSA phi(t) | | SSA.cs:166:10:166:13 | this | SSA.cs:166:19:166:22 | this access | | SSA.cs:168:22:168:28 | tainted | SSA.cs:173:24:173:30 | access to parameter tainted | | SSA.cs:168:35:168:35 | i | SSA.cs:171:13:171:13 | access to parameter i | @@ -696,6 +709,7 @@ | SSA.cs:170:27:170:28 | "" | SSA.cs:170:16:170:28 | SSA def(ssaSink5) | | SSA.cs:171:13:171:15 | SSA def(i) | SSA.cs:174:20:174:20 | SSA phi(i) | | SSA.cs:173:13:173:30 | SSA def(ssaSink5) | SSA.cs:176:21:176:28 | access to local variable ssaSink5 | +| SSA.cs:173:13:173:30 | SSA def(ssaSink5) | SSA.cs:180:9:180:24 | SSA phi(ssaSink5) | | SSA.cs:173:24:173:30 | access to parameter tainted | SSA.cs:173:13:173:30 | SSA def(ssaSink5) | | SSA.cs:174:20:174:20 | SSA phi(i) | SSA.cs:174:20:174:20 | access to parameter i | | SSA.cs:174:20:174:22 | SSA def(i) | SSA.cs:174:20:174:20 | SSA phi(i) | diff --git a/csharp/ql/test/library-tests/dataflow/local/LocalDataFlow.cs b/csharp/ql/test/library-tests/dataflow/local/LocalDataFlow.cs index a5a1e34178f..900a2161715 100644 --- a/csharp/ql/test/library-tests/dataflow/local/LocalDataFlow.cs +++ b/csharp/ql/test/library-tests/dataflow/local/LocalDataFlow.cs @@ -363,4 +363,22 @@ public class LocalDataFlow Span<object> span = args; // flow (library operator) LocalDataFlow x = args; // no flow (source code operator) } + + void PhiFlow(bool b1, bool b2) + { + var x = ""; + + if (b1) + { + x = "tainted"; + if (b2) + { + Console.WriteLine(x); + return; + } + } + else + x = "not tainted"; + Check(x); + } } diff --git a/csharp/ql/test/library-tests/dataflow/local/TaintTrackingStep.expected b/csharp/ql/test/library-tests/dataflow/local/TaintTrackingStep.expected index e33df037f81..37e5fee2dc9 100644 --- a/csharp/ql/test/library-tests/dataflow/local/TaintTrackingStep.expected +++ b/csharp/ql/test/library-tests/dataflow/local/TaintTrackingStep.expected @@ -421,6 +421,8 @@ | LocalDataFlow.cs:243:30:243:37 | access to local variable nonSink0 | LocalDataFlow.cs:243:9:243:38 | call to method AppendLine | | LocalDataFlow.cs:247:13:247:52 | SSA def(taintedDataContract) | LocalDataFlow.cs:248:22:248:40 | access to local variable taintedDataContract | | LocalDataFlow.cs:247:13:247:52 | SSA qualifier def(taintedDataContract.AList) | LocalDataFlow.cs:250:22:250:46 | access to property AList | +| LocalDataFlow.cs:247:13:247:52 | SSA qualifier def(taintedDataContract.AString) | LocalDataFlow.cs:248:22:248:48 | access to property AString | +| LocalDataFlow.cs:247:13:247:52 | SSA qualifier def(taintedDataContract.AnInt) | LocalDataFlow.cs:257:20:257:44 | access to property AnInt | | LocalDataFlow.cs:247:35:247:52 | object creation of type DataContract | LocalDataFlow.cs:247:13:247:52 | SSA def(taintedDataContract) | | LocalDataFlow.cs:248:13:248:48 | SSA def(sink53) | LocalDataFlow.cs:249:15:249:20 | access to local variable sink53 | | LocalDataFlow.cs:248:22:248:40 | [post] access to local variable taintedDataContract | LocalDataFlow.cs:250:22:250:40 | access to local variable taintedDataContract | @@ -437,6 +439,7 @@ | LocalDataFlow.cs:250:22:250:49 | access to indexer | LocalDataFlow.cs:250:22:250:57 | access to property AString | | LocalDataFlow.cs:250:22:250:57 | access to property AString | LocalDataFlow.cs:250:13:250:57 | SSA def(sink54) | | LocalDataFlow.cs:254:13:254:55 | SSA def(nonTaintedDataContract) | LocalDataFlow.cs:255:20:255:41 | access to local variable nonTaintedDataContract | +| LocalDataFlow.cs:254:13:254:55 | SSA qualifier def(nonTaintedDataContract.AString) | LocalDataFlow.cs:255:20:255:49 | access to property AString | | LocalDataFlow.cs:254:38:254:55 | object creation of type DataContract | LocalDataFlow.cs:254:13:254:55 | SSA def(nonTaintedDataContract) | | LocalDataFlow.cs:255:9:255:49 | SSA def(nonSink0) | LocalDataFlow.cs:256:15:256:22 | access to local variable nonSink0 | | LocalDataFlow.cs:255:20:255:41 | access to local variable nonTaintedDataContract | LocalDataFlow.cs:255:20:255:49 | access to property AString | @@ -450,11 +453,13 @@ | LocalDataFlow.cs:259:20:259:44 | access to property AList | LocalDataFlow.cs:259:20:259:47 | access to indexer | | LocalDataFlow.cs:259:20:259:53 | access to property AnInt | LocalDataFlow.cs:259:9:259:53 | SSA def(nonSink2) | | LocalDataFlow.cs:263:17:263:37 | SSA def(taintedTextBox) | LocalDataFlow.cs:264:22:264:35 | access to local variable taintedTextBox | +| LocalDataFlow.cs:263:17:263:37 | SSA qualifier def(taintedTextBox.Text) | LocalDataFlow.cs:264:22:264:40 | access to property Text | | LocalDataFlow.cs:263:34:263:37 | null | LocalDataFlow.cs:263:17:263:37 | SSA def(taintedTextBox) | | LocalDataFlow.cs:264:13:264:40 | SSA def(sink60) | LocalDataFlow.cs:265:15:265:20 | access to local variable sink60 | | LocalDataFlow.cs:264:22:264:35 | access to local variable taintedTextBox | LocalDataFlow.cs:264:22:264:40 | access to property Text | | LocalDataFlow.cs:264:22:264:40 | access to property Text | LocalDataFlow.cs:264:13:264:40 | SSA def(sink60) | | LocalDataFlow.cs:268:17:268:40 | SSA def(nonTaintedTextBox) | LocalDataFlow.cs:269:20:269:36 | access to local variable nonTaintedTextBox | +| LocalDataFlow.cs:268:17:268:40 | SSA qualifier def(nonTaintedTextBox.Text) | LocalDataFlow.cs:269:20:269:41 | access to property Text | | LocalDataFlow.cs:268:37:268:40 | null | LocalDataFlow.cs:268:17:268:40 | SSA def(nonTaintedTextBox) | | LocalDataFlow.cs:269:9:269:41 | SSA def(nonSink0) | LocalDataFlow.cs:270:15:270:22 | access to local variable nonSink0 | | LocalDataFlow.cs:269:20:269:36 | access to local variable nonTaintedTextBox | LocalDataFlow.cs:269:20:269:41 | access to property Text | @@ -505,6 +510,7 @@ | LocalDataFlow.cs:314:22:314:26 | access to local variable sink0 | LocalDataFlow.cs:314:22:314:38 | ... ?? ... | | LocalDataFlow.cs:314:22:314:38 | ... ?? ... | LocalDataFlow.cs:314:13:314:38 | SSA def(sink74) | | LocalDataFlow.cs:314:31:314:38 | access to local variable nonSink0 | LocalDataFlow.cs:314:22:314:38 | ... ?? ... | +| LocalDataFlow.cs:334:28:334:30 | SSA entry def(this.anInt) | LocalDataFlow.cs:334:41:334:45 | access to field anInt | | LocalDataFlow.cs:334:28:334:30 | this | LocalDataFlow.cs:334:41:334:45 | this access | | LocalDataFlow.cs:334:50:334:52 | this | LocalDataFlow.cs:334:56:334:60 | this access | | LocalDataFlow.cs:334:50:334:52 | value | LocalDataFlow.cs:334:64:334:68 | access to parameter value | @@ -518,6 +524,14 @@ | LocalDataFlow.cs:363:29:363:32 | [post] access to parameter args | LocalDataFlow.cs:364:27:364:30 | access to parameter args | | LocalDataFlow.cs:363:29:363:32 | access to parameter args | LocalDataFlow.cs:363:29:363:32 | call to operator implicit conversion | | LocalDataFlow.cs:363:29:363:32 | access to parameter args | LocalDataFlow.cs:364:27:364:30 | access to parameter args | +| LocalDataFlow.cs:367:23:367:24 | b1 | LocalDataFlow.cs:371:13:371:14 | access to parameter b1 | +| LocalDataFlow.cs:367:32:367:33 | b2 | LocalDataFlow.cs:374:17:374:18 | access to parameter b2 | +| LocalDataFlow.cs:373:13:373:25 | SSA def(x) | LocalDataFlow.cs:376:35:376:35 | access to local variable x | +| LocalDataFlow.cs:373:13:373:25 | SSA def(x) | LocalDataFlow.cs:382:9:382:17 | SSA phi(x) | +| LocalDataFlow.cs:373:17:373:25 | "tainted" | LocalDataFlow.cs:373:13:373:25 | SSA def(x) | +| LocalDataFlow.cs:381:13:381:29 | SSA def(x) | LocalDataFlow.cs:382:9:382:17 | SSA phi(x) | +| LocalDataFlow.cs:381:17:381:29 | "not tainted" | LocalDataFlow.cs:381:13:381:29 | SSA def(x) | +| LocalDataFlow.cs:382:9:382:17 | SSA phi(x) | LocalDataFlow.cs:382:15:382:15 | access to local variable x | | SSA.cs:5:17:5:17 | SSA entry def(this.S) | SSA.cs:67:9:67:14 | access to field S | | SSA.cs:5:17:5:17 | this | SSA.cs:67:9:67:12 | this access | | SSA.cs:5:26:5:32 | tainted | SSA.cs:8:24:8:30 | access to parameter tainted | @@ -814,7 +828,6 @@ | SSA.cs:154:13:154:13 | access to parameter t | SSA.cs:154:13:154:13 | (...) ... | | SSA.cs:154:13:154:13 | access to parameter t | SSA.cs:155:25:155:25 | access to parameter t | | SSA.cs:155:25:155:25 | SSA def(t) | SSA.cs:152:17:152:28 | SSA phi(t) | -| SSA.cs:155:25:155:25 | access to parameter t | SSA.cs:152:17:152:28 | SSA phi(t) | | SSA.cs:166:10:166:13 | this | SSA.cs:166:19:166:22 | this access | | SSA.cs:168:22:168:28 | tainted | SSA.cs:173:24:173:30 | access to parameter tainted | | SSA.cs:168:35:168:35 | i | SSA.cs:171:13:171:13 | access to parameter i | @@ -823,6 +836,7 @@ | SSA.cs:171:13:171:15 | ...-- | SSA.cs:171:13:171:19 | ... > ... | | SSA.cs:171:13:171:15 | SSA def(i) | SSA.cs:174:20:174:20 | SSA phi(i) | | SSA.cs:173:13:173:30 | SSA def(ssaSink5) | SSA.cs:176:21:176:28 | access to local variable ssaSink5 | +| SSA.cs:173:13:173:30 | SSA def(ssaSink5) | SSA.cs:180:9:180:24 | SSA phi(ssaSink5) | | SSA.cs:173:24:173:30 | access to parameter tainted | SSA.cs:173:13:173:30 | SSA def(ssaSink5) | | SSA.cs:174:20:174:20 | SSA phi(i) | SSA.cs:174:20:174:20 | access to parameter i | | SSA.cs:174:20:174:22 | ...-- | SSA.cs:174:20:174:26 | ... > ... | diff --git a/csharp/ql/test/library-tests/dataflow/signanalysis/SignAnalysis.expected b/csharp/ql/test/library-tests/dataflow/signanalysis/SignAnalysis.expected index 303715e1894..2081a3423cd 100644 --- a/csharp/ql/test/library-tests/dataflow/signanalysis/SignAnalysis.expected +++ b/csharp/ql/test/library-tests/dataflow/signanalysis/SignAnalysis.expected @@ -199,8 +199,6 @@ | SignAnalysis.cs:377:21:377:22 | &... | positive | | SignAnalysis.cs:378:18:378:19 | access to local variable dp | positive | | SignAnalysis.cs:381:38:381:38 | access to local variable x | strictlyNegative | -| SignAnalysis.cs:385:50:385:99 | access to constant Explicit | strictlyPositive | -| SignAnalysis.cs:385:109:385:110 | 15 | strictlyPositive | | SignAnalysis.cs:390:13:390:32 | Int32 x = ... | strictlyPositive | | SignAnalysis.cs:390:17:390:32 | sizeof(..) | strictlyPositive | | SignAnalysis.cs:391:34:391:34 | access to local variable x | strictlyPositive | diff --git a/csharp/ql/test/library-tests/dataflow/ssa/Capture.cs b/csharp/ql/test/library-tests/dataflow/ssa/Capture.cs index d11947afed6..a74d480668d 100644 --- a/csharp/ql/test/library-tests/dataflow/ssa/Capture.cs +++ b/csharp/ql/test/library-tests/dataflow/ssa/Capture.cs @@ -99,7 +99,7 @@ class Capture return x; }); - var z = 12; // Should *not* get an SSA definition + var z = 12; // Should *not* get an SSA definition, but currently does because it is considered live via the lambda fn(() => { z = 0; @@ -119,7 +119,7 @@ class Capture }; M1(); - var b = 12; // Should *not* get an SSA definition + var b = 12; // Should *not* get an SSA definition, but currently does because it is considered live via the lambda void M2() { b = 0; @@ -155,7 +155,7 @@ class Capture Use(f); void M6() { - f = 0; // Should *not* get an SSA definition (`f` is not read after `M6` is called) + f = 0; // Should *not* get an SSA definition (`f` is not read after `M6` is called), but currently does because it is considered live via the call to `M6` } M6(); diff --git a/csharp/ql/test/library-tests/dataflow/ssa/PreSsaConsistency.ql b/csharp/ql/test/library-tests/dataflow/ssa/PreSsaConsistency.ql index b740f89e91b..9345525f486 100644 --- a/csharp/ql/test/library-tests/dataflow/ssa/PreSsaConsistency.ql +++ b/csharp/ql/test/library-tests/dataflow/ssa/PreSsaConsistency.ql @@ -1,6 +1,7 @@ import csharp import semmle.code.csharp.controlflow.internal.PreSsa as PreSsa import semmle.code.csharp.controlflow.internal.ControlFlowGraphImpl +import semmle.code.csharp.dataflow.internal.SsaImpl as SsaImpl class CallableWithSplitting extends Callable { CallableWithSplitting() { this = any(SplitControlFlowElement e).getEnclosingCallable() } @@ -46,13 +47,11 @@ query predicate readReadInconsistency( b = true and a = read1.getTarget() and PreSsa::adjacentReadPairSameVar(read1, read2) and - not Ssa::Internal::adjacentReadPairSameVar(_, read1.getAControlFlowNode(), - read2.getAControlFlowNode()) + not SsaImpl::adjacentReadPairSameVar(_, read1.getAControlFlowNode(), read2.getAControlFlowNode()) or b = false and a = read1.getTarget() and - Ssa::Internal::adjacentReadPairSameVar(_, read1.getAControlFlowNode(), - read2.getAControlFlowNode()) and + SsaImpl::adjacentReadPairSameVar(_, read1.getAControlFlowNode(), read2.getAControlFlowNode()) and read1.getTarget() instanceof PreSsa::SimpleAssignable and not PreSsa::adjacentReadPairSameVar(read1, read2) and // Exclude split CFG elements because SSA may be more precise than pre-SSA @@ -77,7 +76,7 @@ query predicate phiInconsistency( edef = phi.getAnUltimateDefinition() | edef.getADefinition() = adef and - phi.definesAt(bb, _) and + phi.definesAt(_, bb, _) and cfe = bb.getFirstNode().getElement() ) ) @@ -88,7 +87,7 @@ query predicate phiInconsistency( | edef = phi.getAnUltimateDefinition() and edef.getADefinition() = adef and - phi.definesAt(bb, _) and + phi.definesAt(_, bb, _) and cfe = bb.getFirstNode().getElement() and not exists(PreSsa::Definition def | adef = def.getAPhiInput+().getDefinition() and diff --git a/csharp/ql/test/library-tests/dataflow/ssa/SsaDef.expected b/csharp/ql/test/library-tests/dataflow/ssa/SsaDef.expected index bc2b8dd23d9..bf944248e67 100644 --- a/csharp/ql/test/library-tests/dataflow/ssa/SsaDef.expected +++ b/csharp/ql/test/library-tests/dataflow/ssa/SsaDef.expected @@ -49,10 +49,12 @@ | Capture.cs:94:13:94:13 | y | Capture.cs:94:13:94:18 | SSA def(y) | | Capture.cs:94:13:94:13 | y | Capture.cs:96:12:100:9 | SSA capture def(y) | | Capture.cs:98:17:98:17 | x | Capture.cs:98:17:98:21 | SSA def(x) | +| Capture.cs:102:13:102:13 | z | Capture.cs:102:13:102:18 | SSA def(z) | | Capture.cs:102:13:102:13 | z | Capture.cs:105:13:105:17 | SSA def(z) | | Capture.cs:114:13:114:13 | a | Capture.cs:114:13:114:18 | SSA def(a) | | Capture.cs:114:13:114:13 | a | Capture.cs:115:9:119:9 | SSA capture def(a) | | Capture.cs:117:17:117:17 | x | Capture.cs:117:17:117:21 | SSA def(x) | +| Capture.cs:122:13:122:13 | b | Capture.cs:122:13:122:18 | SSA def(b) | | Capture.cs:122:13:122:13 | b | Capture.cs:125:13:125:17 | SSA def(b) | | Capture.cs:130:13:130:13 | c | Capture.cs:130:13:130:18 | SSA def(c) | | Capture.cs:130:13:130:13 | c | Capture.cs:133:13:133:17 | SSA def(c) | @@ -62,6 +64,7 @@ | Capture.cs:139:13:139:13 | d | Capture.cs:144:9:144:12 | SSA call def(d) | | Capture.cs:147:13:147:13 | e | Capture.cs:148:9:152:9 | SSA capture def(e) | | Capture.cs:154:13:154:13 | f | Capture.cs:154:13:154:18 | SSA def(f) | +| Capture.cs:154:13:154:13 | f | Capture.cs:158:13:158:17 | SSA def(f) | | Capture.cs:162:13:162:13 | g | Capture.cs:163:9:166:9 | SSA capture def(g) | | Capture.cs:168:13:168:13 | h | Capture.cs:171:13:171:17 | SSA def(h) | | Capture.cs:168:13:168:13 | h | Capture.cs:174:17:174:21 | SSA def(h) | @@ -193,11 +196,9 @@ | Fields.cs:33:19:33:22 | Fields.stat | Fields.cs:49:17:49:28 | SSA call def(Fields.stat) | | Fields.cs:33:19:33:22 | Fields.stat | Fields.cs:50:9:50:17 | SSA phi(Fields.stat) | | Fields.cs:33:19:33:22 | Fields.stat | Fields.cs:51:9:51:20 | SSA call def(Fields.stat) | -| Fields.cs:63:16:63:28 | this.VolatileField | Fields.cs:63:16:63:28 | SSA untracked def(this.VolatileField) | -| Fields.cs:63:16:63:28 | this.VolatileField | Fields.cs:69:21:69:33 | SSA untracked def(this.VolatileField) | | Fields.cs:65:24:65:32 | this.LoopField | Fields.cs:61:17:61:17 | SSA entry def(this.LoopField) | -| Fields.cs:71:17:71:35 | this.SingleAccessedField | Fields.cs:71:17:71:35 | SSA untracked def(this.SingleAccessedField) | -| Fields.cs:76:20:76:38 | this.SingleAccessedField | Fields.cs:76:20:76:38 | SSA untracked def(this.SingleAccessedField) | +| Fields.cs:71:17:71:35 | this.SingleAccessedField | Fields.cs:61:17:61:17 | SSA entry def(this.SingleAccessedField) | +| Fields.cs:76:20:76:38 | this.SingleAccessedField | Fields.cs:74:17:74:17 | SSA entry def(this.SingleAccessedField) | | Fields.cs:77:13:77:13 | f | Fields.cs:77:13:77:45 | SSA def(f) | | Fields.cs:77:13:77:13 | f | Fields.cs:78:27:78:54 | SSA capture def(f) | | Fields.cs:78:23:78:23 | a | Fields.cs:78:23:78:54 | SSA def(a) | @@ -220,9 +221,9 @@ | Fields.cs:107:33:107:33 | f | Fields.cs:107:33:107:33 | SSA param(f) | | Fields.cs:115:20:115:29 | this.Field | Fields.cs:109:10:109:10 | SSA entry def(this.Field) | | Fields.cs:115:20:115:29 | this.Field | Fields.cs:114:9:114:22 | SSA call def(this.Field) | -| Fields.cs:115:20:115:35 | this.Field.Field | Fields.cs:109:10:109:10 | SSA entry def(this.Field.Field) | +| Fields.cs:115:20:115:35 | this.Field.Field | Fields.cs:109:10:109:10 | SSA qualifier def(this.Field.Field) | | Fields.cs:115:20:115:35 | this.Field.Field | Fields.cs:114:9:114:22 | SSA call def(this.Field.Field) | -| Fields.cs:116:21:116:39 | this.Field.Field.xs | Fields.cs:109:10:109:10 | SSA entry def(this.Field.Field.xs) | +| Fields.cs:116:21:116:39 | this.Field.Field.xs | Fields.cs:109:10:109:10 | SSA qualifier def(this.Field.Field.xs) | | Fields.cs:116:21:116:39 | this.Field.Field.xs | Fields.cs:114:9:114:22 | SSA qualifier def(this.Field.Field.xs) | | OutRef.cs:9:13:9:13 | j | OutRef.cs:9:13:9:17 | SSA def(j) | | OutRef.cs:9:13:9:13 | j | OutRef.cs:10:32:10:32 | SSA def(j) | @@ -283,8 +284,8 @@ | Properties.cs:61:23:61:23 | i | Properties.cs:63:16:63:16 | SSA phi(i) | | Properties.cs:61:23:61:23 | i | Properties.cs:63:16:63:18 | SSA def(i) | | Properties.cs:65:24:65:31 | this.LoopProp | Properties.cs:61:17:61:17 | SSA entry def(this.LoopProp) | -| Properties.cs:67:21:67:38 | this.SingleAccessedProp | Properties.cs:67:21:67:38 | SSA untracked def(this.SingleAccessedProp) | -| Properties.cs:72:20:72:37 | this.SingleAccessedProp | Properties.cs:72:20:72:37 | SSA untracked def(this.SingleAccessedProp) | +| Properties.cs:67:21:67:38 | this.SingleAccessedProp | Properties.cs:61:17:61:17 | SSA entry def(this.SingleAccessedProp) | +| Properties.cs:72:20:72:37 | this.SingleAccessedProp | Properties.cs:70:17:70:17 | SSA entry def(this.SingleAccessedProp) | | Properties.cs:73:13:73:13 | f | Properties.cs:73:13:73:32 | SSA def(f) | | Properties.cs:73:13:73:13 | f | Properties.cs:74:27:74:54 | SSA capture def(f) | | Properties.cs:74:23:74:23 | a | Properties.cs:74:23:74:54 | SSA def(a) | @@ -298,17 +299,12 @@ | Properties.cs:76:9:76:12 | f.xs | Properties.cs:84:9:84:25 | SSA def(f.xs) | | Properties.cs:78:9:78:15 | this.xs | Properties.cs:81:9:81:22 | SSA def(this.xs) | | Properties.cs:78:9:78:15 | this.xs | Properties.cs:83:9:83:22 | SSA def(this.xs) | -| Properties.cs:94:9:94:27 | this.NonTrivialProp | Properties.cs:95:20:95:38 | SSA untracked def(this.NonTrivialProp) | -| Properties.cs:97:9:97:24 | this.VirtualProp | Properties.cs:98:16:98:31 | SSA untracked def(this.VirtualProp) | -| Properties.cs:100:9:100:26 | this.VolatileField | Properties.cs:100:9:100:26 | SSA untracked def(this.VolatileField) | -| Properties.cs:100:9:100:26 | this.VolatileField | Properties.cs:101:21:101:38 | SSA untracked def(this.VolatileField) | -| Properties.cs:100:9:100:29 | this.VolatileField.xs | Properties.cs:101:21:101:41 | SSA untracked def(this.VolatileField.xs) | | Properties.cs:106:37:106:37 | p | Properties.cs:106:37:106:37 | SSA param(p) | | Properties.cs:114:20:114:29 | this.Props | Properties.cs:108:10:108:10 | SSA entry def(this.Props) | | Properties.cs:114:20:114:29 | this.Props | Properties.cs:113:9:113:22 | SSA call def(this.Props) | -| Properties.cs:114:20:114:35 | this.Props.Props | Properties.cs:108:10:108:10 | SSA entry def(this.Props.Props) | +| Properties.cs:114:20:114:35 | this.Props.Props | Properties.cs:108:10:108:10 | SSA qualifier def(this.Props.Props) | | Properties.cs:114:20:114:35 | this.Props.Props | Properties.cs:113:9:113:22 | SSA call def(this.Props.Props) | -| Properties.cs:115:21:115:39 | this.Props.Props.xs | Properties.cs:108:10:108:10 | SSA entry def(this.Props.Props.xs) | +| Properties.cs:115:21:115:39 | this.Props.Props.xs | Properties.cs:108:10:108:10 | SSA qualifier def(this.Props.Props.xs) | | Properties.cs:115:21:115:39 | this.Props.Props.xs | Properties.cs:113:9:113:22 | SSA qualifier def(this.Props.Props.xs) | | Splitting.cs:3:18:3:18 | b | Splitting.cs:3:18:3:18 | SSA param(b) | | Splitting.cs:5:13:5:13 | x | Splitting.cs:7:13:7:19 | [b (line 3): true] SSA def(x) | diff --git a/csharp/ql/test/library-tests/dataflow/ssa/SsaDefElement.expected b/csharp/ql/test/library-tests/dataflow/ssa/SsaDefElement.expected index bc176624df5..a259546f403 100644 --- a/csharp/ql/test/library-tests/dataflow/ssa/SsaDefElement.expected +++ b/csharp/ql/test/library-tests/dataflow/ssa/SsaDefElement.expected @@ -49,10 +49,12 @@ | Capture.cs:94:13:94:18 | SSA def(y) | Capture.cs:94:13:94:18 | Int32 y = ... | | Capture.cs:96:12:100:9 | SSA capture def(y) | Capture.cs:96:12:100:9 | (...) => ... | | Capture.cs:98:17:98:21 | SSA def(x) | Capture.cs:98:17:98:21 | Int32 x = ... | +| Capture.cs:102:13:102:18 | SSA def(z) | Capture.cs:102:13:102:18 | Int32 z = ... | | Capture.cs:105:13:105:17 | SSA def(z) | Capture.cs:105:13:105:17 | ... = ... | | Capture.cs:114:13:114:18 | SSA def(a) | Capture.cs:114:13:114:18 | Int32 a = ... | | Capture.cs:115:9:119:9 | SSA capture def(a) | Capture.cs:115:9:119:9 | M1 | | Capture.cs:117:17:117:21 | SSA def(x) | Capture.cs:117:17:117:21 | Int32 x = ... | +| Capture.cs:122:13:122:18 | SSA def(b) | Capture.cs:122:13:122:18 | Int32 b = ... | | Capture.cs:125:13:125:17 | SSA def(b) | Capture.cs:125:13:125:17 | ... = ... | | Capture.cs:130:13:130:18 | SSA def(c) | Capture.cs:130:13:130:18 | Int32 c = ... | | Capture.cs:133:13:133:17 | SSA def(c) | Capture.cs:133:13:133:17 | ... = ... | @@ -62,6 +64,7 @@ | Capture.cs:144:9:144:12 | SSA call def(d) | Capture.cs:144:9:144:12 | call to local function M4 | | Capture.cs:148:9:152:9 | SSA capture def(e) | Capture.cs:148:9:152:9 | M5 | | Capture.cs:154:13:154:18 | SSA def(f) | Capture.cs:154:13:154:18 | Int32 f = ... | +| Capture.cs:158:13:158:17 | SSA def(f) | Capture.cs:158:13:158:17 | ... = ... | | Capture.cs:163:9:166:9 | SSA capture def(g) | Capture.cs:163:9:166:9 | M7 | | Capture.cs:171:13:171:17 | SSA def(h) | Capture.cs:171:13:171:17 | ... = ... | | Capture.cs:174:17:174:21 | SSA def(h) | Capture.cs:174:17:174:21 | ... = ... | @@ -183,10 +186,8 @@ | Fields.cs:49:17:49:28 | SSA call def(Fields.stat) | Fields.cs:49:17:49:28 | object creation of type Fields | | Fields.cs:51:9:51:20 | SSA call def(Fields.stat) | Fields.cs:51:9:51:20 | object creation of type Fields | | Fields.cs:61:17:61:17 | SSA entry def(this.LoopField) | Fields.cs:61:17:61:17 | H | -| Fields.cs:63:16:63:28 | SSA untracked def(this.VolatileField) | Fields.cs:63:16:63:28 | this access | -| Fields.cs:69:21:69:33 | SSA untracked def(this.VolatileField) | Fields.cs:69:21:69:33 | this access | -| Fields.cs:71:17:71:35 | SSA untracked def(this.SingleAccessedField) | Fields.cs:71:17:71:35 | this access | -| Fields.cs:76:20:76:38 | SSA untracked def(this.SingleAccessedField) | Fields.cs:76:20:76:38 | this access | +| Fields.cs:61:17:61:17 | SSA entry def(this.SingleAccessedField) | Fields.cs:61:17:61:17 | H | +| Fields.cs:74:17:74:17 | SSA entry def(this.SingleAccessedField) | Fields.cs:74:17:74:17 | I | | Fields.cs:77:13:77:45 | SSA def(f) | Fields.cs:77:13:77:45 | Fields f = ... | | Fields.cs:78:23:78:54 | SSA def(a) | Fields.cs:78:23:78:54 | Action a = ... | | Fields.cs:78:27:78:54 | SSA capture def(f) | Fields.cs:78:27:78:54 | (...) => ... | @@ -208,8 +209,6 @@ | Fields.cs:102:9:102:28 | SSA def(this.Field) | Fields.cs:102:9:102:28 | ... = ... | | Fields.cs:107:33:107:33 | SSA param(f) | Fields.cs:107:33:107:33 | f | | Fields.cs:109:10:109:10 | SSA entry def(this.Field) | Fields.cs:109:10:109:10 | K | -| Fields.cs:109:10:109:10 | SSA entry def(this.Field.Field) | Fields.cs:109:10:109:10 | K | -| Fields.cs:109:10:109:10 | SSA entry def(this.Field.Field.xs) | Fields.cs:109:10:109:10 | K | | Fields.cs:114:9:114:22 | SSA call def(this.Field) | Fields.cs:114:9:114:22 | call to method SetField | | Fields.cs:114:9:114:22 | SSA call def(this.Field.Field) | Fields.cs:114:9:114:22 | call to method SetField | | Fields.cs:114:9:114:22 | SSA qualifier def(this.Field.Field.xs) | Fields.cs:114:9:114:22 | call to method SetField | @@ -264,10 +263,10 @@ | Properties.cs:49:17:49:32 | SSA call def(Properties.stat) | Properties.cs:49:17:49:32 | object creation of type Properties | | Properties.cs:51:9:51:24 | SSA call def(Properties.stat) | Properties.cs:51:9:51:24 | object creation of type Properties | | Properties.cs:61:17:61:17 | SSA entry def(this.LoopProp) | Properties.cs:61:17:61:17 | H | +| Properties.cs:61:17:61:17 | SSA entry def(this.SingleAccessedProp) | Properties.cs:61:17:61:17 | H | | Properties.cs:61:23:61:23 | SSA param(i) | Properties.cs:61:23:61:23 | i | | Properties.cs:63:16:63:18 | SSA def(i) | Properties.cs:63:16:63:18 | ...-- | -| Properties.cs:67:21:67:38 | SSA untracked def(this.SingleAccessedProp) | Properties.cs:67:21:67:38 | this access | -| Properties.cs:72:20:72:37 | SSA untracked def(this.SingleAccessedProp) | Properties.cs:72:20:72:37 | this access | +| Properties.cs:70:17:70:17 | SSA entry def(this.SingleAccessedProp) | Properties.cs:70:17:70:17 | I | | Properties.cs:73:13:73:32 | SSA def(f) | Properties.cs:73:13:73:32 | Properties f = ... | | Properties.cs:74:23:74:54 | SSA def(a) | Properties.cs:74:23:74:54 | Action a = ... | | Properties.cs:74:27:74:54 | SSA capture def(f) | Properties.cs:74:27:74:54 | (...) => ... | @@ -281,15 +280,8 @@ | Properties.cs:83:9:83:22 | SSA def(this.xs) | Properties.cs:83:9:83:22 | ... = ... | | Properties.cs:84:9:84:25 | SSA def(f.xs) | Properties.cs:84:9:84:25 | ... = ... | | Properties.cs:85:24:85:46 | SSA capture def(b) | Properties.cs:85:24:85:46 | (...) => ... | -| Properties.cs:95:20:95:38 | SSA untracked def(this.NonTrivialProp) | Properties.cs:95:20:95:23 | this access | -| Properties.cs:98:16:98:31 | SSA untracked def(this.VirtualProp) | Properties.cs:98:16:98:19 | this access | -| Properties.cs:100:9:100:26 | SSA untracked def(this.VolatileField) | Properties.cs:100:9:100:12 | this access | -| Properties.cs:101:21:101:38 | SSA untracked def(this.VolatileField) | Properties.cs:101:21:101:24 | this access | -| Properties.cs:101:21:101:41 | SSA untracked def(this.VolatileField.xs) | Properties.cs:101:21:101:38 | access to field VolatileField | | Properties.cs:106:37:106:37 | SSA param(p) | Properties.cs:106:37:106:37 | p | | Properties.cs:108:10:108:10 | SSA entry def(this.Props) | Properties.cs:108:10:108:10 | K | -| Properties.cs:108:10:108:10 | SSA entry def(this.Props.Props) | Properties.cs:108:10:108:10 | K | -| Properties.cs:108:10:108:10 | SSA entry def(this.Props.Props.xs) | Properties.cs:108:10:108:10 | K | | Properties.cs:113:9:113:22 | SSA call def(this.Props) | Properties.cs:113:9:113:22 | call to method SetProps | | Properties.cs:113:9:113:22 | SSA call def(this.Props.Props) | Properties.cs:113:9:113:22 | call to method SetProps | | Properties.cs:113:9:113:22 | SSA qualifier def(this.Props.Props.xs) | Properties.cs:113:9:113:22 | call to method SetProps | diff --git a/csharp/ql/test/library-tests/dataflow/ssa/SsaDefLastRead.expected b/csharp/ql/test/library-tests/dataflow/ssa/SsaDefLastRead.expected index d9534f06ff1..35ad76fe651 100644 --- a/csharp/ql/test/library-tests/dataflow/ssa/SsaDefLastRead.expected +++ b/csharp/ql/test/library-tests/dataflow/ssa/SsaDefLastRead.expected @@ -151,6 +151,8 @@ | Fields.cs:33:19:33:22 | Fields.stat | Fields.cs:38:9:38:13 | SSA call def(Fields.stat) | Fields.cs:41:13:41:16 | access to field stat | | Fields.cs:33:19:33:22 | Fields.stat | Fields.cs:51:9:51:20 | SSA call def(Fields.stat) | Fields.cs:54:13:54:16 | access to field stat | | Fields.cs:65:24:65:32 | this.LoopField | Fields.cs:61:17:61:17 | SSA entry def(this.LoopField) | Fields.cs:65:24:65:32 | access to field LoopField | +| Fields.cs:71:17:71:35 | this.SingleAccessedField | Fields.cs:61:17:61:17 | SSA entry def(this.SingleAccessedField) | Fields.cs:71:17:71:35 | access to field SingleAccessedField | +| Fields.cs:76:20:76:38 | this.SingleAccessedField | Fields.cs:74:17:74:17 | SSA entry def(this.SingleAccessedField) | Fields.cs:76:20:76:38 | access to field SingleAccessedField | | Fields.cs:77:13:77:13 | f | Fields.cs:77:13:77:45 | SSA def(f) | Fields.cs:90:19:90:19 | access to local variable f | | Fields.cs:77:13:77:13 | f | Fields.cs:78:27:78:54 | SSA capture def(f) | Fields.cs:78:35:78:35 | access to local variable f | | Fields.cs:78:23:78:23 | a | Fields.cs:78:23:78:54 | SSA def(a) | Fields.cs:81:9:81:9 | access to local variable a | @@ -219,6 +221,8 @@ | Properties.cs:33:19:33:22 | Properties.stat | Properties.cs:51:9:51:24 | SSA call def(Properties.stat) | Properties.cs:54:13:54:16 | access to property stat | | Properties.cs:61:23:61:23 | i | Properties.cs:63:16:63:16 | SSA phi(i) | Properties.cs:63:16:63:16 | access to parameter i | | Properties.cs:65:24:65:31 | this.LoopProp | Properties.cs:61:17:61:17 | SSA entry def(this.LoopProp) | Properties.cs:65:24:65:31 | access to property LoopProp | +| Properties.cs:67:21:67:38 | this.SingleAccessedProp | Properties.cs:61:17:61:17 | SSA entry def(this.SingleAccessedProp) | Properties.cs:67:21:67:38 | access to property SingleAccessedProp | +| Properties.cs:72:20:72:37 | this.SingleAccessedProp | Properties.cs:70:17:70:17 | SSA entry def(this.SingleAccessedProp) | Properties.cs:72:20:72:37 | access to property SingleAccessedProp | | Properties.cs:73:13:73:13 | f | Properties.cs:73:13:73:32 | SSA def(f) | Properties.cs:86:19:86:19 | access to local variable f | | Properties.cs:73:13:73:13 | f | Properties.cs:74:27:74:54 | SSA capture def(f) | Properties.cs:74:35:74:35 | access to local variable f | | Properties.cs:74:23:74:23 | a | Properties.cs:74:23:74:54 | SSA def(a) | Properties.cs:77:9:77:9 | access to local variable a | diff --git a/csharp/ql/test/library-tests/dataflow/ssa/SsaExplicitDef.expected b/csharp/ql/test/library-tests/dataflow/ssa/SsaExplicitDef.expected index 6f5c8a4238b..45f023ec4ef 100644 --- a/csharp/ql/test/library-tests/dataflow/ssa/SsaExplicitDef.expected +++ b/csharp/ql/test/library-tests/dataflow/ssa/SsaExplicitDef.expected @@ -33,15 +33,18 @@ | Capture.cs:92:18:92:18 | d | Capture.cs:92:18:92:18 | SSA param(d) | Capture.cs:92:18:92:18 | d | | Capture.cs:94:13:94:13 | y | Capture.cs:94:13:94:18 | SSA def(y) | Capture.cs:94:13:94:18 | Int32 y = ... | | Capture.cs:98:17:98:17 | x | Capture.cs:98:17:98:21 | SSA def(x) | Capture.cs:98:17:98:21 | Int32 x = ... | +| Capture.cs:102:13:102:13 | z | Capture.cs:102:13:102:18 | SSA def(z) | Capture.cs:102:13:102:18 | Int32 z = ... | | Capture.cs:102:13:102:13 | z | Capture.cs:105:13:105:17 | SSA def(z) | Capture.cs:105:13:105:17 | ... = ... | | Capture.cs:114:13:114:13 | a | Capture.cs:114:13:114:18 | SSA def(a) | Capture.cs:114:13:114:18 | Int32 a = ... | | Capture.cs:117:17:117:17 | x | Capture.cs:117:17:117:21 | SSA def(x) | Capture.cs:117:17:117:21 | Int32 x = ... | +| Capture.cs:122:13:122:13 | b | Capture.cs:122:13:122:18 | SSA def(b) | Capture.cs:122:13:122:18 | Int32 b = ... | | Capture.cs:122:13:122:13 | b | Capture.cs:125:13:125:17 | SSA def(b) | Capture.cs:125:13:125:17 | ... = ... | | Capture.cs:130:13:130:13 | c | Capture.cs:130:13:130:18 | SSA def(c) | Capture.cs:130:13:130:18 | Int32 c = ... | | Capture.cs:130:13:130:13 | c | Capture.cs:133:13:133:17 | SSA def(c) | Capture.cs:133:13:133:17 | ... = ... | | Capture.cs:139:13:139:13 | d | Capture.cs:139:13:139:18 | SSA def(d) | Capture.cs:139:13:139:18 | Int32 d = ... | | Capture.cs:139:13:139:13 | d | Capture.cs:142:13:142:17 | SSA def(d) | Capture.cs:142:13:142:17 | ... = ... | | Capture.cs:154:13:154:13 | f | Capture.cs:154:13:154:18 | SSA def(f) | Capture.cs:154:13:154:18 | Int32 f = ... | +| Capture.cs:154:13:154:13 | f | Capture.cs:158:13:158:17 | SSA def(f) | Capture.cs:158:13:158:17 | ... = ... | | Capture.cs:168:13:168:13 | h | Capture.cs:171:13:171:17 | SSA def(h) | Capture.cs:171:13:171:17 | ... = ... | | Capture.cs:168:13:168:13 | h | Capture.cs:174:17:174:21 | SSA def(h) | Capture.cs:174:17:174:21 | ... = ... | | Capture.cs:182:17:182:17 | i | Capture.cs:182:17:182:21 | SSA def(i) | Capture.cs:182:17:182:21 | Int32 i = ... | diff --git a/csharp/ql/test/library-tests/dataflow/ssa/SsaImplicitQualifier.expected b/csharp/ql/test/library-tests/dataflow/ssa/SsaImplicitQualifier.expected index 2b3febca122..c64c419cb48 100644 --- a/csharp/ql/test/library-tests/dataflow/ssa/SsaImplicitQualifier.expected +++ b/csharp/ql/test/library-tests/dataflow/ssa/SsaImplicitQualifier.expected @@ -4,8 +4,12 @@ | Fields.cs:98:20:98:32 | f.Field.Field | Fields.cs:97:9:97:30 | SSA qualifier def(f.Field.Field) | Fields.cs:97:9:97:30 | SSA def(f.Field) | | Fields.cs:99:16:99:34 | f.Field.Field.Field | Fields.cs:97:9:97:30 | SSA qualifier def(f.Field.Field.Field) | Fields.cs:97:9:97:30 | SSA qualifier def(f.Field.Field) | | Fields.cs:100:16:100:40 | f.Field.Field.Field.Field | Fields.cs:97:9:97:30 | SSA qualifier def(f.Field.Field.Field.Field) | Fields.cs:97:9:97:30 | SSA qualifier def(f.Field.Field.Field) | +| Fields.cs:115:20:115:35 | this.Field.Field | Fields.cs:109:10:109:10 | SSA qualifier def(this.Field.Field) | Fields.cs:109:10:109:10 | SSA entry def(this.Field) | +| Fields.cs:116:21:116:39 | this.Field.Field.xs | Fields.cs:109:10:109:10 | SSA qualifier def(this.Field.Field.xs) | Fields.cs:109:10:109:10 | SSA qualifier def(this.Field.Field) | | Fields.cs:116:21:116:39 | this.Field.Field.xs | Fields.cs:114:9:114:22 | SSA qualifier def(this.Field.Field.xs) | Fields.cs:114:9:114:22 | SSA call def(this.Field.Field) | | OutRef.cs:19:32:19:38 | t.Field | OutRef.cs:18:13:18:28 | SSA qualifier def(t.Field) | OutRef.cs:18:13:18:28 | SSA def(t) | | Properties.cs:31:19:31:22 | f.xs | Properties.cs:30:13:30:32 | SSA qualifier def(f.xs) | Properties.cs:30:13:30:32 | SSA def(f) | | Properties.cs:31:19:31:22 | f.xs | Properties.cs:49:13:49:32 | SSA qualifier def(f.xs) | Properties.cs:49:13:49:32 | SSA def(f) | +| Properties.cs:114:20:114:35 | this.Props.Props | Properties.cs:108:10:108:10 | SSA qualifier def(this.Props.Props) | Properties.cs:108:10:108:10 | SSA entry def(this.Props) | +| Properties.cs:115:21:115:39 | this.Props.Props.xs | Properties.cs:108:10:108:10 | SSA qualifier def(this.Props.Props.xs) | Properties.cs:108:10:108:10 | SSA qualifier def(this.Props.Props) | | Properties.cs:115:21:115:39 | this.Props.Props.xs | Properties.cs:113:9:113:22 | SSA qualifier def(this.Props.Props.xs) | Properties.cs:113:9:113:22 | SSA call def(this.Props.Props) | diff --git a/csharp/ql/test/library-tests/dataflow/ssa/SsaRead.expected b/csharp/ql/test/library-tests/dataflow/ssa/SsaRead.expected index 13aad35a44a..d6a958b32d7 100644 --- a/csharp/ql/test/library-tests/dataflow/ssa/SsaRead.expected +++ b/csharp/ql/test/library-tests/dataflow/ssa/SsaRead.expected @@ -185,11 +185,9 @@ | Fields.cs:33:19:33:22 | Fields.stat | Fields.cs:34:9:34:16 | SSA call def(Fields.stat) | Fields.cs:37:13:37:16 | access to field stat | | Fields.cs:33:19:33:22 | Fields.stat | Fields.cs:38:9:38:13 | SSA call def(Fields.stat) | Fields.cs:41:13:41:16 | access to field stat | | Fields.cs:33:19:33:22 | Fields.stat | Fields.cs:51:9:51:20 | SSA call def(Fields.stat) | Fields.cs:54:13:54:16 | access to field stat | -| Fields.cs:63:16:63:28 | this.VolatileField | Fields.cs:63:16:63:28 | SSA untracked def(this.VolatileField) | Fields.cs:63:16:63:28 | access to field VolatileField | -| Fields.cs:63:16:63:28 | this.VolatileField | Fields.cs:69:21:69:33 | SSA untracked def(this.VolatileField) | Fields.cs:69:21:69:33 | access to field VolatileField | | Fields.cs:65:24:65:32 | this.LoopField | Fields.cs:61:17:61:17 | SSA entry def(this.LoopField) | Fields.cs:65:24:65:32 | access to field LoopField | -| Fields.cs:71:17:71:35 | this.SingleAccessedField | Fields.cs:71:17:71:35 | SSA untracked def(this.SingleAccessedField) | Fields.cs:71:17:71:35 | access to field SingleAccessedField | -| Fields.cs:76:20:76:38 | this.SingleAccessedField | Fields.cs:76:20:76:38 | SSA untracked def(this.SingleAccessedField) | Fields.cs:76:20:76:38 | access to field SingleAccessedField | +| Fields.cs:71:17:71:35 | this.SingleAccessedField | Fields.cs:61:17:61:17 | SSA entry def(this.SingleAccessedField) | Fields.cs:71:17:71:35 | access to field SingleAccessedField | +| Fields.cs:76:20:76:38 | this.SingleAccessedField | Fields.cs:74:17:74:17 | SSA entry def(this.SingleAccessedField) | Fields.cs:76:20:76:38 | access to field SingleAccessedField | | Fields.cs:77:13:77:13 | f | Fields.cs:77:13:77:45 | SSA def(f) | Fields.cs:80:9:80:9 | access to local variable f | | Fields.cs:77:13:77:13 | f | Fields.cs:77:13:77:45 | SSA def(f) | Fields.cs:82:19:82:19 | access to local variable f | | Fields.cs:77:13:77:13 | f | Fields.cs:77:13:77:45 | SSA def(f) | Fields.cs:83:9:83:9 | access to local variable f | @@ -302,8 +300,8 @@ | Properties.cs:33:19:33:22 | Properties.stat | Properties.cs:51:9:51:24 | SSA call def(Properties.stat) | Properties.cs:54:13:54:16 | access to property stat | | Properties.cs:61:23:61:23 | i | Properties.cs:63:16:63:16 | SSA phi(i) | Properties.cs:63:16:63:16 | access to parameter i | | Properties.cs:65:24:65:31 | this.LoopProp | Properties.cs:61:17:61:17 | SSA entry def(this.LoopProp) | Properties.cs:65:24:65:31 | access to property LoopProp | -| Properties.cs:67:21:67:38 | this.SingleAccessedProp | Properties.cs:67:21:67:38 | SSA untracked def(this.SingleAccessedProp) | Properties.cs:67:21:67:38 | access to property SingleAccessedProp | -| Properties.cs:72:20:72:37 | this.SingleAccessedProp | Properties.cs:72:20:72:37 | SSA untracked def(this.SingleAccessedProp) | Properties.cs:72:20:72:37 | access to property SingleAccessedProp | +| Properties.cs:67:21:67:38 | this.SingleAccessedProp | Properties.cs:61:17:61:17 | SSA entry def(this.SingleAccessedProp) | Properties.cs:67:21:67:38 | access to property SingleAccessedProp | +| Properties.cs:72:20:72:37 | this.SingleAccessedProp | Properties.cs:70:17:70:17 | SSA entry def(this.SingleAccessedProp) | Properties.cs:72:20:72:37 | access to property SingleAccessedProp | | Properties.cs:73:13:73:13 | f | Properties.cs:73:13:73:32 | SSA def(f) | Properties.cs:76:9:76:9 | access to local variable f | | Properties.cs:73:13:73:13 | f | Properties.cs:73:13:73:32 | SSA def(f) | Properties.cs:78:19:78:19 | access to local variable f | | Properties.cs:73:13:73:13 | f | Properties.cs:73:13:73:32 | SSA def(f) | Properties.cs:79:9:79:9 | access to local variable f | @@ -322,11 +320,6 @@ | Properties.cs:76:9:76:12 | f.xs | Properties.cs:84:9:84:25 | SSA def(f.xs) | Properties.cs:86:19:86:22 | access to property xs | | Properties.cs:78:9:78:15 | this.xs | Properties.cs:81:9:81:22 | SSA def(this.xs) | Properties.cs:82:9:82:15 | access to property xs | | Properties.cs:78:9:78:15 | this.xs | Properties.cs:83:9:83:22 | SSA def(this.xs) | Properties.cs:85:9:85:15 | access to property xs | -| Properties.cs:94:9:94:27 | this.NonTrivialProp | Properties.cs:95:20:95:38 | SSA untracked def(this.NonTrivialProp) | Properties.cs:95:20:95:38 | access to property NonTrivialProp | -| Properties.cs:97:9:97:24 | this.VirtualProp | Properties.cs:98:16:98:31 | SSA untracked def(this.VirtualProp) | Properties.cs:98:16:98:31 | access to property VirtualProp | -| Properties.cs:100:9:100:26 | this.VolatileField | Properties.cs:100:9:100:26 | SSA untracked def(this.VolatileField) | Properties.cs:100:9:100:26 | access to field VolatileField | -| Properties.cs:100:9:100:26 | this.VolatileField | Properties.cs:101:21:101:38 | SSA untracked def(this.VolatileField) | Properties.cs:101:21:101:38 | access to field VolatileField | -| Properties.cs:100:9:100:29 | this.VolatileField.xs | Properties.cs:101:21:101:41 | SSA untracked def(this.VolatileField.xs) | Properties.cs:101:21:101:41 | access to property xs | | Properties.cs:106:37:106:37 | p | Properties.cs:106:37:106:37 | SSA param(p) | Properties.cs:106:42:106:42 | access to parameter p | | Properties.cs:114:20:114:29 | this.Props | Properties.cs:113:9:113:22 | SSA call def(this.Props) | Properties.cs:114:20:114:29 | access to field Props | | Properties.cs:114:20:114:29 | this.Props | Properties.cs:113:9:113:22 | SSA call def(this.Props) | Properties.cs:115:21:115:30 | access to field Props | diff --git a/csharp/ql/test/library-tests/dataflow/ssa/SsaUltimateDef.expected b/csharp/ql/test/library-tests/dataflow/ssa/SsaUltimateDef.expected index f84d9f953a3..f3bb6f1461d 100644 --- a/csharp/ql/test/library-tests/dataflow/ssa/SsaUltimateDef.expected +++ b/csharp/ql/test/library-tests/dataflow/ssa/SsaUltimateDef.expected @@ -56,10 +56,12 @@ | Capture.cs:94:13:94:13 | y | Capture.cs:94:13:94:18 | SSA def(y) | Capture.cs:94:13:94:18 | SSA def(y) | | Capture.cs:94:13:94:13 | y | Capture.cs:96:12:100:9 | SSA capture def(y) | Capture.cs:96:12:100:9 | SSA capture def(y) | | Capture.cs:98:17:98:17 | x | Capture.cs:98:17:98:21 | SSA def(x) | Capture.cs:98:17:98:21 | SSA def(x) | +| Capture.cs:102:13:102:13 | z | Capture.cs:102:13:102:18 | SSA def(z) | Capture.cs:102:13:102:18 | SSA def(z) | | Capture.cs:102:13:102:13 | z | Capture.cs:105:13:105:17 | SSA def(z) | Capture.cs:105:13:105:17 | SSA def(z) | | Capture.cs:114:13:114:13 | a | Capture.cs:114:13:114:18 | SSA def(a) | Capture.cs:114:13:114:18 | SSA def(a) | | Capture.cs:114:13:114:13 | a | Capture.cs:115:9:119:9 | SSA capture def(a) | Capture.cs:115:9:119:9 | SSA capture def(a) | | Capture.cs:117:17:117:17 | x | Capture.cs:117:17:117:21 | SSA def(x) | Capture.cs:117:17:117:21 | SSA def(x) | +| Capture.cs:122:13:122:13 | b | Capture.cs:122:13:122:18 | SSA def(b) | Capture.cs:122:13:122:18 | SSA def(b) | | Capture.cs:122:13:122:13 | b | Capture.cs:125:13:125:17 | SSA def(b) | Capture.cs:125:13:125:17 | SSA def(b) | | Capture.cs:130:13:130:13 | c | Capture.cs:130:13:130:18 | SSA def(c) | Capture.cs:130:13:130:18 | SSA def(c) | | Capture.cs:130:13:130:13 | c | Capture.cs:133:13:133:17 | SSA def(c) | Capture.cs:133:13:133:17 | SSA def(c) | @@ -71,6 +73,7 @@ | Capture.cs:139:13:139:13 | d | Capture.cs:144:9:144:12 | SSA call def(d) | Capture.cs:144:9:144:12 | SSA call def(d) | | Capture.cs:147:13:147:13 | e | Capture.cs:148:9:152:9 | SSA capture def(e) | Capture.cs:148:9:152:9 | SSA capture def(e) | | Capture.cs:154:13:154:13 | f | Capture.cs:154:13:154:18 | SSA def(f) | Capture.cs:154:13:154:18 | SSA def(f) | +| Capture.cs:154:13:154:13 | f | Capture.cs:158:13:158:17 | SSA def(f) | Capture.cs:158:13:158:17 | SSA def(f) | | Capture.cs:162:13:162:13 | g | Capture.cs:163:9:166:9 | SSA capture def(g) | Capture.cs:163:9:166:9 | SSA capture def(g) | | Capture.cs:168:13:168:13 | h | Capture.cs:171:13:171:17 | SSA def(h) | Capture.cs:171:13:171:17 | SSA def(h) | | Capture.cs:168:13:168:13 | h | Capture.cs:174:17:174:21 | SSA def(h) | Capture.cs:174:17:174:21 | SSA def(h) | @@ -247,11 +250,9 @@ | Fields.cs:33:19:33:22 | Fields.stat | Fields.cs:51:9:51:20 | SSA call def(Fields.stat) | Fields.cs:38:9:38:13 | SSA call def(Fields.stat) | | Fields.cs:33:19:33:22 | Fields.stat | Fields.cs:51:9:51:20 | SSA call def(Fields.stat) | Fields.cs:49:17:49:28 | SSA call def(Fields.stat) | | Fields.cs:33:19:33:22 | Fields.stat | Fields.cs:51:9:51:20 | SSA call def(Fields.stat) | Fields.cs:51:9:51:20 | SSA call def(Fields.stat) | -| Fields.cs:63:16:63:28 | this.VolatileField | Fields.cs:63:16:63:28 | SSA untracked def(this.VolatileField) | Fields.cs:63:16:63:28 | SSA untracked def(this.VolatileField) | -| Fields.cs:63:16:63:28 | this.VolatileField | Fields.cs:69:21:69:33 | SSA untracked def(this.VolatileField) | Fields.cs:69:21:69:33 | SSA untracked def(this.VolatileField) | | Fields.cs:65:24:65:32 | this.LoopField | Fields.cs:61:17:61:17 | SSA entry def(this.LoopField) | Fields.cs:61:17:61:17 | SSA entry def(this.LoopField) | -| Fields.cs:71:17:71:35 | this.SingleAccessedField | Fields.cs:71:17:71:35 | SSA untracked def(this.SingleAccessedField) | Fields.cs:71:17:71:35 | SSA untracked def(this.SingleAccessedField) | -| Fields.cs:76:20:76:38 | this.SingleAccessedField | Fields.cs:76:20:76:38 | SSA untracked def(this.SingleAccessedField) | Fields.cs:76:20:76:38 | SSA untracked def(this.SingleAccessedField) | +| Fields.cs:71:17:71:35 | this.SingleAccessedField | Fields.cs:61:17:61:17 | SSA entry def(this.SingleAccessedField) | Fields.cs:61:17:61:17 | SSA entry def(this.SingleAccessedField) | +| Fields.cs:76:20:76:38 | this.SingleAccessedField | Fields.cs:74:17:74:17 | SSA entry def(this.SingleAccessedField) | Fields.cs:74:17:74:17 | SSA entry def(this.SingleAccessedField) | | Fields.cs:77:13:77:13 | f | Fields.cs:77:13:77:45 | SSA def(f) | Fields.cs:77:13:77:45 | SSA def(f) | | Fields.cs:77:13:77:13 | f | Fields.cs:78:27:78:54 | SSA capture def(f) | Fields.cs:78:27:78:54 | SSA capture def(f) | | Fields.cs:78:23:78:23 | a | Fields.cs:78:23:78:54 | SSA def(a) | Fields.cs:78:23:78:54 | SSA def(a) | @@ -277,11 +278,11 @@ | Fields.cs:115:20:115:29 | this.Field | Fields.cs:109:10:109:10 | SSA entry def(this.Field) | Fields.cs:109:10:109:10 | SSA entry def(this.Field) | | Fields.cs:115:20:115:29 | this.Field | Fields.cs:114:9:114:22 | SSA call def(this.Field) | Fields.cs:109:10:109:10 | SSA entry def(this.Field) | | Fields.cs:115:20:115:29 | this.Field | Fields.cs:114:9:114:22 | SSA call def(this.Field) | Fields.cs:114:9:114:22 | SSA call def(this.Field) | -| Fields.cs:115:20:115:35 | this.Field.Field | Fields.cs:109:10:109:10 | SSA entry def(this.Field.Field) | Fields.cs:109:10:109:10 | SSA entry def(this.Field.Field) | -| Fields.cs:115:20:115:35 | this.Field.Field | Fields.cs:114:9:114:22 | SSA call def(this.Field.Field) | Fields.cs:109:10:109:10 | SSA entry def(this.Field.Field) | +| Fields.cs:115:20:115:35 | this.Field.Field | Fields.cs:109:10:109:10 | SSA qualifier def(this.Field.Field) | Fields.cs:109:10:109:10 | SSA qualifier def(this.Field.Field) | +| Fields.cs:115:20:115:35 | this.Field.Field | Fields.cs:114:9:114:22 | SSA call def(this.Field.Field) | Fields.cs:109:10:109:10 | SSA qualifier def(this.Field.Field) | | Fields.cs:115:20:115:35 | this.Field.Field | Fields.cs:114:9:114:22 | SSA call def(this.Field.Field) | Fields.cs:114:9:114:22 | SSA call def(this.Field.Field) | -| Fields.cs:116:21:116:39 | this.Field.Field.xs | Fields.cs:109:10:109:10 | SSA entry def(this.Field.Field.xs) | Fields.cs:109:10:109:10 | SSA entry def(this.Field.Field.xs) | -| Fields.cs:116:21:116:39 | this.Field.Field.xs | Fields.cs:114:9:114:22 | SSA qualifier def(this.Field.Field.xs) | Fields.cs:109:10:109:10 | SSA entry def(this.Field.Field.xs) | +| Fields.cs:116:21:116:39 | this.Field.Field.xs | Fields.cs:109:10:109:10 | SSA qualifier def(this.Field.Field.xs) | Fields.cs:109:10:109:10 | SSA qualifier def(this.Field.Field.xs) | +| Fields.cs:116:21:116:39 | this.Field.Field.xs | Fields.cs:114:9:114:22 | SSA qualifier def(this.Field.Field.xs) | Fields.cs:109:10:109:10 | SSA qualifier def(this.Field.Field.xs) | | Fields.cs:116:21:116:39 | this.Field.Field.xs | Fields.cs:114:9:114:22 | SSA qualifier def(this.Field.Field.xs) | Fields.cs:114:9:114:22 | SSA qualifier def(this.Field.Field.xs) | | OutRef.cs:9:13:9:13 | j | OutRef.cs:9:13:9:17 | SSA def(j) | OutRef.cs:9:13:9:17 | SSA def(j) | | OutRef.cs:9:13:9:13 | j | OutRef.cs:10:32:10:32 | SSA def(j) | OutRef.cs:10:32:10:32 | SSA def(j) | @@ -377,8 +378,8 @@ | Properties.cs:61:23:61:23 | i | Properties.cs:63:16:63:16 | SSA phi(i) | Properties.cs:63:16:63:18 | SSA def(i) | | Properties.cs:61:23:61:23 | i | Properties.cs:63:16:63:18 | SSA def(i) | Properties.cs:63:16:63:18 | SSA def(i) | | Properties.cs:65:24:65:31 | this.LoopProp | Properties.cs:61:17:61:17 | SSA entry def(this.LoopProp) | Properties.cs:61:17:61:17 | SSA entry def(this.LoopProp) | -| Properties.cs:67:21:67:38 | this.SingleAccessedProp | Properties.cs:67:21:67:38 | SSA untracked def(this.SingleAccessedProp) | Properties.cs:67:21:67:38 | SSA untracked def(this.SingleAccessedProp) | -| Properties.cs:72:20:72:37 | this.SingleAccessedProp | Properties.cs:72:20:72:37 | SSA untracked def(this.SingleAccessedProp) | Properties.cs:72:20:72:37 | SSA untracked def(this.SingleAccessedProp) | +| Properties.cs:67:21:67:38 | this.SingleAccessedProp | Properties.cs:61:17:61:17 | SSA entry def(this.SingleAccessedProp) | Properties.cs:61:17:61:17 | SSA entry def(this.SingleAccessedProp) | +| Properties.cs:72:20:72:37 | this.SingleAccessedProp | Properties.cs:70:17:70:17 | SSA entry def(this.SingleAccessedProp) | Properties.cs:70:17:70:17 | SSA entry def(this.SingleAccessedProp) | | Properties.cs:73:13:73:13 | f | Properties.cs:73:13:73:32 | SSA def(f) | Properties.cs:73:13:73:32 | SSA def(f) | | Properties.cs:73:13:73:13 | f | Properties.cs:74:27:74:54 | SSA capture def(f) | Properties.cs:74:27:74:54 | SSA capture def(f) | | Properties.cs:74:23:74:23 | a | Properties.cs:74:23:74:54 | SSA def(a) | Properties.cs:74:23:74:54 | SSA def(a) | @@ -394,20 +395,15 @@ | Properties.cs:76:9:76:12 | f.xs | Properties.cs:84:9:84:25 | SSA def(f.xs) | Properties.cs:84:9:84:25 | SSA def(f.xs) | | Properties.cs:78:9:78:15 | this.xs | Properties.cs:81:9:81:22 | SSA def(this.xs) | Properties.cs:81:9:81:22 | SSA def(this.xs) | | Properties.cs:78:9:78:15 | this.xs | Properties.cs:83:9:83:22 | SSA def(this.xs) | Properties.cs:83:9:83:22 | SSA def(this.xs) | -| Properties.cs:94:9:94:27 | this.NonTrivialProp | Properties.cs:95:20:95:38 | SSA untracked def(this.NonTrivialProp) | Properties.cs:95:20:95:38 | SSA untracked def(this.NonTrivialProp) | -| Properties.cs:97:9:97:24 | this.VirtualProp | Properties.cs:98:16:98:31 | SSA untracked def(this.VirtualProp) | Properties.cs:98:16:98:31 | SSA untracked def(this.VirtualProp) | -| Properties.cs:100:9:100:26 | this.VolatileField | Properties.cs:100:9:100:26 | SSA untracked def(this.VolatileField) | Properties.cs:100:9:100:26 | SSA untracked def(this.VolatileField) | -| Properties.cs:100:9:100:26 | this.VolatileField | Properties.cs:101:21:101:38 | SSA untracked def(this.VolatileField) | Properties.cs:101:21:101:38 | SSA untracked def(this.VolatileField) | -| Properties.cs:100:9:100:29 | this.VolatileField.xs | Properties.cs:101:21:101:41 | SSA untracked def(this.VolatileField.xs) | Properties.cs:101:21:101:41 | SSA untracked def(this.VolatileField.xs) | | Properties.cs:106:37:106:37 | p | Properties.cs:106:37:106:37 | SSA param(p) | Properties.cs:106:37:106:37 | SSA param(p) | | Properties.cs:114:20:114:29 | this.Props | Properties.cs:108:10:108:10 | SSA entry def(this.Props) | Properties.cs:108:10:108:10 | SSA entry def(this.Props) | | Properties.cs:114:20:114:29 | this.Props | Properties.cs:113:9:113:22 | SSA call def(this.Props) | Properties.cs:108:10:108:10 | SSA entry def(this.Props) | | Properties.cs:114:20:114:29 | this.Props | Properties.cs:113:9:113:22 | SSA call def(this.Props) | Properties.cs:113:9:113:22 | SSA call def(this.Props) | -| Properties.cs:114:20:114:35 | this.Props.Props | Properties.cs:108:10:108:10 | SSA entry def(this.Props.Props) | Properties.cs:108:10:108:10 | SSA entry def(this.Props.Props) | -| Properties.cs:114:20:114:35 | this.Props.Props | Properties.cs:113:9:113:22 | SSA call def(this.Props.Props) | Properties.cs:108:10:108:10 | SSA entry def(this.Props.Props) | +| Properties.cs:114:20:114:35 | this.Props.Props | Properties.cs:108:10:108:10 | SSA qualifier def(this.Props.Props) | Properties.cs:108:10:108:10 | SSA qualifier def(this.Props.Props) | +| Properties.cs:114:20:114:35 | this.Props.Props | Properties.cs:113:9:113:22 | SSA call def(this.Props.Props) | Properties.cs:108:10:108:10 | SSA qualifier def(this.Props.Props) | | Properties.cs:114:20:114:35 | this.Props.Props | Properties.cs:113:9:113:22 | SSA call def(this.Props.Props) | Properties.cs:113:9:113:22 | SSA call def(this.Props.Props) | -| Properties.cs:115:21:115:39 | this.Props.Props.xs | Properties.cs:108:10:108:10 | SSA entry def(this.Props.Props.xs) | Properties.cs:108:10:108:10 | SSA entry def(this.Props.Props.xs) | -| Properties.cs:115:21:115:39 | this.Props.Props.xs | Properties.cs:113:9:113:22 | SSA qualifier def(this.Props.Props.xs) | Properties.cs:108:10:108:10 | SSA entry def(this.Props.Props.xs) | +| Properties.cs:115:21:115:39 | this.Props.Props.xs | Properties.cs:108:10:108:10 | SSA qualifier def(this.Props.Props.xs) | Properties.cs:108:10:108:10 | SSA qualifier def(this.Props.Props.xs) | +| Properties.cs:115:21:115:39 | this.Props.Props.xs | Properties.cs:113:9:113:22 | SSA qualifier def(this.Props.Props.xs) | Properties.cs:108:10:108:10 | SSA qualifier def(this.Props.Props.xs) | | Properties.cs:115:21:115:39 | this.Props.Props.xs | Properties.cs:113:9:113:22 | SSA qualifier def(this.Props.Props.xs) | Properties.cs:113:9:113:22 | SSA qualifier def(this.Props.Props.xs) | | Splitting.cs:3:18:3:18 | b | Splitting.cs:3:18:3:18 | SSA param(b) | Splitting.cs:3:18:3:18 | SSA param(b) | | Splitting.cs:5:13:5:13 | x | Splitting.cs:7:13:7:19 | [b (line 3): true] SSA def(x) | Splitting.cs:7:13:7:19 | [b (line 3): true] SSA def(x) | diff --git a/csharp/ql/test/library-tests/exceptions/Exceptions1.expected b/csharp/ql/test/library-tests/exceptions/Exceptions1.expected index 9c88ed1e60a..f3e813a7395 100644 --- a/csharp/ql/test/library-tests/exceptions/Exceptions1.expected +++ b/csharp/ql/test/library-tests/exceptions/Exceptions1.expected @@ -12,7 +12,6 @@ | exceptions.cs:105:13:105:13 | ; | exceptions.cs:114:13:114:13 | ; | | exceptions.cs:134:13:134:13 | ; | exceptions.cs:143:13:143:13 | ; | | exceptions.cs:163:13:163:13 | ; | exceptions.cs:172:13:172:13 | ; | -| exceptions.cs:192:13:192:13 | ; | exceptions.cs:205:13:205:13 | ; | | exceptions.cs:222:13:222:13 | ; | exceptions.cs:235:13:235:13 | ; | | exceptions.cs:280:13:280:13 | ; | exceptions.cs:297:13:297:13 | ; | | exceptions.cs:309:13:309:13 | ; | exceptions.cs:314:13:314:13 | ; | diff --git a/csharp/ql/test/library-tests/expressions/DelegateCall1.ql b/csharp/ql/test/library-tests/expressions/DelegateCall1.ql index 430d2fdc43a..8d8f818a9e6 100644 --- a/csharp/ql/test/library-tests/expressions/DelegateCall1.ql +++ b/csharp/ql/test/library-tests/expressions/DelegateCall1.ql @@ -9,7 +9,7 @@ where m.hasName("MainDelegateAndMethodAccesses") and e.getEnclosingCallable() = m and e.getNumberOfArguments() = 1 and - e.getDelegateExpr() = a and + e.getExpr() = a and a.getTarget().hasName("cd1") and e.getArgument(0).getValue() = "-40" select m, e, a diff --git a/csharp/ql/test/library-tests/expressions/DelegateCall2.ql b/csharp/ql/test/library-tests/expressions/DelegateCall2.ql index 4fb915f3086..fee6f1c703a 100644 --- a/csharp/ql/test/library-tests/expressions/DelegateCall2.ql +++ b/csharp/ql/test/library-tests/expressions/DelegateCall2.ql @@ -9,7 +9,7 @@ where m.hasName("MainDelegateAndMethodAccesses") and e.getEnclosingCallable() = m and e.getNumberOfArguments() = 1 and - e.getDelegateExpr() = a and + e.getExpr() = a and a.getTarget().hasName("cd7") and e.getArgument(0).(AddExpr).getRightOperand().(LocalVariableAccess).getTarget().hasName("x") select m, e, a diff --git a/csharp/ql/test/library-tests/expressions/DelegateCall3.ql b/csharp/ql/test/library-tests/expressions/DelegateCall3.ql index 5702cad683a..b68b35dde45 100644 --- a/csharp/ql/test/library-tests/expressions/DelegateCall3.ql +++ b/csharp/ql/test/library-tests/expressions/DelegateCall3.ql @@ -8,7 +8,7 @@ from Method m, DelegateCall e, LocalVariableAccess a where m.hasName("MainDelegateAndMethodAccesses") and e.getEnclosingCallable() = m and - e.getDelegateExpr() = a and + e.getExpr() = a and a.getTarget().hasName("cd7") and a.getTarget().getType().(DelegateType).hasQualifiedName("Expressions.D") select m, e, a diff --git a/csharp/ql/test/library-tests/expressions/EventAccess3.ql b/csharp/ql/test/library-tests/expressions/EventAccess3.ql index 741f973b221..56d5cb1beb9 100644 --- a/csharp/ql/test/library-tests/expressions/EventAccess3.ql +++ b/csharp/ql/test/library-tests/expressions/EventAccess3.ql @@ -11,7 +11,7 @@ where e.getTarget().getName() = "Click" and e.getTarget().getDeclaringType() = m.getDeclaringType() and d.getEnclosingCallable() = m and - d.getDelegateExpr() = e and + d.getExpr() = e and d.getArgument(0) instanceof ThisAccess and d.getArgument(1).(ParameterAccess).getTarget().hasName("e") select m, d, e diff --git a/csharp/ql/test/library-tests/expressions/PrintAst.expected b/csharp/ql/test/library-tests/expressions/PrintAst.expected index 28c483285ad..5c23d3eb03f 100644 --- a/csharp/ql/test/library-tests/expressions/PrintAst.expected +++ b/csharp/ql/test/library-tests/expressions/PrintAst.expected @@ -599,7 +599,7 @@ expressions.cs: # 64| 0: [PropertyCall] access to property Length # 64| -1: [ParameterAccess] access to parameter s # 64| 1: [ParameterAccess] access to parameter x -# 67| 14: [IndexerProperty] Name +# 67| 14: [Property] Name # 67| -1: [TypeMention] string # 69| 3: [Getter] get_Name # 69| 4: [BlockStmt] {...} @@ -1504,7 +1504,7 @@ expressions.cs: # 375| 1: [ObjectCreation] object creation of type List<String> # 375| 0: [TypeMention] List<String> # 375| 1: [TypeMention] string -# 377| 7: [IndexerProperty] Name +# 377| 7: [Property] Name # 377| -1: [TypeMention] string # 377| 3: [Getter] get_Name # 377| 4: [BlockStmt] {...} @@ -1518,7 +1518,7 @@ expressions.cs: # 377| 0: [AssignExpr] ... = ... # 377| 0: [FieldAccess] access to field name # 377| 1: [ParameterAccess] access to parameter value -# 378| 8: [IndexerProperty] PhoneNumbers +# 378| 8: [Property] PhoneNumbers # 378| -1: [TypeMention] List<String> # 378| 1: [TypeMention] string # 378| 3: [Getter] get_PhoneNumbers diff --git a/csharp/ql/test/library-tests/frameworks/EntityFramework/Dataflow.expected b/csharp/ql/test/library-tests/frameworks/EntityFramework/Dataflow.expected index c940d709220..7d0bd289f9c 100644 --- a/csharp/ql/test/library-tests/frameworks/EntityFramework/Dataflow.expected +++ b/csharp/ql/test/library-tests/frameworks/EntityFramework/Dataflow.expected @@ -1,16 +1,34 @@ edges +| ../../../resources/stubs/EntityFramework.cs:40:20:40:30 | this [Addresses, [], Street] : String | EntityFramework.cs:214:18:214:30 | access to property Addresses [[], Street] : String | +| ../../../resources/stubs/EntityFramework.cs:40:20:40:30 | this [Addresses, [], Street] : String | EntityFramework.cs:221:18:221:28 | access to property Persons [[], Addresses, [], Street] : String | +| ../../../resources/stubs/EntityFramework.cs:40:20:40:30 | this [PersonAddresses, [], Address, Street] : String | EntityFramework.cs:214:18:214:30 | access to property Addresses [[], Street] : String | +| ../../../resources/stubs/EntityFramework.cs:40:20:40:30 | this [PersonAddresses, [], Address, Street] : String | EntityFramework.cs:221:18:221:28 | access to property Persons [[], Addresses, [], Street] : String | +| ../../../resources/stubs/EntityFramework.cs:40:20:40:30 | this [PersonAddresses, [], Person, Name] : String | EntityFramework.cs:206:18:206:28 | access to property Persons [[], Name] : String | +| ../../../resources/stubs/EntityFramework.cs:40:20:40:30 | this [Persons, [], Addresses, [], Street] : String | EntityFramework.cs:214:18:214:30 | access to property Addresses [[], Street] : String | +| ../../../resources/stubs/EntityFramework.cs:40:20:40:30 | this [Persons, [], Addresses, [], Street] : String | EntityFramework.cs:221:18:221:28 | access to property Persons [[], Addresses, [], Street] : String | +| ../../../resources/stubs/EntityFramework.cs:40:20:40:30 | this [Persons, [], Name] : String | EntityFramework.cs:206:18:206:28 | access to property Persons [[], Name] : String | +| ../../../resources/stubs/EntityFramework.cs:41:49:41:64 | this [Persons, [], Name] : String | EntityFramework.cs:206:18:206:28 | access to property Persons [[], Name] : String | +| ../../../resources/stubs/EntityFramework.cs:80:20:80:30 | this [Addresses, [], Street] : String | EntityFrameworkCore.cs:238:18:238:30 | access to property Addresses [[], Street] : String | +| ../../../resources/stubs/EntityFramework.cs:80:20:80:30 | this [Addresses, [], Street] : String | EntityFrameworkCore.cs:245:18:245:28 | access to property Persons [[], Addresses, [], Street] : String | +| ../../../resources/stubs/EntityFramework.cs:80:20:80:30 | this [PersonAddresses, [], Address, Street] : String | EntityFrameworkCore.cs:238:18:238:30 | access to property Addresses [[], Street] : String | +| ../../../resources/stubs/EntityFramework.cs:80:20:80:30 | this [PersonAddresses, [], Address, Street] : String | EntityFrameworkCore.cs:245:18:245:28 | access to property Persons [[], Addresses, [], Street] : String | +| ../../../resources/stubs/EntityFramework.cs:80:20:80:30 | this [PersonAddresses, [], Person, Name] : String | EntityFrameworkCore.cs:230:18:230:28 | access to property Persons [[], Name] : String | +| ../../../resources/stubs/EntityFramework.cs:80:20:80:30 | this [Persons, [], Addresses, [], Street] : String | EntityFrameworkCore.cs:238:18:238:30 | access to property Addresses [[], Street] : String | +| ../../../resources/stubs/EntityFramework.cs:80:20:80:30 | this [Persons, [], Addresses, [], Street] : String | EntityFrameworkCore.cs:245:18:245:28 | access to property Persons [[], Addresses, [], Street] : String | +| ../../../resources/stubs/EntityFramework.cs:80:20:80:30 | this [Persons, [], Name] : String | EntityFrameworkCore.cs:230:18:230:28 | access to property Persons [[], Name] : String | +| ../../../resources/stubs/EntityFramework.cs:81:49:81:64 | this [Persons, [], Name] : String | EntityFrameworkCore.cs:230:18:230:28 | access to property Persons [[], Name] : String | | EntityFramework.cs:61:13:64:13 | { ..., ... } [Name] : String | EntityFramework.cs:68:29:68:30 | access to local variable p1 [Name] : String | | EntityFramework.cs:63:24:63:32 | "tainted" : String | EntityFramework.cs:61:13:64:13 | { ..., ... } [Name] : String | | EntityFramework.cs:68:13:68:15 | [post] access to local variable ctx [Persons, [], Name] : String | EntityFramework.cs:70:13:70:15 | access to local variable ctx [Persons, [], Name] : String | | EntityFramework.cs:68:13:68:23 | [post] access to property Persons [[], Name] : String | EntityFramework.cs:68:13:68:15 | [post] access to local variable ctx [Persons, [], Name] : String | | EntityFramework.cs:68:29:68:30 | access to local variable p1 [Name] : String | EntityFramework.cs:68:13:68:23 | [post] access to property Persons [[], Name] : String | -| EntityFramework.cs:70:13:70:15 | access to local variable ctx [Persons, [], Name] : String | EntityFramework.cs:206:18:206:28 | access to property Persons [[], Name] : String | +| EntityFramework.cs:70:13:70:15 | access to local variable ctx [Persons, [], Name] : String | ../../../resources/stubs/EntityFramework.cs:40:20:40:30 | this [Persons, [], Name] : String | | EntityFramework.cs:83:13:86:13 | { ..., ... } [Name] : String | EntityFramework.cs:90:29:90:30 | access to local variable p1 [Name] : String | | EntityFramework.cs:85:24:85:32 | "tainted" : String | EntityFramework.cs:83:13:86:13 | { ..., ... } [Name] : String | | EntityFramework.cs:90:13:90:15 | [post] access to local variable ctx [Persons, [], Name] : String | EntityFramework.cs:92:19:92:21 | access to local variable ctx [Persons, [], Name] : String | | EntityFramework.cs:90:13:90:23 | [post] access to property Persons [[], Name] : String | EntityFramework.cs:90:13:90:15 | [post] access to local variable ctx [Persons, [], Name] : String | | EntityFramework.cs:90:29:90:30 | access to local variable p1 [Name] : String | EntityFramework.cs:90:13:90:23 | [post] access to property Persons [[], Name] : String | -| EntityFramework.cs:92:19:92:21 | access to local variable ctx [Persons, [], Name] : String | EntityFramework.cs:206:18:206:28 | access to property Persons [[], Name] : String | +| EntityFramework.cs:92:19:92:21 | access to local variable ctx [Persons, [], Name] : String | ../../../resources/stubs/EntityFramework.cs:41:49:41:64 | this [Persons, [], Name] : String | | EntityFramework.cs:105:13:108:13 | { ..., ... } [Name] : String | EntityFramework.cs:111:27:111:28 | access to local variable p1 [Name] : String | | EntityFramework.cs:107:24:107:32 | "tainted" : String | EntityFramework.cs:105:13:108:13 | { ..., ... } [Name] : String | | EntityFramework.cs:111:27:111:28 | access to local variable p1 [Name] : String | EntityFramework.cs:195:35:195:35 | p [Name] : String | @@ -29,24 +47,18 @@ edges | EntityFramework.cs:151:13:151:15 | [post] access to local variable ctx [Persons, [], Addresses, [], Street] : String | EntityFramework.cs:168:13:168:15 | access to local variable ctx [Persons, [], Addresses, [], Street] : String | | EntityFramework.cs:151:13:151:23 | [post] access to property Persons [[], Addresses, [], Street] : String | EntityFramework.cs:151:13:151:15 | [post] access to local variable ctx [Persons, [], Addresses, [], Street] : String | | EntityFramework.cs:151:29:151:30 | access to local variable p1 [Addresses, [], Street] : String | EntityFramework.cs:151:13:151:23 | [post] access to property Persons [[], Addresses, [], Street] : String | -| EntityFramework.cs:152:13:152:15 | access to local variable ctx [Persons, [], Addresses, [], Street] : String | EntityFramework.cs:214:18:214:30 | access to property Addresses [[], Street] : String | -| EntityFramework.cs:152:13:152:15 | access to local variable ctx [Persons, [], Addresses, [], Street] : String | EntityFramework.cs:221:18:221:28 | access to property Persons [[], Addresses, [], Street] : String | -| EntityFramework.cs:156:13:156:15 | access to local variable ctx [Persons, [], Addresses, [], Street] : String | EntityFramework.cs:214:18:214:30 | access to property Addresses [[], Street] : String | -| EntityFramework.cs:156:13:156:15 | access to local variable ctx [Persons, [], Addresses, [], Street] : String | EntityFramework.cs:221:18:221:28 | access to property Persons [[], Addresses, [], Street] : String | +| EntityFramework.cs:152:13:152:15 | access to local variable ctx [Persons, [], Addresses, [], Street] : String | ../../../resources/stubs/EntityFramework.cs:40:20:40:30 | this [Persons, [], Addresses, [], Street] : String | +| EntityFramework.cs:156:13:156:15 | access to local variable ctx [Persons, [], Addresses, [], Street] : String | ../../../resources/stubs/EntityFramework.cs:40:20:40:30 | this [Persons, [], Addresses, [], Street] : String | | EntityFramework.cs:159:13:162:13 | { ..., ... } [Street] : String | EntityFramework.cs:163:31:163:32 | access to local variable a1 [Street] : String | | EntityFramework.cs:161:26:161:34 | "tainted" : String | EntityFramework.cs:159:13:162:13 | { ..., ... } [Street] : String | | EntityFramework.cs:163:13:163:15 | [post] access to local variable ctx [Addresses, [], Street] : String | EntityFramework.cs:164:13:164:15 | access to local variable ctx [Addresses, [], Street] : String | | EntityFramework.cs:163:13:163:15 | [post] access to local variable ctx [Addresses, [], Street] : String | EntityFramework.cs:168:13:168:15 | access to local variable ctx [Addresses, [], Street] : String | | EntityFramework.cs:163:13:163:25 | [post] access to property Addresses [[], Street] : String | EntityFramework.cs:163:13:163:15 | [post] access to local variable ctx [Addresses, [], Street] : String | | EntityFramework.cs:163:31:163:32 | access to local variable a1 [Street] : String | EntityFramework.cs:163:13:163:25 | [post] access to property Addresses [[], Street] : String | -| EntityFramework.cs:164:13:164:15 | access to local variable ctx [Addresses, [], Street] : String | EntityFramework.cs:214:18:214:30 | access to property Addresses [[], Street] : String | -| EntityFramework.cs:164:13:164:15 | access to local variable ctx [Addresses, [], Street] : String | EntityFramework.cs:221:18:221:28 | access to property Persons [[], Addresses, [], Street] : String | -| EntityFramework.cs:164:13:164:15 | access to local variable ctx [Persons, [], Addresses, [], Street] : String | EntityFramework.cs:214:18:214:30 | access to property Addresses [[], Street] : String | -| EntityFramework.cs:164:13:164:15 | access to local variable ctx [Persons, [], Addresses, [], Street] : String | EntityFramework.cs:221:18:221:28 | access to property Persons [[], Addresses, [], Street] : String | -| EntityFramework.cs:168:13:168:15 | access to local variable ctx [Addresses, [], Street] : String | EntityFramework.cs:214:18:214:30 | access to property Addresses [[], Street] : String | -| EntityFramework.cs:168:13:168:15 | access to local variable ctx [Addresses, [], Street] : String | EntityFramework.cs:221:18:221:28 | access to property Persons [[], Addresses, [], Street] : String | -| EntityFramework.cs:168:13:168:15 | access to local variable ctx [Persons, [], Addresses, [], Street] : String | EntityFramework.cs:214:18:214:30 | access to property Addresses [[], Street] : String | -| EntityFramework.cs:168:13:168:15 | access to local variable ctx [Persons, [], Addresses, [], Street] : String | EntityFramework.cs:221:18:221:28 | access to property Persons [[], Addresses, [], Street] : String | +| EntityFramework.cs:164:13:164:15 | access to local variable ctx [Addresses, [], Street] : String | ../../../resources/stubs/EntityFramework.cs:40:20:40:30 | this [Addresses, [], Street] : String | +| EntityFramework.cs:164:13:164:15 | access to local variable ctx [Persons, [], Addresses, [], Street] : String | ../../../resources/stubs/EntityFramework.cs:40:20:40:30 | this [Persons, [], Addresses, [], Street] : String | +| EntityFramework.cs:168:13:168:15 | access to local variable ctx [Addresses, [], Street] : String | ../../../resources/stubs/EntityFramework.cs:40:20:40:30 | this [Addresses, [], Street] : String | +| EntityFramework.cs:168:13:168:15 | access to local variable ctx [Persons, [], Addresses, [], Street] : String | ../../../resources/stubs/EntityFramework.cs:40:20:40:30 | this [Persons, [], Addresses, [], Street] : String | | EntityFramework.cs:175:13:178:13 | { ..., ... } [Name] : String | EntityFramework.cs:184:71:184:72 | access to local variable p1 [Name] : String | | EntityFramework.cs:177:24:177:32 | "tainted" : String | EntityFramework.cs:175:13:178:13 | { ..., ... } [Name] : String | | EntityFramework.cs:180:13:183:13 | { ..., ... } [Street] : String | EntityFramework.cs:184:85:184:86 | access to local variable a1 [Street] : String | @@ -63,17 +75,15 @@ edges | EntityFramework.cs:185:13:185:31 | [post] access to property PersonAddresses [[], Person, Name] : String | EntityFramework.cs:185:13:185:15 | [post] access to local variable ctx [PersonAddresses, [], Person, Name] : String | | EntityFramework.cs:185:37:185:53 | access to local variable personAddressMap1 [Address, Street] : String | EntityFramework.cs:185:13:185:31 | [post] access to property PersonAddresses [[], Address, Street] : String | | EntityFramework.cs:185:37:185:53 | access to local variable personAddressMap1 [Person, Name] : String | EntityFramework.cs:185:13:185:31 | [post] access to property PersonAddresses [[], Person, Name] : String | -| EntityFramework.cs:186:13:186:15 | access to local variable ctx [PersonAddresses, [], Address, Street] : String | EntityFramework.cs:214:18:214:30 | access to property Addresses [[], Street] : String | -| EntityFramework.cs:186:13:186:15 | access to local variable ctx [PersonAddresses, [], Address, Street] : String | EntityFramework.cs:221:18:221:28 | access to property Persons [[], Addresses, [], Street] : String | -| EntityFramework.cs:186:13:186:15 | access to local variable ctx [PersonAddresses, [], Person, Name] : String | EntityFramework.cs:206:18:206:28 | access to property Persons [[], Name] : String | -| EntityFramework.cs:192:13:192:15 | access to local variable ctx [PersonAddresses, [], Address, Street] : String | EntityFramework.cs:214:18:214:30 | access to property Addresses [[], Street] : String | -| EntityFramework.cs:192:13:192:15 | access to local variable ctx [PersonAddresses, [], Address, Street] : String | EntityFramework.cs:221:18:221:28 | access to property Persons [[], Addresses, [], Street] : String | -| EntityFramework.cs:192:13:192:15 | access to local variable ctx [PersonAddresses, [], Person, Name] : String | EntityFramework.cs:206:18:206:28 | access to property Persons [[], Name] : String | +| EntityFramework.cs:186:13:186:15 | access to local variable ctx [PersonAddresses, [], Address, Street] : String | ../../../resources/stubs/EntityFramework.cs:40:20:40:30 | this [PersonAddresses, [], Address, Street] : String | +| EntityFramework.cs:186:13:186:15 | access to local variable ctx [PersonAddresses, [], Person, Name] : String | ../../../resources/stubs/EntityFramework.cs:40:20:40:30 | this [PersonAddresses, [], Person, Name] : String | +| EntityFramework.cs:192:13:192:15 | access to local variable ctx [PersonAddresses, [], Address, Street] : String | ../../../resources/stubs/EntityFramework.cs:40:20:40:30 | this [PersonAddresses, [], Address, Street] : String | +| EntityFramework.cs:192:13:192:15 | access to local variable ctx [PersonAddresses, [], Person, Name] : String | ../../../resources/stubs/EntityFramework.cs:40:20:40:30 | this [PersonAddresses, [], Person, Name] : String | | EntityFramework.cs:195:35:195:35 | p [Name] : String | EntityFramework.cs:198:29:198:29 | access to parameter p [Name] : String | | EntityFramework.cs:198:13:198:15 | [post] access to local variable ctx [Persons, [], Name] : String | EntityFramework.cs:199:13:199:15 | access to local variable ctx [Persons, [], Name] : String | | EntityFramework.cs:198:13:198:23 | [post] access to property Persons [[], Name] : String | EntityFramework.cs:198:13:198:15 | [post] access to local variable ctx [Persons, [], Name] : String | | EntityFramework.cs:198:29:198:29 | access to parameter p [Name] : String | EntityFramework.cs:198:13:198:23 | [post] access to property Persons [[], Name] : String | -| EntityFramework.cs:199:13:199:15 | access to local variable ctx [Persons, [], Name] : String | EntityFramework.cs:206:18:206:28 | access to property Persons [[], Name] : String | +| EntityFramework.cs:199:13:199:15 | access to local variable ctx [Persons, [], Name] : String | ../../../resources/stubs/EntityFramework.cs:40:20:40:30 | this [Persons, [], Name] : String | | EntityFramework.cs:206:18:206:28 | access to property Persons [[], Name] : String | EntityFramework.cs:206:18:206:36 | call to method First [Name] : String | | EntityFramework.cs:206:18:206:36 | call to method First [Name] : String | EntityFramework.cs:206:18:206:41 | access to property Name | | EntityFramework.cs:214:18:214:30 | access to property Addresses [[], Street] : String | EntityFramework.cs:214:18:214:38 | call to method First [Street] : String | @@ -94,13 +104,13 @@ edges | EntityFrameworkCore.cs:92:13:92:15 | [post] access to local variable ctx [Persons, [], Name] : String | EntityFrameworkCore.cs:94:13:94:15 | access to local variable ctx [Persons, [], Name] : String | | EntityFrameworkCore.cs:92:13:92:23 | [post] access to property Persons [[], Name] : String | EntityFrameworkCore.cs:92:13:92:15 | [post] access to local variable ctx [Persons, [], Name] : String | | EntityFrameworkCore.cs:92:29:92:30 | access to local variable p1 [Name] : String | EntityFrameworkCore.cs:92:13:92:23 | [post] access to property Persons [[], Name] : String | -| EntityFrameworkCore.cs:94:13:94:15 | access to local variable ctx [Persons, [], Name] : String | EntityFrameworkCore.cs:230:18:230:28 | access to property Persons [[], Name] : String | +| EntityFrameworkCore.cs:94:13:94:15 | access to local variable ctx [Persons, [], Name] : String | ../../../resources/stubs/EntityFramework.cs:80:20:80:30 | this [Persons, [], Name] : String | | EntityFrameworkCore.cs:107:13:110:13 | { ..., ... } [Name] : String | EntityFrameworkCore.cs:114:29:114:30 | access to local variable p1 [Name] : String | | EntityFrameworkCore.cs:109:24:109:32 | "tainted" : String | EntityFrameworkCore.cs:107:13:110:13 | { ..., ... } [Name] : String | | EntityFrameworkCore.cs:114:13:114:15 | [post] access to local variable ctx [Persons, [], Name] : String | EntityFrameworkCore.cs:116:19:116:21 | access to local variable ctx [Persons, [], Name] : String | | EntityFrameworkCore.cs:114:13:114:23 | [post] access to property Persons [[], Name] : String | EntityFrameworkCore.cs:114:13:114:15 | [post] access to local variable ctx [Persons, [], Name] : String | | EntityFrameworkCore.cs:114:29:114:30 | access to local variable p1 [Name] : String | EntityFrameworkCore.cs:114:13:114:23 | [post] access to property Persons [[], Name] : String | -| EntityFrameworkCore.cs:116:19:116:21 | access to local variable ctx [Persons, [], Name] : String | EntityFrameworkCore.cs:230:18:230:28 | access to property Persons [[], Name] : String | +| EntityFrameworkCore.cs:116:19:116:21 | access to local variable ctx [Persons, [], Name] : String | ../../../resources/stubs/EntityFramework.cs:81:49:81:64 | this [Persons, [], Name] : String | | EntityFrameworkCore.cs:129:13:132:13 | { ..., ... } [Name] : String | EntityFrameworkCore.cs:135:27:135:28 | access to local variable p1 [Name] : String | | EntityFrameworkCore.cs:131:24:131:32 | "tainted" : String | EntityFrameworkCore.cs:129:13:132:13 | { ..., ... } [Name] : String | | EntityFrameworkCore.cs:135:27:135:28 | access to local variable p1 [Name] : String | EntityFrameworkCore.cs:219:35:219:35 | p [Name] : String | @@ -119,24 +129,18 @@ edges | EntityFrameworkCore.cs:175:13:175:15 | [post] access to local variable ctx [Persons, [], Addresses, [], Street] : String | EntityFrameworkCore.cs:192:13:192:15 | access to local variable ctx [Persons, [], Addresses, [], Street] : String | | EntityFrameworkCore.cs:175:13:175:23 | [post] access to property Persons [[], Addresses, [], Street] : String | EntityFrameworkCore.cs:175:13:175:15 | [post] access to local variable ctx [Persons, [], Addresses, [], Street] : String | | EntityFrameworkCore.cs:175:29:175:30 | access to local variable p1 [Addresses, [], Street] : String | EntityFrameworkCore.cs:175:13:175:23 | [post] access to property Persons [[], Addresses, [], Street] : String | -| EntityFrameworkCore.cs:176:13:176:15 | access to local variable ctx [Persons, [], Addresses, [], Street] : String | EntityFrameworkCore.cs:238:18:238:30 | access to property Addresses [[], Street] : String | -| EntityFrameworkCore.cs:176:13:176:15 | access to local variable ctx [Persons, [], Addresses, [], Street] : String | EntityFrameworkCore.cs:245:18:245:28 | access to property Persons [[], Addresses, [], Street] : String | -| EntityFrameworkCore.cs:180:13:180:15 | access to local variable ctx [Persons, [], Addresses, [], Street] : String | EntityFrameworkCore.cs:238:18:238:30 | access to property Addresses [[], Street] : String | -| EntityFrameworkCore.cs:180:13:180:15 | access to local variable ctx [Persons, [], Addresses, [], Street] : String | EntityFrameworkCore.cs:245:18:245:28 | access to property Persons [[], Addresses, [], Street] : String | +| EntityFrameworkCore.cs:176:13:176:15 | access to local variable ctx [Persons, [], Addresses, [], Street] : String | ../../../resources/stubs/EntityFramework.cs:80:20:80:30 | this [Persons, [], Addresses, [], Street] : String | +| EntityFrameworkCore.cs:180:13:180:15 | access to local variable ctx [Persons, [], Addresses, [], Street] : String | ../../../resources/stubs/EntityFramework.cs:80:20:80:30 | this [Persons, [], Addresses, [], Street] : String | | EntityFrameworkCore.cs:183:13:186:13 | { ..., ... } [Street] : String | EntityFrameworkCore.cs:187:31:187:32 | access to local variable a1 [Street] : String | | EntityFrameworkCore.cs:185:26:185:34 | "tainted" : String | EntityFrameworkCore.cs:183:13:186:13 | { ..., ... } [Street] : String | | EntityFrameworkCore.cs:187:13:187:15 | [post] access to local variable ctx [Addresses, [], Street] : String | EntityFrameworkCore.cs:188:13:188:15 | access to local variable ctx [Addresses, [], Street] : String | | EntityFrameworkCore.cs:187:13:187:15 | [post] access to local variable ctx [Addresses, [], Street] : String | EntityFrameworkCore.cs:192:13:192:15 | access to local variable ctx [Addresses, [], Street] : String | | EntityFrameworkCore.cs:187:13:187:25 | [post] access to property Addresses [[], Street] : String | EntityFrameworkCore.cs:187:13:187:15 | [post] access to local variable ctx [Addresses, [], Street] : String | | EntityFrameworkCore.cs:187:31:187:32 | access to local variable a1 [Street] : String | EntityFrameworkCore.cs:187:13:187:25 | [post] access to property Addresses [[], Street] : String | -| EntityFrameworkCore.cs:188:13:188:15 | access to local variable ctx [Addresses, [], Street] : String | EntityFrameworkCore.cs:238:18:238:30 | access to property Addresses [[], Street] : String | -| EntityFrameworkCore.cs:188:13:188:15 | access to local variable ctx [Addresses, [], Street] : String | EntityFrameworkCore.cs:245:18:245:28 | access to property Persons [[], Addresses, [], Street] : String | -| EntityFrameworkCore.cs:188:13:188:15 | access to local variable ctx [Persons, [], Addresses, [], Street] : String | EntityFrameworkCore.cs:238:18:238:30 | access to property Addresses [[], Street] : String | -| EntityFrameworkCore.cs:188:13:188:15 | access to local variable ctx [Persons, [], Addresses, [], Street] : String | EntityFrameworkCore.cs:245:18:245:28 | access to property Persons [[], Addresses, [], Street] : String | -| EntityFrameworkCore.cs:192:13:192:15 | access to local variable ctx [Addresses, [], Street] : String | EntityFrameworkCore.cs:238:18:238:30 | access to property Addresses [[], Street] : String | -| EntityFrameworkCore.cs:192:13:192:15 | access to local variable ctx [Addresses, [], Street] : String | EntityFrameworkCore.cs:245:18:245:28 | access to property Persons [[], Addresses, [], Street] : String | -| EntityFrameworkCore.cs:192:13:192:15 | access to local variable ctx [Persons, [], Addresses, [], Street] : String | EntityFrameworkCore.cs:238:18:238:30 | access to property Addresses [[], Street] : String | -| EntityFrameworkCore.cs:192:13:192:15 | access to local variable ctx [Persons, [], Addresses, [], Street] : String | EntityFrameworkCore.cs:245:18:245:28 | access to property Persons [[], Addresses, [], Street] : String | +| EntityFrameworkCore.cs:188:13:188:15 | access to local variable ctx [Addresses, [], Street] : String | ../../../resources/stubs/EntityFramework.cs:80:20:80:30 | this [Addresses, [], Street] : String | +| EntityFrameworkCore.cs:188:13:188:15 | access to local variable ctx [Persons, [], Addresses, [], Street] : String | ../../../resources/stubs/EntityFramework.cs:80:20:80:30 | this [Persons, [], Addresses, [], Street] : String | +| EntityFrameworkCore.cs:192:13:192:15 | access to local variable ctx [Addresses, [], Street] : String | ../../../resources/stubs/EntityFramework.cs:80:20:80:30 | this [Addresses, [], Street] : String | +| EntityFrameworkCore.cs:192:13:192:15 | access to local variable ctx [Persons, [], Addresses, [], Street] : String | ../../../resources/stubs/EntityFramework.cs:80:20:80:30 | this [Persons, [], Addresses, [], Street] : String | | EntityFrameworkCore.cs:199:13:202:13 | { ..., ... } [Name] : String | EntityFrameworkCore.cs:208:71:208:72 | access to local variable p1 [Name] : String | | EntityFrameworkCore.cs:201:24:201:32 | "tainted" : String | EntityFrameworkCore.cs:199:13:202:13 | { ..., ... } [Name] : String | | EntityFrameworkCore.cs:204:13:207:13 | { ..., ... } [Street] : String | EntityFrameworkCore.cs:208:85:208:86 | access to local variable a1 [Street] : String | @@ -153,17 +157,15 @@ edges | EntityFrameworkCore.cs:209:13:209:31 | [post] access to property PersonAddresses [[], Person, Name] : String | EntityFrameworkCore.cs:209:13:209:15 | [post] access to local variable ctx [PersonAddresses, [], Person, Name] : String | | EntityFrameworkCore.cs:209:37:209:53 | access to local variable personAddressMap1 [Address, Street] : String | EntityFrameworkCore.cs:209:13:209:31 | [post] access to property PersonAddresses [[], Address, Street] : String | | EntityFrameworkCore.cs:209:37:209:53 | access to local variable personAddressMap1 [Person, Name] : String | EntityFrameworkCore.cs:209:13:209:31 | [post] access to property PersonAddresses [[], Person, Name] : String | -| EntityFrameworkCore.cs:210:13:210:15 | access to local variable ctx [PersonAddresses, [], Address, Street] : String | EntityFrameworkCore.cs:238:18:238:30 | access to property Addresses [[], Street] : String | -| EntityFrameworkCore.cs:210:13:210:15 | access to local variable ctx [PersonAddresses, [], Address, Street] : String | EntityFrameworkCore.cs:245:18:245:28 | access to property Persons [[], Addresses, [], Street] : String | -| EntityFrameworkCore.cs:210:13:210:15 | access to local variable ctx [PersonAddresses, [], Person, Name] : String | EntityFrameworkCore.cs:230:18:230:28 | access to property Persons [[], Name] : String | -| EntityFrameworkCore.cs:216:13:216:15 | access to local variable ctx [PersonAddresses, [], Address, Street] : String | EntityFrameworkCore.cs:238:18:238:30 | access to property Addresses [[], Street] : String | -| EntityFrameworkCore.cs:216:13:216:15 | access to local variable ctx [PersonAddresses, [], Address, Street] : String | EntityFrameworkCore.cs:245:18:245:28 | access to property Persons [[], Addresses, [], Street] : String | -| EntityFrameworkCore.cs:216:13:216:15 | access to local variable ctx [PersonAddresses, [], Person, Name] : String | EntityFrameworkCore.cs:230:18:230:28 | access to property Persons [[], Name] : String | +| EntityFrameworkCore.cs:210:13:210:15 | access to local variable ctx [PersonAddresses, [], Address, Street] : String | ../../../resources/stubs/EntityFramework.cs:80:20:80:30 | this [PersonAddresses, [], Address, Street] : String | +| EntityFrameworkCore.cs:210:13:210:15 | access to local variable ctx [PersonAddresses, [], Person, Name] : String | ../../../resources/stubs/EntityFramework.cs:80:20:80:30 | this [PersonAddresses, [], Person, Name] : String | +| EntityFrameworkCore.cs:216:13:216:15 | access to local variable ctx [PersonAddresses, [], Address, Street] : String | ../../../resources/stubs/EntityFramework.cs:80:20:80:30 | this [PersonAddresses, [], Address, Street] : String | +| EntityFrameworkCore.cs:216:13:216:15 | access to local variable ctx [PersonAddresses, [], Person, Name] : String | ../../../resources/stubs/EntityFramework.cs:80:20:80:30 | this [PersonAddresses, [], Person, Name] : String | | EntityFrameworkCore.cs:219:35:219:35 | p [Name] : String | EntityFrameworkCore.cs:222:29:222:29 | access to parameter p [Name] : String | | EntityFrameworkCore.cs:222:13:222:15 | [post] access to local variable ctx [Persons, [], Name] : String | EntityFrameworkCore.cs:223:13:223:15 | access to local variable ctx [Persons, [], Name] : String | | EntityFrameworkCore.cs:222:13:222:23 | [post] access to property Persons [[], Name] : String | EntityFrameworkCore.cs:222:13:222:15 | [post] access to local variable ctx [Persons, [], Name] : String | | EntityFrameworkCore.cs:222:29:222:29 | access to parameter p [Name] : String | EntityFrameworkCore.cs:222:13:222:23 | [post] access to property Persons [[], Name] : String | -| EntityFrameworkCore.cs:223:13:223:15 | access to local variable ctx [Persons, [], Name] : String | EntityFrameworkCore.cs:230:18:230:28 | access to property Persons [[], Name] : String | +| EntityFrameworkCore.cs:223:13:223:15 | access to local variable ctx [Persons, [], Name] : String | ../../../resources/stubs/EntityFramework.cs:80:20:80:30 | this [Persons, [], Name] : String | | EntityFrameworkCore.cs:230:18:230:28 | access to property Persons [[], Name] : String | EntityFrameworkCore.cs:230:18:230:36 | call to method First [Name] : String | | EntityFrameworkCore.cs:230:18:230:36 | call to method First [Name] : String | EntityFrameworkCore.cs:230:18:230:41 | access to property Name | | EntityFrameworkCore.cs:238:18:238:30 | access to property Addresses [[], Street] : String | EntityFrameworkCore.cs:238:18:238:38 | call to method First [Street] : String | @@ -173,6 +175,18 @@ edges | EntityFrameworkCore.cs:245:18:245:46 | access to property Addresses [[], Street] : String | EntityFrameworkCore.cs:245:18:245:54 | call to method First [Street] : String | | EntityFrameworkCore.cs:245:18:245:54 | call to method First [Street] : String | EntityFrameworkCore.cs:245:18:245:61 | access to property Street | nodes +| ../../../resources/stubs/EntityFramework.cs:40:20:40:30 | this [Addresses, [], Street] : String | semmle.label | this [Addresses, [], Street] : String | +| ../../../resources/stubs/EntityFramework.cs:40:20:40:30 | this [PersonAddresses, [], Address, Street] : String | semmle.label | this [PersonAddresses, [], Address, Street] : String | +| ../../../resources/stubs/EntityFramework.cs:40:20:40:30 | this [PersonAddresses, [], Person, Name] : String | semmle.label | this [PersonAddresses, [], Person, Name] : String | +| ../../../resources/stubs/EntityFramework.cs:40:20:40:30 | this [Persons, [], Addresses, [], Street] : String | semmle.label | this [Persons, [], Addresses, [], Street] : String | +| ../../../resources/stubs/EntityFramework.cs:40:20:40:30 | this [Persons, [], Name] : String | semmle.label | this [Persons, [], Name] : String | +| ../../../resources/stubs/EntityFramework.cs:41:49:41:64 | this [Persons, [], Name] : String | semmle.label | this [Persons, [], Name] : String | +| ../../../resources/stubs/EntityFramework.cs:80:20:80:30 | this [Addresses, [], Street] : String | semmle.label | this [Addresses, [], Street] : String | +| ../../../resources/stubs/EntityFramework.cs:80:20:80:30 | this [PersonAddresses, [], Address, Street] : String | semmle.label | this [PersonAddresses, [], Address, Street] : String | +| ../../../resources/stubs/EntityFramework.cs:80:20:80:30 | this [PersonAddresses, [], Person, Name] : String | semmle.label | this [PersonAddresses, [], Person, Name] : String | +| ../../../resources/stubs/EntityFramework.cs:80:20:80:30 | this [Persons, [], Addresses, [], Street] : String | semmle.label | this [Persons, [], Addresses, [], Street] : String | +| ../../../resources/stubs/EntityFramework.cs:80:20:80:30 | this [Persons, [], Name] : String | semmle.label | this [Persons, [], Name] : String | +| ../../../resources/stubs/EntityFramework.cs:81:49:81:64 | this [Persons, [], Name] : String | semmle.label | this [Persons, [], Name] : String | | EntityFramework.cs:61:13:64:13 | { ..., ... } [Name] : String | semmle.label | { ..., ... } [Name] : String | | EntityFramework.cs:63:24:63:32 | "tainted" : String | semmle.label | "tainted" : String | | EntityFramework.cs:68:13:68:15 | [post] access to local variable ctx [Persons, [], Name] : String | semmle.label | [post] access to local variable ctx [Persons, [], Name] : String | diff --git a/csharp/ql/test/library-tests/frameworks/test/Test.expected b/csharp/ql/test/library-tests/frameworks/test/Test.expected index d988aadc549..2d16ac51cfa 100644 --- a/csharp/ql/test/library-tests/frameworks/test/Test.expected +++ b/csharp/ql/test/library-tests/frameworks/test/Test.expected @@ -1,33 +1,14 @@ -| VisualStudio.cs:9:11:9:21 | MyTestSuite | TestClass | LeafType | -| VisualStudio.cs:9:11:9:21 | MyTestSuite | TestClass | VSTestClass | -| VisualStudio.cs:12:21:12:25 | Test1 | TestMethod | CallableOrCFE | -| VisualStudio.cs:12:21:12:25 | Test1 | TestMethod | InstanceCallable | -| VisualStudio.cs:12:21:12:25 | Test1 | TestMethod | VSTestMethod | -| VisualStudio.cs:17:21:17:25 | Test2 | TestMethod | CallableOrCFE | -| VisualStudio.cs:17:21:17:25 | Test2 | TestMethod | InstanceCallable | -| VisualStudio.cs:17:21:17:25 | Test2 | TestMethod | VSTestMethod | -| XUnit.cs:22:11:22:21 | MyTestSuite | TestClass | LeafType | -| XUnit.cs:22:11:22:21 | MyTestSuite | TestClass | XUnitTestClass | -| XUnit.cs:25:21:25:25 | Test1 | TestMethod | CallableOrCFE | -| XUnit.cs:25:21:25:25 | Test1 | TestMethod | InstanceCallable | -| XUnit.cs:25:21:25:25 | Test1 | TestMethod | XUnitTestMethod | -| XUnit.cs:30:21:30:25 | Test2 | TestMethod | CallableOrCFE | -| XUnit.cs:30:21:30:25 | Test2 | TestMethod | InstanceCallable | -| XUnit.cs:30:21:30:25 | Test2 | TestMethod | XUnitTestMethod | -| nunit.cs:75:11:75:21 | MyTestSuite | TestClass | LeafType | -| nunit.cs:75:11:75:21 | MyTestSuite | TestClass | NUnitFixture | -| nunit.cs:85:21:85:25 | Test1 | TestMethod | CallableOrCFE | -| nunit.cs:85:21:85:25 | Test1 | TestMethod | InstanceCallable | -| nunit.cs:85:21:85:25 | Test1 | TestMethod | NUnitTestMethod | -| nunit.cs:90:21:90:25 | Test2 | TestMethod | CallableOrCFE | -| nunit.cs:90:21:90:25 | Test2 | TestMethod | InstanceCallable | -| nunit.cs:90:21:90:25 | Test2 | TestMethod | NUnitTestMethod | -| nunit.cs:95:21:95:25 | Test3 | TestMethod | CallableOrCFE | -| nunit.cs:95:21:95:25 | Test3 | TestMethod | InstanceCallable | -| nunit.cs:95:21:95:25 | Test3 | TestMethod | NUnitTestMethod | -| nunit.cs:100:21:100:25 | Test4 | TestMethod | CallableOrCFE | -| nunit.cs:100:21:100:25 | Test4 | TestMethod | InstanceCallable | -| nunit.cs:100:21:100:25 | Test4 | TestMethod | NUnitTestMethod | -| nunit.cs:105:21:105:25 | Test5 | TestMethod | CallableOrCFE | -| nunit.cs:105:21:105:25 | Test5 | TestMethod | InstanceCallable | -| nunit.cs:105:21:105:25 | Test5 | TestMethod | NUnitTestMethod | +testClass +| VisualStudio.cs:9:11:9:21 | MyTestSuite | +| XUnit.cs:22:11:22:21 | MyTestSuite | +| nunit.cs:75:11:75:21 | MyTestSuite | +testMethod +| VisualStudio.cs:12:21:12:25 | Test1 | +| VisualStudio.cs:17:21:17:25 | Test2 | +| XUnit.cs:25:21:25:25 | Test1 | +| XUnit.cs:30:21:30:25 | Test2 | +| nunit.cs:85:21:85:25 | Test1 | +| nunit.cs:90:21:90:25 | Test2 | +| nunit.cs:95:21:95:25 | Test3 | +| nunit.cs:100:21:100:25 | Test4 | +| nunit.cs:105:21:105:25 | Test5 | diff --git a/csharp/ql/test/library-tests/frameworks/test/Test.ql b/csharp/ql/test/library-tests/frameworks/test/Test.ql index 0288245f7c1..faa71788c7e 100644 --- a/csharp/ql/test/library-tests/frameworks/test/Test.ql +++ b/csharp/ql/test/library-tests/frameworks/test/Test.ql @@ -1,18 +1,6 @@ import csharp import semmle.code.csharp.frameworks.Test -from Element e, string type, string framework -where - ( - framework = e.(TestClass).getAQlClass() and type = "TestClass" - or - framework = e.(TestMethod).getAQlClass() and type = "TestMethod" - ) and - not framework = "NonNestedType" and - not framework = "UnboundDeclarationType" and - not framework = "SourceDeclarationCallable" and - not framework = "SourceDeclarationMethod" and - not framework = "NonConstructedMethod" and - not framework = "RuntimeInstanceMethod" and - not framework = "SummarizableMethod" -select e, type, framework +query predicate testClass(TestClass c) { any() } + +query predicate testMethod(TestMethod m) { any() } diff --git a/csharp/ql/test/library-tests/generics/ConsistencyChecks.ql b/csharp/ql/test/library-tests/generics/ConsistencyChecks.ql index 83f2597f856..def07f2c435 100644 --- a/csharp/ql/test/library-tests/generics/ConsistencyChecks.ql +++ b/csharp/ql/test/library-tests/generics/ConsistencyChecks.ql @@ -6,4 +6,4 @@ import semmle.code.csharp.commons.ConsistencyChecks from Element e, string m where consistencyFailure(e, m) -select e, "Element class " + e.getAQlClass() + " has consistency check failed: " + m +select e, "Element class " + e.getAPrimaryQlClass() + " has consistency check failed: " + m diff --git a/csharp/ql/test/library-tests/generics/PrintAst.expected b/csharp/ql/test/library-tests/generics/PrintAst.expected index b22594ba87c..0762a97d3ae 100644 --- a/csharp/ql/test/library-tests/generics/PrintAst.expected +++ b/csharp/ql/test/library-tests/generics/PrintAst.expected @@ -289,7 +289,7 @@ generics.cs: # 33| 9: [Method] staticFoo # 33| -1: [TypeMention] Void # 33| 4: [BlockStmt] {...} -# 35| 10: [IndexerProperty] Name +# 35| 10: [Property] Name # 35| -1: [TypeMention] string # 35| 3: [Getter] get_Name # 35| 4: [BlockStmt] {...} diff --git a/csharp/ql/test/library-tests/members/PrintAst.expected b/csharp/ql/test/library-tests/members/PrintAst.expected index 002192558fa..6db54ebb7b8 100644 --- a/csharp/ql/test/library-tests/members/PrintAst.expected +++ b/csharp/ql/test/library-tests/members/PrintAst.expected @@ -34,7 +34,7 @@ Members.cs: # 14| 4: [BlockStmt] {...} # 16| 7: [Field] Field # 16| -1: [TypeMention] string -# 18| 8: [IndexerProperty] Prop +# 18| 8: [Property] Prop # 18| -1: [TypeMention] string # 18| 3: [Getter] get_Prop # 18| 4: [Setter] set_Prop @@ -68,7 +68,7 @@ Members.cs: # 26| 4: [BlockStmt] {...} # 28| 8: [Field] Field # 28| -1: [TypeMention] string -# 30| 9: [IndexerProperty] Prop +# 30| 9: [Property] Prop # 30| -1: [TypeMention] string # 30| 3: [Getter] get_Prop # 30| 4: [Setter] set_Prop @@ -110,7 +110,7 @@ Members.cs: # 40| 4: [BlockStmt] {...} # 41| 7: [Field] Field # 41| -1: [TypeMention] string -# 42| 8: [IndexerProperty] Prop +# 42| 8: [Property] Prop # 42| -1: [TypeMention] string # 42| 3: [Getter] get_Prop # 42| 4: [Setter] set_Prop @@ -144,7 +144,7 @@ Members.cs: # 47| 4: [BlockStmt] {...} # 48| 8: [Field] Field # 48| -1: [TypeMention] string -# 49| 9: [IndexerProperty] Prop +# 49| 9: [Property] Prop # 49| -1: [TypeMention] string # 49| 3: [Getter] get_Prop # 49| 4: [Setter] set_Prop @@ -173,7 +173,7 @@ Members.cs: #-----| 2: (Parameters) # 57| 0: [Parameter] i # 57| 1: [Parameter] value -# 58| 6: [IndexerProperty] Prop +# 58| 6: [Property] Prop # 58| -1: [TypeMention] string # 58| 3: [Getter] get_Prop # 58| 4: [Setter] set_Prop @@ -202,7 +202,7 @@ Members.cs: #-----| 2: (Parameters) # 65| 0: [Parameter] i # 65| 1: [Parameter] value -# 66| 6: [IndexerProperty] Prop +# 66| 6: [Property] Prop # 66| -1: [TypeMention] string # 66| 3: [Getter] get_Prop # 66| 4: [Setter] set_Prop diff --git a/csharp/ql/test/library-tests/properties/PrintAst.expected b/csharp/ql/test/library-tests/properties/PrintAst.expected index 7c306bdc789..03a0f1bc293 100644 --- a/csharp/ql/test/library-tests/properties/PrintAst.expected +++ b/csharp/ql/test/library-tests/properties/PrintAst.expected @@ -3,7 +3,7 @@ properties.cs: # 7| 1: [Class] Button # 10| 5: [Field] caption # 10| -1: [TypeMention] string -# 12| 6: [IndexerProperty] Caption +# 12| 6: [Property] Caption # 12| -1: [TypeMention] string # 15| 3: [Getter] get_Caption # 15| 4: [BlockStmt] {...} diff --git a/csharp/ql/test/library-tests/typeMentions/NullableDisabled.cs b/csharp/ql/test/library-tests/typeMentions/NullableDisabled.cs new file mode 100644 index 00000000000..b7627a992d7 --- /dev/null +++ b/csharp/ql/test/library-tests/typeMentions/NullableDisabled.cs @@ -0,0 +1,22 @@ +using System; + +#nullable disable + +public class Base { } +public class Derived : Base { } +public interface I0 { } +public interface I1 : I0 { } +public struct Str : I1 { } + +public class C1 +{ + public void M1() + { + Derived? d0 = new Derived(); + Derived d1 = new Derived(); + Str? s0 = new Str(); + Str s1 = new Str(); + I1? i0 = new Str(); + I1 i1 = new Str(); + } +} \ No newline at end of file diff --git a/csharp/ql/test/library-tests/typeMentions/NullableEnabled.cs b/csharp/ql/test/library-tests/typeMentions/NullableEnabled.cs new file mode 100644 index 00000000000..e9240aa9d77 --- /dev/null +++ b/csharp/ql/test/library-tests/typeMentions/NullableEnabled.cs @@ -0,0 +1,24 @@ +using System; + +#nullable enable + +public class Base { } +public class Derived : Base { } +public interface I0 { } +public interface I1 : I0 { } +public struct Str : I1 { } + +public class C1 +{ + public void M1() + { + Derived? d0 = new Derived(); + Derived d1 = new Derived(); + Str? s0 = new Str(); + Str s1 = new Str(); + I1? i0 = new Str(); + I1 i1 = new Str(); + } +} + +// semmle-extractor-options: --separate-compilation \ No newline at end of file diff --git a/csharp/ql/test/library-tests/typeMentions/TypeMentions.expected b/csharp/ql/test/library-tests/typeMentions/TypeMentions.expected new file mode 100644 index 00000000000..b0e69ebc377 --- /dev/null +++ b/csharp/ql/test/library-tests/typeMentions/TypeMentions.expected @@ -0,0 +1,37 @@ +typeMentions +| NullableDisabled.cs:6:24:6:27 | Base | +| NullableDisabled.cs:8:23:8:24 | I0 | +| NullableDisabled.cs:9:21:9:22 | I1 | +| NullableDisabled.cs:13:12:13:15 | Void | +| NullableDisabled.cs:15:9:15:15 | Derived | +| NullableDisabled.cs:15:27:15:33 | Derived | +| NullableDisabled.cs:16:9:16:15 | Derived | +| NullableDisabled.cs:16:26:16:32 | Derived | +| NullableDisabled.cs:17:9:17:11 | Str | +| NullableDisabled.cs:17:9:17:12 | Nullable<Str> | +| NullableDisabled.cs:17:23:17:25 | Str | +| NullableDisabled.cs:18:9:18:11 | Str | +| NullableDisabled.cs:18:22:18:24 | Str | +| NullableDisabled.cs:19:9:19:10 | I1 | +| NullableDisabled.cs:19:22:19:24 | Str | +| NullableDisabled.cs:20:9:20:10 | I1 | +| NullableDisabled.cs:20:21:20:23 | Str | +| NullableEnabled.cs:6:24:6:27 | Base | +| NullableEnabled.cs:8:23:8:24 | I0 | +| NullableEnabled.cs:9:21:9:22 | I1 | +| NullableEnabled.cs:13:12:13:15 | Void | +| NullableEnabled.cs:15:9:15:15 | Derived | +| NullableEnabled.cs:15:27:15:33 | Derived | +| NullableEnabled.cs:16:9:16:15 | Derived | +| NullableEnabled.cs:16:26:16:32 | Derived | +| NullableEnabled.cs:17:9:17:11 | Str | +| NullableEnabled.cs:17:9:17:12 | Nullable<Str> | +| NullableEnabled.cs:17:23:17:25 | Str | +| NullableEnabled.cs:18:9:18:11 | Str | +| NullableEnabled.cs:18:22:18:24 | Str | +| NullableEnabled.cs:19:9:19:10 | I1 | +| NullableEnabled.cs:19:22:19:24 | Str | +| NullableEnabled.cs:20:9:20:10 | I1 | +| NullableEnabled.cs:20:21:20:23 | Str | +duplicates +diff diff --git a/csharp/ql/test/library-tests/typeMentions/TypeMentions.ql b/csharp/ql/test/library-tests/typeMentions/TypeMentions.ql new file mode 100644 index 00000000000..abe0a12ed0e --- /dev/null +++ b/csharp/ql/test/library-tests/typeMentions/TypeMentions.ql @@ -0,0 +1,29 @@ +import csharp + +private predicate matchingLineLoc(TypeMention tm0, TypeMention tm1) { + tm0.getLocation().getStartLine() = tm1.getLocation().getStartLine() and + tm0.getLocation().getEndLine() = tm1.getLocation().getEndLine() and + tm0.getLocation().getStartColumn() = tm1.getLocation().getStartColumn() and + tm0.getLocation().getEndColumn() = tm1.getLocation().getEndColumn() +} + +private predicate matchingFile(TypeMention tm0, TypeMention tm1) { + tm0.getLocation().getFile().getStem() = tm1.getLocation().getFile().getStem() +} + +query predicate typeMentions(TypeMention tm) { any() } + +query predicate duplicates(TypeMention tm) { + exists(TypeMention other | + matchingLineLoc(other, tm) and + matchingFile(other, tm) and + other != tm + ) +} + +query predicate diff(TypeMention tm) { + not exists(TypeMention other | + matchingLineLoc(other, tm) and + not matchingFile(other, tm) + ) +} diff --git a/csharp/ql/test/qlpack.yml b/csharp/ql/test/qlpack.yml index 2b8cce91f07..9882ae18d14 100644 --- a/csharp/ql/test/qlpack.yml +++ b/csharp/ql/test/qlpack.yml @@ -2,3 +2,4 @@ name: codeql-csharp-tests version: 0.0.0 libraryPathDependencies: codeql-csharp extractor: csharp +tests: . diff --git a/csharp/ql/test/query-tests/API Abuse/FormatInvalid/FormatInvalid.cs b/csharp/ql/test/query-tests/API Abuse/FormatInvalid/FormatInvalid.cs index 6dd9cc6f384..81aa6953e84 100644 --- a/csharp/ql/test/query-tests/API Abuse/FormatInvalid/FormatInvalid.cs +++ b/csharp/ql/test/query-tests/API Abuse/FormatInvalid/FormatInvalid.cs @@ -1,7 +1,7 @@ using System; using System.Text; -class Class1 +class FormatInvalid { void FormatStringTests() { @@ -115,6 +115,8 @@ class Class1 System.Diagnostics.Debug.Assert(true, "Error", "}", ps); sw.Write("}", 0); System.Diagnostics.Debug.Print("}", ps); + + Console.WriteLine("}"); // GOOD } System.IO.StringWriter sw; diff --git a/csharp/ql/test/query-tests/API Abuse/FormatInvalid/FormatInvalid.expected b/csharp/ql/test/query-tests/API Abuse/FormatInvalid/FormatInvalid.expected index 18340a5d5c8..9443b7284fc 100644 --- a/csharp/ql/test/query-tests/API Abuse/FormatInvalid/FormatInvalid.expected +++ b/csharp/ql/test/query-tests/API Abuse/FormatInvalid/FormatInvalid.expected @@ -1,3 +1,6 @@ +edges +| FormatMissingArgument.cs:22:16:22:20 | "{1}" : String | FormatMissingArgument.cs:28:24:28:29 | format : String | +| FormatMissingArgument.cs:28:24:28:29 | format : String | FormatMissingArgument.cs:31:23:31:28 | access to parameter format | nodes | FormatInvalid.cs:9:23:9:27 | "{0}" | semmle.label | "{0}" | | FormatInvalid.cs:12:23:12:29 | "{0,1}" | semmle.label | "{0,1}" | @@ -51,49 +54,106 @@ nodes | FormatInvalid.cs:115:56:115:58 | [assertion success] "}" | semmle.label | [assertion success] "}" | | FormatInvalid.cs:116:18:116:20 | "}" | semmle.label | "}" | | FormatInvalid.cs:117:40:117:42 | "}" | semmle.label | "}" | +| FormatInvalid.cs:119:27:119:29 | "}" | semmle.label | "}" | | FormatInvalidBad.cs:7:30:7:44 | "class {0} { }" | semmle.label | "class {0} { }" | | FormatInvalidGood.cs:7:30:7:46 | "class {0} {{ }}" | semmle.label | "class {0} {{ }}" | -edges +| FormatMissingArgument.cs:8:23:8:27 | "{0}" | semmle.label | "{0}" | +| FormatMissingArgument.cs:11:23:11:27 | "{1}" | semmle.label | "{1}" | +| FormatMissingArgument.cs:14:23:14:31 | "{2} {3}" | semmle.label | "{2} {3}" | +| FormatMissingArgument.cs:17:23:17:35 | "{0} {1} {2}" | semmle.label | "{0} {1} {2}" | +| FormatMissingArgument.cs:20:23:20:39 | "{0} {1} {2} {3}" | semmle.label | "{0} {1} {2} {3}" | +| FormatMissingArgument.cs:22:16:22:20 | "{1}" : String | semmle.label | "{1}" : String | +| FormatMissingArgument.cs:25:27:25:31 | "{0}" | semmle.label | "{0}" | +| FormatMissingArgument.cs:28:24:28:29 | format : String | semmle.label | format : String | +| FormatMissingArgument.cs:31:23:31:28 | access to parameter format | semmle.label | access to parameter format | +| FormatMissingArgumentBad.cs:7:27:7:41 | "Hello {0} {1}" | semmle.label | "Hello {0} {1}" | +| FormatMissingArgumentBad.cs:8:27:8:41 | "Hello {1} {2}" | semmle.label | "Hello {1} {2}" | +| FormatMissingArgumentGood.cs:7:27:7:41 | "Hello {0} {1}" | semmle.label | "Hello {0} {1}" | +| FormatUnusedArgument.cs:8:23:8:35 | "{0} {1} {2}" | semmle.label | "{0} {1} {2}" | +| FormatUnusedArgument.cs:11:23:11:25 | "X" | semmle.label | "X" | +| FormatUnusedArgument.cs:14:23:14:27 | "{0}" | semmle.label | "{0}" | +| FormatUnusedArgument.cs:17:23:17:31 | "{0} {0}" | semmle.label | "{0} {0}" | +| FormatUnusedArgument.cs:20:23:20:31 | "{1} {1}" | semmle.label | "{1} {1}" | +| FormatUnusedArgument.cs:23:23:23:31 | "abcdefg" | semmle.label | "abcdefg" | +| FormatUnusedArgument.cs:26:23:26:31 | "{{sdc}}" | semmle.label | "{{sdc}}" | +| FormatUnusedArgument.cs:29:23:29:33 | "{{{0:D}}}" | semmle.label | "{{{0:D}}}" | +| FormatUnusedArgument.cs:32:23:32:39 | "{0} {1} {2} {3}" | semmle.label | "{0} {1} {2} {3}" | +| FormatUnusedArgument.cs:35:23:35:35 | "{0} {1} {2}" | semmle.label | "{0} {1} {2}" | +| FormatUnusedArgument.cs:38:23:38:29 | "{{0}}" | semmle.label | "{{0}}" | +| FormatUnusedArgument.cs:42:23:42:24 | "" | semmle.label | "" | +| FormatUnusedArgumentBad.cs:7:27:7:54 | "Error processing file: {0}" | semmle.label | "Error processing file: {0}" | +| FormatUnusedArgumentBad.cs:8:27:8:60 | "Error processing file: {1} ({1})" | semmle.label | "Error processing file: {1} ({1})" | +| FormatUnusedArgumentBad.cs:9:27:9:58 | "Error processing file: %s (%d)" | semmle.label | "Error processing file: %s (%d)" | #select -| FormatInvalid.cs:27:24:27:28 | "{ 0}" | FormatInvalid.cs:27:23:27:28 | "{ 0}" | FormatInvalid.cs:27:23:27:28 | "{ 0}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:27:9:27:32 | call to method Format | this | -| FormatInvalid.cs:30:24:30:31 | "{0,--1}" | FormatInvalid.cs:30:23:30:31 | "{0,--1}" | FormatInvalid.cs:30:23:30:31 | "{0,--1}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:30:9:30:35 | call to method Format | this | -| FormatInvalid.cs:33:24:33:30 | "{0:{}}" | FormatInvalid.cs:33:23:33:30 | "{0:{}}" | FormatInvalid.cs:33:23:33:30 | "{0:{}}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:33:9:33:34 | call to method Format | this | -| FormatInvalid.cs:39:27:39:33 | "{{0}-{1}}" | FormatInvalid.cs:39:23:39:33 | "{{0}-{1}}" | FormatInvalid.cs:39:23:39:33 | "{{0}-{1}}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:39:9:39:40 | call to method Format | this | -| FormatInvalid.cs:42:27:42:28 | "{0}}" | FormatInvalid.cs:42:23:42:28 | "{0}}" | FormatInvalid.cs:42:23:42:28 | "{0}}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:42:9:42:35 | call to method Format | this | -| FormatInvalid.cs:45:24:45:32 | "{foo{0}}" | FormatInvalid.cs:45:23:45:32 | "{foo{0}}" | FormatInvalid.cs:45:23:45:32 | "{foo{0}}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:45:9:45:36 | call to method Format | this | -| FormatInvalid.cs:51:24:51:25 | "}" | FormatInvalid.cs:51:23:51:25 | "}" | FormatInvalid.cs:51:23:51:25 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:51:9:51:29 | call to method Format | this | -| FormatInvalid.cs:75:24:75:25 | "}" | FormatInvalid.cs:75:23:75:25 | "}" | FormatInvalid.cs:75:23:75:25 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:75:9:75:29 | call to method Format | this | -| FormatInvalid.cs:76:24:76:25 | "}" | FormatInvalid.cs:76:23:76:25 | "}" | FormatInvalid.cs:76:23:76:25 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:76:9:76:30 | call to method Format | this | -| FormatInvalid.cs:77:28:77:29 | "}" | FormatInvalid.cs:77:27:77:29 | "}" | FormatInvalid.cs:77:27:77:29 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:77:9:77:34 | call to method Format | this | -| FormatInvalid.cs:78:24:78:25 | "}" | FormatInvalid.cs:78:23:78:25 | "}" | FormatInvalid.cs:78:23:78:25 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:78:9:78:32 | call to method Format | this | -| FormatInvalid.cs:79:24:79:25 | "}" | FormatInvalid.cs:79:23:79:25 | "}" | FormatInvalid.cs:79:23:79:25 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:79:9:79:35 | call to method Format | this | -| FormatInvalid.cs:80:24:80:25 | "}" | FormatInvalid.cs:80:23:80:25 | "}" | FormatInvalid.cs:80:23:80:25 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:80:9:80:38 | call to method Format | this | -| FormatInvalid.cs:82:26:82:27 | "}" | FormatInvalid.cs:82:25:82:27 | "}" | FormatInvalid.cs:82:25:82:27 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:82:9:82:31 | call to method AppendFormat | this | -| FormatInvalid.cs:83:26:83:27 | "}" | FormatInvalid.cs:83:25:83:27 | "}" | FormatInvalid.cs:83:25:83:27 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:83:9:83:32 | call to method AppendFormat | this | -| FormatInvalid.cs:84:30:84:31 | "}" | FormatInvalid.cs:84:29:84:31 | "}" | FormatInvalid.cs:84:29:84:31 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:84:9:84:36 | call to method AppendFormat | this | -| FormatInvalid.cs:85:26:85:27 | "}" | FormatInvalid.cs:85:25:85:27 | "}" | FormatInvalid.cs:85:25:85:27 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:85:9:85:34 | call to method AppendFormat | this | -| FormatInvalid.cs:86:26:86:27 | "}" | FormatInvalid.cs:86:25:86:27 | "}" | FormatInvalid.cs:86:25:86:27 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:86:9:86:37 | call to method AppendFormat | this | -| FormatInvalid.cs:87:26:87:27 | "}" | FormatInvalid.cs:87:25:87:27 | "}" | FormatInvalid.cs:87:25:87:27 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:87:9:87:40 | call to method AppendFormat | this | -| FormatInvalid.cs:89:28:89:29 | "}" | FormatInvalid.cs:89:27:89:29 | "}" | FormatInvalid.cs:89:27:89:29 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:89:9:89:33 | call to method WriteLine | this | -| FormatInvalid.cs:90:28:90:29 | "}" | FormatInvalid.cs:90:27:90:29 | "}" | FormatInvalid.cs:90:27:90:29 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:90:9:90:34 | call to method WriteLine | this | -| FormatInvalid.cs:91:28:91:29 | "}" | FormatInvalid.cs:91:27:91:29 | "}" | FormatInvalid.cs:91:27:91:29 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:91:9:91:36 | call to method WriteLine | this | -| FormatInvalid.cs:92:28:92:29 | "}" | FormatInvalid.cs:92:27:92:29 | "}" | FormatInvalid.cs:92:27:92:29 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:92:9:92:39 | call to method WriteLine | this | -| FormatInvalid.cs:93:28:93:29 | "}" | FormatInvalid.cs:93:27:93:29 | "}" | FormatInvalid.cs:93:27:93:29 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:93:9:93:42 | call to method WriteLine | this | -| FormatInvalid.cs:95:23:95:24 | "}" | FormatInvalid.cs:95:22:95:24 | "}" | FormatInvalid.cs:95:22:95:24 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:95:9:95:28 | call to method WriteLine | this | -| FormatInvalid.cs:96:23:96:24 | "}" | FormatInvalid.cs:96:22:96:24 | "}" | FormatInvalid.cs:96:22:96:24 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:96:9:96:29 | call to method WriteLine | this | -| FormatInvalid.cs:97:23:97:24 | "}" | FormatInvalid.cs:97:22:97:24 | "}" | FormatInvalid.cs:97:22:97:24 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:97:9:97:31 | call to method WriteLine | this | -| FormatInvalid.cs:98:23:98:24 | "}" | FormatInvalid.cs:98:22:98:24 | "}" | FormatInvalid.cs:98:22:98:24 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:98:9:98:34 | call to method WriteLine | this | -| FormatInvalid.cs:99:23:99:24 | "}" | FormatInvalid.cs:99:22:99:24 | "}" | FormatInvalid.cs:99:22:99:24 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:99:9:99:37 | call to method WriteLine | this | -| FormatInvalid.cs:101:45:101:46 | "}" | FormatInvalid.cs:101:44:101:46 | "}" | FormatInvalid.cs:101:44:101:46 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:101:9:101:51 | call to method WriteLine | this | -| FormatInvalid.cs:102:46:102:47 | "}" | FormatInvalid.cs:102:45:102:47 | "}" | FormatInvalid.cs:102:45:102:47 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:102:9:102:51 | call to method TraceError | this | -| FormatInvalid.cs:103:52:103:53 | "}" | FormatInvalid.cs:103:51:103:53 | "}" | FormatInvalid.cs:103:51:103:53 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:103:9:103:57 | call to method TraceInformation | this | -| FormatInvalid.cs:104:48:104:49 | "}" | FormatInvalid.cs:104:47:104:49 | "}" | FormatInvalid.cs:104:47:104:49 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:104:9:104:53 | call to method TraceWarning | this | -| FormatInvalid.cs:105:30:105:31 | "}" | FormatInvalid.cs:105:29:105:31 | "}" | FormatInvalid.cs:105:29:105:31 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:105:9:105:35 | call to method TraceInformation | this | -| FormatInvalid.cs:107:24:107:25 | "}" | FormatInvalid.cs:107:23:107:25 | "}" | FormatInvalid.cs:107:23:107:25 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:107:9:107:29 | call to method Write | this | -| FormatInvalid.cs:108:24:108:25 | "}" | FormatInvalid.cs:108:23:108:25 | "}" | FormatInvalid.cs:108:23:108:25 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:108:9:108:32 | call to method Write | this | -| FormatInvalid.cs:109:24:109:25 | "}" | FormatInvalid.cs:109:23:109:25 | "}" | FormatInvalid.cs:109:23:109:25 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:109:9:109:35 | call to method Write | this | -| FormatInvalid.cs:110:24:110:25 | "}" | FormatInvalid.cs:110:23:110:25 | "}" | FormatInvalid.cs:110:23:110:25 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:110:9:110:38 | call to method Write | this | -| FormatInvalid.cs:115:57:115:58 | "}" | FormatInvalid.cs:115:56:115:58 | [assertion success] "}" | FormatInvalid.cs:115:56:115:58 | [assertion success] "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:115:9:115:63 | call to method Assert | this | -| FormatInvalid.cs:116:19:116:20 | "}" | FormatInvalid.cs:116:18:116:20 | "}" | FormatInvalid.cs:116:18:116:20 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:116:9:116:24 | call to method Write | this | -| FormatInvalid.cs:117:41:117:42 | "}" | FormatInvalid.cs:117:40:117:42 | "}" | FormatInvalid.cs:117:40:117:42 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:117:9:117:47 | call to method Print | this | -| FormatInvalidBad.cs:7:41:7:44 | "class {0} { }" | FormatInvalidBad.cs:7:30:7:44 | "class {0} { }" | FormatInvalidBad.cs:7:30:7:44 | "class {0} { }" | Invalid format string used in $@ formatting call. | FormatInvalidBad.cs:7:16:7:45 | call to method Format | this | +| FormatInvalid.cs:27:23:27:28 | "{ 0}" | FormatInvalid.cs:27:23:27:28 | "{ 0}" | FormatInvalid.cs:27:23:27:28 | "{ 0}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:27:9:27:32 | call to method Format | this | FormatInvalid.cs:27:9:27:32 | call to method Format | this | +| FormatInvalid.cs:30:23:30:31 | "{0,--1}" | FormatInvalid.cs:30:23:30:31 | "{0,--1}" | FormatInvalid.cs:30:23:30:31 | "{0,--1}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:30:9:30:35 | call to method Format | this | FormatInvalid.cs:30:9:30:35 | call to method Format | this | +| FormatInvalid.cs:33:23:33:30 | "{0:{}}" | FormatInvalid.cs:33:23:33:30 | "{0:{}}" | FormatInvalid.cs:33:23:33:30 | "{0:{}}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:33:9:33:34 | call to method Format | this | FormatInvalid.cs:33:9:33:34 | call to method Format | this | +| FormatInvalid.cs:36:9:36:30 | call to method Format | FormatInvalid.cs:36:23:36:26 | "%d" | FormatInvalid.cs:36:23:36:26 | "%d" | The $@ ignores $@. | FormatInvalid.cs:36:23:36:26 | "%d" | format string | FormatInvalid.cs:36:29:36:29 | (...) ... | this supplied value | +| FormatInvalid.cs:39:23:39:33 | "{{0}-{1}}" | FormatInvalid.cs:39:23:39:33 | "{{0}-{1}}" | FormatInvalid.cs:39:23:39:33 | "{{0}-{1}}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:39:9:39:40 | call to method Format | this | FormatInvalid.cs:39:9:39:40 | call to method Format | this | +| FormatInvalid.cs:42:23:42:28 | "{0}}" | FormatInvalid.cs:42:23:42:28 | "{0}}" | FormatInvalid.cs:42:23:42:28 | "{0}}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:42:9:42:35 | call to method Format | this | FormatInvalid.cs:42:9:42:35 | call to method Format | this | +| FormatInvalid.cs:45:23:45:32 | "{foo{0}}" | FormatInvalid.cs:45:23:45:32 | "{foo{0}}" | FormatInvalid.cs:45:23:45:32 | "{foo{0}}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:45:9:45:36 | call to method Format | this | FormatInvalid.cs:45:9:45:36 | call to method Format | this | +| FormatInvalid.cs:48:9:48:35 | call to method Format | FormatInvalid.cs:48:23:48:31 | "{{sdc}}" | FormatInvalid.cs:48:23:48:31 | "{{sdc}}" | The $@ ignores $@. | FormatInvalid.cs:48:23:48:31 | "{{sdc}}" | format string | FormatInvalid.cs:48:34:48:34 | (...) ... | this supplied value | +| FormatInvalid.cs:51:23:51:25 | "}" | FormatInvalid.cs:51:23:51:25 | "}" | FormatInvalid.cs:51:23:51:25 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:51:9:51:29 | call to method Format | this | FormatInvalid.cs:51:9:51:29 | call to method Format | this | +| FormatInvalid.cs:54:9:54:46 | call to method Format | FormatInvalid.cs:54:23:54:42 | "new {0} ({1} => {{" | FormatInvalid.cs:54:23:54:42 | "new {0} ({1} => {{" | Argument '{1}' has not been supplied to $@ format string. | FormatInvalid.cs:54:23:54:42 | "new {0} ({1} => {{" | this | FormatInvalid.cs:54:23:54:42 | "new {0} ({1} => {{" | this | +| FormatInvalid.cs:57:9:57:31 | call to method Format | FormatInvalid.cs:57:23:57:26 | "{{" | FormatInvalid.cs:57:23:57:26 | "{{" | The $@ ignores $@. | FormatInvalid.cs:57:23:57:26 | "{{" | format string | FormatInvalid.cs:57:29:57:30 | "" | this supplied value | +| FormatInvalid.cs:58:9:58:35 | call to method Format | FormatInvalid.cs:58:23:58:30 | "{{{{}}" | FormatInvalid.cs:58:23:58:30 | "{{{{}}" | The $@ ignores $@. | FormatInvalid.cs:58:23:58:30 | "{{{{}}" | format string | FormatInvalid.cs:58:33:58:34 | "" | this supplied value | +| FormatInvalid.cs:75:23:75:25 | "}" | FormatInvalid.cs:75:23:75:25 | "}" | FormatInvalid.cs:75:23:75:25 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:75:9:75:29 | call to method Format | this | FormatInvalid.cs:75:9:75:29 | call to method Format | this | +| FormatInvalid.cs:76:23:76:25 | "}" | FormatInvalid.cs:76:23:76:25 | "}" | FormatInvalid.cs:76:23:76:25 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:76:9:76:30 | call to method Format | this | FormatInvalid.cs:76:9:76:30 | call to method Format | this | +| FormatInvalid.cs:77:27:77:29 | "}" | FormatInvalid.cs:77:27:77:29 | "}" | FormatInvalid.cs:77:27:77:29 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:77:9:77:34 | call to method Format | this | FormatInvalid.cs:77:9:77:34 | call to method Format | this | +| FormatInvalid.cs:78:23:78:25 | "}" | FormatInvalid.cs:78:23:78:25 | "}" | FormatInvalid.cs:78:23:78:25 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:78:9:78:32 | call to method Format | this | FormatInvalid.cs:78:9:78:32 | call to method Format | this | +| FormatInvalid.cs:79:23:79:25 | "}" | FormatInvalid.cs:79:23:79:25 | "}" | FormatInvalid.cs:79:23:79:25 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:79:9:79:35 | call to method Format | this | FormatInvalid.cs:79:9:79:35 | call to method Format | this | +| FormatInvalid.cs:80:23:80:25 | "}" | FormatInvalid.cs:80:23:80:25 | "}" | FormatInvalid.cs:80:23:80:25 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:80:9:80:38 | call to method Format | this | FormatInvalid.cs:80:9:80:38 | call to method Format | this | +| FormatInvalid.cs:82:25:82:27 | "}" | FormatInvalid.cs:82:25:82:27 | "}" | FormatInvalid.cs:82:25:82:27 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:82:9:82:31 | call to method AppendFormat | this | FormatInvalid.cs:82:9:82:31 | call to method AppendFormat | this | +| FormatInvalid.cs:83:25:83:27 | "}" | FormatInvalid.cs:83:25:83:27 | "}" | FormatInvalid.cs:83:25:83:27 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:83:9:83:32 | call to method AppendFormat | this | FormatInvalid.cs:83:9:83:32 | call to method AppendFormat | this | +| FormatInvalid.cs:84:29:84:31 | "}" | FormatInvalid.cs:84:29:84:31 | "}" | FormatInvalid.cs:84:29:84:31 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:84:9:84:36 | call to method AppendFormat | this | FormatInvalid.cs:84:9:84:36 | call to method AppendFormat | this | +| FormatInvalid.cs:85:25:85:27 | "}" | FormatInvalid.cs:85:25:85:27 | "}" | FormatInvalid.cs:85:25:85:27 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:85:9:85:34 | call to method AppendFormat | this | FormatInvalid.cs:85:9:85:34 | call to method AppendFormat | this | +| FormatInvalid.cs:86:25:86:27 | "}" | FormatInvalid.cs:86:25:86:27 | "}" | FormatInvalid.cs:86:25:86:27 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:86:9:86:37 | call to method AppendFormat | this | FormatInvalid.cs:86:9:86:37 | call to method AppendFormat | this | +| FormatInvalid.cs:87:25:87:27 | "}" | FormatInvalid.cs:87:25:87:27 | "}" | FormatInvalid.cs:87:25:87:27 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:87:9:87:40 | call to method AppendFormat | this | FormatInvalid.cs:87:9:87:40 | call to method AppendFormat | this | +| FormatInvalid.cs:89:27:89:29 | "}" | FormatInvalid.cs:89:27:89:29 | "}" | FormatInvalid.cs:89:27:89:29 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:89:9:89:33 | call to method WriteLine | this | FormatInvalid.cs:89:9:89:33 | call to method WriteLine | this | +| FormatInvalid.cs:90:27:90:29 | "}" | FormatInvalid.cs:90:27:90:29 | "}" | FormatInvalid.cs:90:27:90:29 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:90:9:90:34 | call to method WriteLine | this | FormatInvalid.cs:90:9:90:34 | call to method WriteLine | this | +| FormatInvalid.cs:91:27:91:29 | "}" | FormatInvalid.cs:91:27:91:29 | "}" | FormatInvalid.cs:91:27:91:29 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:91:9:91:36 | call to method WriteLine | this | FormatInvalid.cs:91:9:91:36 | call to method WriteLine | this | +| FormatInvalid.cs:92:27:92:29 | "}" | FormatInvalid.cs:92:27:92:29 | "}" | FormatInvalid.cs:92:27:92:29 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:92:9:92:39 | call to method WriteLine | this | FormatInvalid.cs:92:9:92:39 | call to method WriteLine | this | +| FormatInvalid.cs:93:27:93:29 | "}" | FormatInvalid.cs:93:27:93:29 | "}" | FormatInvalid.cs:93:27:93:29 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:93:9:93:42 | call to method WriteLine | this | FormatInvalid.cs:93:9:93:42 | call to method WriteLine | this | +| FormatInvalid.cs:95:22:95:24 | "}" | FormatInvalid.cs:95:22:95:24 | "}" | FormatInvalid.cs:95:22:95:24 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:95:9:95:28 | call to method WriteLine | this | FormatInvalid.cs:95:9:95:28 | call to method WriteLine | this | +| FormatInvalid.cs:96:22:96:24 | "}" | FormatInvalid.cs:96:22:96:24 | "}" | FormatInvalid.cs:96:22:96:24 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:96:9:96:29 | call to method WriteLine | this | FormatInvalid.cs:96:9:96:29 | call to method WriteLine | this | +| FormatInvalid.cs:97:22:97:24 | "}" | FormatInvalid.cs:97:22:97:24 | "}" | FormatInvalid.cs:97:22:97:24 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:97:9:97:31 | call to method WriteLine | this | FormatInvalid.cs:97:9:97:31 | call to method WriteLine | this | +| FormatInvalid.cs:98:22:98:24 | "}" | FormatInvalid.cs:98:22:98:24 | "}" | FormatInvalid.cs:98:22:98:24 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:98:9:98:34 | call to method WriteLine | this | FormatInvalid.cs:98:9:98:34 | call to method WriteLine | this | +| FormatInvalid.cs:99:22:99:24 | "}" | FormatInvalid.cs:99:22:99:24 | "}" | FormatInvalid.cs:99:22:99:24 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:99:9:99:37 | call to method WriteLine | this | FormatInvalid.cs:99:9:99:37 | call to method WriteLine | this | +| FormatInvalid.cs:101:44:101:46 | "}" | FormatInvalid.cs:101:44:101:46 | "}" | FormatInvalid.cs:101:44:101:46 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:101:9:101:51 | call to method WriteLine | this | FormatInvalid.cs:101:9:101:51 | call to method WriteLine | this | +| FormatInvalid.cs:102:45:102:47 | "}" | FormatInvalid.cs:102:45:102:47 | "}" | FormatInvalid.cs:102:45:102:47 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:102:9:102:51 | call to method TraceError | this | FormatInvalid.cs:102:9:102:51 | call to method TraceError | this | +| FormatInvalid.cs:103:51:103:53 | "}" | FormatInvalid.cs:103:51:103:53 | "}" | FormatInvalid.cs:103:51:103:53 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:103:9:103:57 | call to method TraceInformation | this | FormatInvalid.cs:103:9:103:57 | call to method TraceInformation | this | +| FormatInvalid.cs:104:47:104:49 | "}" | FormatInvalid.cs:104:47:104:49 | "}" | FormatInvalid.cs:104:47:104:49 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:104:9:104:53 | call to method TraceWarning | this | FormatInvalid.cs:104:9:104:53 | call to method TraceWarning | this | +| FormatInvalid.cs:105:29:105:31 | "}" | FormatInvalid.cs:105:29:105:31 | "}" | FormatInvalid.cs:105:29:105:31 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:105:9:105:35 | call to method TraceInformation | this | FormatInvalid.cs:105:9:105:35 | call to method TraceInformation | this | +| FormatInvalid.cs:107:23:107:25 | "}" | FormatInvalid.cs:107:23:107:25 | "}" | FormatInvalid.cs:107:23:107:25 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:107:9:107:29 | call to method Write | this | FormatInvalid.cs:107:9:107:29 | call to method Write | this | +| FormatInvalid.cs:108:23:108:25 | "}" | FormatInvalid.cs:108:23:108:25 | "}" | FormatInvalid.cs:108:23:108:25 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:108:9:108:32 | call to method Write | this | FormatInvalid.cs:108:9:108:32 | call to method Write | this | +| FormatInvalid.cs:109:23:109:25 | "}" | FormatInvalid.cs:109:23:109:25 | "}" | FormatInvalid.cs:109:23:109:25 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:109:9:109:35 | call to method Write | this | FormatInvalid.cs:109:9:109:35 | call to method Write | this | +| FormatInvalid.cs:110:23:110:25 | "}" | FormatInvalid.cs:110:23:110:25 | "}" | FormatInvalid.cs:110:23:110:25 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:110:9:110:38 | call to method Write | this | FormatInvalid.cs:110:9:110:38 | call to method Write | this | +| FormatInvalid.cs:115:56:115:58 | "}" | FormatInvalid.cs:115:56:115:58 | [assertion success] "}" | FormatInvalid.cs:115:56:115:58 | [assertion success] "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:115:9:115:63 | call to method Assert | this | FormatInvalid.cs:115:9:115:63 | call to method Assert | this | +| FormatInvalid.cs:116:18:116:20 | "}" | FormatInvalid.cs:116:18:116:20 | "}" | FormatInvalid.cs:116:18:116:20 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:116:9:116:24 | call to method Write | this | FormatInvalid.cs:116:9:116:24 | call to method Write | this | +| FormatInvalid.cs:117:40:117:42 | "}" | FormatInvalid.cs:117:40:117:42 | "}" | FormatInvalid.cs:117:40:117:42 | "}" | Invalid format string used in $@ formatting call. | FormatInvalid.cs:117:9:117:47 | call to method Print | this | FormatInvalid.cs:117:9:117:47 | call to method Print | this | +| FormatInvalidBad.cs:7:30:7:44 | "class {0} { }" | FormatInvalidBad.cs:7:30:7:44 | "class {0} { }" | FormatInvalidBad.cs:7:30:7:44 | "class {0} { }" | Invalid format string used in $@ formatting call. | FormatInvalidBad.cs:7:16:7:50 | call to method Format | this | FormatInvalidBad.cs:7:16:7:50 | call to method Format | this | +| FormatMissingArgument.cs:11:9:11:31 | call to method Format | FormatMissingArgument.cs:11:23:11:27 | "{1}" | FormatMissingArgument.cs:11:23:11:27 | "{1}" | Argument '{1}' has not been supplied to $@ format string. | FormatMissingArgument.cs:11:23:11:27 | "{1}" | this | FormatMissingArgument.cs:11:23:11:27 | "{1}" | this | +| FormatMissingArgument.cs:11:9:11:31 | call to method Format | FormatMissingArgument.cs:11:23:11:27 | "{1}" | FormatMissingArgument.cs:11:23:11:27 | "{1}" | The $@ ignores $@. | FormatMissingArgument.cs:11:23:11:27 | "{1}" | format string | FormatMissingArgument.cs:11:30:11:30 | (...) ... | this supplied value | +| FormatMissingArgument.cs:14:9:14:38 | call to method Format | FormatMissingArgument.cs:14:23:14:31 | "{2} {3}" | FormatMissingArgument.cs:14:23:14:31 | "{2} {3}" | Argument '{2}' has not been supplied to $@ format string. | FormatMissingArgument.cs:14:23:14:31 | "{2} {3}" | this | FormatMissingArgument.cs:14:23:14:31 | "{2} {3}" | this | +| FormatMissingArgument.cs:14:9:14:38 | call to method Format | FormatMissingArgument.cs:14:23:14:31 | "{2} {3}" | FormatMissingArgument.cs:14:23:14:31 | "{2} {3}" | Argument '{3}' has not been supplied to $@ format string. | FormatMissingArgument.cs:14:23:14:31 | "{2} {3}" | this | FormatMissingArgument.cs:14:23:14:31 | "{2} {3}" | this | +| FormatMissingArgument.cs:14:9:14:38 | call to method Format | FormatMissingArgument.cs:14:23:14:31 | "{2} {3}" | FormatMissingArgument.cs:14:23:14:31 | "{2} {3}" | The $@ ignores $@. | FormatMissingArgument.cs:14:23:14:31 | "{2} {3}" | format string | FormatMissingArgument.cs:14:34:14:34 | (...) ... | this supplied value | +| FormatMissingArgument.cs:14:9:14:38 | call to method Format | FormatMissingArgument.cs:14:23:14:31 | "{2} {3}" | FormatMissingArgument.cs:14:23:14:31 | "{2} {3}" | The $@ ignores $@. | FormatMissingArgument.cs:14:23:14:31 | "{2} {3}" | format string | FormatMissingArgument.cs:14:37:14:37 | (...) ... | this supplied value | +| FormatMissingArgument.cs:25:9:25:32 | call to method WriteLine | FormatMissingArgument.cs:25:27:25:31 | "{0}" | FormatMissingArgument.cs:25:27:25:31 | "{0}" | Argument '{0}' has not been supplied to $@ format string. | FormatMissingArgument.cs:25:27:25:31 | "{0}" | this | FormatMissingArgument.cs:25:27:25:31 | "{0}" | this | +| FormatMissingArgument.cs:31:9:31:32 | call to method Format | FormatMissingArgument.cs:22:16:22:20 | "{1}" : String | FormatMissingArgument.cs:31:23:31:28 | access to parameter format | Argument '{1}' has not been supplied to $@ format string. | FormatMissingArgument.cs:22:16:22:20 | "{1}" | this | FormatMissingArgument.cs:22:16:22:20 | "{1}" | this | +| FormatMissingArgument.cs:31:9:31:32 | call to method Format | FormatMissingArgument.cs:22:16:22:20 | "{1}" : String | FormatMissingArgument.cs:31:23:31:28 | access to parameter format | The $@ ignores $@. | FormatMissingArgument.cs:22:16:22:20 | "{1}" | format string | FormatMissingArgument.cs:31:31:31:31 | (...) ... | this supplied value | +| FormatMissingArgumentBad.cs:7:9:7:49 | call to method WriteLine | FormatMissingArgumentBad.cs:7:27:7:41 | "Hello {0} {1}" | FormatMissingArgumentBad.cs:7:27:7:41 | "Hello {0} {1}" | Argument '{1}' has not been supplied to $@ format string. | FormatMissingArgumentBad.cs:7:27:7:41 | "Hello {0} {1}" | this | FormatMissingArgumentBad.cs:7:27:7:41 | "Hello {0} {1}" | this | +| FormatMissingArgumentBad.cs:8:9:8:55 | call to method WriteLine | FormatMissingArgumentBad.cs:8:27:8:41 | "Hello {1} {2}" | FormatMissingArgumentBad.cs:8:27:8:41 | "Hello {1} {2}" | Argument '{2}' has not been supplied to $@ format string. | FormatMissingArgumentBad.cs:8:27:8:41 | "Hello {1} {2}" | this | FormatMissingArgumentBad.cs:8:27:8:41 | "Hello {1} {2}" | this | +| FormatMissingArgumentBad.cs:8:9:8:55 | call to method WriteLine | FormatMissingArgumentBad.cs:8:27:8:41 | "Hello {1} {2}" | FormatMissingArgumentBad.cs:8:27:8:41 | "Hello {1} {2}" | The $@ ignores $@. | FormatMissingArgumentBad.cs:8:27:8:41 | "Hello {1} {2}" | format string | FormatMissingArgumentBad.cs:8:44:8:48 | access to parameter first | this supplied value | +| FormatUnusedArgument.cs:11:9:11:29 | call to method Format | FormatUnusedArgument.cs:11:23:11:25 | "X" | FormatUnusedArgument.cs:11:23:11:25 | "X" | The $@ ignores $@. | FormatUnusedArgument.cs:11:23:11:25 | "X" | format string | FormatUnusedArgument.cs:11:28:11:28 | (...) ... | this supplied value | +| FormatUnusedArgument.cs:14:9:14:34 | call to method Format | FormatUnusedArgument.cs:14:23:14:27 | "{0}" | FormatUnusedArgument.cs:14:23:14:27 | "{0}" | The $@ ignores $@. | FormatUnusedArgument.cs:14:23:14:27 | "{0}" | format string | FormatUnusedArgument.cs:14:33:14:33 | (...) ... | this supplied value | +| FormatUnusedArgument.cs:17:9:17:38 | call to method Format | FormatUnusedArgument.cs:17:23:17:31 | "{0} {0}" | FormatUnusedArgument.cs:17:23:17:31 | "{0} {0}" | The $@ ignores $@. | FormatUnusedArgument.cs:17:23:17:31 | "{0} {0}" | format string | FormatUnusedArgument.cs:17:37:17:37 | (...) ... | this supplied value | +| FormatUnusedArgument.cs:20:9:20:38 | call to method Format | FormatUnusedArgument.cs:20:23:20:31 | "{1} {1}" | FormatUnusedArgument.cs:20:23:20:31 | "{1} {1}" | The $@ ignores $@. | FormatUnusedArgument.cs:20:23:20:31 | "{1} {1}" | format string | FormatUnusedArgument.cs:20:34:20:34 | (...) ... | this supplied value | +| FormatUnusedArgument.cs:23:9:23:41 | call to method Format | FormatUnusedArgument.cs:23:23:23:31 | "abcdefg" | FormatUnusedArgument.cs:23:23:23:31 | "abcdefg" | The $@ ignores $@. | FormatUnusedArgument.cs:23:23:23:31 | "abcdefg" | format string | FormatUnusedArgument.cs:23:34:23:34 | (...) ... | this supplied value | +| FormatUnusedArgument.cs:23:9:23:41 | call to method Format | FormatUnusedArgument.cs:23:23:23:31 | "abcdefg" | FormatUnusedArgument.cs:23:23:23:31 | "abcdefg" | The $@ ignores $@. | FormatUnusedArgument.cs:23:23:23:31 | "abcdefg" | format string | FormatUnusedArgument.cs:23:37:23:37 | (...) ... | this supplied value | +| FormatUnusedArgument.cs:23:9:23:41 | call to method Format | FormatUnusedArgument.cs:23:23:23:31 | "abcdefg" | FormatUnusedArgument.cs:23:23:23:31 | "abcdefg" | The $@ ignores $@. | FormatUnusedArgument.cs:23:23:23:31 | "abcdefg" | format string | FormatUnusedArgument.cs:23:40:23:40 | (...) ... | this supplied value | +| FormatUnusedArgument.cs:26:9:26:35 | call to method Format | FormatUnusedArgument.cs:26:23:26:31 | "{{sdc}}" | FormatUnusedArgument.cs:26:23:26:31 | "{{sdc}}" | The $@ ignores $@. | FormatUnusedArgument.cs:26:23:26:31 | "{{sdc}}" | format string | FormatUnusedArgument.cs:26:34:26:34 | (...) ... | this supplied value | +| FormatUnusedArgument.cs:38:9:38:33 | call to method Format | FormatUnusedArgument.cs:38:23:38:29 | "{{0}}" | FormatUnusedArgument.cs:38:23:38:29 | "{{0}}" | The $@ ignores $@. | FormatUnusedArgument.cs:38:23:38:29 | "{{0}}" | format string | FormatUnusedArgument.cs:38:32:38:32 | (...) ... | this supplied value | +| FormatUnusedArgumentBad.cs:7:9:7:71 | call to method WriteLine | FormatUnusedArgumentBad.cs:7:27:7:54 | "Error processing file: {0}" | FormatUnusedArgumentBad.cs:7:27:7:54 | "Error processing file: {0}" | The $@ ignores $@. | FormatUnusedArgumentBad.cs:7:27:7:54 | "Error processing file: {0}" | format string | FormatUnusedArgumentBad.cs:7:61:7:70 | (...) ... | this supplied value | +| FormatUnusedArgumentBad.cs:8:9:8:77 | call to method WriteLine | FormatUnusedArgumentBad.cs:8:27:8:60 | "Error processing file: {1} ({1})" | FormatUnusedArgumentBad.cs:8:27:8:60 | "Error processing file: {1} ({1})" | The $@ ignores $@. | FormatUnusedArgumentBad.cs:8:27:8:60 | "Error processing file: {1} ({1})" | format string | FormatUnusedArgumentBad.cs:8:63:8:64 | access to parameter ex | this supplied value | +| FormatUnusedArgumentBad.cs:9:9:9:75 | call to method WriteLine | FormatUnusedArgumentBad.cs:9:27:9:58 | "Error processing file: %s (%d)" | FormatUnusedArgumentBad.cs:9:27:9:58 | "Error processing file: %s (%d)" | The $@ ignores $@. | FormatUnusedArgumentBad.cs:9:27:9:58 | "Error processing file: %s (%d)" | format string | FormatUnusedArgumentBad.cs:9:61:9:62 | access to parameter ex | this supplied value | +| FormatUnusedArgumentBad.cs:9:9:9:75 | call to method WriteLine | FormatUnusedArgumentBad.cs:9:27:9:58 | "Error processing file: %s (%d)" | FormatUnusedArgumentBad.cs:9:27:9:58 | "Error processing file: %s (%d)" | The $@ ignores $@. | FormatUnusedArgumentBad.cs:9:27:9:58 | "Error processing file: %s (%d)" | format string | FormatUnusedArgumentBad.cs:9:65:9:74 | (...) ... | this supplied value | diff --git a/csharp/ql/test/query-tests/API Abuse/FormatInvalid/FormatInvalidBad.cs b/csharp/ql/test/query-tests/API Abuse/FormatInvalid/FormatInvalidBad.cs index 7f7faad5bdc..ec3df72655d 100644 --- a/csharp/ql/test/query-tests/API Abuse/FormatInvalid/FormatInvalidBad.cs +++ b/csharp/ql/test/query-tests/API Abuse/FormatInvalid/FormatInvalidBad.cs @@ -1,9 +1,9 @@ using System; -class Bad +class Bad1 { string GenerateEmptyClass(string c) { - return string.Format("class {0} { }"); + return string.Format("class {0} { }", "C"); } } diff --git a/csharp/ql/test/query-tests/API Abuse/FormatInvalid/FormatInvalidGood.cs b/csharp/ql/test/query-tests/API Abuse/FormatInvalid/FormatInvalidGood.cs index 2060501541d..efc62a07391 100644 --- a/csharp/ql/test/query-tests/API Abuse/FormatInvalid/FormatInvalidGood.cs +++ b/csharp/ql/test/query-tests/API Abuse/FormatInvalid/FormatInvalidGood.cs @@ -1,9 +1,9 @@ using System; -class Good +class Good1 { string GenerateEmptyClass(string c) { - return string.Format("class {0} {{ }}"); + return string.Format("class {0} {{ }}", "C"); } } diff --git a/csharp/ql/test/query-tests/API Abuse/FormatMissingArgument/FormatMissingArgument.cs b/csharp/ql/test/query-tests/API Abuse/FormatInvalid/FormatMissingArgument.cs similarity index 90% rename from csharp/ql/test/query-tests/API Abuse/FormatMissingArgument/FormatMissingArgument.cs rename to csharp/ql/test/query-tests/API Abuse/FormatInvalid/FormatMissingArgument.cs index 97d2d707726..94201c0ddf8 100644 --- a/csharp/ql/test/query-tests/API Abuse/FormatMissingArgument/FormatMissingArgument.cs +++ b/csharp/ql/test/query-tests/API Abuse/FormatInvalid/FormatMissingArgument.cs @@ -20,6 +20,9 @@ class Class1 String.Format("{0} {1} {2} {3}", 0, 1, 2, 3); helper("{1}"); + + // BAD: Missing {0} + Console.WriteLine("{0}"); } void helper(string format) diff --git a/csharp/ql/test/query-tests/API Abuse/FormatMissingArgument/FormatMissingArgumentBad.cs b/csharp/ql/test/query-tests/API Abuse/FormatInvalid/FormatMissingArgumentBad.cs similarity index 94% rename from csharp/ql/test/query-tests/API Abuse/FormatMissingArgument/FormatMissingArgumentBad.cs rename to csharp/ql/test/query-tests/API Abuse/FormatInvalid/FormatMissingArgumentBad.cs index 0fc5b21f1ae..a66eea4cf32 100644 --- a/csharp/ql/test/query-tests/API Abuse/FormatMissingArgument/FormatMissingArgumentBad.cs +++ b/csharp/ql/test/query-tests/API Abuse/FormatInvalid/FormatMissingArgumentBad.cs @@ -1,6 +1,6 @@ using System; -class Bad +class Bad3 { void Hello(string first, string last) { diff --git a/csharp/ql/test/query-tests/API Abuse/FormatMissingArgument/FormatMissingArgumentGood.cs b/csharp/ql/test/query-tests/API Abuse/FormatInvalid/FormatMissingArgumentGood.cs similarity index 91% rename from csharp/ql/test/query-tests/API Abuse/FormatMissingArgument/FormatMissingArgumentGood.cs rename to csharp/ql/test/query-tests/API Abuse/FormatInvalid/FormatMissingArgumentGood.cs index 36fbe2de8a7..817da4d8336 100644 --- a/csharp/ql/test/query-tests/API Abuse/FormatMissingArgument/FormatMissingArgumentGood.cs +++ b/csharp/ql/test/query-tests/API Abuse/FormatInvalid/FormatMissingArgumentGood.cs @@ -1,6 +1,6 @@ using System; -class Good +class Good3 { void Hello(string first, string last) { diff --git a/csharp/ql/test/query-tests/API Abuse/FormatUnusedArgument/FormatUnusedArgument.cs b/csharp/ql/test/query-tests/API Abuse/FormatInvalid/FormatUnusedArgument.cs similarity index 100% rename from csharp/ql/test/query-tests/API Abuse/FormatUnusedArgument/FormatUnusedArgument.cs rename to csharp/ql/test/query-tests/API Abuse/FormatInvalid/FormatUnusedArgument.cs diff --git a/csharp/ql/test/query-tests/API Abuse/FormatUnusedArgument/FormatUnusedArgumentBad.cs b/csharp/ql/test/query-tests/API Abuse/FormatInvalid/FormatUnusedArgumentBad.cs similarity index 96% rename from csharp/ql/test/query-tests/API Abuse/FormatUnusedArgument/FormatUnusedArgumentBad.cs rename to csharp/ql/test/query-tests/API Abuse/FormatInvalid/FormatUnusedArgumentBad.cs index 838c1f27944..25bce1a742e 100644 --- a/csharp/ql/test/query-tests/API Abuse/FormatUnusedArgument/FormatUnusedArgumentBad.cs +++ b/csharp/ql/test/query-tests/API Abuse/FormatInvalid/FormatUnusedArgumentBad.cs @@ -1,6 +1,6 @@ using System; -class Bad +class Bad2 { void M(Exception ex) { diff --git a/csharp/ql/test/query-tests/API Abuse/FormatMissingArgument/FormatMissingArgument.expected b/csharp/ql/test/query-tests/API Abuse/FormatMissingArgument/FormatMissingArgument.expected deleted file mode 100644 index ceb279a17b2..00000000000 --- a/csharp/ql/test/query-tests/API Abuse/FormatMissingArgument/FormatMissingArgument.expected +++ /dev/null @@ -1,22 +0,0 @@ -nodes -| FormatMissingArgument.cs:8:23:8:27 | "{0}" | semmle.label | "{0}" | -| FormatMissingArgument.cs:11:23:11:27 | "{1}" | semmle.label | "{1}" | -| FormatMissingArgument.cs:14:23:14:31 | "{2} {3}" | semmle.label | "{2} {3}" | -| FormatMissingArgument.cs:17:23:17:35 | "{0} {1} {2}" | semmle.label | "{0} {1} {2}" | -| FormatMissingArgument.cs:20:23:20:39 | "{0} {1} {2} {3}" | semmle.label | "{0} {1} {2} {3}" | -| FormatMissingArgument.cs:22:16:22:20 | "{1}" : String | semmle.label | "{1}" : String | -| FormatMissingArgument.cs:25:24:25:29 | format : String | semmle.label | format : String | -| FormatMissingArgument.cs:28:23:28:28 | access to parameter format | semmle.label | access to parameter format | -| FormatMissingArgumentBad.cs:7:27:7:41 | "Hello {0} {1}" | semmle.label | "Hello {0} {1}" | -| FormatMissingArgumentBad.cs:8:27:8:41 | "Hello {1} {2}" | semmle.label | "Hello {1} {2}" | -| FormatMissingArgumentGood.cs:7:27:7:41 | "Hello {0} {1}" | semmle.label | "Hello {0} {1}" | -edges -| FormatMissingArgument.cs:22:16:22:20 | "{1}" : String | FormatMissingArgument.cs:25:24:25:29 | format : String | -| FormatMissingArgument.cs:25:24:25:29 | format : String | FormatMissingArgument.cs:28:23:28:28 | access to parameter format | -#select -| FormatMissingArgument.cs:11:9:11:31 | call to method Format | FormatMissingArgument.cs:11:23:11:27 | "{1}" | FormatMissingArgument.cs:11:23:11:27 | "{1}" | Argument '{1}' has not been supplied to $@ format string. | FormatMissingArgument.cs:11:23:11:27 | "{1}" | this | -| FormatMissingArgument.cs:14:9:14:38 | call to method Format | FormatMissingArgument.cs:14:23:14:31 | "{2} {3}" | FormatMissingArgument.cs:14:23:14:31 | "{2} {3}" | Argument '{2}' has not been supplied to $@ format string. | FormatMissingArgument.cs:14:23:14:31 | "{2} {3}" | this | -| FormatMissingArgument.cs:14:9:14:38 | call to method Format | FormatMissingArgument.cs:14:23:14:31 | "{2} {3}" | FormatMissingArgument.cs:14:23:14:31 | "{2} {3}" | Argument '{3}' has not been supplied to $@ format string. | FormatMissingArgument.cs:14:23:14:31 | "{2} {3}" | this | -| FormatMissingArgument.cs:28:9:28:32 | call to method Format | FormatMissingArgument.cs:22:16:22:20 | "{1}" : String | FormatMissingArgument.cs:28:23:28:28 | access to parameter format | Argument '{1}' has not been supplied to $@ format string. | FormatMissingArgument.cs:22:16:22:20 | "{1}" | this | -| FormatMissingArgumentBad.cs:7:9:7:49 | call to method WriteLine | FormatMissingArgumentBad.cs:7:27:7:41 | "Hello {0} {1}" | FormatMissingArgumentBad.cs:7:27:7:41 | "Hello {0} {1}" | Argument '{1}' has not been supplied to $@ format string. | FormatMissingArgumentBad.cs:7:27:7:41 | "Hello {0} {1}" | this | -| FormatMissingArgumentBad.cs:8:9:8:55 | call to method WriteLine | FormatMissingArgumentBad.cs:8:27:8:41 | "Hello {1} {2}" | FormatMissingArgumentBad.cs:8:27:8:41 | "Hello {1} {2}" | Argument '{2}' has not been supplied to $@ format string. | FormatMissingArgumentBad.cs:8:27:8:41 | "Hello {1} {2}" | this | diff --git a/csharp/ql/test/query-tests/API Abuse/FormatMissingArgument/FormatMissingArgument.qlref b/csharp/ql/test/query-tests/API Abuse/FormatMissingArgument/FormatMissingArgument.qlref deleted file mode 100644 index 9176440f3c2..00000000000 --- a/csharp/ql/test/query-tests/API Abuse/FormatMissingArgument/FormatMissingArgument.qlref +++ /dev/null @@ -1 +0,0 @@ -API Abuse/FormatMissingArgument.ql \ No newline at end of file diff --git a/csharp/ql/test/query-tests/API Abuse/FormatUnusedArgument/FormatUnusedArgument.expected b/csharp/ql/test/query-tests/API Abuse/FormatUnusedArgument/FormatUnusedArgument.expected deleted file mode 100644 index db2726ea591..00000000000 --- a/csharp/ql/test/query-tests/API Abuse/FormatUnusedArgument/FormatUnusedArgument.expected +++ /dev/null @@ -1,31 +0,0 @@ -nodes -| FormatUnusedArgument.cs:8:23:8:35 | "{0} {1} {2}" | semmle.label | "{0} {1} {2}" | -| FormatUnusedArgument.cs:11:23:11:25 | "X" | semmle.label | "X" | -| FormatUnusedArgument.cs:14:23:14:27 | "{0}" | semmle.label | "{0}" | -| FormatUnusedArgument.cs:17:23:17:31 | "{0} {0}" | semmle.label | "{0} {0}" | -| FormatUnusedArgument.cs:20:23:20:31 | "{1} {1}" | semmle.label | "{1} {1}" | -| FormatUnusedArgument.cs:23:23:23:31 | "abcdefg" | semmle.label | "abcdefg" | -| FormatUnusedArgument.cs:26:23:26:31 | "{{sdc}}" | semmle.label | "{{sdc}}" | -| FormatUnusedArgument.cs:29:23:29:33 | "{{{0:D}}}" | semmle.label | "{{{0:D}}}" | -| FormatUnusedArgument.cs:32:23:32:39 | "{0} {1} {2} {3}" | semmle.label | "{0} {1} {2} {3}" | -| FormatUnusedArgument.cs:35:23:35:35 | "{0} {1} {2}" | semmle.label | "{0} {1} {2}" | -| FormatUnusedArgument.cs:38:23:38:29 | "{{0}}" | semmle.label | "{{0}}" | -| FormatUnusedArgument.cs:42:23:42:24 | "" | semmle.label | "" | -| FormatUnusedArgumentBad.cs:7:27:7:54 | "Error processing file: {0}" | semmle.label | "Error processing file: {0}" | -| FormatUnusedArgumentBad.cs:8:27:8:60 | "Error processing file: {1} ({1})" | semmle.label | "Error processing file: {1} ({1})" | -| FormatUnusedArgumentBad.cs:9:27:9:58 | "Error processing file: %s (%d)" | semmle.label | "Error processing file: %s (%d)" | -edges -#select -| FormatUnusedArgument.cs:11:9:11:29 | call to method Format | FormatUnusedArgument.cs:11:23:11:25 | "X" | FormatUnusedArgument.cs:11:23:11:25 | "X" | The $@ ignores $@. | FormatUnusedArgument.cs:11:23:11:25 | "X" | format string | FormatUnusedArgument.cs:11:28:11:28 | (...) ... | this supplied value | -| FormatUnusedArgument.cs:14:9:14:34 | call to method Format | FormatUnusedArgument.cs:14:23:14:27 | "{0}" | FormatUnusedArgument.cs:14:23:14:27 | "{0}" | The $@ ignores $@. | FormatUnusedArgument.cs:14:23:14:27 | "{0}" | format string | FormatUnusedArgument.cs:14:33:14:33 | (...) ... | this supplied value | -| FormatUnusedArgument.cs:17:9:17:38 | call to method Format | FormatUnusedArgument.cs:17:23:17:31 | "{0} {0}" | FormatUnusedArgument.cs:17:23:17:31 | "{0} {0}" | The $@ ignores $@. | FormatUnusedArgument.cs:17:23:17:31 | "{0} {0}" | format string | FormatUnusedArgument.cs:17:37:17:37 | (...) ... | this supplied value | -| FormatUnusedArgument.cs:20:9:20:38 | call to method Format | FormatUnusedArgument.cs:20:23:20:31 | "{1} {1}" | FormatUnusedArgument.cs:20:23:20:31 | "{1} {1}" | The $@ ignores $@. | FormatUnusedArgument.cs:20:23:20:31 | "{1} {1}" | format string | FormatUnusedArgument.cs:20:34:20:34 | (...) ... | this supplied value | -| FormatUnusedArgument.cs:23:9:23:41 | call to method Format | FormatUnusedArgument.cs:23:23:23:31 | "abcdefg" | FormatUnusedArgument.cs:23:23:23:31 | "abcdefg" | The $@ ignores $@. | FormatUnusedArgument.cs:23:23:23:31 | "abcdefg" | format string | FormatUnusedArgument.cs:23:34:23:34 | (...) ... | this supplied value | -| FormatUnusedArgument.cs:23:9:23:41 | call to method Format | FormatUnusedArgument.cs:23:23:23:31 | "abcdefg" | FormatUnusedArgument.cs:23:23:23:31 | "abcdefg" | The $@ ignores $@. | FormatUnusedArgument.cs:23:23:23:31 | "abcdefg" | format string | FormatUnusedArgument.cs:23:37:23:37 | (...) ... | this supplied value | -| FormatUnusedArgument.cs:23:9:23:41 | call to method Format | FormatUnusedArgument.cs:23:23:23:31 | "abcdefg" | FormatUnusedArgument.cs:23:23:23:31 | "abcdefg" | The $@ ignores $@. | FormatUnusedArgument.cs:23:23:23:31 | "abcdefg" | format string | FormatUnusedArgument.cs:23:40:23:40 | (...) ... | this supplied value | -| FormatUnusedArgument.cs:26:9:26:35 | call to method Format | FormatUnusedArgument.cs:26:23:26:31 | "{{sdc}}" | FormatUnusedArgument.cs:26:23:26:31 | "{{sdc}}" | The $@ ignores $@. | FormatUnusedArgument.cs:26:23:26:31 | "{{sdc}}" | format string | FormatUnusedArgument.cs:26:34:26:34 | (...) ... | this supplied value | -| FormatUnusedArgument.cs:38:9:38:33 | call to method Format | FormatUnusedArgument.cs:38:23:38:29 | "{{0}}" | FormatUnusedArgument.cs:38:23:38:29 | "{{0}}" | The $@ ignores $@. | FormatUnusedArgument.cs:38:23:38:29 | "{{0}}" | format string | FormatUnusedArgument.cs:38:32:38:32 | (...) ... | this supplied value | -| FormatUnusedArgumentBad.cs:7:9:7:71 | call to method WriteLine | FormatUnusedArgumentBad.cs:7:27:7:54 | "Error processing file: {0}" | FormatUnusedArgumentBad.cs:7:27:7:54 | "Error processing file: {0}" | The $@ ignores $@. | FormatUnusedArgumentBad.cs:7:27:7:54 | "Error processing file: {0}" | format string | FormatUnusedArgumentBad.cs:7:61:7:70 | (...) ... | this supplied value | -| FormatUnusedArgumentBad.cs:8:9:8:77 | call to method WriteLine | FormatUnusedArgumentBad.cs:8:27:8:60 | "Error processing file: {1} ({1})" | FormatUnusedArgumentBad.cs:8:27:8:60 | "Error processing file: {1} ({1})" | The $@ ignores $@. | FormatUnusedArgumentBad.cs:8:27:8:60 | "Error processing file: {1} ({1})" | format string | FormatUnusedArgumentBad.cs:8:63:8:64 | access to parameter ex | this supplied value | -| FormatUnusedArgumentBad.cs:9:9:9:75 | call to method WriteLine | FormatUnusedArgumentBad.cs:9:27:9:58 | "Error processing file: %s (%d)" | FormatUnusedArgumentBad.cs:9:27:9:58 | "Error processing file: %s (%d)" | The $@ ignores $@. | FormatUnusedArgumentBad.cs:9:27:9:58 | "Error processing file: %s (%d)" | format string | FormatUnusedArgumentBad.cs:9:61:9:62 | access to parameter ex | this supplied value | -| FormatUnusedArgumentBad.cs:9:9:9:75 | call to method WriteLine | FormatUnusedArgumentBad.cs:9:27:9:58 | "Error processing file: %s (%d)" | FormatUnusedArgumentBad.cs:9:27:9:58 | "Error processing file: %s (%d)" | The $@ ignores $@. | FormatUnusedArgumentBad.cs:9:27:9:58 | "Error processing file: %s (%d)" | format string | FormatUnusedArgumentBad.cs:9:65:9:74 | (...) ... | this supplied value | diff --git a/csharp/ql/test/query-tests/API Abuse/FormatUnusedArgument/FormatUnusedArgument.qlref b/csharp/ql/test/query-tests/API Abuse/FormatUnusedArgument/FormatUnusedArgument.qlref deleted file mode 100644 index 050d9e62798..00000000000 --- a/csharp/ql/test/query-tests/API Abuse/FormatUnusedArgument/FormatUnusedArgument.qlref +++ /dev/null @@ -1 +0,0 @@ -API Abuse/FormatUnusedArgument.ql \ No newline at end of file diff --git a/csharp/ql/test/query-tests/Dead Code/DeadStoreOfLocal/DeadStoreOfLocal.cs b/csharp/ql/test/query-tests/Dead Code/DeadStoreOfLocal/DeadStoreOfLocal.cs index b787401f941..64f903f80ea 100644 --- a/csharp/ql/test/query-tests/Dead Code/DeadStoreOfLocal/DeadStoreOfLocal.cs +++ b/csharp/ql/test/query-tests/Dead Code/DeadStoreOfLocal/DeadStoreOfLocal.cs @@ -194,7 +194,7 @@ public class Captured void M2() { - var x = M6(); // BAD + var x = M6(); // BAD [FALSE NEGATIVE] Action a = () => { x = 1; // GOOD @@ -208,7 +208,7 @@ public class Captured int x; Action a = () => { - x = 1; // BAD + x = 1; // BAD [FALSE NEGATIVE] }; a(); } diff --git a/csharp/ql/test/query-tests/Dead Code/DeadStoreOfLocal/DeadStoreOfLocal.expected b/csharp/ql/test/query-tests/Dead Code/DeadStoreOfLocal/DeadStoreOfLocal.expected index 9720249c28d..9fe67ecf854 100644 --- a/csharp/ql/test/query-tests/Dead Code/DeadStoreOfLocal/DeadStoreOfLocal.expected +++ b/csharp/ql/test/query-tests/Dead Code/DeadStoreOfLocal/DeadStoreOfLocal.expected @@ -7,8 +7,6 @@ | DeadStoreOfLocal.cs:101:13:101:37 | ... = ... | This assignment to $@ is useless, since its value is never read. | DeadStoreOfLocal.cs:94:40:94:44 | extra | extra | | DeadStoreOfLocal.cs:104:13:104:37 | ... = ... | This assignment to $@ is useless, since its value is never read. | DeadStoreOfLocal.cs:94:16:94:20 | info1 | info1 | | DeadStoreOfLocal.cs:142:26:142:27 | Exception ex | This assignment to $@ is useless, since its value is never read. | DeadStoreOfLocal.cs:142:26:142:27 | ex | ex | -| DeadStoreOfLocal.cs:197:13:197:20 | Int32 x = ... | This assignment to $@ is useless, since its value is never read. | DeadStoreOfLocal.cs:197:13:197:13 | x | x | -| DeadStoreOfLocal.cs:211:13:211:17 | ... = ... | This assignment to $@ is useless, since its value is never read. | DeadStoreOfLocal.cs:208:13:208:13 | x | x | | DeadStoreOfLocal.cs:246:17:246:24 | Int32 y = ... | This assignment to $@ is useless, since its value is never read. | DeadStoreOfLocal.cs:246:17:246:17 | y | y | | DeadStoreOfLocal.cs:261:17:261:21 | Int32 x = ... | This assignment to $@ is useless, since its value is never read. | DeadStoreOfLocal.cs:261:17:261:17 | x | x | | DeadStoreOfLocal.cs:289:23:289:28 | Object v1 | This assignment to $@ is useless, since its value is never read. | DeadStoreOfLocal.cs:289:27:289:28 | v1 | v1 | diff --git a/csharp/ql/test/query-tests/Nullness/NullMaybe.expected b/csharp/ql/test/query-tests/Nullness/NullMaybe.expected index a93069cf7e4..fc6cb442cb0 100644 --- a/csharp/ql/test/query-tests/Nullness/NullMaybe.expected +++ b/csharp/ql/test/query-tests/Nullness/NullMaybe.expected @@ -191,6 +191,7 @@ nodes | D.cs:253:13:253:14 | access to local variable o2 | | D.cs:258:16:258:23 | SSA def(o) | | D.cs:266:9:267:25 | if (...) ... | +| D.cs:266:13:266:27 | [true] ... is ... | | D.cs:267:13:267:13 | access to local variable o | | D.cs:269:9:269:16 | SSA def(o) | | D.cs:272:25:272:25 | access to local variable i | @@ -345,6 +346,7 @@ nodes | E.cs:201:13:201:13 | access to local variable o | | E.cs:203:13:203:13 | access to local variable o | | E.cs:206:28:206:28 | SSA param(s) | +| E.cs:208:13:208:23 | [false] ... is ... | | E.cs:210:16:210:16 | access to parameter s | | E.cs:217:13:217:20 | [b (line 213): true] SSA def(x) | | E.cs:218:9:218:9 | access to local variable x | @@ -364,6 +366,7 @@ nodes | E.cs:301:13:301:27 | SSA def(s) | | E.cs:302:9:302:9 | access to local variable s | | E.cs:319:29:319:30 | SSA param(s1) | +| E.cs:321:13:321:30 | [true] ... is ... | | E.cs:321:14:321:21 | ... ?? ... | | E.cs:321:20:321:21 | access to parameter s2 | | E.cs:323:13:323:14 | access to parameter s1 | @@ -597,7 +600,8 @@ edges | D.cs:244:9:247:25 | if (...) ... | D.cs:247:13:247:13 | access to local variable o | | D.cs:249:13:249:38 | SSA def(o2) | D.cs:253:13:253:14 | access to local variable o2 | | D.cs:258:16:258:23 | SSA def(o) | D.cs:266:9:267:25 | if (...) ... | -| D.cs:266:9:267:25 | if (...) ... | D.cs:267:13:267:13 | access to local variable o | +| D.cs:266:9:267:25 | if (...) ... | D.cs:266:13:266:27 | [true] ... is ... | +| D.cs:266:13:266:27 | [true] ... is ... | D.cs:267:13:267:13 | access to local variable o | | D.cs:269:9:269:16 | SSA def(o) | D.cs:272:25:272:25 | access to local variable i | | D.cs:272:25:272:25 | access to local variable i | D.cs:273:9:288:9 | {...} | | D.cs:272:25:272:25 | access to local variable i | D.cs:290:9:291:25 | if (...) ... | @@ -744,7 +748,8 @@ edges | E.cs:190:29:190:29 | SSA param(o) | E.cs:192:17:192:17 | access to parameter o | | E.cs:198:13:198:29 | [b (line 196): false] SSA def(o) | E.cs:203:13:203:13 | access to local variable o | | E.cs:198:13:198:29 | [b (line 196): true] SSA def(o) | E.cs:201:13:201:13 | access to local variable o | -| E.cs:206:28:206:28 | SSA param(s) | E.cs:210:16:210:16 | access to parameter s | +| E.cs:206:28:206:28 | SSA param(s) | E.cs:208:13:208:23 | [false] ... is ... | +| E.cs:208:13:208:23 | [false] ... is ... | E.cs:210:16:210:16 | access to parameter s | | E.cs:217:13:217:20 | [b (line 213): true] SSA def(x) | E.cs:218:9:218:9 | access to local variable x | | E.cs:217:13:217:20 | [b (line 213): true] SSA def(x) | E.cs:220:13:220:13 | access to local variable x | | E.cs:227:13:227:20 | [b (line 223): true] SSA def(x) | E.cs:229:13:229:13 | access to local variable x | @@ -756,7 +761,8 @@ edges | E.cs:283:13:283:22 | [b (line 279): true] SSA def(o) | E.cs:285:9:285:9 | access to local variable o | | E.cs:301:13:301:27 | SSA def(s) | E.cs:302:9:302:9 | access to local variable s | | E.cs:319:29:319:30 | SSA param(s1) | E.cs:321:20:321:21 | access to parameter s2 | -| E.cs:321:14:321:21 | ... ?? ... | E.cs:323:13:323:14 | access to parameter s1 | +| E.cs:321:13:321:30 | [true] ... is ... | E.cs:323:13:323:14 | access to parameter s1 | +| E.cs:321:14:321:21 | ... ?? ... | E.cs:321:13:321:30 | [true] ... is ... | | E.cs:321:20:321:21 | access to parameter s2 | E.cs:321:14:321:21 | ... ?? ... | | E.cs:330:13:330:36 | SSA def(x) | E.cs:331:9:331:9 | access to local variable x | | E.cs:342:13:342:32 | SSA def(x) | E.cs:343:9:343:9 | access to local variable x | diff --git a/csharp/ql/test/query-tests/Security Features/CWE-134/UncontrolledFormatString.cs b/csharp/ql/test/query-tests/Security Features/CWE-134/UncontrolledFormatString.cs index a0408813a6a..064f91133cd 100644 --- a/csharp/ql/test/query-tests/Security Features/CWE-134/UncontrolledFormatString.cs +++ b/csharp/ql/test/query-tests/Security Features/CWE-134/UncontrolledFormatString.cs @@ -21,6 +21,9 @@ public class TaintedPathHandler : IHttpHandler // GOOD: Not the format string. String.Format((IFormatProvider)null, "Do not do this", path); + + // GOOD: Not a formatting call + Console.WriteLine(path); } System.Windows.Forms.TextBox box1; diff --git a/csharp/ql/test/query-tests/Security Features/CWE-134/UncontrolledFormatString.expected b/csharp/ql/test/query-tests/Security Features/CWE-134/UncontrolledFormatString.expected index d8ac18d9227..bc87c96b194 100644 --- a/csharp/ql/test/query-tests/Security Features/CWE-134/UncontrolledFormatString.expected +++ b/csharp/ql/test/query-tests/Security Features/CWE-134/UncontrolledFormatString.expected @@ -6,11 +6,11 @@ nodes | UncontrolledFormatString.cs:11:23:11:45 | access to property QueryString : NameValueCollection | semmle.label | access to property QueryString : NameValueCollection | | UncontrolledFormatString.cs:14:23:14:26 | access to local variable path | semmle.label | access to local variable path | | UncontrolledFormatString.cs:17:46:17:49 | access to local variable path | semmle.label | access to local variable path | -| UncontrolledFormatString.cs:31:23:31:31 | access to property Text | semmle.label | access to property Text | +| UncontrolledFormatString.cs:34:23:34:31 | access to property Text | semmle.label | access to property Text | | UncontrolledFormatStringBad.cs:9:25:9:47 | access to property QueryString : NameValueCollection | semmle.label | access to property QueryString : NameValueCollection | | UncontrolledFormatStringBad.cs:12:39:12:44 | access to local variable format | semmle.label | access to local variable format | #select | UncontrolledFormatString.cs:14:23:14:26 | access to local variable path | UncontrolledFormatString.cs:11:23:11:45 | access to property QueryString : NameValueCollection | UncontrolledFormatString.cs:14:23:14:26 | access to local variable path | $@ flows to here and is used as a format string. | UncontrolledFormatString.cs:11:23:11:45 | access to property QueryString | access to property QueryString | | UncontrolledFormatString.cs:17:46:17:49 | access to local variable path | UncontrolledFormatString.cs:11:23:11:45 | access to property QueryString : NameValueCollection | UncontrolledFormatString.cs:17:46:17:49 | access to local variable path | $@ flows to here and is used as a format string. | UncontrolledFormatString.cs:11:23:11:45 | access to property QueryString | access to property QueryString | -| UncontrolledFormatString.cs:31:23:31:31 | access to property Text | UncontrolledFormatString.cs:31:23:31:31 | access to property Text | UncontrolledFormatString.cs:31:23:31:31 | access to property Text | $@ flows to here and is used as a format string. | UncontrolledFormatString.cs:31:23:31:31 | access to property Text | access to property Text | +| UncontrolledFormatString.cs:34:23:34:31 | access to property Text | UncontrolledFormatString.cs:34:23:34:31 | access to property Text | UncontrolledFormatString.cs:34:23:34:31 | access to property Text | $@ flows to here and is used as a format string. | UncontrolledFormatString.cs:34:23:34:31 | access to property Text | access to property Text | | UncontrolledFormatStringBad.cs:12:39:12:44 | access to local variable format | UncontrolledFormatStringBad.cs:9:25:9:47 | access to property QueryString : NameValueCollection | UncontrolledFormatStringBad.cs:12:39:12:44 | access to local variable format | $@ flows to here and is used as a format string. | UncontrolledFormatStringBad.cs:9:25:9:47 | access to property QueryString | access to property QueryString | diff --git a/csharp/upgrades/094972aab8c537db2cec0b9508361ca9d4cc2006/old.dbscheme b/csharp/upgrades/094972aab8c537db2cec0b9508361ca9d4cc2006/old.dbscheme new file mode 100644 index 00000000000..094972aab8c --- /dev/null +++ b/csharp/upgrades/094972aab8c537db2cec0b9508361ca9d4cc2006/old.dbscheme @@ -0,0 +1,1906 @@ + +/** + * An invocation of the compiler. Note that more than one file may be + * compiled per invocation. For example, this command compiles three + * source files: + * + * csc f1.cs f2.cs f3.cs + * + * The `id` simply identifies the invocation, while `cwd` is the working + * directory from which the compiler was invoked. + */ +compilations( + unique int id : @compilation, + string cwd : string ref +); + +/** + * The arguments that were passed to the extractor for a compiler + * invocation. If `id` is for the compiler invocation + * + * csc f1.cs f2.cs f3.cs + * + * then typically there will be rows for + * + * num | arg + * --- | --- + * 0 | --compiler + * 1 | *path to compiler* + * 2 | --cil + * 3 | f1.cs + * 4 | f2.cs + * 5 | f3.cs + */ +#keyset[id, num] +compilation_args( + int id : @compilation ref, + int num : int ref, + string arg : string ref +); + +/** + * The source files that are compiled by a compiler invocation. + * If `id` is for the compiler invocation + * + * csc f1.cs f2.cs f3.cs + * + * then there will be rows for + * + * num | arg + * --- | --- + * 0 | f1.cs + * 1 | f2.cs + * 2 | f3.cs + */ +#keyset[id, num] +compilation_compiling_files( + int id : @compilation ref, + int num : int ref, + int file : @file ref +); + +/** + * The references used by a compiler invocation. + * If `id` is for the compiler invocation + * + * csc f1.cs f2.cs f3.cs /r:ref1.dll /r:ref2.dll /r:ref3.dll + * + * then there will be rows for + * + * num | arg + * --- | --- + * 0 | ref1.dll + * 1 | ref2.dll + * 2 | ref3.dll + */ +#keyset[id, num] +compilation_referencing_files( + int id : @compilation ref, + int num : int ref, + int file : @file ref +); + +/** + * The time taken by the extractor for a compiler invocation. + * + * For each file `num`, there will be rows for + * + * kind | seconds + * ---- | --- + * 1 | CPU seconds used by the extractor frontend + * 2 | Elapsed seconds during the extractor frontend + * 3 | CPU seconds used by the extractor backend + * 4 | Elapsed seconds during the extractor backend + */ +#keyset[id, num, kind] +compilation_time( + int id : @compilation ref, + int num : int ref, + /* kind: + 1 = frontend_cpu_seconds + 2 = frontend_elapsed_seconds + 3 = extractor_cpu_seconds + 4 = extractor_elapsed_seconds + */ + int kind : int ref, + float seconds : float ref +); + +/** + * An error or warning generated by the extractor. + * The diagnostic message `diagnostic` was generated during compiler + * invocation `compilation`, and is the `file_number_diagnostic_number`th + * message generated while extracting the `file_number`th file of that + * invocation. + */ +#keyset[compilation, file_number, file_number_diagnostic_number] +diagnostic_for( + unique int diagnostic : @diagnostic ref, + int compilation : @compilation ref, + int file_number : int ref, + int file_number_diagnostic_number : int ref +); + +diagnostics( + unique int id: @diagnostic, + int severity: int ref, + string error_tag: string ref, + string error_message: string ref, + string full_error_message: string ref, + int location: @location_default ref +); + +extractor_messages( + unique int id: @extractor_message, + int severity: int ref, + string origin : string ref, + string text : string ref, + string entity : string ref, + int location: @location_default ref, + string stack_trace : string ref +); + +/** + * If extraction was successful, then `cpu_seconds` and + * `elapsed_seconds` are the CPU time and elapsed time (respectively) + * that extraction took for compiler invocation `id`. + */ +compilation_finished( + unique int id : @compilation ref, + float cpu_seconds : float ref, + float elapsed_seconds : float ref +); + +/* + * External artifacts + */ + +externalDefects( + unique int id: @externalDefect, + string queryPath: string ref, + int location: @location ref, + string message: string ref, + float severity: float ref); + +externalMetrics( + unique int id: @externalMetric, + string queryPath: string ref, + int location: @location ref, + float value: float ref); + +externalData( + int id: @externalDataElement, + string path: string ref, + int column: int ref, + string value: string ref); + +snapshotDate( + unique date snapshotDate: date ref); + +sourceLocationPrefix( + string prefix: string ref); + +/* + * Duplicate code + */ + +duplicateCode( + unique int id: @duplication, + string relativePath: string ref, + int equivClass: int ref); + +similarCode( + unique int id: @similarity, + string relativePath: string ref, + int equivClass: int ref); + +@duplication_or_similarity = @duplication | @similarity + +tokens( + int id: @duplication_or_similarity ref, + int offset: int ref, + int beginLine: int ref, + int beginColumn: int ref, + int endLine: int ref, + int endColumn: int ref); + +/* + * C# dbscheme + */ + +/** ELEMENTS **/ + +@element = @declaration | @stmt | @expr | @modifier | @attribute | @namespace_declaration + | @using_directive | @type_parameter_constraints | @external_element + | @xmllocatable | @asp_element | @namespace; + +@declaration = @callable | @generic | @assignable | @namespace; + +@named_element = @namespace | @declaration; + +@declaration_with_accessors = @property | @indexer | @event; + +@assignable = @variable | @assignable_with_accessors | @event; + +@assignable_with_accessors = @property | @indexer; + +@external_element = @externalMetric | @externalDefect | @externalDataElement; + +@attributable = @assembly | @field | @parameter | @operator | @method | @constructor + | @destructor | @callable_accessor | @value_or_ref_type | @declaration_with_accessors + | @local_function; + +/** LOCATIONS, ASEMMBLIES, MODULES, FILES and FOLDERS **/ + +@location = @location_default | @assembly; + +locations_default( + unique int id: @location_default, + int file: @file ref, + int beginLine: int ref, + int beginColumn: int ref, + int endLine: int ref, + int endColumn: int ref); + +@sourceline = @file | @callable | @xmllocatable; + +numlines( + int element_id: @sourceline ref, + int num_lines: int ref, + int num_code: int ref, + int num_comment: int ref); + +assemblies( + unique int id: @assembly, + int file: @file ref, + string fullname: string ref, + string name: string ref, + string version: string ref); + +/* + fromSource(0) = unknown, + fromSource(1) = from source, + fromSource(2) = from library +*/ +files( + unique int id: @file, + string name: string ref, + string simple: string ref, + string ext: string ref, + int fromSource: int ref); + +folders( + unique int id: @folder, + string name: string ref, + string simple: string ref); + +@container = @folder | @file ; + +containerparent( + int parent: @container ref, + unique int child: @container ref); + +file_extraction_mode( + unique int file: @file ref, + int mode: int ref + /* 0 = normal, 1 = standalone extractor */ + ); + +/** NAMESPACES **/ + +@type_container = @namespace | @type; + +namespaces( + unique int id: @namespace, + string name: string ref); + +namespace_declarations( + unique int id: @namespace_declaration, + int namespace_id: @namespace ref); + +namespace_declaration_location( + unique int id: @namespace_declaration ref, + int loc: @location ref); + +parent_namespace( + unique int child_id: @type_container ref, + int namespace_id: @namespace ref); + +@declaration_or_directive = @namespace_declaration | @type | @using_directive; + +parent_namespace_declaration( + int child_id: @declaration_or_directive ref, // cannot be unique because of partial classes + int namespace_id: @namespace_declaration ref); + +@using_directive = @using_namespace_directive | @using_static_directive; + +using_namespace_directives( + unique int id: @using_namespace_directive, + int namespace_id: @namespace ref); + +using_static_directives( + unique int id: @using_static_directive, + int type_id: @type_or_ref ref); + +using_directive_location( + unique int id: @using_directive ref, + int loc: @location ref); + +/** TYPES **/ + +types( + unique int id: @type, + int kind: int ref, + string name: string ref); + +case @type.kind of + 1 = @bool_type +| 2 = @char_type +| 3 = @decimal_type +| 4 = @sbyte_type +| 5 = @short_type +| 6 = @int_type +| 7 = @long_type +| 8 = @byte_type +| 9 = @ushort_type +| 10 = @uint_type +| 11 = @ulong_type +| 12 = @float_type +| 13 = @double_type +| 14 = @enum_type +| 15 = @struct_type +| 17 = @class_type +| 19 = @interface_type +| 20 = @delegate_type +| 21 = @null_type +| 22 = @type_parameter +| 23 = @pointer_type +| 24 = @nullable_type +| 25 = @array_type +| 26 = @void_type +| 27 = @int_ptr_type +| 28 = @uint_ptr_type +| 29 = @dynamic_type +| 30 = @arglist_type +| 31 = @unknown_type +| 32 = @tuple_type + ; + +@simple_type = @bool_type | @char_type | @integral_type | @floating_point_type | @decimal_type; +@integral_type = @signed_integral_type | @unsigned_integral_type; +@signed_integral_type = @sbyte_type | @short_type | @int_type | @long_type; +@unsigned_integral_type = @byte_type | @ushort_type | @uint_type | @ulong_type; +@floating_point_type = @float_type | @double_type; +@value_type = @simple_type | @enum_type | @struct_type | @nullable_type | @int_ptr_type + | @uint_ptr_type | @tuple_type; +@ref_type = @class_type | @interface_type | @array_type | @delegate_type | @null_type + | @dynamic_type; +@value_or_ref_type = @value_type | @ref_type; + +typerefs( + unique int id: @typeref, + string name: string ref); + +typeref_type( + int id: @typeref ref, + unique int typeId: @type ref); + +@type_or_ref = @type | @typeref; + +array_element_type( + unique int array: @array_type ref, + int dimension: int ref, + int rank: int ref, + int element: @type_or_ref ref); + +nullable_underlying_type( + unique int nullable: @nullable_type ref, + int underlying: @type_or_ref ref); + +pointer_referent_type( + unique int pointer: @pointer_type ref, + int referent: @type_or_ref ref); + +enum_underlying_type( + unique int enum_id: @enum_type ref, + int underlying_type_id: @type_or_ref ref); + +delegate_return_type( + unique int delegate_id: @delegate_type ref, + int return_type_id: @type_or_ref ref); + +extend( + unique int sub: @type ref, + int super: @type_or_ref ref); + +@interface_or_ref = @interface_type | @typeref; + +implement( + int sub: @type ref, + int super: @type_or_ref ref); + +type_location( + int id: @type ref, + int loc: @location ref); + +tuple_underlying_type( + unique int tuple: @tuple_type ref, + int struct: @type_or_ref ref); + +#keyset[tuple, index] +tuple_element( + int tuple: @tuple_type ref, + int index: int ref, + unique int field: @field ref); + +attributes( + unique int id: @attribute, + int type_id: @type_or_ref ref, + int target: @attributable ref); + +attribute_location( + int id: @attribute ref, + int loc: @location ref); + +@type_mention_parent = @element | @type_mention; + +type_mention( + unique int id: @type_mention, + int type_id: @type_or_ref ref, + int parent: @type_mention_parent ref); + +type_mention_location( + unique int id: @type_mention ref, + int loc: @location ref); + +@has_type_annotation = @assignable | @type_parameter | @callable | @expr | @delegate_type | @generic; + +/** + * A direct annotation on an entity, for example `string? x;`. + * + * Annotations: + * 2 = reftype is not annotated "!" + * 3 = reftype is annotated "?" + * 4 = readonly ref type / in parameter + * 5 = ref type parameter, return or local variable + * 6 = out parameter + * + * Note that the annotation depends on the element it annotates. + * @assignable: The annotation is on the type of the assignable, for example the variable type. + * @type_parameter: The annotation is on the reftype constraint + * @callable: The annotation is on the return type + * @array_type: The annotation is on the element type + */ +type_annotation(int id: @has_type_annotation ref, int annotation: int ref); + +nullability(unique int nullability: @nullability, int kind: int ref); + +case @nullability.kind of + 0 = @oblivious +| 1 = @not_annotated +| 2 = @annotated +; + +#keyset[parent, index] +nullability_parent(int nullability: @nullability ref, int index: int ref, int parent: @nullability ref) + +type_nullability(int id: @has_type_annotation ref, int nullability: @nullability ref); + +/** + * The nullable flow state of an expression, as determined by Roslyn. + * 0 = none (default, not populated) + * 1 = not null + * 2 = maybe null + */ +expr_flowstate(unique int id: @expr ref, int state: int ref); + +/** GENERICS **/ + +@generic = @type | @method | @local_function; + +type_parameters( + unique int id: @type_parameter ref, + int index: int ref, + int generic_id: @generic ref, + int variance: int ref /* none = 0, out = 1, in = 2 */); + +#keyset[constructed_id, index] +type_arguments( + int id: @type_or_ref ref, + int index: int ref, + int constructed_id: @generic_or_ref ref); + +@generic_or_ref = @generic | @typeref; + +constructed_generic( + unique int constructed: @generic ref, + int generic: @generic_or_ref ref); + +type_parameter_constraints( + unique int id: @type_parameter_constraints, + int param_id: @type_parameter ref); + +type_parameter_constraints_location( + int id: @type_parameter_constraints ref, + int loc: @location ref); + +general_type_parameter_constraints( + int id: @type_parameter_constraints ref, + int kind: int ref /* class = 1, struct = 2, new = 3 */); + +specific_type_parameter_constraints( + int id: @type_parameter_constraints ref, + int base_id: @type_or_ref ref); + +specific_type_parameter_nullability( + int id: @type_parameter_constraints ref, + int base_id: @type_or_ref ref, + int nullability: @nullability ref); + +/** MODIFIERS */ + +@modifiable = @modifiable_direct | @event_accessor; + +@modifiable_direct = @member | @accessor | @local_function | @anonymous_function_expr; + +modifiers( + unique int id: @modifier, + string name: string ref); + +has_modifiers( + int id: @modifiable_direct ref, + int mod_id: @modifier ref); + +compiler_generated(unique int id: @modifiable_direct ref); + +/** MEMBERS **/ + +@member = @method | @constructor | @destructor | @field | @property | @event | @operator | @indexer | @type; + +@named_exprorstmt = @goto_stmt | @labeled_stmt | @expr; + +@virtualizable = @method | @property | @indexer | @event; + +exprorstmt_name( + unique int parent_id: @named_exprorstmt ref, + string name: string ref); + +nested_types( + unique int id: @type ref, + int declaring_type_id: @type ref, + int unbound_id: @type ref); + +properties( + unique int id: @property, + string name: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @property ref); + +property_location( + int id: @property ref, + int loc: @location ref); + +indexers( + unique int id: @indexer, + string name: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @indexer ref); + +indexer_location( + int id: @indexer ref, + int loc: @location ref); + +accessors( + unique int id: @accessor, + int kind: int ref, + string name: string ref, + int declaring_member_id: @member ref, + int unbound_id: @accessor ref); + +case @accessor.kind of + 1 = @getter +| 2 = @setter + ; + +init_only_accessors( + unique int id: @accessor ref); + +accessor_location( + int id: @accessor ref, + int loc: @location ref); + +events( + unique int id: @event, + string name: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @event ref); + +event_location( + int id: @event ref, + int loc: @location ref); + +event_accessors( + unique int id: @event_accessor, + int kind: int ref, + string name: string ref, + int declaring_event_id: @event ref, + int unbound_id: @event_accessor ref); + +case @event_accessor.kind of + 1 = @add_event_accessor +| 2 = @remove_event_accessor + ; + +event_accessor_location( + int id: @event_accessor ref, + int loc: @location ref); + +operators( + unique int id: @operator, + string name: string ref, + string symbol: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @operator ref); + +operator_location( + int id: @operator ref, + int loc: @location ref); + +constant_value( + int id: @variable ref, + string value: string ref); + +/** CALLABLES **/ + +@callable = @method | @constructor | @destructor | @operator | @callable_accessor | @anonymous_function_expr | @local_function; + +@callable_accessor = @accessor | @event_accessor; + +methods( + unique int id: @method, + string name: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @method ref); + +method_location( + int id: @method ref, + int loc: @location ref); + +constructors( + unique int id: @constructor, + string name: string ref, + int declaring_type_id: @type ref, + int unbound_id: @constructor ref); + +constructor_location( + int id: @constructor ref, + int loc: @location ref); + +destructors( + unique int id: @destructor, + string name: string ref, + int declaring_type_id: @type ref, + int unbound_id: @destructor ref); + +destructor_location( + int id: @destructor ref, + int loc: @location ref); + +overrides( + int id: @callable ref, + int base_id: @callable ref); + +explicitly_implements( + int id: @member ref, + int interface_id: @interface_or_ref ref); + +local_functions( + unique int id: @local_function, + string name: string ref, + int return_type: @type ref, + int unbound_id: @local_function ref); + +local_function_stmts( + unique int fn: @local_function_stmt ref, + int stmt: @local_function ref); + +/** VARIABLES **/ + +@variable = @local_scope_variable | @field; + +@local_scope_variable = @local_variable | @parameter; + +fields( + unique int id: @field, + int kind: int ref, + string name: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @field ref); + +case @field.kind of + 1 = @addressable_field +| 2 = @constant + ; + +field_location( + int id: @field ref, + int loc: @location ref); + +localvars( + unique int id: @local_variable, + int kind: int ref, + string name: string ref, + int implicitly_typed: int ref /* 0 = no, 1 = yes */, + int type_id: @type_or_ref ref, + int parent_id: @local_var_decl_expr ref); + +case @local_variable.kind of + 1 = @addressable_local_variable +| 2 = @local_constant +| 3 = @local_variable_ref + ; + +localvar_location( + unique int id: @local_variable ref, + int loc: @location ref); + +@parameterizable = @callable | @delegate_type | @indexer; + +#keyset[name, parent_id] +#keyset[index, parent_id] +params( + unique int id: @parameter, + string name: string ref, + int type_id: @type_or_ref ref, + int index: int ref, + int mode: int ref, /* value = 0, ref = 1, out = 2, array = 3, this = 4 */ + int parent_id: @parameterizable ref, + int unbound_id: @parameter ref); + +param_location( + int id: @parameter ref, + int loc: @location ref); + +/** STATEMENTS **/ + +@exprorstmt_parent = @control_flow_element | @top_level_exprorstmt_parent; + +statements( + unique int id: @stmt, + int kind: int ref); + +#keyset[index, parent] +stmt_parent( + unique int stmt: @stmt ref, + int index: int ref, + int parent: @control_flow_element ref); + +@top_level_stmt_parent = @callable; + +// [index, parent] is not a keyset because the same parent may be compiled multiple times +stmt_parent_top_level( + unique int stmt: @stmt ref, + int index: int ref, + int parent: @top_level_stmt_parent ref); + +case @stmt.kind of + 1 = @block_stmt +| 2 = @expr_stmt +| 3 = @if_stmt +| 4 = @switch_stmt +| 5 = @while_stmt +| 6 = @do_stmt +| 7 = @for_stmt +| 8 = @foreach_stmt +| 9 = @break_stmt +| 10 = @continue_stmt +| 11 = @goto_stmt +| 12 = @goto_case_stmt +| 13 = @goto_default_stmt +| 14 = @throw_stmt +| 15 = @return_stmt +| 16 = @yield_stmt +| 17 = @try_stmt +| 18 = @checked_stmt +| 19 = @unchecked_stmt +| 20 = @lock_stmt +| 21 = @using_block_stmt +| 22 = @var_decl_stmt +| 23 = @const_decl_stmt +| 24 = @empty_stmt +| 25 = @unsafe_stmt +| 26 = @fixed_stmt +| 27 = @label_stmt +| 28 = @catch +| 29 = @case_stmt +| 30 = @local_function_stmt +| 31 = @using_decl_stmt + ; + +@using_stmt = @using_block_stmt | @using_decl_stmt; + +@labeled_stmt = @label_stmt | @case; + +@decl_stmt = @var_decl_stmt | @const_decl_stmt | @using_decl_stmt; + +@cond_stmt = @if_stmt | @switch_stmt; + +@loop_stmt = @while_stmt | @do_stmt | @for_stmt | @foreach_stmt; + +@jump_stmt = @break_stmt | @goto_any_stmt | @continue_stmt | @throw_stmt | @return_stmt + | @yield_stmt; + +@goto_any_stmt = @goto_default_stmt | @goto_case_stmt | @goto_stmt; + + +stmt_location( + unique int id: @stmt ref, + int loc: @location ref); + +catch_type( + unique int catch_id: @catch ref, + int type_id: @type_or_ref ref, + int kind: int ref /* explicit = 1, implicit = 2 */); + +/** EXPRESSIONS **/ + +expressions( + unique int id: @expr, + int kind: int ref, + int type_id: @type_or_ref ref); + +#keyset[index, parent] +expr_parent( + unique int expr: @expr ref, + int index: int ref, + int parent: @control_flow_element ref); + +@top_level_expr_parent = @attribute | @field | @property | @indexer | @parameter; + +@top_level_exprorstmt_parent = @top_level_expr_parent | @top_level_stmt_parent; + +// [index, parent] is not a keyset because the same parent may be compiled multiple times +expr_parent_top_level( + unique int expr: @expr ref, + int index: int ref, + int parent: @top_level_exprorstmt_parent ref); + +case @expr.kind of +/* literal */ + 1 = @bool_literal_expr +| 2 = @char_literal_expr +| 3 = @decimal_literal_expr +| 4 = @int_literal_expr +| 5 = @long_literal_expr +| 6 = @uint_literal_expr +| 7 = @ulong_literal_expr +| 8 = @float_literal_expr +| 9 = @double_literal_expr +| 10 = @string_literal_expr +| 11 = @null_literal_expr +/* primary & unary */ +| 12 = @this_access_expr +| 13 = @base_access_expr +| 14 = @local_variable_access_expr +| 15 = @parameter_access_expr +| 16 = @field_access_expr +| 17 = @property_access_expr +| 18 = @method_access_expr +| 19 = @event_access_expr +| 20 = @indexer_access_expr +| 21 = @array_access_expr +| 22 = @type_access_expr +| 23 = @typeof_expr +| 24 = @method_invocation_expr +| 25 = @delegate_invocation_expr +| 26 = @operator_invocation_expr +| 27 = @cast_expr +| 28 = @object_creation_expr +| 29 = @explicit_delegate_creation_expr +| 30 = @implicit_delegate_creation_expr +| 31 = @array_creation_expr +| 32 = @default_expr +| 33 = @plus_expr +| 34 = @minus_expr +| 35 = @bit_not_expr +| 36 = @log_not_expr +| 37 = @post_incr_expr +| 38 = @post_decr_expr +| 39 = @pre_incr_expr +| 40 = @pre_decr_expr +/* multiplicative */ +| 41 = @mul_expr +| 42 = @div_expr +| 43 = @rem_expr +/* additive */ +| 44 = @add_expr +| 45 = @sub_expr +/* shift */ +| 46 = @lshift_expr +| 47 = @rshift_expr +/* relational */ +| 48 = @lt_expr +| 49 = @gt_expr +| 50 = @le_expr +| 51 = @ge_expr +/* equality */ +| 52 = @eq_expr +| 53 = @ne_expr +/* logical */ +| 54 = @bit_and_expr +| 55 = @bit_xor_expr +| 56 = @bit_or_expr +| 57 = @log_and_expr +| 58 = @log_or_expr +/* type testing */ +| 59 = @is_expr +| 60 = @as_expr +/* null coalescing */ +| 61 = @null_coalescing_expr +/* conditional */ +| 62 = @conditional_expr +/* assignment */ +| 63 = @simple_assign_expr +| 64 = @assign_add_expr +| 65 = @assign_sub_expr +| 66 = @assign_mul_expr +| 67 = @assign_div_expr +| 68 = @assign_rem_expr +| 69 = @assign_and_expr +| 70 = @assign_xor_expr +| 71 = @assign_or_expr +| 72 = @assign_lshift_expr +| 73 = @assign_rshift_expr +/* more */ +| 74 = @object_init_expr +| 75 = @collection_init_expr +| 76 = @array_init_expr +| 77 = @checked_expr +| 78 = @unchecked_expr +| 79 = @constructor_init_expr +| 80 = @add_event_expr +| 81 = @remove_event_expr +| 82 = @par_expr +| 83 = @local_var_decl_expr +| 84 = @lambda_expr +| 85 = @anonymous_method_expr +| 86 = @namespace_expr +/* dynamic */ +| 92 = @dynamic_element_access_expr +| 93 = @dynamic_member_access_expr +/* unsafe */ +| 100 = @pointer_indirection_expr +| 101 = @address_of_expr +| 102 = @sizeof_expr +/* async */ +| 103 = @await_expr +/* C# 6.0 */ +| 104 = @nameof_expr +| 105 = @interpolated_string_expr +| 106 = @unknown_expr +/* C# 7.0 */ +| 107 = @throw_expr +| 108 = @tuple_expr +| 109 = @local_function_invocation_expr +| 110 = @ref_expr +| 111 = @discard_expr +/* C# 8.0 */ +| 112 = @range_expr +| 113 = @index_expr +| 114 = @switch_expr +| 115 = @recursive_pattern_expr +| 116 = @property_pattern_expr +| 117 = @positional_pattern_expr +| 118 = @switch_case_expr +| 119 = @assign_coalesce_expr +| 120 = @suppress_nullable_warning_expr +| 121 = @namespace_access_expr +; + +@switch = @switch_stmt | @switch_expr; +@case = @case_stmt | @switch_case_expr; +@pattern_match = @case | @is_expr; + +@integer_literal_expr = @int_literal_expr | @long_literal_expr | @uint_literal_expr | @ulong_literal_expr; +@real_literal_expr = @float_literal_expr | @double_literal_expr | @decimal_literal_expr; +@literal_expr = @bool_literal_expr | @char_literal_expr | @integer_literal_expr | @real_literal_expr + | @string_literal_expr | @null_literal_expr; + +@assign_expr = @simple_assign_expr | @assign_op_expr | @local_var_decl_expr; +@assign_op_expr = @assign_arith_expr | @assign_bitwise_expr | @assign_event_expr | @assign_coalesce_expr; +@assign_event_expr = @add_event_expr | @remove_event_expr; + +@assign_arith_expr = @assign_add_expr | @assign_sub_expr | @assign_mul_expr | @assign_div_expr + | @assign_rem_expr +@assign_bitwise_expr = @assign_and_expr | @assign_or_expr | @assign_xor_expr + | @assign_lshift_expr | @assign_rshift_expr; + +@member_access_expr = @field_access_expr | @property_access_expr | @indexer_access_expr | @event_access_expr + | @method_access_expr | @type_access_expr | @dynamic_member_access_expr; +@access_expr = @member_access_expr | @this_access_expr | @base_access_expr | @assignable_access_expr | @namespace_access_expr; +@element_access_expr = @indexer_access_expr | @array_access_expr | @dynamic_element_access_expr; + +@local_variable_access = @local_variable_access_expr | @local_var_decl_expr; +@local_scope_variable_access_expr = @parameter_access_expr | @local_variable_access; +@variable_access_expr = @local_scope_variable_access_expr | @field_access_expr; + +@assignable_access_expr = @variable_access_expr | @property_access_expr | @element_access_expr + | @event_access_expr | @dynamic_member_access_expr; + +@objectorcollection_init_expr = @object_init_expr | @collection_init_expr; + +@delegate_creation_expr = @explicit_delegate_creation_expr | @implicit_delegate_creation_expr; + +@bin_arith_op_expr = @mul_expr | @div_expr | @rem_expr | @add_expr | @sub_expr; +@incr_op_expr = @pre_incr_expr | @post_incr_expr; +@decr_op_expr = @pre_decr_expr | @post_decr_expr; +@mut_op_expr = @incr_op_expr | @decr_op_expr; +@un_arith_op_expr = @plus_expr | @minus_expr | @mut_op_expr; +@arith_op_expr = @bin_arith_op_expr | @un_arith_op_expr; + +@ternary_log_op_expr = @conditional_expr; +@bin_log_op_expr = @log_and_expr | @log_or_expr | @null_coalescing_expr; +@un_log_op_expr = @log_not_expr; +@log_expr = @un_log_op_expr | @bin_log_op_expr | @ternary_log_op_expr; + +@bin_bit_op_expr = @bit_and_expr | @bit_or_expr | @bit_xor_expr | @lshift_expr + | @rshift_expr; +@un_bit_op_expr = @bit_not_expr; +@bit_expr = @un_bit_op_expr | @bin_bit_op_expr; + +@equality_op_expr = @eq_expr | @ne_expr; +@rel_op_expr = @gt_expr | @lt_expr| @ge_expr | @le_expr; +@comp_expr = @equality_op_expr | @rel_op_expr; + +@op_expr = @assign_expr | @un_op | @bin_op | @ternary_op; + +@ternary_op = @ternary_log_op_expr; +@bin_op = @bin_arith_op_expr | @bin_log_op_expr | @bin_bit_op_expr | @comp_expr; +@un_op = @un_arith_op_expr | @un_log_op_expr | @un_bit_op_expr | @sizeof_expr + | @pointer_indirection_expr | @address_of_expr; + +@anonymous_function_expr = @lambda_expr | @anonymous_method_expr; + +@call = @method_invocation_expr | @constructor_init_expr | @operator_invocation_expr + | @delegate_invocation_expr | @object_creation_expr | @call_access_expr + | @local_function_invocation_expr; + +@call_access_expr = @property_access_expr | @event_access_expr | @indexer_access_expr; + +@late_bindable_expr = @dynamic_element_access_expr | @dynamic_member_access_expr + | @object_creation_expr | @method_invocation_expr | @operator_invocation_expr; + +@throw_element = @throw_expr | @throw_stmt; + +@implicitly_typeable_object_creation_expr = @object_creation_expr | @explicit_delegate_creation_expr; + +implicitly_typed_array_creation( + unique int id: @array_creation_expr ref); + +explicitly_sized_array_creation( + unique int id: @array_creation_expr ref); + +stackalloc_array_creation( + unique int id: @array_creation_expr ref); + +implicitly_typed_object_creation( + unique int id: @implicitly_typeable_object_creation_expr ref); + +mutator_invocation_mode( + unique int id: @operator_invocation_expr ref, + int mode: int ref /* prefix = 1, postfix = 2*/); + +expr_compiler_generated( + unique int id: @expr ref); + +expr_value( + unique int id: @expr ref, + string value: string ref); + +expr_call( + unique int caller_id: @expr ref, + int target_id: @callable ref); + +expr_access( + unique int accesser_id: @access_expr ref, + int target_id: @accessible ref); + +@accessible = @method | @assignable | @local_function | @namespace; + +expr_location( + unique int id: @expr ref, + int loc: @location ref); + +dynamic_member_name( + unique int id: @late_bindable_expr ref, + string name: string ref); + +@qualifiable_expr = @member_access_expr + | @method_invocation_expr + | @element_access_expr; + +conditional_access( + unique int id: @qualifiable_expr ref); + +expr_argument( + unique int id: @expr ref, + int mode: int ref); + /* mode is the same as params: value = 0, ref = 1, out = 2 */ + +expr_argument_name( + unique int id: @expr ref, + string name: string ref); + +/** CONTROL/DATA FLOW **/ + +@control_flow_element = @stmt | @expr; + +/* XML Files */ + +xmlEncoding ( + unique int id: @file ref, + string encoding: string ref); + +xmlDTDs( + unique int id: @xmldtd, + string root: string ref, + string publicId: string ref, + string systemId: string ref, + int fileid: @file ref); + +xmlElements( + unique int id: @xmlelement, + string name: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int fileid: @file ref); + +xmlAttrs( + unique int id: @xmlattribute, + int elementid: @xmlelement ref, + string name: string ref, + string value: string ref, + int idx: int ref, + int fileid: @file ref); + +xmlNs( + int id: @xmlnamespace, + string prefixName: string ref, + string URI: string ref, + int fileid: @file ref); + +xmlHasNs( + int elementId: @xmlnamespaceable ref, + int nsId: @xmlnamespace ref, + int fileid: @file ref); + +xmlComments( + unique int id: @xmlcomment, + string text: string ref, + int parentid: @xmlparent ref, + int fileid: @file ref); + +xmlChars( + unique int id: @xmlcharacters, + string text: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int isCDATA: int ref, + int fileid: @file ref); + +@xmlparent = @file | @xmlelement; +@xmlnamespaceable = @xmlelement | @xmlattribute; + +xmllocations( + int xmlElement: @xmllocatable ref, + int location: @location_default ref); + +@xmllocatable = @xmlcharacters | @xmlelement | @xmlcomment | @xmlattribute | @xmldtd | @file | @xmlnamespace; + +/* Comments */ + +commentline( + unique int id: @commentline, + int kind: int ref, + string text: string ref, + string rawtext: string ref); + +case @commentline.kind of + 0 = @singlelinecomment +| 1 = @xmldoccomment +| 2 = @multilinecomment; + +commentline_location( + unique int id: @commentline ref, + int loc: @location ref); + +commentblock( + unique int id : @commentblock); + +commentblock_location( + unique int id: @commentblock ref, + int loc: @location ref); + +commentblock_binding( + int id: @commentblock ref, + int entity: @element ref, + int bindtype: int ref); /* 0: Parent, 1: Best, 2: Before, 3: After */ + +commentblock_child( + int id: @commentblock ref, + int commentline: @commentline ref, + int index: int ref); + +/* ASP.NET */ + +case @asp_element.kind of + 0=@asp_close_tag +| 1=@asp_code +| 2=@asp_comment +| 3=@asp_data_binding +| 4=@asp_directive +| 5=@asp_open_tag +| 6=@asp_quoted_string +| 7=@asp_text +| 8=@asp_xml_directive; + +@asp_attribute = @asp_code | @asp_data_binding | @asp_quoted_string; + +asp_elements( + unique int id: @asp_element, + int kind: int ref, + int loc: @location ref); + +asp_comment_server(unique int comment: @asp_comment ref); +asp_code_inline(unique int code: @asp_code ref); +asp_directive_attribute( + int directive: @asp_directive ref, + int index: int ref, + string name: string ref, + int value: @asp_quoted_string ref); +asp_directive_name( + unique int directive: @asp_directive ref, + string name: string ref); +asp_element_body( + unique int element: @asp_element ref, + string body: string ref); +asp_tag_attribute( + int tag: @asp_open_tag ref, + int index: int ref, + string name: string ref, + int attribute: @asp_attribute ref); +asp_tag_name( + unique int tag: @asp_open_tag ref, + string name: string ref); +asp_tag_isempty(int tag: @asp_open_tag ref); + +/* Common Intermediate Language - CIL */ + +case @cil_instruction.opcode of + 0 = @cil_nop +| 1 = @cil_break +| 2 = @cil_ldarg_0 +| 3 = @cil_ldarg_1 +| 4 = @cil_ldarg_2 +| 5 = @cil_ldarg_3 +| 6 = @cil_ldloc_0 +| 7 = @cil_ldloc_1 +| 8 = @cil_ldloc_2 +| 9 = @cil_ldloc_3 +| 10 = @cil_stloc_0 +| 11 = @cil_stloc_1 +| 12 = @cil_stloc_2 +| 13 = @cil_stloc_3 +| 14 = @cil_ldarg_s +| 15 = @cil_ldarga_s +| 16 = @cil_starg_s +| 17 = @cil_ldloc_s +| 18 = @cil_ldloca_s +| 19 = @cil_stloc_s +| 20 = @cil_ldnull +| 21 = @cil_ldc_i4_m1 +| 22 = @cil_ldc_i4_0 +| 23 = @cil_ldc_i4_1 +| 24 = @cil_ldc_i4_2 +| 25 = @cil_ldc_i4_3 +| 26 = @cil_ldc_i4_4 +| 27 = @cil_ldc_i4_5 +| 28 = @cil_ldc_i4_6 +| 29 = @cil_ldc_i4_7 +| 30 = @cil_ldc_i4_8 +| 31 = @cil_ldc_i4_s +| 32 = @cil_ldc_i4 +| 33 = @cil_ldc_i8 +| 34 = @cil_ldc_r4 +| 35 = @cil_ldc_r8 +| 37 = @cil_dup +| 38 = @cil_pop +| 39 = @cil_jmp +| 40 = @cil_call +| 41 = @cil_calli +| 42 = @cil_ret +| 43 = @cil_br_s +| 44 = @cil_brfalse_s +| 45 = @cil_brtrue_s +| 46 = @cil_beq_s +| 47 = @cil_bge_s +| 48 = @cil_bgt_s +| 49 = @cil_ble_s +| 50 = @cil_blt_s +| 51 = @cil_bne_un_s +| 52 = @cil_bge_un_s +| 53 = @cil_bgt_un_s +| 54 = @cil_ble_un_s +| 55 = @cil_blt_un_s +| 56 = @cil_br +| 57 = @cil_brfalse +| 58 = @cil_brtrue +| 59 = @cil_beq +| 60 = @cil_bge +| 61 = @cil_bgt +| 62 = @cil_ble +| 63 = @cil_blt +| 64 = @cil_bne_un +| 65 = @cil_bge_un +| 66 = @cil_bgt_un +| 67 = @cil_ble_un +| 68 = @cil_blt_un +| 69 = @cil_switch +| 70 = @cil_ldind_i1 +| 71 = @cil_ldind_u1 +| 72 = @cil_ldind_i2 +| 73 = @cil_ldind_u2 +| 74 = @cil_ldind_i4 +| 75 = @cil_ldind_u4 +| 76 = @cil_ldind_i8 +| 77 = @cil_ldind_i +| 78 = @cil_ldind_r4 +| 79 = @cil_ldind_r8 +| 80 = @cil_ldind_ref +| 81 = @cil_stind_ref +| 82 = @cil_stind_i1 +| 83 = @cil_stind_i2 +| 84 = @cil_stind_i4 +| 85 = @cil_stind_i8 +| 86 = @cil_stind_r4 +| 87 = @cil_stind_r8 +| 88 = @cil_add +| 89 = @cil_sub +| 90 = @cil_mul +| 91 = @cil_div +| 92 = @cil_div_un +| 93 = @cil_rem +| 94 = @cil_rem_un +| 95 = @cil_and +| 96 = @cil_or +| 97 = @cil_xor +| 98 = @cil_shl +| 99 = @cil_shr +| 100 = @cil_shr_un +| 101 = @cil_neg +| 102 = @cil_not +| 103 = @cil_conv_i1 +| 104 = @cil_conv_i2 +| 105 = @cil_conv_i4 +| 106 = @cil_conv_i8 +| 107 = @cil_conv_r4 +| 108 = @cil_conv_r8 +| 109 = @cil_conv_u4 +| 110 = @cil_conv_u8 +| 111 = @cil_callvirt +| 112 = @cil_cpobj +| 113 = @cil_ldobj +| 114 = @cil_ldstr +| 115 = @cil_newobj +| 116 = @cil_castclass +| 117 = @cil_isinst +| 118 = @cil_conv_r_un +| 121 = @cil_unbox +| 122 = @cil_throw +| 123 = @cil_ldfld +| 124 = @cil_ldflda +| 125 = @cil_stfld +| 126 = @cil_ldsfld +| 127 = @cil_ldsflda +| 128 = @cil_stsfld +| 129 = @cil_stobj +| 130 = @cil_conv_ovf_i1_un +| 131 = @cil_conv_ovf_i2_un +| 132 = @cil_conv_ovf_i4_un +| 133 = @cil_conv_ovf_i8_un +| 134 = @cil_conv_ovf_u1_un +| 135 = @cil_conv_ovf_u2_un +| 136 = @cil_conv_ovf_u4_un +| 137 = @cil_conv_ovf_u8_un +| 138 = @cil_conv_ovf_i_un +| 139 = @cil_conv_ovf_u_un +| 140 = @cil_box +| 141 = @cil_newarr +| 142 = @cil_ldlen +| 143 = @cil_ldelema +| 144 = @cil_ldelem_i1 +| 145 = @cil_ldelem_u1 +| 146 = @cil_ldelem_i2 +| 147 = @cil_ldelem_u2 +| 148 = @cil_ldelem_i4 +| 149 = @cil_ldelem_u4 +| 150 = @cil_ldelem_i8 +| 151 = @cil_ldelem_i +| 152 = @cil_ldelem_r4 +| 153 = @cil_ldelem_r8 +| 154 = @cil_ldelem_ref +| 155 = @cil_stelem_i +| 156 = @cil_stelem_i1 +| 157 = @cil_stelem_i2 +| 158 = @cil_stelem_i4 +| 159 = @cil_stelem_i8 +| 160 = @cil_stelem_r4 +| 161 = @cil_stelem_r8 +| 162 = @cil_stelem_ref +| 163 = @cil_ldelem +| 164 = @cil_stelem +| 165 = @cil_unbox_any +| 179 = @cil_conv_ovf_i1 +| 180 = @cil_conv_ovf_u1 +| 181 = @cil_conv_ovf_i2 +| 182 = @cil_conv_ovf_u2 +| 183 = @cil_conv_ovf_i4 +| 184 = @cil_conv_ovf_u4 +| 185 = @cil_conv_ovf_i8 +| 186 = @cil_conv_ovf_u8 +| 194 = @cil_refanyval +| 195 = @cil_ckinfinite +| 198 = @cil_mkrefany +| 208 = @cil_ldtoken +| 209 = @cil_conv_u2 +| 210 = @cil_conv_u1 +| 211 = @cil_conv_i +| 212 = @cil_conv_ovf_i +| 213 = @cil_conv_ovf_u +| 214 = @cil_add_ovf +| 215 = @cil_add_ovf_un +| 216 = @cil_mul_ovf +| 217 = @cil_mul_ovf_un +| 218 = @cil_sub_ovf +| 219 = @cil_sub_ovf_un +| 220 = @cil_endfinally +| 221 = @cil_leave +| 222 = @cil_leave_s +| 223 = @cil_stind_i +| 224 = @cil_conv_u +| 65024 = @cil_arglist +| 65025 = @cil_ceq +| 65026 = @cil_cgt +| 65027 = @cil_cgt_un +| 65028 = @cil_clt +| 65029 = @cil_clt_un +| 65030 = @cil_ldftn +| 65031 = @cil_ldvirtftn +| 65033 = @cil_ldarg +| 65034 = @cil_ldarga +| 65035 = @cil_starg +| 65036 = @cil_ldloc +| 65037 = @cil_ldloca +| 65038 = @cil_stloc +| 65039 = @cil_localloc +| 65041 = @cil_endfilter +| 65042 = @cil_unaligned +| 65043 = @cil_volatile +| 65044 = @cil_tail +| 65045 = @cil_initobj +| 65046 = @cil_constrained +| 65047 = @cil_cpblk +| 65048 = @cil_initblk +| 65050 = @cil_rethrow +| 65052 = @cil_sizeof +| 65053 = @cil_refanytype +| 65054 = @cil_readonly +; + +// CIL ignored instructions + +@cil_ignore = @cil_nop | @cil_break | @cil_volatile | @cil_unaligned; + +// CIL local/parameter/field access + +@cil_ldarg_any = @cil_ldarg_0 | @cil_ldarg_1 | @cil_ldarg_2 | @cil_ldarg_3 | @cil_ldarg_s | @cil_ldarga_s | @cil_ldarg | @cil_ldarga; +@cil_starg_any = @cil_starg | @cil_starg_s; + +@cil_ldloc_any = @cil_ldloc_0 | @cil_ldloc_1 | @cil_ldloc_2 | @cil_ldloc_3 | @cil_ldloc_s | @cil_ldloca_s | @cil_ldloc | @cil_ldloca; +@cil_stloc_any = @cil_stloc_0 | @cil_stloc_1 | @cil_stloc_2 | @cil_stloc_3 | @cil_stloc_s | @cil_stloc; + +@cil_ldfld_any = @cil_ldfld | @cil_ldsfld | @cil_ldsflda | @cil_ldflda; +@cil_stfld_any = @cil_stfld | @cil_stsfld; + +@cil_local_access = @cil_stloc_any | @cil_ldloc_any; +@cil_arg_access = @cil_starg_any | @cil_ldarg_any; +@cil_read_access = @cil_ldloc_any | @cil_ldarg_any | @cil_ldfld_any; +@cil_write_access = @cil_stloc_any | @cil_starg_any | @cil_stfld_any; + +@cil_stack_access = @cil_local_access | @cil_arg_access; +@cil_field_access = @cil_ldfld_any | @cil_stfld_any; + +@cil_access = @cil_read_access | @cil_write_access; + +// CIL constant/literal instructions + +@cil_ldc_i = @cil_ldc_i4_any | @cil_ldc_i8; + +@cil_ldc_i4_any = @cil_ldc_i4_m1 | @cil_ldc_i4_0 | @cil_ldc_i4_1 | @cil_ldc_i4_2 | @cil_ldc_i4_3 | + @cil_ldc_i4_4 | @cil_ldc_i4_5 | @cil_ldc_i4_6 | @cil_ldc_i4_7 | @cil_ldc_i4_8 | @cil_ldc_i4_s | @cil_ldc_i4; + +@cil_ldc_r = @cil_ldc_r4 | @cil_ldc_r8; + +@cil_literal = @cil_ldnull | @cil_ldc_i | @cil_ldc_r | @cil_ldstr; + +// Control flow + +@cil_conditional_jump = @cil_binary_jump | @cil_unary_jump; +@cil_binary_jump = @cil_beq_s | @cil_bge_s | @cil_bgt_s | @cil_ble_s | @cil_blt_s | + @cil_bne_un_s | @cil_bge_un_s | @cil_bgt_un_s | @cil_ble_un_s | @cil_blt_un_s | + @cil_beq | @cil_bge | @cil_bgt | @cil_ble | @cil_blt | + @cil_bne_un | @cil_bge_un | @cil_bgt_un | @cil_ble_un | @cil_blt_un; +@cil_unary_jump = @cil_brfalse_s | @cil_brtrue_s | @cil_brfalse | @cil_brtrue | @cil_switch; +@cil_unconditional_jump = @cil_br | @cil_br_s | @cil_leave_any; +@cil_leave_any = @cil_leave | @cil_leave_s; +@cil_jump = @cil_unconditional_jump | @cil_conditional_jump; + +// CIL call instructions + +@cil_call_any = @cil_jmp | @cil_call | @cil_calli | @cil_tail | @cil_callvirt | @cil_newobj; + +// CIL expression instructions + +@cil_expr = @cil_literal | @cil_binary_expr | @cil_unary_expr | @cil_call_any | @cil_read_access | + @cil_newarr | @cil_ldtoken | @cil_sizeof | + @cil_ldftn | @cil_ldvirtftn | @cil_localloc | @cil_mkrefany | @cil_refanytype | @cil_arglist | @cil_dup; + +@cil_unary_expr = + @cil_conversion_operation | @cil_unary_arithmetic_operation | @cil_unary_bitwise_operation| + @cil_ldlen | @cil_isinst | @cil_box | @cil_ldobj | @cil_castclass | @cil_unbox_any | + @cil_ldind | @cil_unbox; + +@cil_conversion_operation = + @cil_conv_i1 | @cil_conv_i2 | @cil_conv_i4 | @cil_conv_i8 | + @cil_conv_u1 | @cil_conv_u2 | @cil_conv_u4 | @cil_conv_u8 | + @cil_conv_ovf_i | @cil_conv_ovf_i_un | @cil_conv_ovf_i1 | @cil_conv_ovf_i1_un | + @cil_conv_ovf_i2 | @cil_conv_ovf_i2_un | @cil_conv_ovf_i4 | @cil_conv_ovf_i4_un | + @cil_conv_ovf_i8 | @cil_conv_ovf_i8_un | @cil_conv_ovf_u | @cil_conv_ovf_u_un | + @cil_conv_ovf_u1 | @cil_conv_ovf_u1_un | @cil_conv_ovf_u2 | @cil_conv_ovf_u2_un | + @cil_conv_ovf_u4 | @cil_conv_ovf_u4_un | @cil_conv_ovf_u8 | @cil_conv_ovf_u8_un | + @cil_conv_r4 | @cil_conv_r8 | @cil_conv_ovf_u2 | @cil_conv_ovf_u2_un | + @cil_conv_i | @cil_conv_u | @cil_conv_r_un; + +@cil_ldind = @cil_ldind_i | @cil_ldind_i1 | @cil_ldind_i2 | @cil_ldind_i4 | @cil_ldind_i8 | + @cil_ldind_r4 | @cil_ldind_r8 | @cil_ldind_ref | @cil_ldind_u1 | @cil_ldind_u2 | @cil_ldind_u4; + +@cil_stind = @cil_stind_i | @cil_stind_i1 | @cil_stind_i2 | @cil_stind_i4 | @cil_stind_i8 | + @cil_stind_r4 | @cil_stind_r8 | @cil_stind_ref; + +@cil_bitwise_operation = @cil_binary_bitwise_operation | @cil_unary_bitwise_operation; + +@cil_binary_bitwise_operation = @cil_and | @cil_or | @cil_xor | @cil_shr | @cil_shr | @cil_shr_un | @cil_shl; + +@cil_binary_arithmetic_operation = @cil_add | @cil_sub | @cil_mul | @cil_div | @cil_div_un | + @cil_rem | @cil_rem_un | @cil_add_ovf | @cil_add_ovf_un | @cil_mul_ovf | @cil_mul_ovf_un | + @cil_sub_ovf | @cil_sub_ovf_un; + +@cil_unary_bitwise_operation = @cil_not; + +@cil_binary_expr = @cil_binary_arithmetic_operation | @cil_binary_bitwise_operation | @cil_read_array | @cil_comparison_operation; + +@cil_unary_arithmetic_operation = @cil_neg; + +@cil_comparison_operation = @cil_cgt_un | @cil_ceq | @cil_cgt | @cil_clt | @cil_clt_un; + +// Elements that retrieve an address of something +@cil_read_ref = @cil_ldloca_s | @cil_ldarga_s | @cil_ldflda | @cil_ldsflda | @cil_ldelema; + +// CIL array instructions + +@cil_read_array = + @cil_ldelem | @cil_ldelema | @cil_ldelem_i1 | @cil_ldelem_ref | @cil_ldelem_i | + @cil_ldelem_i1 | @cil_ldelem_i2 | @cil_ldelem_i4 | @cil_ldelem_i8 | @cil_ldelem_r4 | + @cil_ldelem_r8 | @cil_ldelem_u1 | @cil_ldelem_u2 | @cil_ldelem_u4; + +@cil_write_array = @cil_stelem | @cil_stelem_ref | + @cil_stelem_i | @cil_stelem_i1 | @cil_stelem_i2 | @cil_stelem_i4 | @cil_stelem_i8 | + @cil_stelem_r4 | @cil_stelem_r8; + +@cil_throw_any = @cil_throw | @cil_rethrow; + +#keyset[impl, index] +cil_instruction( + unique int id: @cil_instruction, + int opcode: int ref, + int index: int ref, + int impl: @cil_method_implementation ref); + +cil_jump( + unique int instruction: @cil_jump ref, + int target: @cil_instruction ref); + +cil_access( + unique int instruction: @cil_instruction ref, + int target: @cil_accessible ref); + +cil_value( + unique int instruction: @cil_literal ref, + string value: string ref); + +#keyset[instruction, index] +cil_switch( + int instruction: @cil_switch ref, + int index: int ref, + int target: @cil_instruction ref); + +cil_instruction_location( + unique int id: @cil_instruction ref, + int loc: @location ref); + +cil_type_location( + int id: @cil_type ref, + int loc: @location ref); + +cil_method_location( + int id: @cil_method ref, + int loc: @location ref); + +@cil_namespace = @namespace; + +@cil_type_container = @cil_type | @cil_namespace | @cil_method; + +case @cil_type.kind of + 0 = @cil_valueorreftype +| 1 = @cil_typeparameter +| 2 = @cil_array_type +| 3 = @cil_pointer_type +; + +cil_type( + unique int id: @cil_type, + string name: string ref, + int kind: int ref, + int parent: @cil_type_container ref, + int sourceDecl: @cil_type ref); + +cil_pointer_type( + unique int id: @cil_pointer_type ref, + int pointee: @cil_type ref); + +cil_array_type( + unique int id: @cil_array_type ref, + int element_type: @cil_type ref, + int rank: int ref); + +cil_method( + unique int id: @cil_method, + string name: string ref, + int parent: @cil_type ref, + int return_type: @cil_type ref); + +cil_method_source_declaration( + unique int method: @cil_method ref, + int source: @cil_method ref); + +cil_method_implementation( + unique int id: @cil_method_implementation, + int method: @cil_method ref, + int location: @assembly ref); + +cil_implements( + int id: @cil_method ref, + int decl: @cil_method ref); + +#keyset[parent, name] +cil_field( + unique int id: @cil_field, + int parent: @cil_type ref, + string name: string ref, + int field_type: @cil_type ref); + +@cil_element = @cil_instruction | @cil_declaration | @cil_handler | @cil_attribute | @cil_namespace; +@cil_named_element = @cil_declaration | @cil_namespace; +@cil_declaration = @cil_variable | @cil_method | @cil_type | @cil_member; +@cil_accessible = @cil_declaration; +@cil_variable = @cil_field | @cil_stack_variable; +@cil_stack_variable = @cil_local_variable | @cil_parameter; +@cil_member = @cil_method | @cil_type | @cil_field | @cil_property | @cil_event; +@cil_custom_modifier_receiver = @cil_method | @cil_property | @cil_parameter | @cil_field; // todo: add function pointer type + +#keyset[method, index] +cil_parameter( + unique int id: @cil_parameter, + int method: @cil_method ref, + int index: int ref, + int param_type: @cil_type ref); + +cil_parameter_in(unique int id: @cil_parameter ref); +cil_parameter_out(unique int id: @cil_parameter ref); + +cil_setter(unique int prop: @cil_property ref, + int method: @cil_method ref); + +#keyset[id, modifier] +cil_custom_modifiers( + int id: @cil_custom_modifier_receiver ref, + int modifier: @cil_type ref, + int kind: int ref); // modreq: 1, modopt: 0 + +cil_getter(unique int prop: @cil_property ref, + int method: @cil_method ref); + +cil_adder(unique int event: @cil_event ref, + int method: @cil_method ref); + +cil_remover(unique int event: @cil_event ref, int method: @cil_method ref); + +cil_raiser(unique int event: @cil_event ref, int method: @cil_method ref); + +cil_property( + unique int id: @cil_property, + int parent: @cil_type ref, + string name: string ref, + int property_type: @cil_type ref); + +#keyset[parent, name] +cil_event(unique int id: @cil_event, + int parent: @cil_type ref, + string name: string ref, + int event_type: @cil_type ref); + +#keyset[impl, index] +cil_local_variable( + unique int id: @cil_local_variable, + int impl: @cil_method_implementation ref, + int index: int ref, + int var_type: @cil_type ref); + +// CIL handlers (exception handlers etc). + +case @cil_handler.kind of + 0 = @cil_catch_handler +| 1 = @cil_filter_handler +| 2 = @cil_finally_handler +| 4 = @cil_fault_handler +; + +#keyset[impl, index] +cil_handler( + unique int id: @cil_handler, + int impl: @cil_method_implementation ref, + int index: int ref, + int kind: int ref, + int try_start: @cil_instruction ref, + int try_end: @cil_instruction ref, + int handler_start: @cil_instruction ref); + +cil_handler_filter( + unique int id: @cil_handler ref, + int filter_start: @cil_instruction ref); + +cil_handler_type( + unique int id: @cil_handler ref, + int catch_type: @cil_type ref); + +@cil_controlflow_node = @cil_entry_point | @cil_instruction; + +@cil_entry_point = @cil_method_implementation | @cil_handler; + +@cil_dataflow_node = @cil_instruction | @cil_variable | @cil_method; + +cil_method_stack_size( + unique int method: @cil_method_implementation ref, + int size: int ref); + +// CIL modifiers + +cil_public(int id: @cil_member ref); +cil_private(int id: @cil_member ref); +cil_protected(int id: @cil_member ref); +cil_internal(int id: @cil_member ref); +cil_static(int id: @cil_member ref); +cil_sealed(int id: @cil_member ref); +cil_virtual(int id: @cil_method ref); +cil_abstract(int id: @cil_member ref); +cil_class(int id: @cil_type ref); +cil_interface(int id: @cil_type ref); +cil_security(int id: @cil_member ref); +cil_requiresecobject(int id: @cil_method ref); +cil_specialname(int id: @cil_method ref); +cil_newslot(int id: @cil_method ref); + +cil_base_class(unique int id: @cil_type ref, int base: @cil_type ref); +cil_base_interface(int id: @cil_type ref, int base: @cil_type ref); +cil_enum_underlying_type(unique int id: @cil_type ref, int underlying: @cil_type ref); + +#keyset[unbound, index] +cil_type_parameter( + int unbound: @cil_member ref, + int index: int ref, + int param: @cil_typeparameter ref); + +#keyset[bound, index] +cil_type_argument( + int bound: @cil_member ref, + int index: int ref, + int t: @cil_type ref); + +// CIL type parameter constraints + +cil_typeparam_covariant(int tp: @cil_typeparameter ref); +cil_typeparam_contravariant(int tp: @cil_typeparameter ref); +cil_typeparam_class(int tp: @cil_typeparameter ref); +cil_typeparam_struct(int tp: @cil_typeparameter ref); +cil_typeparam_new(int tp: @cil_typeparameter ref); +cil_typeparam_constraint(int tp: @cil_typeparameter ref, int supertype: @cil_type ref); + +// CIL attributes + +cil_attribute( + unique int attributeid: @cil_attribute, + int element: @cil_declaration ref, + int constructor: @cil_method ref); + +#keyset[attribute_id, param] +cil_attribute_named_argument( + int attribute_id: @cil_attribute ref, + string param: string ref, + string value: string ref); + +#keyset[attribute_id, index] +cil_attribute_positional_argument( + int attribute_id: @cil_attribute ref, + int index: int ref, + string value: string ref); + + +// Common .Net data model covering both C# and CIL + +// Common elements +@dotnet_element = @element | @cil_element; +@dotnet_named_element = @named_element | @cil_named_element; +@dotnet_callable = @callable | @cil_method; +@dotnet_variable = @variable | @cil_variable; +@dotnet_field = @field | @cil_field; +@dotnet_parameter = @parameter | @cil_parameter; +@dotnet_declaration = @declaration | @cil_declaration; +@dotnet_member = @member | @cil_member; +@dotnet_event = @event | @cil_event; +@dotnet_property = @property | @cil_property | @indexer; + +// Common types +@dotnet_type = @type | @cil_type; +@dotnet_call = @call | @cil_call_any; +@dotnet_throw = @throw_element | @cil_throw_any; +@dotnet_valueorreftype = @cil_valueorreftype | @value_or_ref_type | @cil_array_type | @void_type; +@dotnet_typeparameter = @type_parameter | @cil_typeparameter; +@dotnet_array_type = @array_type | @cil_array_type; +@dotnet_pointer_type = @pointer_type | @cil_pointer_type; +@dotnet_type_parameter = @type_parameter | @cil_typeparameter; +@dotnet_generic = @dotnet_valueorreftype | @dotnet_callable; + +// Attributes +@dotnet_attribute = @attribute | @cil_attribute; + +// Expressions +@dotnet_expr = @expr | @cil_expr; + +// Literals +@dotnet_literal = @literal_expr | @cil_literal; +@dotnet_string_literal = @string_literal_expr | @cil_ldstr; +@dotnet_int_literal = @integer_literal_expr | @cil_ldc_i; +@dotnet_float_literal = @float_literal_expr | @cil_ldc_r; +@dotnet_null_literal = @null_literal_expr | @cil_ldnull; + +@metadata_entity = @cil_method | @cil_type | @cil_field | @cil_property | @field | @property | + @callable | @value_or_ref_type | @void_type; + +#keyset[entity, location] +metadata_handle(int entity : @metadata_entity ref, int location: @assembly ref, int handle: int ref) diff --git a/csharp/upgrades/094972aab8c537db2cec0b9508361ca9d4cc2006/semmlecode.csharp.dbscheme b/csharp/upgrades/094972aab8c537db2cec0b9508361ca9d4cc2006/semmlecode.csharp.dbscheme new file mode 100644 index 00000000000..26249c105a8 --- /dev/null +++ b/csharp/upgrades/094972aab8c537db2cec0b9508361ca9d4cc2006/semmlecode.csharp.dbscheme @@ -0,0 +1,1909 @@ + +/** + * An invocation of the compiler. Note that more than one file may be + * compiled per invocation. For example, this command compiles three + * source files: + * + * csc f1.cs f2.cs f3.cs + * + * The `id` simply identifies the invocation, while `cwd` is the working + * directory from which the compiler was invoked. + */ +compilations( + unique int id : @compilation, + string cwd : string ref +); + +/** + * The arguments that were passed to the extractor for a compiler + * invocation. If `id` is for the compiler invocation + * + * csc f1.cs f2.cs f3.cs + * + * then typically there will be rows for + * + * num | arg + * --- | --- + * 0 | --compiler + * 1 | *path to compiler* + * 2 | --cil + * 3 | f1.cs + * 4 | f2.cs + * 5 | f3.cs + */ +#keyset[id, num] +compilation_args( + int id : @compilation ref, + int num : int ref, + string arg : string ref +); + +/** + * The source files that are compiled by a compiler invocation. + * If `id` is for the compiler invocation + * + * csc f1.cs f2.cs f3.cs + * + * then there will be rows for + * + * num | arg + * --- | --- + * 0 | f1.cs + * 1 | f2.cs + * 2 | f3.cs + */ +#keyset[id, num] +compilation_compiling_files( + int id : @compilation ref, + int num : int ref, + int file : @file ref +); + +/** + * The references used by a compiler invocation. + * If `id` is for the compiler invocation + * + * csc f1.cs f2.cs f3.cs /r:ref1.dll /r:ref2.dll /r:ref3.dll + * + * then there will be rows for + * + * num | arg + * --- | --- + * 0 | ref1.dll + * 1 | ref2.dll + * 2 | ref3.dll + */ +#keyset[id, num] +compilation_referencing_files( + int id : @compilation ref, + int num : int ref, + int file : @file ref +); + +/** + * The time taken by the extractor for a compiler invocation. + * + * For each file `num`, there will be rows for + * + * kind | seconds + * ---- | --- + * 1 | CPU seconds used by the extractor frontend + * 2 | Elapsed seconds during the extractor frontend + * 3 | CPU seconds used by the extractor backend + * 4 | Elapsed seconds during the extractor backend + */ +#keyset[id, num, kind] +compilation_time( + int id : @compilation ref, + int num : int ref, + /* kind: + 1 = frontend_cpu_seconds + 2 = frontend_elapsed_seconds + 3 = extractor_cpu_seconds + 4 = extractor_elapsed_seconds + */ + int kind : int ref, + float seconds : float ref +); + +/** + * An error or warning generated by the extractor. + * The diagnostic message `diagnostic` was generated during compiler + * invocation `compilation`, and is the `file_number_diagnostic_number`th + * message generated while extracting the `file_number`th file of that + * invocation. + */ +#keyset[compilation, file_number, file_number_diagnostic_number] +diagnostic_for( + unique int diagnostic : @diagnostic ref, + int compilation : @compilation ref, + int file_number : int ref, + int file_number_diagnostic_number : int ref +); + +diagnostics( + unique int id: @diagnostic, + int severity: int ref, + string error_tag: string ref, + string error_message: string ref, + string full_error_message: string ref, + int location: @location_default ref +); + +extractor_messages( + unique int id: @extractor_message, + int severity: int ref, + string origin : string ref, + string text : string ref, + string entity : string ref, + int location: @location_default ref, + string stack_trace : string ref +); + +/** + * If extraction was successful, then `cpu_seconds` and + * `elapsed_seconds` are the CPU time and elapsed time (respectively) + * that extraction took for compiler invocation `id`. + */ +compilation_finished( + unique int id : @compilation ref, + float cpu_seconds : float ref, + float elapsed_seconds : float ref +); + +/* + * External artifacts + */ + +externalDefects( + unique int id: @externalDefect, + string queryPath: string ref, + int location: @location ref, + string message: string ref, + float severity: float ref); + +externalMetrics( + unique int id: @externalMetric, + string queryPath: string ref, + int location: @location ref, + float value: float ref); + +externalData( + int id: @externalDataElement, + string path: string ref, + int column: int ref, + string value: string ref); + +snapshotDate( + unique date snapshotDate: date ref); + +sourceLocationPrefix( + string prefix: string ref); + +/* + * Duplicate code + */ + +duplicateCode( + unique int id: @duplication, + string relativePath: string ref, + int equivClass: int ref); + +similarCode( + unique int id: @similarity, + string relativePath: string ref, + int equivClass: int ref); + +@duplication_or_similarity = @duplication | @similarity + +tokens( + int id: @duplication_or_similarity ref, + int offset: int ref, + int beginLine: int ref, + int beginColumn: int ref, + int endLine: int ref, + int endColumn: int ref); + +/* + * C# dbscheme + */ + +/** ELEMENTS **/ + +@element = @declaration | @stmt | @expr | @modifier | @attribute | @namespace_declaration + | @using_directive | @type_parameter_constraints | @external_element + | @xmllocatable | @asp_element | @namespace; + +@declaration = @callable | @generic | @assignable | @namespace; + +@named_element = @namespace | @declaration; + +@declaration_with_accessors = @property | @indexer | @event; + +@assignable = @variable | @assignable_with_accessors | @event; + +@assignable_with_accessors = @property | @indexer; + +@external_element = @externalMetric | @externalDefect | @externalDataElement; + +@attributable = @assembly | @field | @parameter | @operator | @method | @constructor + | @destructor | @callable_accessor | @value_or_ref_type | @declaration_with_accessors + | @local_function; + +/** LOCATIONS, ASEMMBLIES, MODULES, FILES and FOLDERS **/ + +@location = @location_default | @assembly; + +locations_default( + unique int id: @location_default, + int file: @file ref, + int beginLine: int ref, + int beginColumn: int ref, + int endLine: int ref, + int endColumn: int ref); + +@sourceline = @file | @callable | @xmllocatable; + +numlines( + int element_id: @sourceline ref, + int num_lines: int ref, + int num_code: int ref, + int num_comment: int ref); + +assemblies( + unique int id: @assembly, + int file: @file ref, + string fullname: string ref, + string name: string ref, + string version: string ref); + +/* + fromSource(0) = unknown, + fromSource(1) = from source, + fromSource(2) = from library +*/ +files( + unique int id: @file, + string name: string ref, + string simple: string ref, + string ext: string ref, + int fromSource: int ref); + +folders( + unique int id: @folder, + string name: string ref, + string simple: string ref); + +@container = @folder | @file ; + +containerparent( + int parent: @container ref, + unique int child: @container ref); + +file_extraction_mode( + unique int file: @file ref, + int mode: int ref + /* 0 = normal, 1 = standalone extractor */ + ); + +/** NAMESPACES **/ + +@type_container = @namespace | @type; + +namespaces( + unique int id: @namespace, + string name: string ref); + +namespace_declarations( + unique int id: @namespace_declaration, + int namespace_id: @namespace ref); + +namespace_declaration_location( + unique int id: @namespace_declaration ref, + int loc: @location ref); + +parent_namespace( + unique int child_id: @type_container ref, + int namespace_id: @namespace ref); + +@declaration_or_directive = @namespace_declaration | @type | @using_directive; + +parent_namespace_declaration( + int child_id: @declaration_or_directive ref, // cannot be unique because of partial classes + int namespace_id: @namespace_declaration ref); + +@using_directive = @using_namespace_directive | @using_static_directive; + +using_namespace_directives( + unique int id: @using_namespace_directive, + int namespace_id: @namespace ref); + +using_static_directives( + unique int id: @using_static_directive, + int type_id: @type_or_ref ref); + +using_directive_location( + unique int id: @using_directive ref, + int loc: @location ref); + +/** TYPES **/ + +types( + unique int id: @type, + int kind: int ref, + string name: string ref); + +case @type.kind of + 1 = @bool_type +| 2 = @char_type +| 3 = @decimal_type +| 4 = @sbyte_type +| 5 = @short_type +| 6 = @int_type +| 7 = @long_type +| 8 = @byte_type +| 9 = @ushort_type +| 10 = @uint_type +| 11 = @ulong_type +| 12 = @float_type +| 13 = @double_type +| 14 = @enum_type +| 15 = @struct_type +| 17 = @class_type +| 19 = @interface_type +| 20 = @delegate_type +| 21 = @null_type +| 22 = @type_parameter +| 23 = @pointer_type +| 24 = @nullable_type +| 25 = @array_type +| 26 = @void_type +| 27 = @int_ptr_type +| 28 = @uint_ptr_type +| 29 = @dynamic_type +| 30 = @arglist_type +| 31 = @unknown_type +| 32 = @tuple_type + ; + +@simple_type = @bool_type | @char_type | @integral_type | @floating_point_type | @decimal_type; +@integral_type = @signed_integral_type | @unsigned_integral_type; +@signed_integral_type = @sbyte_type | @short_type | @int_type | @long_type; +@unsigned_integral_type = @byte_type | @ushort_type | @uint_type | @ulong_type; +@floating_point_type = @float_type | @double_type; +@value_type = @simple_type | @enum_type | @struct_type | @nullable_type | @int_ptr_type + | @uint_ptr_type | @tuple_type; +@ref_type = @class_type | @interface_type | @array_type | @delegate_type | @null_type + | @dynamic_type; +@value_or_ref_type = @value_type | @ref_type; + +typerefs( + unique int id: @typeref, + string name: string ref); + +typeref_type( + int id: @typeref ref, + unique int typeId: @type ref); + +@type_or_ref = @type | @typeref; + +array_element_type( + unique int array: @array_type ref, + int dimension: int ref, + int rank: int ref, + int element: @type_or_ref ref); + +nullable_underlying_type( + unique int nullable: @nullable_type ref, + int underlying: @type_or_ref ref); + +pointer_referent_type( + unique int pointer: @pointer_type ref, + int referent: @type_or_ref ref); + +enum_underlying_type( + unique int enum_id: @enum_type ref, + int underlying_type_id: @type_or_ref ref); + +delegate_return_type( + unique int delegate_id: @delegate_type ref, + int return_type_id: @type_or_ref ref); + +extend( + unique int sub: @type ref, + int super: @type_or_ref ref); + +anonymous_types( + unique int id: @type ref); + +@interface_or_ref = @interface_type | @typeref; + +implement( + int sub: @type ref, + int super: @type_or_ref ref); + +type_location( + int id: @type ref, + int loc: @location ref); + +tuple_underlying_type( + unique int tuple: @tuple_type ref, + int struct: @type_or_ref ref); + +#keyset[tuple, index] +tuple_element( + int tuple: @tuple_type ref, + int index: int ref, + unique int field: @field ref); + +attributes( + unique int id: @attribute, + int type_id: @type_or_ref ref, + int target: @attributable ref); + +attribute_location( + int id: @attribute ref, + int loc: @location ref); + +@type_mention_parent = @element | @type_mention; + +type_mention( + unique int id: @type_mention, + int type_id: @type_or_ref ref, + int parent: @type_mention_parent ref); + +type_mention_location( + unique int id: @type_mention ref, + int loc: @location ref); + +@has_type_annotation = @assignable | @type_parameter | @callable | @expr | @delegate_type | @generic; + +/** + * A direct annotation on an entity, for example `string? x;`. + * + * Annotations: + * 2 = reftype is not annotated "!" + * 3 = reftype is annotated "?" + * 4 = readonly ref type / in parameter + * 5 = ref type parameter, return or local variable + * 6 = out parameter + * + * Note that the annotation depends on the element it annotates. + * @assignable: The annotation is on the type of the assignable, for example the variable type. + * @type_parameter: The annotation is on the reftype constraint + * @callable: The annotation is on the return type + * @array_type: The annotation is on the element type + */ +type_annotation(int id: @has_type_annotation ref, int annotation: int ref); + +nullability(unique int nullability: @nullability, int kind: int ref); + +case @nullability.kind of + 0 = @oblivious +| 1 = @not_annotated +| 2 = @annotated +; + +#keyset[parent, index] +nullability_parent(int nullability: @nullability ref, int index: int ref, int parent: @nullability ref) + +type_nullability(int id: @has_type_annotation ref, int nullability: @nullability ref); + +/** + * The nullable flow state of an expression, as determined by Roslyn. + * 0 = none (default, not populated) + * 1 = not null + * 2 = maybe null + */ +expr_flowstate(unique int id: @expr ref, int state: int ref); + +/** GENERICS **/ + +@generic = @type | @method | @local_function; + +type_parameters( + unique int id: @type_parameter ref, + int index: int ref, + int generic_id: @generic ref, + int variance: int ref /* none = 0, out = 1, in = 2 */); + +#keyset[constructed_id, index] +type_arguments( + int id: @type_or_ref ref, + int index: int ref, + int constructed_id: @generic_or_ref ref); + +@generic_or_ref = @generic | @typeref; + +constructed_generic( + unique int constructed: @generic ref, + int generic: @generic_or_ref ref); + +type_parameter_constraints( + unique int id: @type_parameter_constraints, + int param_id: @type_parameter ref); + +type_parameter_constraints_location( + int id: @type_parameter_constraints ref, + int loc: @location ref); + +general_type_parameter_constraints( + int id: @type_parameter_constraints ref, + int kind: int ref /* class = 1, struct = 2, new = 3 */); + +specific_type_parameter_constraints( + int id: @type_parameter_constraints ref, + int base_id: @type_or_ref ref); + +specific_type_parameter_nullability( + int id: @type_parameter_constraints ref, + int base_id: @type_or_ref ref, + int nullability: @nullability ref); + +/** MODIFIERS */ + +@modifiable = @modifiable_direct | @event_accessor; + +@modifiable_direct = @member | @accessor | @local_function | @anonymous_function_expr; + +modifiers( + unique int id: @modifier, + string name: string ref); + +has_modifiers( + int id: @modifiable_direct ref, + int mod_id: @modifier ref); + +compiler_generated(unique int id: @modifiable_direct ref); + +/** MEMBERS **/ + +@member = @method | @constructor | @destructor | @field | @property | @event | @operator | @indexer | @type; + +@named_exprorstmt = @goto_stmt | @labeled_stmt | @expr; + +@virtualizable = @method | @property | @indexer | @event; + +exprorstmt_name( + unique int parent_id: @named_exprorstmt ref, + string name: string ref); + +nested_types( + unique int id: @type ref, + int declaring_type_id: @type ref, + int unbound_id: @type ref); + +properties( + unique int id: @property, + string name: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @property ref); + +property_location( + int id: @property ref, + int loc: @location ref); + +indexers( + unique int id: @indexer, + string name: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @indexer ref); + +indexer_location( + int id: @indexer ref, + int loc: @location ref); + +accessors( + unique int id: @accessor, + int kind: int ref, + string name: string ref, + int declaring_member_id: @member ref, + int unbound_id: @accessor ref); + +case @accessor.kind of + 1 = @getter +| 2 = @setter + ; + +init_only_accessors( + unique int id: @accessor ref); + +accessor_location( + int id: @accessor ref, + int loc: @location ref); + +events( + unique int id: @event, + string name: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @event ref); + +event_location( + int id: @event ref, + int loc: @location ref); + +event_accessors( + unique int id: @event_accessor, + int kind: int ref, + string name: string ref, + int declaring_event_id: @event ref, + int unbound_id: @event_accessor ref); + +case @event_accessor.kind of + 1 = @add_event_accessor +| 2 = @remove_event_accessor + ; + +event_accessor_location( + int id: @event_accessor ref, + int loc: @location ref); + +operators( + unique int id: @operator, + string name: string ref, + string symbol: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @operator ref); + +operator_location( + int id: @operator ref, + int loc: @location ref); + +constant_value( + int id: @variable ref, + string value: string ref); + +/** CALLABLES **/ + +@callable = @method | @constructor | @destructor | @operator | @callable_accessor | @anonymous_function_expr | @local_function; + +@callable_accessor = @accessor | @event_accessor; + +methods( + unique int id: @method, + string name: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @method ref); + +method_location( + int id: @method ref, + int loc: @location ref); + +constructors( + unique int id: @constructor, + string name: string ref, + int declaring_type_id: @type ref, + int unbound_id: @constructor ref); + +constructor_location( + int id: @constructor ref, + int loc: @location ref); + +destructors( + unique int id: @destructor, + string name: string ref, + int declaring_type_id: @type ref, + int unbound_id: @destructor ref); + +destructor_location( + int id: @destructor ref, + int loc: @location ref); + +overrides( + int id: @callable ref, + int base_id: @callable ref); + +explicitly_implements( + int id: @member ref, + int interface_id: @interface_or_ref ref); + +local_functions( + unique int id: @local_function, + string name: string ref, + int return_type: @type ref, + int unbound_id: @local_function ref); + +local_function_stmts( + unique int fn: @local_function_stmt ref, + int stmt: @local_function ref); + +/** VARIABLES **/ + +@variable = @local_scope_variable | @field; + +@local_scope_variable = @local_variable | @parameter; + +fields( + unique int id: @field, + int kind: int ref, + string name: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @field ref); + +case @field.kind of + 1 = @addressable_field +| 2 = @constant + ; + +field_location( + int id: @field ref, + int loc: @location ref); + +localvars( + unique int id: @local_variable, + int kind: int ref, + string name: string ref, + int implicitly_typed: int ref /* 0 = no, 1 = yes */, + int type_id: @type_or_ref ref, + int parent_id: @local_var_decl_expr ref); + +case @local_variable.kind of + 1 = @addressable_local_variable +| 2 = @local_constant +| 3 = @local_variable_ref + ; + +localvar_location( + unique int id: @local_variable ref, + int loc: @location ref); + +@parameterizable = @callable | @delegate_type | @indexer; + +#keyset[name, parent_id] +#keyset[index, parent_id] +params( + unique int id: @parameter, + string name: string ref, + int type_id: @type_or_ref ref, + int index: int ref, + int mode: int ref, /* value = 0, ref = 1, out = 2, array = 3, this = 4 */ + int parent_id: @parameterizable ref, + int unbound_id: @parameter ref); + +param_location( + int id: @parameter ref, + int loc: @location ref); + +/** STATEMENTS **/ + +@exprorstmt_parent = @control_flow_element | @top_level_exprorstmt_parent; + +statements( + unique int id: @stmt, + int kind: int ref); + +#keyset[index, parent] +stmt_parent( + unique int stmt: @stmt ref, + int index: int ref, + int parent: @control_flow_element ref); + +@top_level_stmt_parent = @callable; + +// [index, parent] is not a keyset because the same parent may be compiled multiple times +stmt_parent_top_level( + unique int stmt: @stmt ref, + int index: int ref, + int parent: @top_level_stmt_parent ref); + +case @stmt.kind of + 1 = @block_stmt +| 2 = @expr_stmt +| 3 = @if_stmt +| 4 = @switch_stmt +| 5 = @while_stmt +| 6 = @do_stmt +| 7 = @for_stmt +| 8 = @foreach_stmt +| 9 = @break_stmt +| 10 = @continue_stmt +| 11 = @goto_stmt +| 12 = @goto_case_stmt +| 13 = @goto_default_stmt +| 14 = @throw_stmt +| 15 = @return_stmt +| 16 = @yield_stmt +| 17 = @try_stmt +| 18 = @checked_stmt +| 19 = @unchecked_stmt +| 20 = @lock_stmt +| 21 = @using_block_stmt +| 22 = @var_decl_stmt +| 23 = @const_decl_stmt +| 24 = @empty_stmt +| 25 = @unsafe_stmt +| 26 = @fixed_stmt +| 27 = @label_stmt +| 28 = @catch +| 29 = @case_stmt +| 30 = @local_function_stmt +| 31 = @using_decl_stmt + ; + +@using_stmt = @using_block_stmt | @using_decl_stmt; + +@labeled_stmt = @label_stmt | @case; + +@decl_stmt = @var_decl_stmt | @const_decl_stmt | @using_decl_stmt; + +@cond_stmt = @if_stmt | @switch_stmt; + +@loop_stmt = @while_stmt | @do_stmt | @for_stmt | @foreach_stmt; + +@jump_stmt = @break_stmt | @goto_any_stmt | @continue_stmt | @throw_stmt | @return_stmt + | @yield_stmt; + +@goto_any_stmt = @goto_default_stmt | @goto_case_stmt | @goto_stmt; + + +stmt_location( + unique int id: @stmt ref, + int loc: @location ref); + +catch_type( + unique int catch_id: @catch ref, + int type_id: @type_or_ref ref, + int kind: int ref /* explicit = 1, implicit = 2 */); + +/** EXPRESSIONS **/ + +expressions( + unique int id: @expr, + int kind: int ref, + int type_id: @type_or_ref ref); + +#keyset[index, parent] +expr_parent( + unique int expr: @expr ref, + int index: int ref, + int parent: @control_flow_element ref); + +@top_level_expr_parent = @attribute | @field | @property | @indexer | @parameter; + +@top_level_exprorstmt_parent = @top_level_expr_parent | @top_level_stmt_parent; + +// [index, parent] is not a keyset because the same parent may be compiled multiple times +expr_parent_top_level( + unique int expr: @expr ref, + int index: int ref, + int parent: @top_level_exprorstmt_parent ref); + +case @expr.kind of +/* literal */ + 1 = @bool_literal_expr +| 2 = @char_literal_expr +| 3 = @decimal_literal_expr +| 4 = @int_literal_expr +| 5 = @long_literal_expr +| 6 = @uint_literal_expr +| 7 = @ulong_literal_expr +| 8 = @float_literal_expr +| 9 = @double_literal_expr +| 10 = @string_literal_expr +| 11 = @null_literal_expr +/* primary & unary */ +| 12 = @this_access_expr +| 13 = @base_access_expr +| 14 = @local_variable_access_expr +| 15 = @parameter_access_expr +| 16 = @field_access_expr +| 17 = @property_access_expr +| 18 = @method_access_expr +| 19 = @event_access_expr +| 20 = @indexer_access_expr +| 21 = @array_access_expr +| 22 = @type_access_expr +| 23 = @typeof_expr +| 24 = @method_invocation_expr +| 25 = @delegate_invocation_expr +| 26 = @operator_invocation_expr +| 27 = @cast_expr +| 28 = @object_creation_expr +| 29 = @explicit_delegate_creation_expr +| 30 = @implicit_delegate_creation_expr +| 31 = @array_creation_expr +| 32 = @default_expr +| 33 = @plus_expr +| 34 = @minus_expr +| 35 = @bit_not_expr +| 36 = @log_not_expr +| 37 = @post_incr_expr +| 38 = @post_decr_expr +| 39 = @pre_incr_expr +| 40 = @pre_decr_expr +/* multiplicative */ +| 41 = @mul_expr +| 42 = @div_expr +| 43 = @rem_expr +/* additive */ +| 44 = @add_expr +| 45 = @sub_expr +/* shift */ +| 46 = @lshift_expr +| 47 = @rshift_expr +/* relational */ +| 48 = @lt_expr +| 49 = @gt_expr +| 50 = @le_expr +| 51 = @ge_expr +/* equality */ +| 52 = @eq_expr +| 53 = @ne_expr +/* logical */ +| 54 = @bit_and_expr +| 55 = @bit_xor_expr +| 56 = @bit_or_expr +| 57 = @log_and_expr +| 58 = @log_or_expr +/* type testing */ +| 59 = @is_expr +| 60 = @as_expr +/* null coalescing */ +| 61 = @null_coalescing_expr +/* conditional */ +| 62 = @conditional_expr +/* assignment */ +| 63 = @simple_assign_expr +| 64 = @assign_add_expr +| 65 = @assign_sub_expr +| 66 = @assign_mul_expr +| 67 = @assign_div_expr +| 68 = @assign_rem_expr +| 69 = @assign_and_expr +| 70 = @assign_xor_expr +| 71 = @assign_or_expr +| 72 = @assign_lshift_expr +| 73 = @assign_rshift_expr +/* more */ +| 74 = @object_init_expr +| 75 = @collection_init_expr +| 76 = @array_init_expr +| 77 = @checked_expr +| 78 = @unchecked_expr +| 79 = @constructor_init_expr +| 80 = @add_event_expr +| 81 = @remove_event_expr +| 82 = @par_expr +| 83 = @local_var_decl_expr +| 84 = @lambda_expr +| 85 = @anonymous_method_expr +| 86 = @namespace_expr +/* dynamic */ +| 92 = @dynamic_element_access_expr +| 93 = @dynamic_member_access_expr +/* unsafe */ +| 100 = @pointer_indirection_expr +| 101 = @address_of_expr +| 102 = @sizeof_expr +/* async */ +| 103 = @await_expr +/* C# 6.0 */ +| 104 = @nameof_expr +| 105 = @interpolated_string_expr +| 106 = @unknown_expr +/* C# 7.0 */ +| 107 = @throw_expr +| 108 = @tuple_expr +| 109 = @local_function_invocation_expr +| 110 = @ref_expr +| 111 = @discard_expr +/* C# 8.0 */ +| 112 = @range_expr +| 113 = @index_expr +| 114 = @switch_expr +| 115 = @recursive_pattern_expr +| 116 = @property_pattern_expr +| 117 = @positional_pattern_expr +| 118 = @switch_case_expr +| 119 = @assign_coalesce_expr +| 120 = @suppress_nullable_warning_expr +| 121 = @namespace_access_expr +; + +@switch = @switch_stmt | @switch_expr; +@case = @case_stmt | @switch_case_expr; +@pattern_match = @case | @is_expr; + +@integer_literal_expr = @int_literal_expr | @long_literal_expr | @uint_literal_expr | @ulong_literal_expr; +@real_literal_expr = @float_literal_expr | @double_literal_expr | @decimal_literal_expr; +@literal_expr = @bool_literal_expr | @char_literal_expr | @integer_literal_expr | @real_literal_expr + | @string_literal_expr | @null_literal_expr; + +@assign_expr = @simple_assign_expr | @assign_op_expr | @local_var_decl_expr; +@assign_op_expr = @assign_arith_expr | @assign_bitwise_expr | @assign_event_expr | @assign_coalesce_expr; +@assign_event_expr = @add_event_expr | @remove_event_expr; + +@assign_arith_expr = @assign_add_expr | @assign_sub_expr | @assign_mul_expr | @assign_div_expr + | @assign_rem_expr +@assign_bitwise_expr = @assign_and_expr | @assign_or_expr | @assign_xor_expr + | @assign_lshift_expr | @assign_rshift_expr; + +@member_access_expr = @field_access_expr | @property_access_expr | @indexer_access_expr | @event_access_expr + | @method_access_expr | @type_access_expr | @dynamic_member_access_expr; +@access_expr = @member_access_expr | @this_access_expr | @base_access_expr | @assignable_access_expr | @namespace_access_expr; +@element_access_expr = @indexer_access_expr | @array_access_expr | @dynamic_element_access_expr; + +@local_variable_access = @local_variable_access_expr | @local_var_decl_expr; +@local_scope_variable_access_expr = @parameter_access_expr | @local_variable_access; +@variable_access_expr = @local_scope_variable_access_expr | @field_access_expr; + +@assignable_access_expr = @variable_access_expr | @property_access_expr | @element_access_expr + | @event_access_expr | @dynamic_member_access_expr; + +@objectorcollection_init_expr = @object_init_expr | @collection_init_expr; + +@delegate_creation_expr = @explicit_delegate_creation_expr | @implicit_delegate_creation_expr; + +@bin_arith_op_expr = @mul_expr | @div_expr | @rem_expr | @add_expr | @sub_expr; +@incr_op_expr = @pre_incr_expr | @post_incr_expr; +@decr_op_expr = @pre_decr_expr | @post_decr_expr; +@mut_op_expr = @incr_op_expr | @decr_op_expr; +@un_arith_op_expr = @plus_expr | @minus_expr | @mut_op_expr; +@arith_op_expr = @bin_arith_op_expr | @un_arith_op_expr; + +@ternary_log_op_expr = @conditional_expr; +@bin_log_op_expr = @log_and_expr | @log_or_expr | @null_coalescing_expr; +@un_log_op_expr = @log_not_expr; +@log_expr = @un_log_op_expr | @bin_log_op_expr | @ternary_log_op_expr; + +@bin_bit_op_expr = @bit_and_expr | @bit_or_expr | @bit_xor_expr | @lshift_expr + | @rshift_expr; +@un_bit_op_expr = @bit_not_expr; +@bit_expr = @un_bit_op_expr | @bin_bit_op_expr; + +@equality_op_expr = @eq_expr | @ne_expr; +@rel_op_expr = @gt_expr | @lt_expr| @ge_expr | @le_expr; +@comp_expr = @equality_op_expr | @rel_op_expr; + +@op_expr = @assign_expr | @un_op | @bin_op | @ternary_op; + +@ternary_op = @ternary_log_op_expr; +@bin_op = @bin_arith_op_expr | @bin_log_op_expr | @bin_bit_op_expr | @comp_expr; +@un_op = @un_arith_op_expr | @un_log_op_expr | @un_bit_op_expr | @sizeof_expr + | @pointer_indirection_expr | @address_of_expr; + +@anonymous_function_expr = @lambda_expr | @anonymous_method_expr; + +@call = @method_invocation_expr | @constructor_init_expr | @operator_invocation_expr + | @delegate_invocation_expr | @object_creation_expr | @call_access_expr + | @local_function_invocation_expr; + +@call_access_expr = @property_access_expr | @event_access_expr | @indexer_access_expr; + +@late_bindable_expr = @dynamic_element_access_expr | @dynamic_member_access_expr + | @object_creation_expr | @method_invocation_expr | @operator_invocation_expr; + +@throw_element = @throw_expr | @throw_stmt; + +@implicitly_typeable_object_creation_expr = @object_creation_expr | @explicit_delegate_creation_expr; + +implicitly_typed_array_creation( + unique int id: @array_creation_expr ref); + +explicitly_sized_array_creation( + unique int id: @array_creation_expr ref); + +stackalloc_array_creation( + unique int id: @array_creation_expr ref); + +implicitly_typed_object_creation( + unique int id: @implicitly_typeable_object_creation_expr ref); + +mutator_invocation_mode( + unique int id: @operator_invocation_expr ref, + int mode: int ref /* prefix = 1, postfix = 2*/); + +expr_compiler_generated( + unique int id: @expr ref); + +expr_value( + unique int id: @expr ref, + string value: string ref); + +expr_call( + unique int caller_id: @expr ref, + int target_id: @callable ref); + +expr_access( + unique int accesser_id: @access_expr ref, + int target_id: @accessible ref); + +@accessible = @method | @assignable | @local_function | @namespace; + +expr_location( + unique int id: @expr ref, + int loc: @location ref); + +dynamic_member_name( + unique int id: @late_bindable_expr ref, + string name: string ref); + +@qualifiable_expr = @member_access_expr + | @method_invocation_expr + | @element_access_expr; + +conditional_access( + unique int id: @qualifiable_expr ref); + +expr_argument( + unique int id: @expr ref, + int mode: int ref); + /* mode is the same as params: value = 0, ref = 1, out = 2 */ + +expr_argument_name( + unique int id: @expr ref, + string name: string ref); + +/** CONTROL/DATA FLOW **/ + +@control_flow_element = @stmt | @expr; + +/* XML Files */ + +xmlEncoding ( + unique int id: @file ref, + string encoding: string ref); + +xmlDTDs( + unique int id: @xmldtd, + string root: string ref, + string publicId: string ref, + string systemId: string ref, + int fileid: @file ref); + +xmlElements( + unique int id: @xmlelement, + string name: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int fileid: @file ref); + +xmlAttrs( + unique int id: @xmlattribute, + int elementid: @xmlelement ref, + string name: string ref, + string value: string ref, + int idx: int ref, + int fileid: @file ref); + +xmlNs( + int id: @xmlnamespace, + string prefixName: string ref, + string URI: string ref, + int fileid: @file ref); + +xmlHasNs( + int elementId: @xmlnamespaceable ref, + int nsId: @xmlnamespace ref, + int fileid: @file ref); + +xmlComments( + unique int id: @xmlcomment, + string text: string ref, + int parentid: @xmlparent ref, + int fileid: @file ref); + +xmlChars( + unique int id: @xmlcharacters, + string text: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int isCDATA: int ref, + int fileid: @file ref); + +@xmlparent = @file | @xmlelement; +@xmlnamespaceable = @xmlelement | @xmlattribute; + +xmllocations( + int xmlElement: @xmllocatable ref, + int location: @location_default ref); + +@xmllocatable = @xmlcharacters | @xmlelement | @xmlcomment | @xmlattribute | @xmldtd | @file | @xmlnamespace; + +/* Comments */ + +commentline( + unique int id: @commentline, + int kind: int ref, + string text: string ref, + string rawtext: string ref); + +case @commentline.kind of + 0 = @singlelinecomment +| 1 = @xmldoccomment +| 2 = @multilinecomment; + +commentline_location( + unique int id: @commentline ref, + int loc: @location ref); + +commentblock( + unique int id : @commentblock); + +commentblock_location( + unique int id: @commentblock ref, + int loc: @location ref); + +commentblock_binding( + int id: @commentblock ref, + int entity: @element ref, + int bindtype: int ref); /* 0: Parent, 1: Best, 2: Before, 3: After */ + +commentblock_child( + int id: @commentblock ref, + int commentline: @commentline ref, + int index: int ref); + +/* ASP.NET */ + +case @asp_element.kind of + 0=@asp_close_tag +| 1=@asp_code +| 2=@asp_comment +| 3=@asp_data_binding +| 4=@asp_directive +| 5=@asp_open_tag +| 6=@asp_quoted_string +| 7=@asp_text +| 8=@asp_xml_directive; + +@asp_attribute = @asp_code | @asp_data_binding | @asp_quoted_string; + +asp_elements( + unique int id: @asp_element, + int kind: int ref, + int loc: @location ref); + +asp_comment_server(unique int comment: @asp_comment ref); +asp_code_inline(unique int code: @asp_code ref); +asp_directive_attribute( + int directive: @asp_directive ref, + int index: int ref, + string name: string ref, + int value: @asp_quoted_string ref); +asp_directive_name( + unique int directive: @asp_directive ref, + string name: string ref); +asp_element_body( + unique int element: @asp_element ref, + string body: string ref); +asp_tag_attribute( + int tag: @asp_open_tag ref, + int index: int ref, + string name: string ref, + int attribute: @asp_attribute ref); +asp_tag_name( + unique int tag: @asp_open_tag ref, + string name: string ref); +asp_tag_isempty(int tag: @asp_open_tag ref); + +/* Common Intermediate Language - CIL */ + +case @cil_instruction.opcode of + 0 = @cil_nop +| 1 = @cil_break +| 2 = @cil_ldarg_0 +| 3 = @cil_ldarg_1 +| 4 = @cil_ldarg_2 +| 5 = @cil_ldarg_3 +| 6 = @cil_ldloc_0 +| 7 = @cil_ldloc_1 +| 8 = @cil_ldloc_2 +| 9 = @cil_ldloc_3 +| 10 = @cil_stloc_0 +| 11 = @cil_stloc_1 +| 12 = @cil_stloc_2 +| 13 = @cil_stloc_3 +| 14 = @cil_ldarg_s +| 15 = @cil_ldarga_s +| 16 = @cil_starg_s +| 17 = @cil_ldloc_s +| 18 = @cil_ldloca_s +| 19 = @cil_stloc_s +| 20 = @cil_ldnull +| 21 = @cil_ldc_i4_m1 +| 22 = @cil_ldc_i4_0 +| 23 = @cil_ldc_i4_1 +| 24 = @cil_ldc_i4_2 +| 25 = @cil_ldc_i4_3 +| 26 = @cil_ldc_i4_4 +| 27 = @cil_ldc_i4_5 +| 28 = @cil_ldc_i4_6 +| 29 = @cil_ldc_i4_7 +| 30 = @cil_ldc_i4_8 +| 31 = @cil_ldc_i4_s +| 32 = @cil_ldc_i4 +| 33 = @cil_ldc_i8 +| 34 = @cil_ldc_r4 +| 35 = @cil_ldc_r8 +| 37 = @cil_dup +| 38 = @cil_pop +| 39 = @cil_jmp +| 40 = @cil_call +| 41 = @cil_calli +| 42 = @cil_ret +| 43 = @cil_br_s +| 44 = @cil_brfalse_s +| 45 = @cil_brtrue_s +| 46 = @cil_beq_s +| 47 = @cil_bge_s +| 48 = @cil_bgt_s +| 49 = @cil_ble_s +| 50 = @cil_blt_s +| 51 = @cil_bne_un_s +| 52 = @cil_bge_un_s +| 53 = @cil_bgt_un_s +| 54 = @cil_ble_un_s +| 55 = @cil_blt_un_s +| 56 = @cil_br +| 57 = @cil_brfalse +| 58 = @cil_brtrue +| 59 = @cil_beq +| 60 = @cil_bge +| 61 = @cil_bgt +| 62 = @cil_ble +| 63 = @cil_blt +| 64 = @cil_bne_un +| 65 = @cil_bge_un +| 66 = @cil_bgt_un +| 67 = @cil_ble_un +| 68 = @cil_blt_un +| 69 = @cil_switch +| 70 = @cil_ldind_i1 +| 71 = @cil_ldind_u1 +| 72 = @cil_ldind_i2 +| 73 = @cil_ldind_u2 +| 74 = @cil_ldind_i4 +| 75 = @cil_ldind_u4 +| 76 = @cil_ldind_i8 +| 77 = @cil_ldind_i +| 78 = @cil_ldind_r4 +| 79 = @cil_ldind_r8 +| 80 = @cil_ldind_ref +| 81 = @cil_stind_ref +| 82 = @cil_stind_i1 +| 83 = @cil_stind_i2 +| 84 = @cil_stind_i4 +| 85 = @cil_stind_i8 +| 86 = @cil_stind_r4 +| 87 = @cil_stind_r8 +| 88 = @cil_add +| 89 = @cil_sub +| 90 = @cil_mul +| 91 = @cil_div +| 92 = @cil_div_un +| 93 = @cil_rem +| 94 = @cil_rem_un +| 95 = @cil_and +| 96 = @cil_or +| 97 = @cil_xor +| 98 = @cil_shl +| 99 = @cil_shr +| 100 = @cil_shr_un +| 101 = @cil_neg +| 102 = @cil_not +| 103 = @cil_conv_i1 +| 104 = @cil_conv_i2 +| 105 = @cil_conv_i4 +| 106 = @cil_conv_i8 +| 107 = @cil_conv_r4 +| 108 = @cil_conv_r8 +| 109 = @cil_conv_u4 +| 110 = @cil_conv_u8 +| 111 = @cil_callvirt +| 112 = @cil_cpobj +| 113 = @cil_ldobj +| 114 = @cil_ldstr +| 115 = @cil_newobj +| 116 = @cil_castclass +| 117 = @cil_isinst +| 118 = @cil_conv_r_un +| 121 = @cil_unbox +| 122 = @cil_throw +| 123 = @cil_ldfld +| 124 = @cil_ldflda +| 125 = @cil_stfld +| 126 = @cil_ldsfld +| 127 = @cil_ldsflda +| 128 = @cil_stsfld +| 129 = @cil_stobj +| 130 = @cil_conv_ovf_i1_un +| 131 = @cil_conv_ovf_i2_un +| 132 = @cil_conv_ovf_i4_un +| 133 = @cil_conv_ovf_i8_un +| 134 = @cil_conv_ovf_u1_un +| 135 = @cil_conv_ovf_u2_un +| 136 = @cil_conv_ovf_u4_un +| 137 = @cil_conv_ovf_u8_un +| 138 = @cil_conv_ovf_i_un +| 139 = @cil_conv_ovf_u_un +| 140 = @cil_box +| 141 = @cil_newarr +| 142 = @cil_ldlen +| 143 = @cil_ldelema +| 144 = @cil_ldelem_i1 +| 145 = @cil_ldelem_u1 +| 146 = @cil_ldelem_i2 +| 147 = @cil_ldelem_u2 +| 148 = @cil_ldelem_i4 +| 149 = @cil_ldelem_u4 +| 150 = @cil_ldelem_i8 +| 151 = @cil_ldelem_i +| 152 = @cil_ldelem_r4 +| 153 = @cil_ldelem_r8 +| 154 = @cil_ldelem_ref +| 155 = @cil_stelem_i +| 156 = @cil_stelem_i1 +| 157 = @cil_stelem_i2 +| 158 = @cil_stelem_i4 +| 159 = @cil_stelem_i8 +| 160 = @cil_stelem_r4 +| 161 = @cil_stelem_r8 +| 162 = @cil_stelem_ref +| 163 = @cil_ldelem +| 164 = @cil_stelem +| 165 = @cil_unbox_any +| 179 = @cil_conv_ovf_i1 +| 180 = @cil_conv_ovf_u1 +| 181 = @cil_conv_ovf_i2 +| 182 = @cil_conv_ovf_u2 +| 183 = @cil_conv_ovf_i4 +| 184 = @cil_conv_ovf_u4 +| 185 = @cil_conv_ovf_i8 +| 186 = @cil_conv_ovf_u8 +| 194 = @cil_refanyval +| 195 = @cil_ckinfinite +| 198 = @cil_mkrefany +| 208 = @cil_ldtoken +| 209 = @cil_conv_u2 +| 210 = @cil_conv_u1 +| 211 = @cil_conv_i +| 212 = @cil_conv_ovf_i +| 213 = @cil_conv_ovf_u +| 214 = @cil_add_ovf +| 215 = @cil_add_ovf_un +| 216 = @cil_mul_ovf +| 217 = @cil_mul_ovf_un +| 218 = @cil_sub_ovf +| 219 = @cil_sub_ovf_un +| 220 = @cil_endfinally +| 221 = @cil_leave +| 222 = @cil_leave_s +| 223 = @cil_stind_i +| 224 = @cil_conv_u +| 65024 = @cil_arglist +| 65025 = @cil_ceq +| 65026 = @cil_cgt +| 65027 = @cil_cgt_un +| 65028 = @cil_clt +| 65029 = @cil_clt_un +| 65030 = @cil_ldftn +| 65031 = @cil_ldvirtftn +| 65033 = @cil_ldarg +| 65034 = @cil_ldarga +| 65035 = @cil_starg +| 65036 = @cil_ldloc +| 65037 = @cil_ldloca +| 65038 = @cil_stloc +| 65039 = @cil_localloc +| 65041 = @cil_endfilter +| 65042 = @cil_unaligned +| 65043 = @cil_volatile +| 65044 = @cil_tail +| 65045 = @cil_initobj +| 65046 = @cil_constrained +| 65047 = @cil_cpblk +| 65048 = @cil_initblk +| 65050 = @cil_rethrow +| 65052 = @cil_sizeof +| 65053 = @cil_refanytype +| 65054 = @cil_readonly +; + +// CIL ignored instructions + +@cil_ignore = @cil_nop | @cil_break | @cil_volatile | @cil_unaligned; + +// CIL local/parameter/field access + +@cil_ldarg_any = @cil_ldarg_0 | @cil_ldarg_1 | @cil_ldarg_2 | @cil_ldarg_3 | @cil_ldarg_s | @cil_ldarga_s | @cil_ldarg | @cil_ldarga; +@cil_starg_any = @cil_starg | @cil_starg_s; + +@cil_ldloc_any = @cil_ldloc_0 | @cil_ldloc_1 | @cil_ldloc_2 | @cil_ldloc_3 | @cil_ldloc_s | @cil_ldloca_s | @cil_ldloc | @cil_ldloca; +@cil_stloc_any = @cil_stloc_0 | @cil_stloc_1 | @cil_stloc_2 | @cil_stloc_3 | @cil_stloc_s | @cil_stloc; + +@cil_ldfld_any = @cil_ldfld | @cil_ldsfld | @cil_ldsflda | @cil_ldflda; +@cil_stfld_any = @cil_stfld | @cil_stsfld; + +@cil_local_access = @cil_stloc_any | @cil_ldloc_any; +@cil_arg_access = @cil_starg_any | @cil_ldarg_any; +@cil_read_access = @cil_ldloc_any | @cil_ldarg_any | @cil_ldfld_any; +@cil_write_access = @cil_stloc_any | @cil_starg_any | @cil_stfld_any; + +@cil_stack_access = @cil_local_access | @cil_arg_access; +@cil_field_access = @cil_ldfld_any | @cil_stfld_any; + +@cil_access = @cil_read_access | @cil_write_access; + +// CIL constant/literal instructions + +@cil_ldc_i = @cil_ldc_i4_any | @cil_ldc_i8; + +@cil_ldc_i4_any = @cil_ldc_i4_m1 | @cil_ldc_i4_0 | @cil_ldc_i4_1 | @cil_ldc_i4_2 | @cil_ldc_i4_3 | + @cil_ldc_i4_4 | @cil_ldc_i4_5 | @cil_ldc_i4_6 | @cil_ldc_i4_7 | @cil_ldc_i4_8 | @cil_ldc_i4_s | @cil_ldc_i4; + +@cil_ldc_r = @cil_ldc_r4 | @cil_ldc_r8; + +@cil_literal = @cil_ldnull | @cil_ldc_i | @cil_ldc_r | @cil_ldstr; + +// Control flow + +@cil_conditional_jump = @cil_binary_jump | @cil_unary_jump; +@cil_binary_jump = @cil_beq_s | @cil_bge_s | @cil_bgt_s | @cil_ble_s | @cil_blt_s | + @cil_bne_un_s | @cil_bge_un_s | @cil_bgt_un_s | @cil_ble_un_s | @cil_blt_un_s | + @cil_beq | @cil_bge | @cil_bgt | @cil_ble | @cil_blt | + @cil_bne_un | @cil_bge_un | @cil_bgt_un | @cil_ble_un | @cil_blt_un; +@cil_unary_jump = @cil_brfalse_s | @cil_brtrue_s | @cil_brfalse | @cil_brtrue | @cil_switch; +@cil_unconditional_jump = @cil_br | @cil_br_s | @cil_leave_any; +@cil_leave_any = @cil_leave | @cil_leave_s; +@cil_jump = @cil_unconditional_jump | @cil_conditional_jump; + +// CIL call instructions + +@cil_call_any = @cil_jmp | @cil_call | @cil_calli | @cil_tail | @cil_callvirt | @cil_newobj; + +// CIL expression instructions + +@cil_expr = @cil_literal | @cil_binary_expr | @cil_unary_expr | @cil_call_any | @cil_read_access | + @cil_newarr | @cil_ldtoken | @cil_sizeof | + @cil_ldftn | @cil_ldvirtftn | @cil_localloc | @cil_mkrefany | @cil_refanytype | @cil_arglist | @cil_dup; + +@cil_unary_expr = + @cil_conversion_operation | @cil_unary_arithmetic_operation | @cil_unary_bitwise_operation| + @cil_ldlen | @cil_isinst | @cil_box | @cil_ldobj | @cil_castclass | @cil_unbox_any | + @cil_ldind | @cil_unbox; + +@cil_conversion_operation = + @cil_conv_i1 | @cil_conv_i2 | @cil_conv_i4 | @cil_conv_i8 | + @cil_conv_u1 | @cil_conv_u2 | @cil_conv_u4 | @cil_conv_u8 | + @cil_conv_ovf_i | @cil_conv_ovf_i_un | @cil_conv_ovf_i1 | @cil_conv_ovf_i1_un | + @cil_conv_ovf_i2 | @cil_conv_ovf_i2_un | @cil_conv_ovf_i4 | @cil_conv_ovf_i4_un | + @cil_conv_ovf_i8 | @cil_conv_ovf_i8_un | @cil_conv_ovf_u | @cil_conv_ovf_u_un | + @cil_conv_ovf_u1 | @cil_conv_ovf_u1_un | @cil_conv_ovf_u2 | @cil_conv_ovf_u2_un | + @cil_conv_ovf_u4 | @cil_conv_ovf_u4_un | @cil_conv_ovf_u8 | @cil_conv_ovf_u8_un | + @cil_conv_r4 | @cil_conv_r8 | @cil_conv_ovf_u2 | @cil_conv_ovf_u2_un | + @cil_conv_i | @cil_conv_u | @cil_conv_r_un; + +@cil_ldind = @cil_ldind_i | @cil_ldind_i1 | @cil_ldind_i2 | @cil_ldind_i4 | @cil_ldind_i8 | + @cil_ldind_r4 | @cil_ldind_r8 | @cil_ldind_ref | @cil_ldind_u1 | @cil_ldind_u2 | @cil_ldind_u4; + +@cil_stind = @cil_stind_i | @cil_stind_i1 | @cil_stind_i2 | @cil_stind_i4 | @cil_stind_i8 | + @cil_stind_r4 | @cil_stind_r8 | @cil_stind_ref; + +@cil_bitwise_operation = @cil_binary_bitwise_operation | @cil_unary_bitwise_operation; + +@cil_binary_bitwise_operation = @cil_and | @cil_or | @cil_xor | @cil_shr | @cil_shr | @cil_shr_un | @cil_shl; + +@cil_binary_arithmetic_operation = @cil_add | @cil_sub | @cil_mul | @cil_div | @cil_div_un | + @cil_rem | @cil_rem_un | @cil_add_ovf | @cil_add_ovf_un | @cil_mul_ovf | @cil_mul_ovf_un | + @cil_sub_ovf | @cil_sub_ovf_un; + +@cil_unary_bitwise_operation = @cil_not; + +@cil_binary_expr = @cil_binary_arithmetic_operation | @cil_binary_bitwise_operation | @cil_read_array | @cil_comparison_operation; + +@cil_unary_arithmetic_operation = @cil_neg; + +@cil_comparison_operation = @cil_cgt_un | @cil_ceq | @cil_cgt | @cil_clt | @cil_clt_un; + +// Elements that retrieve an address of something +@cil_read_ref = @cil_ldloca_s | @cil_ldarga_s | @cil_ldflda | @cil_ldsflda | @cil_ldelema; + +// CIL array instructions + +@cil_read_array = + @cil_ldelem | @cil_ldelema | @cil_ldelem_i1 | @cil_ldelem_ref | @cil_ldelem_i | + @cil_ldelem_i1 | @cil_ldelem_i2 | @cil_ldelem_i4 | @cil_ldelem_i8 | @cil_ldelem_r4 | + @cil_ldelem_r8 | @cil_ldelem_u1 | @cil_ldelem_u2 | @cil_ldelem_u4; + +@cil_write_array = @cil_stelem | @cil_stelem_ref | + @cil_stelem_i | @cil_stelem_i1 | @cil_stelem_i2 | @cil_stelem_i4 | @cil_stelem_i8 | + @cil_stelem_r4 | @cil_stelem_r8; + +@cil_throw_any = @cil_throw | @cil_rethrow; + +#keyset[impl, index] +cil_instruction( + unique int id: @cil_instruction, + int opcode: int ref, + int index: int ref, + int impl: @cil_method_implementation ref); + +cil_jump( + unique int instruction: @cil_jump ref, + int target: @cil_instruction ref); + +cil_access( + unique int instruction: @cil_instruction ref, + int target: @cil_accessible ref); + +cil_value( + unique int instruction: @cil_literal ref, + string value: string ref); + +#keyset[instruction, index] +cil_switch( + int instruction: @cil_switch ref, + int index: int ref, + int target: @cil_instruction ref); + +cil_instruction_location( + unique int id: @cil_instruction ref, + int loc: @location ref); + +cil_type_location( + int id: @cil_type ref, + int loc: @location ref); + +cil_method_location( + int id: @cil_method ref, + int loc: @location ref); + +@cil_namespace = @namespace; + +@cil_type_container = @cil_type | @cil_namespace | @cil_method; + +case @cil_type.kind of + 0 = @cil_valueorreftype +| 1 = @cil_typeparameter +| 2 = @cil_array_type +| 3 = @cil_pointer_type +; + +cil_type( + unique int id: @cil_type, + string name: string ref, + int kind: int ref, + int parent: @cil_type_container ref, + int sourceDecl: @cil_type ref); + +cil_pointer_type( + unique int id: @cil_pointer_type ref, + int pointee: @cil_type ref); + +cil_array_type( + unique int id: @cil_array_type ref, + int element_type: @cil_type ref, + int rank: int ref); + +cil_method( + unique int id: @cil_method, + string name: string ref, + int parent: @cil_type ref, + int return_type: @cil_type ref); + +cil_method_source_declaration( + unique int method: @cil_method ref, + int source: @cil_method ref); + +cil_method_implementation( + unique int id: @cil_method_implementation, + int method: @cil_method ref, + int location: @assembly ref); + +cil_implements( + int id: @cil_method ref, + int decl: @cil_method ref); + +#keyset[parent, name] +cil_field( + unique int id: @cil_field, + int parent: @cil_type ref, + string name: string ref, + int field_type: @cil_type ref); + +@cil_element = @cil_instruction | @cil_declaration | @cil_handler | @cil_attribute | @cil_namespace; +@cil_named_element = @cil_declaration | @cil_namespace; +@cil_declaration = @cil_variable | @cil_method | @cil_type | @cil_member; +@cil_accessible = @cil_declaration; +@cil_variable = @cil_field | @cil_stack_variable; +@cil_stack_variable = @cil_local_variable | @cil_parameter; +@cil_member = @cil_method | @cil_type | @cil_field | @cil_property | @cil_event; +@cil_custom_modifier_receiver = @cil_method | @cil_property | @cil_parameter | @cil_field; // todo: add function pointer type + +#keyset[method, index] +cil_parameter( + unique int id: @cil_parameter, + int method: @cil_method ref, + int index: int ref, + int param_type: @cil_type ref); + +cil_parameter_in(unique int id: @cil_parameter ref); +cil_parameter_out(unique int id: @cil_parameter ref); + +cil_setter(unique int prop: @cil_property ref, + int method: @cil_method ref); + +#keyset[id, modifier] +cil_custom_modifiers( + int id: @cil_custom_modifier_receiver ref, + int modifier: @cil_type ref, + int kind: int ref); // modreq: 1, modopt: 0 + +cil_getter(unique int prop: @cil_property ref, + int method: @cil_method ref); + +cil_adder(unique int event: @cil_event ref, + int method: @cil_method ref); + +cil_remover(unique int event: @cil_event ref, int method: @cil_method ref); + +cil_raiser(unique int event: @cil_event ref, int method: @cil_method ref); + +cil_property( + unique int id: @cil_property, + int parent: @cil_type ref, + string name: string ref, + int property_type: @cil_type ref); + +#keyset[parent, name] +cil_event(unique int id: @cil_event, + int parent: @cil_type ref, + string name: string ref, + int event_type: @cil_type ref); + +#keyset[impl, index] +cil_local_variable( + unique int id: @cil_local_variable, + int impl: @cil_method_implementation ref, + int index: int ref, + int var_type: @cil_type ref); + +// CIL handlers (exception handlers etc). + +case @cil_handler.kind of + 0 = @cil_catch_handler +| 1 = @cil_filter_handler +| 2 = @cil_finally_handler +| 4 = @cil_fault_handler +; + +#keyset[impl, index] +cil_handler( + unique int id: @cil_handler, + int impl: @cil_method_implementation ref, + int index: int ref, + int kind: int ref, + int try_start: @cil_instruction ref, + int try_end: @cil_instruction ref, + int handler_start: @cil_instruction ref); + +cil_handler_filter( + unique int id: @cil_handler ref, + int filter_start: @cil_instruction ref); + +cil_handler_type( + unique int id: @cil_handler ref, + int catch_type: @cil_type ref); + +@cil_controlflow_node = @cil_entry_point | @cil_instruction; + +@cil_entry_point = @cil_method_implementation | @cil_handler; + +@cil_dataflow_node = @cil_instruction | @cil_variable | @cil_method; + +cil_method_stack_size( + unique int method: @cil_method_implementation ref, + int size: int ref); + +// CIL modifiers + +cil_public(int id: @cil_member ref); +cil_private(int id: @cil_member ref); +cil_protected(int id: @cil_member ref); +cil_internal(int id: @cil_member ref); +cil_static(int id: @cil_member ref); +cil_sealed(int id: @cil_member ref); +cil_virtual(int id: @cil_method ref); +cil_abstract(int id: @cil_member ref); +cil_class(int id: @cil_type ref); +cil_interface(int id: @cil_type ref); +cil_security(int id: @cil_member ref); +cil_requiresecobject(int id: @cil_method ref); +cil_specialname(int id: @cil_method ref); +cil_newslot(int id: @cil_method ref); + +cil_base_class(unique int id: @cil_type ref, int base: @cil_type ref); +cil_base_interface(int id: @cil_type ref, int base: @cil_type ref); +cil_enum_underlying_type(unique int id: @cil_type ref, int underlying: @cil_type ref); + +#keyset[unbound, index] +cil_type_parameter( + int unbound: @cil_member ref, + int index: int ref, + int param: @cil_typeparameter ref); + +#keyset[bound, index] +cil_type_argument( + int bound: @cil_member ref, + int index: int ref, + int t: @cil_type ref); + +// CIL type parameter constraints + +cil_typeparam_covariant(int tp: @cil_typeparameter ref); +cil_typeparam_contravariant(int tp: @cil_typeparameter ref); +cil_typeparam_class(int tp: @cil_typeparameter ref); +cil_typeparam_struct(int tp: @cil_typeparameter ref); +cil_typeparam_new(int tp: @cil_typeparameter ref); +cil_typeparam_constraint(int tp: @cil_typeparameter ref, int supertype: @cil_type ref); + +// CIL attributes + +cil_attribute( + unique int attributeid: @cil_attribute, + int element: @cil_declaration ref, + int constructor: @cil_method ref); + +#keyset[attribute_id, param] +cil_attribute_named_argument( + int attribute_id: @cil_attribute ref, + string param: string ref, + string value: string ref); + +#keyset[attribute_id, index] +cil_attribute_positional_argument( + int attribute_id: @cil_attribute ref, + int index: int ref, + string value: string ref); + + +// Common .Net data model covering both C# and CIL + +// Common elements +@dotnet_element = @element | @cil_element; +@dotnet_named_element = @named_element | @cil_named_element; +@dotnet_callable = @callable | @cil_method; +@dotnet_variable = @variable | @cil_variable; +@dotnet_field = @field | @cil_field; +@dotnet_parameter = @parameter | @cil_parameter; +@dotnet_declaration = @declaration | @cil_declaration; +@dotnet_member = @member | @cil_member; +@dotnet_event = @event | @cil_event; +@dotnet_property = @property | @cil_property | @indexer; + +// Common types +@dotnet_type = @type | @cil_type; +@dotnet_call = @call | @cil_call_any; +@dotnet_throw = @throw_element | @cil_throw_any; +@dotnet_valueorreftype = @cil_valueorreftype | @value_or_ref_type | @cil_array_type | @void_type; +@dotnet_typeparameter = @type_parameter | @cil_typeparameter; +@dotnet_array_type = @array_type | @cil_array_type; +@dotnet_pointer_type = @pointer_type | @cil_pointer_type; +@dotnet_type_parameter = @type_parameter | @cil_typeparameter; +@dotnet_generic = @dotnet_valueorreftype | @dotnet_callable; + +// Attributes +@dotnet_attribute = @attribute | @cil_attribute; + +// Expressions +@dotnet_expr = @expr | @cil_expr; + +// Literals +@dotnet_literal = @literal_expr | @cil_literal; +@dotnet_string_literal = @string_literal_expr | @cil_ldstr; +@dotnet_int_literal = @integer_literal_expr | @cil_ldc_i; +@dotnet_float_literal = @float_literal_expr | @cil_ldc_r; +@dotnet_null_literal = @null_literal_expr | @cil_ldnull; + +@metadata_entity = @cil_method | @cil_type | @cil_field | @cil_property | @field | @property | + @callable | @value_or_ref_type | @void_type; + +#keyset[entity, location] +metadata_handle(int entity : @metadata_entity ref, int location: @assembly ref, int handle: int ref) diff --git a/csharp/upgrades/094972aab8c537db2cec0b9508361ca9d4cc2006/upgrade.properties b/csharp/upgrades/094972aab8c537db2cec0b9508361ca9d4cc2006/upgrade.properties new file mode 100644 index 00000000000..d3c8ba2b9bf --- /dev/null +++ b/csharp/upgrades/094972aab8c537db2cec0b9508361ca9d4cc2006/upgrade.properties @@ -0,0 +1,2 @@ +description: Added 'anonymous_types' to store anonymous types. +compatibility: backwards diff --git a/csharp/upgrades/26249c105a81c61ef8738a198928de2d4b763c37/old.dbscheme b/csharp/upgrades/26249c105a81c61ef8738a198928de2d4b763c37/old.dbscheme new file mode 100644 index 00000000000..26249c105a8 --- /dev/null +++ b/csharp/upgrades/26249c105a81c61ef8738a198928de2d4b763c37/old.dbscheme @@ -0,0 +1,1909 @@ + +/** + * An invocation of the compiler. Note that more than one file may be + * compiled per invocation. For example, this command compiles three + * source files: + * + * csc f1.cs f2.cs f3.cs + * + * The `id` simply identifies the invocation, while `cwd` is the working + * directory from which the compiler was invoked. + */ +compilations( + unique int id : @compilation, + string cwd : string ref +); + +/** + * The arguments that were passed to the extractor for a compiler + * invocation. If `id` is for the compiler invocation + * + * csc f1.cs f2.cs f3.cs + * + * then typically there will be rows for + * + * num | arg + * --- | --- + * 0 | --compiler + * 1 | *path to compiler* + * 2 | --cil + * 3 | f1.cs + * 4 | f2.cs + * 5 | f3.cs + */ +#keyset[id, num] +compilation_args( + int id : @compilation ref, + int num : int ref, + string arg : string ref +); + +/** + * The source files that are compiled by a compiler invocation. + * If `id` is for the compiler invocation + * + * csc f1.cs f2.cs f3.cs + * + * then there will be rows for + * + * num | arg + * --- | --- + * 0 | f1.cs + * 1 | f2.cs + * 2 | f3.cs + */ +#keyset[id, num] +compilation_compiling_files( + int id : @compilation ref, + int num : int ref, + int file : @file ref +); + +/** + * The references used by a compiler invocation. + * If `id` is for the compiler invocation + * + * csc f1.cs f2.cs f3.cs /r:ref1.dll /r:ref2.dll /r:ref3.dll + * + * then there will be rows for + * + * num | arg + * --- | --- + * 0 | ref1.dll + * 1 | ref2.dll + * 2 | ref3.dll + */ +#keyset[id, num] +compilation_referencing_files( + int id : @compilation ref, + int num : int ref, + int file : @file ref +); + +/** + * The time taken by the extractor for a compiler invocation. + * + * For each file `num`, there will be rows for + * + * kind | seconds + * ---- | --- + * 1 | CPU seconds used by the extractor frontend + * 2 | Elapsed seconds during the extractor frontend + * 3 | CPU seconds used by the extractor backend + * 4 | Elapsed seconds during the extractor backend + */ +#keyset[id, num, kind] +compilation_time( + int id : @compilation ref, + int num : int ref, + /* kind: + 1 = frontend_cpu_seconds + 2 = frontend_elapsed_seconds + 3 = extractor_cpu_seconds + 4 = extractor_elapsed_seconds + */ + int kind : int ref, + float seconds : float ref +); + +/** + * An error or warning generated by the extractor. + * The diagnostic message `diagnostic` was generated during compiler + * invocation `compilation`, and is the `file_number_diagnostic_number`th + * message generated while extracting the `file_number`th file of that + * invocation. + */ +#keyset[compilation, file_number, file_number_diagnostic_number] +diagnostic_for( + unique int diagnostic : @diagnostic ref, + int compilation : @compilation ref, + int file_number : int ref, + int file_number_diagnostic_number : int ref +); + +diagnostics( + unique int id: @diagnostic, + int severity: int ref, + string error_tag: string ref, + string error_message: string ref, + string full_error_message: string ref, + int location: @location_default ref +); + +extractor_messages( + unique int id: @extractor_message, + int severity: int ref, + string origin : string ref, + string text : string ref, + string entity : string ref, + int location: @location_default ref, + string stack_trace : string ref +); + +/** + * If extraction was successful, then `cpu_seconds` and + * `elapsed_seconds` are the CPU time and elapsed time (respectively) + * that extraction took for compiler invocation `id`. + */ +compilation_finished( + unique int id : @compilation ref, + float cpu_seconds : float ref, + float elapsed_seconds : float ref +); + +/* + * External artifacts + */ + +externalDefects( + unique int id: @externalDefect, + string queryPath: string ref, + int location: @location ref, + string message: string ref, + float severity: float ref); + +externalMetrics( + unique int id: @externalMetric, + string queryPath: string ref, + int location: @location ref, + float value: float ref); + +externalData( + int id: @externalDataElement, + string path: string ref, + int column: int ref, + string value: string ref); + +snapshotDate( + unique date snapshotDate: date ref); + +sourceLocationPrefix( + string prefix: string ref); + +/* + * Duplicate code + */ + +duplicateCode( + unique int id: @duplication, + string relativePath: string ref, + int equivClass: int ref); + +similarCode( + unique int id: @similarity, + string relativePath: string ref, + int equivClass: int ref); + +@duplication_or_similarity = @duplication | @similarity + +tokens( + int id: @duplication_or_similarity ref, + int offset: int ref, + int beginLine: int ref, + int beginColumn: int ref, + int endLine: int ref, + int endColumn: int ref); + +/* + * C# dbscheme + */ + +/** ELEMENTS **/ + +@element = @declaration | @stmt | @expr | @modifier | @attribute | @namespace_declaration + | @using_directive | @type_parameter_constraints | @external_element + | @xmllocatable | @asp_element | @namespace; + +@declaration = @callable | @generic | @assignable | @namespace; + +@named_element = @namespace | @declaration; + +@declaration_with_accessors = @property | @indexer | @event; + +@assignable = @variable | @assignable_with_accessors | @event; + +@assignable_with_accessors = @property | @indexer; + +@external_element = @externalMetric | @externalDefect | @externalDataElement; + +@attributable = @assembly | @field | @parameter | @operator | @method | @constructor + | @destructor | @callable_accessor | @value_or_ref_type | @declaration_with_accessors + | @local_function; + +/** LOCATIONS, ASEMMBLIES, MODULES, FILES and FOLDERS **/ + +@location = @location_default | @assembly; + +locations_default( + unique int id: @location_default, + int file: @file ref, + int beginLine: int ref, + int beginColumn: int ref, + int endLine: int ref, + int endColumn: int ref); + +@sourceline = @file | @callable | @xmllocatable; + +numlines( + int element_id: @sourceline ref, + int num_lines: int ref, + int num_code: int ref, + int num_comment: int ref); + +assemblies( + unique int id: @assembly, + int file: @file ref, + string fullname: string ref, + string name: string ref, + string version: string ref); + +/* + fromSource(0) = unknown, + fromSource(1) = from source, + fromSource(2) = from library +*/ +files( + unique int id: @file, + string name: string ref, + string simple: string ref, + string ext: string ref, + int fromSource: int ref); + +folders( + unique int id: @folder, + string name: string ref, + string simple: string ref); + +@container = @folder | @file ; + +containerparent( + int parent: @container ref, + unique int child: @container ref); + +file_extraction_mode( + unique int file: @file ref, + int mode: int ref + /* 0 = normal, 1 = standalone extractor */ + ); + +/** NAMESPACES **/ + +@type_container = @namespace | @type; + +namespaces( + unique int id: @namespace, + string name: string ref); + +namespace_declarations( + unique int id: @namespace_declaration, + int namespace_id: @namespace ref); + +namespace_declaration_location( + unique int id: @namespace_declaration ref, + int loc: @location ref); + +parent_namespace( + unique int child_id: @type_container ref, + int namespace_id: @namespace ref); + +@declaration_or_directive = @namespace_declaration | @type | @using_directive; + +parent_namespace_declaration( + int child_id: @declaration_or_directive ref, // cannot be unique because of partial classes + int namespace_id: @namespace_declaration ref); + +@using_directive = @using_namespace_directive | @using_static_directive; + +using_namespace_directives( + unique int id: @using_namespace_directive, + int namespace_id: @namespace ref); + +using_static_directives( + unique int id: @using_static_directive, + int type_id: @type_or_ref ref); + +using_directive_location( + unique int id: @using_directive ref, + int loc: @location ref); + +/** TYPES **/ + +types( + unique int id: @type, + int kind: int ref, + string name: string ref); + +case @type.kind of + 1 = @bool_type +| 2 = @char_type +| 3 = @decimal_type +| 4 = @sbyte_type +| 5 = @short_type +| 6 = @int_type +| 7 = @long_type +| 8 = @byte_type +| 9 = @ushort_type +| 10 = @uint_type +| 11 = @ulong_type +| 12 = @float_type +| 13 = @double_type +| 14 = @enum_type +| 15 = @struct_type +| 17 = @class_type +| 19 = @interface_type +| 20 = @delegate_type +| 21 = @null_type +| 22 = @type_parameter +| 23 = @pointer_type +| 24 = @nullable_type +| 25 = @array_type +| 26 = @void_type +| 27 = @int_ptr_type +| 28 = @uint_ptr_type +| 29 = @dynamic_type +| 30 = @arglist_type +| 31 = @unknown_type +| 32 = @tuple_type + ; + +@simple_type = @bool_type | @char_type | @integral_type | @floating_point_type | @decimal_type; +@integral_type = @signed_integral_type | @unsigned_integral_type; +@signed_integral_type = @sbyte_type | @short_type | @int_type | @long_type; +@unsigned_integral_type = @byte_type | @ushort_type | @uint_type | @ulong_type; +@floating_point_type = @float_type | @double_type; +@value_type = @simple_type | @enum_type | @struct_type | @nullable_type | @int_ptr_type + | @uint_ptr_type | @tuple_type; +@ref_type = @class_type | @interface_type | @array_type | @delegate_type | @null_type + | @dynamic_type; +@value_or_ref_type = @value_type | @ref_type; + +typerefs( + unique int id: @typeref, + string name: string ref); + +typeref_type( + int id: @typeref ref, + unique int typeId: @type ref); + +@type_or_ref = @type | @typeref; + +array_element_type( + unique int array: @array_type ref, + int dimension: int ref, + int rank: int ref, + int element: @type_or_ref ref); + +nullable_underlying_type( + unique int nullable: @nullable_type ref, + int underlying: @type_or_ref ref); + +pointer_referent_type( + unique int pointer: @pointer_type ref, + int referent: @type_or_ref ref); + +enum_underlying_type( + unique int enum_id: @enum_type ref, + int underlying_type_id: @type_or_ref ref); + +delegate_return_type( + unique int delegate_id: @delegate_type ref, + int return_type_id: @type_or_ref ref); + +extend( + unique int sub: @type ref, + int super: @type_or_ref ref); + +anonymous_types( + unique int id: @type ref); + +@interface_or_ref = @interface_type | @typeref; + +implement( + int sub: @type ref, + int super: @type_or_ref ref); + +type_location( + int id: @type ref, + int loc: @location ref); + +tuple_underlying_type( + unique int tuple: @tuple_type ref, + int struct: @type_or_ref ref); + +#keyset[tuple, index] +tuple_element( + int tuple: @tuple_type ref, + int index: int ref, + unique int field: @field ref); + +attributes( + unique int id: @attribute, + int type_id: @type_or_ref ref, + int target: @attributable ref); + +attribute_location( + int id: @attribute ref, + int loc: @location ref); + +@type_mention_parent = @element | @type_mention; + +type_mention( + unique int id: @type_mention, + int type_id: @type_or_ref ref, + int parent: @type_mention_parent ref); + +type_mention_location( + unique int id: @type_mention ref, + int loc: @location ref); + +@has_type_annotation = @assignable | @type_parameter | @callable | @expr | @delegate_type | @generic; + +/** + * A direct annotation on an entity, for example `string? x;`. + * + * Annotations: + * 2 = reftype is not annotated "!" + * 3 = reftype is annotated "?" + * 4 = readonly ref type / in parameter + * 5 = ref type parameter, return or local variable + * 6 = out parameter + * + * Note that the annotation depends on the element it annotates. + * @assignable: The annotation is on the type of the assignable, for example the variable type. + * @type_parameter: The annotation is on the reftype constraint + * @callable: The annotation is on the return type + * @array_type: The annotation is on the element type + */ +type_annotation(int id: @has_type_annotation ref, int annotation: int ref); + +nullability(unique int nullability: @nullability, int kind: int ref); + +case @nullability.kind of + 0 = @oblivious +| 1 = @not_annotated +| 2 = @annotated +; + +#keyset[parent, index] +nullability_parent(int nullability: @nullability ref, int index: int ref, int parent: @nullability ref) + +type_nullability(int id: @has_type_annotation ref, int nullability: @nullability ref); + +/** + * The nullable flow state of an expression, as determined by Roslyn. + * 0 = none (default, not populated) + * 1 = not null + * 2 = maybe null + */ +expr_flowstate(unique int id: @expr ref, int state: int ref); + +/** GENERICS **/ + +@generic = @type | @method | @local_function; + +type_parameters( + unique int id: @type_parameter ref, + int index: int ref, + int generic_id: @generic ref, + int variance: int ref /* none = 0, out = 1, in = 2 */); + +#keyset[constructed_id, index] +type_arguments( + int id: @type_or_ref ref, + int index: int ref, + int constructed_id: @generic_or_ref ref); + +@generic_or_ref = @generic | @typeref; + +constructed_generic( + unique int constructed: @generic ref, + int generic: @generic_or_ref ref); + +type_parameter_constraints( + unique int id: @type_parameter_constraints, + int param_id: @type_parameter ref); + +type_parameter_constraints_location( + int id: @type_parameter_constraints ref, + int loc: @location ref); + +general_type_parameter_constraints( + int id: @type_parameter_constraints ref, + int kind: int ref /* class = 1, struct = 2, new = 3 */); + +specific_type_parameter_constraints( + int id: @type_parameter_constraints ref, + int base_id: @type_or_ref ref); + +specific_type_parameter_nullability( + int id: @type_parameter_constraints ref, + int base_id: @type_or_ref ref, + int nullability: @nullability ref); + +/** MODIFIERS */ + +@modifiable = @modifiable_direct | @event_accessor; + +@modifiable_direct = @member | @accessor | @local_function | @anonymous_function_expr; + +modifiers( + unique int id: @modifier, + string name: string ref); + +has_modifiers( + int id: @modifiable_direct ref, + int mod_id: @modifier ref); + +compiler_generated(unique int id: @modifiable_direct ref); + +/** MEMBERS **/ + +@member = @method | @constructor | @destructor | @field | @property | @event | @operator | @indexer | @type; + +@named_exprorstmt = @goto_stmt | @labeled_stmt | @expr; + +@virtualizable = @method | @property | @indexer | @event; + +exprorstmt_name( + unique int parent_id: @named_exprorstmt ref, + string name: string ref); + +nested_types( + unique int id: @type ref, + int declaring_type_id: @type ref, + int unbound_id: @type ref); + +properties( + unique int id: @property, + string name: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @property ref); + +property_location( + int id: @property ref, + int loc: @location ref); + +indexers( + unique int id: @indexer, + string name: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @indexer ref); + +indexer_location( + int id: @indexer ref, + int loc: @location ref); + +accessors( + unique int id: @accessor, + int kind: int ref, + string name: string ref, + int declaring_member_id: @member ref, + int unbound_id: @accessor ref); + +case @accessor.kind of + 1 = @getter +| 2 = @setter + ; + +init_only_accessors( + unique int id: @accessor ref); + +accessor_location( + int id: @accessor ref, + int loc: @location ref); + +events( + unique int id: @event, + string name: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @event ref); + +event_location( + int id: @event ref, + int loc: @location ref); + +event_accessors( + unique int id: @event_accessor, + int kind: int ref, + string name: string ref, + int declaring_event_id: @event ref, + int unbound_id: @event_accessor ref); + +case @event_accessor.kind of + 1 = @add_event_accessor +| 2 = @remove_event_accessor + ; + +event_accessor_location( + int id: @event_accessor ref, + int loc: @location ref); + +operators( + unique int id: @operator, + string name: string ref, + string symbol: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @operator ref); + +operator_location( + int id: @operator ref, + int loc: @location ref); + +constant_value( + int id: @variable ref, + string value: string ref); + +/** CALLABLES **/ + +@callable = @method | @constructor | @destructor | @operator | @callable_accessor | @anonymous_function_expr | @local_function; + +@callable_accessor = @accessor | @event_accessor; + +methods( + unique int id: @method, + string name: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @method ref); + +method_location( + int id: @method ref, + int loc: @location ref); + +constructors( + unique int id: @constructor, + string name: string ref, + int declaring_type_id: @type ref, + int unbound_id: @constructor ref); + +constructor_location( + int id: @constructor ref, + int loc: @location ref); + +destructors( + unique int id: @destructor, + string name: string ref, + int declaring_type_id: @type ref, + int unbound_id: @destructor ref); + +destructor_location( + int id: @destructor ref, + int loc: @location ref); + +overrides( + int id: @callable ref, + int base_id: @callable ref); + +explicitly_implements( + int id: @member ref, + int interface_id: @interface_or_ref ref); + +local_functions( + unique int id: @local_function, + string name: string ref, + int return_type: @type ref, + int unbound_id: @local_function ref); + +local_function_stmts( + unique int fn: @local_function_stmt ref, + int stmt: @local_function ref); + +/** VARIABLES **/ + +@variable = @local_scope_variable | @field; + +@local_scope_variable = @local_variable | @parameter; + +fields( + unique int id: @field, + int kind: int ref, + string name: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @field ref); + +case @field.kind of + 1 = @addressable_field +| 2 = @constant + ; + +field_location( + int id: @field ref, + int loc: @location ref); + +localvars( + unique int id: @local_variable, + int kind: int ref, + string name: string ref, + int implicitly_typed: int ref /* 0 = no, 1 = yes */, + int type_id: @type_or_ref ref, + int parent_id: @local_var_decl_expr ref); + +case @local_variable.kind of + 1 = @addressable_local_variable +| 2 = @local_constant +| 3 = @local_variable_ref + ; + +localvar_location( + unique int id: @local_variable ref, + int loc: @location ref); + +@parameterizable = @callable | @delegate_type | @indexer; + +#keyset[name, parent_id] +#keyset[index, parent_id] +params( + unique int id: @parameter, + string name: string ref, + int type_id: @type_or_ref ref, + int index: int ref, + int mode: int ref, /* value = 0, ref = 1, out = 2, array = 3, this = 4 */ + int parent_id: @parameterizable ref, + int unbound_id: @parameter ref); + +param_location( + int id: @parameter ref, + int loc: @location ref); + +/** STATEMENTS **/ + +@exprorstmt_parent = @control_flow_element | @top_level_exprorstmt_parent; + +statements( + unique int id: @stmt, + int kind: int ref); + +#keyset[index, parent] +stmt_parent( + unique int stmt: @stmt ref, + int index: int ref, + int parent: @control_flow_element ref); + +@top_level_stmt_parent = @callable; + +// [index, parent] is not a keyset because the same parent may be compiled multiple times +stmt_parent_top_level( + unique int stmt: @stmt ref, + int index: int ref, + int parent: @top_level_stmt_parent ref); + +case @stmt.kind of + 1 = @block_stmt +| 2 = @expr_stmt +| 3 = @if_stmt +| 4 = @switch_stmt +| 5 = @while_stmt +| 6 = @do_stmt +| 7 = @for_stmt +| 8 = @foreach_stmt +| 9 = @break_stmt +| 10 = @continue_stmt +| 11 = @goto_stmt +| 12 = @goto_case_stmt +| 13 = @goto_default_stmt +| 14 = @throw_stmt +| 15 = @return_stmt +| 16 = @yield_stmt +| 17 = @try_stmt +| 18 = @checked_stmt +| 19 = @unchecked_stmt +| 20 = @lock_stmt +| 21 = @using_block_stmt +| 22 = @var_decl_stmt +| 23 = @const_decl_stmt +| 24 = @empty_stmt +| 25 = @unsafe_stmt +| 26 = @fixed_stmt +| 27 = @label_stmt +| 28 = @catch +| 29 = @case_stmt +| 30 = @local_function_stmt +| 31 = @using_decl_stmt + ; + +@using_stmt = @using_block_stmt | @using_decl_stmt; + +@labeled_stmt = @label_stmt | @case; + +@decl_stmt = @var_decl_stmt | @const_decl_stmt | @using_decl_stmt; + +@cond_stmt = @if_stmt | @switch_stmt; + +@loop_stmt = @while_stmt | @do_stmt | @for_stmt | @foreach_stmt; + +@jump_stmt = @break_stmt | @goto_any_stmt | @continue_stmt | @throw_stmt | @return_stmt + | @yield_stmt; + +@goto_any_stmt = @goto_default_stmt | @goto_case_stmt | @goto_stmt; + + +stmt_location( + unique int id: @stmt ref, + int loc: @location ref); + +catch_type( + unique int catch_id: @catch ref, + int type_id: @type_or_ref ref, + int kind: int ref /* explicit = 1, implicit = 2 */); + +/** EXPRESSIONS **/ + +expressions( + unique int id: @expr, + int kind: int ref, + int type_id: @type_or_ref ref); + +#keyset[index, parent] +expr_parent( + unique int expr: @expr ref, + int index: int ref, + int parent: @control_flow_element ref); + +@top_level_expr_parent = @attribute | @field | @property | @indexer | @parameter; + +@top_level_exprorstmt_parent = @top_level_expr_parent | @top_level_stmt_parent; + +// [index, parent] is not a keyset because the same parent may be compiled multiple times +expr_parent_top_level( + unique int expr: @expr ref, + int index: int ref, + int parent: @top_level_exprorstmt_parent ref); + +case @expr.kind of +/* literal */ + 1 = @bool_literal_expr +| 2 = @char_literal_expr +| 3 = @decimal_literal_expr +| 4 = @int_literal_expr +| 5 = @long_literal_expr +| 6 = @uint_literal_expr +| 7 = @ulong_literal_expr +| 8 = @float_literal_expr +| 9 = @double_literal_expr +| 10 = @string_literal_expr +| 11 = @null_literal_expr +/* primary & unary */ +| 12 = @this_access_expr +| 13 = @base_access_expr +| 14 = @local_variable_access_expr +| 15 = @parameter_access_expr +| 16 = @field_access_expr +| 17 = @property_access_expr +| 18 = @method_access_expr +| 19 = @event_access_expr +| 20 = @indexer_access_expr +| 21 = @array_access_expr +| 22 = @type_access_expr +| 23 = @typeof_expr +| 24 = @method_invocation_expr +| 25 = @delegate_invocation_expr +| 26 = @operator_invocation_expr +| 27 = @cast_expr +| 28 = @object_creation_expr +| 29 = @explicit_delegate_creation_expr +| 30 = @implicit_delegate_creation_expr +| 31 = @array_creation_expr +| 32 = @default_expr +| 33 = @plus_expr +| 34 = @minus_expr +| 35 = @bit_not_expr +| 36 = @log_not_expr +| 37 = @post_incr_expr +| 38 = @post_decr_expr +| 39 = @pre_incr_expr +| 40 = @pre_decr_expr +/* multiplicative */ +| 41 = @mul_expr +| 42 = @div_expr +| 43 = @rem_expr +/* additive */ +| 44 = @add_expr +| 45 = @sub_expr +/* shift */ +| 46 = @lshift_expr +| 47 = @rshift_expr +/* relational */ +| 48 = @lt_expr +| 49 = @gt_expr +| 50 = @le_expr +| 51 = @ge_expr +/* equality */ +| 52 = @eq_expr +| 53 = @ne_expr +/* logical */ +| 54 = @bit_and_expr +| 55 = @bit_xor_expr +| 56 = @bit_or_expr +| 57 = @log_and_expr +| 58 = @log_or_expr +/* type testing */ +| 59 = @is_expr +| 60 = @as_expr +/* null coalescing */ +| 61 = @null_coalescing_expr +/* conditional */ +| 62 = @conditional_expr +/* assignment */ +| 63 = @simple_assign_expr +| 64 = @assign_add_expr +| 65 = @assign_sub_expr +| 66 = @assign_mul_expr +| 67 = @assign_div_expr +| 68 = @assign_rem_expr +| 69 = @assign_and_expr +| 70 = @assign_xor_expr +| 71 = @assign_or_expr +| 72 = @assign_lshift_expr +| 73 = @assign_rshift_expr +/* more */ +| 74 = @object_init_expr +| 75 = @collection_init_expr +| 76 = @array_init_expr +| 77 = @checked_expr +| 78 = @unchecked_expr +| 79 = @constructor_init_expr +| 80 = @add_event_expr +| 81 = @remove_event_expr +| 82 = @par_expr +| 83 = @local_var_decl_expr +| 84 = @lambda_expr +| 85 = @anonymous_method_expr +| 86 = @namespace_expr +/* dynamic */ +| 92 = @dynamic_element_access_expr +| 93 = @dynamic_member_access_expr +/* unsafe */ +| 100 = @pointer_indirection_expr +| 101 = @address_of_expr +| 102 = @sizeof_expr +/* async */ +| 103 = @await_expr +/* C# 6.0 */ +| 104 = @nameof_expr +| 105 = @interpolated_string_expr +| 106 = @unknown_expr +/* C# 7.0 */ +| 107 = @throw_expr +| 108 = @tuple_expr +| 109 = @local_function_invocation_expr +| 110 = @ref_expr +| 111 = @discard_expr +/* C# 8.0 */ +| 112 = @range_expr +| 113 = @index_expr +| 114 = @switch_expr +| 115 = @recursive_pattern_expr +| 116 = @property_pattern_expr +| 117 = @positional_pattern_expr +| 118 = @switch_case_expr +| 119 = @assign_coalesce_expr +| 120 = @suppress_nullable_warning_expr +| 121 = @namespace_access_expr +; + +@switch = @switch_stmt | @switch_expr; +@case = @case_stmt | @switch_case_expr; +@pattern_match = @case | @is_expr; + +@integer_literal_expr = @int_literal_expr | @long_literal_expr | @uint_literal_expr | @ulong_literal_expr; +@real_literal_expr = @float_literal_expr | @double_literal_expr | @decimal_literal_expr; +@literal_expr = @bool_literal_expr | @char_literal_expr | @integer_literal_expr | @real_literal_expr + | @string_literal_expr | @null_literal_expr; + +@assign_expr = @simple_assign_expr | @assign_op_expr | @local_var_decl_expr; +@assign_op_expr = @assign_arith_expr | @assign_bitwise_expr | @assign_event_expr | @assign_coalesce_expr; +@assign_event_expr = @add_event_expr | @remove_event_expr; + +@assign_arith_expr = @assign_add_expr | @assign_sub_expr | @assign_mul_expr | @assign_div_expr + | @assign_rem_expr +@assign_bitwise_expr = @assign_and_expr | @assign_or_expr | @assign_xor_expr + | @assign_lshift_expr | @assign_rshift_expr; + +@member_access_expr = @field_access_expr | @property_access_expr | @indexer_access_expr | @event_access_expr + | @method_access_expr | @type_access_expr | @dynamic_member_access_expr; +@access_expr = @member_access_expr | @this_access_expr | @base_access_expr | @assignable_access_expr | @namespace_access_expr; +@element_access_expr = @indexer_access_expr | @array_access_expr | @dynamic_element_access_expr; + +@local_variable_access = @local_variable_access_expr | @local_var_decl_expr; +@local_scope_variable_access_expr = @parameter_access_expr | @local_variable_access; +@variable_access_expr = @local_scope_variable_access_expr | @field_access_expr; + +@assignable_access_expr = @variable_access_expr | @property_access_expr | @element_access_expr + | @event_access_expr | @dynamic_member_access_expr; + +@objectorcollection_init_expr = @object_init_expr | @collection_init_expr; + +@delegate_creation_expr = @explicit_delegate_creation_expr | @implicit_delegate_creation_expr; + +@bin_arith_op_expr = @mul_expr | @div_expr | @rem_expr | @add_expr | @sub_expr; +@incr_op_expr = @pre_incr_expr | @post_incr_expr; +@decr_op_expr = @pre_decr_expr | @post_decr_expr; +@mut_op_expr = @incr_op_expr | @decr_op_expr; +@un_arith_op_expr = @plus_expr | @minus_expr | @mut_op_expr; +@arith_op_expr = @bin_arith_op_expr | @un_arith_op_expr; + +@ternary_log_op_expr = @conditional_expr; +@bin_log_op_expr = @log_and_expr | @log_or_expr | @null_coalescing_expr; +@un_log_op_expr = @log_not_expr; +@log_expr = @un_log_op_expr | @bin_log_op_expr | @ternary_log_op_expr; + +@bin_bit_op_expr = @bit_and_expr | @bit_or_expr | @bit_xor_expr | @lshift_expr + | @rshift_expr; +@un_bit_op_expr = @bit_not_expr; +@bit_expr = @un_bit_op_expr | @bin_bit_op_expr; + +@equality_op_expr = @eq_expr | @ne_expr; +@rel_op_expr = @gt_expr | @lt_expr| @ge_expr | @le_expr; +@comp_expr = @equality_op_expr | @rel_op_expr; + +@op_expr = @assign_expr | @un_op | @bin_op | @ternary_op; + +@ternary_op = @ternary_log_op_expr; +@bin_op = @bin_arith_op_expr | @bin_log_op_expr | @bin_bit_op_expr | @comp_expr; +@un_op = @un_arith_op_expr | @un_log_op_expr | @un_bit_op_expr | @sizeof_expr + | @pointer_indirection_expr | @address_of_expr; + +@anonymous_function_expr = @lambda_expr | @anonymous_method_expr; + +@call = @method_invocation_expr | @constructor_init_expr | @operator_invocation_expr + | @delegate_invocation_expr | @object_creation_expr | @call_access_expr + | @local_function_invocation_expr; + +@call_access_expr = @property_access_expr | @event_access_expr | @indexer_access_expr; + +@late_bindable_expr = @dynamic_element_access_expr | @dynamic_member_access_expr + | @object_creation_expr | @method_invocation_expr | @operator_invocation_expr; + +@throw_element = @throw_expr | @throw_stmt; + +@implicitly_typeable_object_creation_expr = @object_creation_expr | @explicit_delegate_creation_expr; + +implicitly_typed_array_creation( + unique int id: @array_creation_expr ref); + +explicitly_sized_array_creation( + unique int id: @array_creation_expr ref); + +stackalloc_array_creation( + unique int id: @array_creation_expr ref); + +implicitly_typed_object_creation( + unique int id: @implicitly_typeable_object_creation_expr ref); + +mutator_invocation_mode( + unique int id: @operator_invocation_expr ref, + int mode: int ref /* prefix = 1, postfix = 2*/); + +expr_compiler_generated( + unique int id: @expr ref); + +expr_value( + unique int id: @expr ref, + string value: string ref); + +expr_call( + unique int caller_id: @expr ref, + int target_id: @callable ref); + +expr_access( + unique int accesser_id: @access_expr ref, + int target_id: @accessible ref); + +@accessible = @method | @assignable | @local_function | @namespace; + +expr_location( + unique int id: @expr ref, + int loc: @location ref); + +dynamic_member_name( + unique int id: @late_bindable_expr ref, + string name: string ref); + +@qualifiable_expr = @member_access_expr + | @method_invocation_expr + | @element_access_expr; + +conditional_access( + unique int id: @qualifiable_expr ref); + +expr_argument( + unique int id: @expr ref, + int mode: int ref); + /* mode is the same as params: value = 0, ref = 1, out = 2 */ + +expr_argument_name( + unique int id: @expr ref, + string name: string ref); + +/** CONTROL/DATA FLOW **/ + +@control_flow_element = @stmt | @expr; + +/* XML Files */ + +xmlEncoding ( + unique int id: @file ref, + string encoding: string ref); + +xmlDTDs( + unique int id: @xmldtd, + string root: string ref, + string publicId: string ref, + string systemId: string ref, + int fileid: @file ref); + +xmlElements( + unique int id: @xmlelement, + string name: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int fileid: @file ref); + +xmlAttrs( + unique int id: @xmlattribute, + int elementid: @xmlelement ref, + string name: string ref, + string value: string ref, + int idx: int ref, + int fileid: @file ref); + +xmlNs( + int id: @xmlnamespace, + string prefixName: string ref, + string URI: string ref, + int fileid: @file ref); + +xmlHasNs( + int elementId: @xmlnamespaceable ref, + int nsId: @xmlnamespace ref, + int fileid: @file ref); + +xmlComments( + unique int id: @xmlcomment, + string text: string ref, + int parentid: @xmlparent ref, + int fileid: @file ref); + +xmlChars( + unique int id: @xmlcharacters, + string text: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int isCDATA: int ref, + int fileid: @file ref); + +@xmlparent = @file | @xmlelement; +@xmlnamespaceable = @xmlelement | @xmlattribute; + +xmllocations( + int xmlElement: @xmllocatable ref, + int location: @location_default ref); + +@xmllocatable = @xmlcharacters | @xmlelement | @xmlcomment | @xmlattribute | @xmldtd | @file | @xmlnamespace; + +/* Comments */ + +commentline( + unique int id: @commentline, + int kind: int ref, + string text: string ref, + string rawtext: string ref); + +case @commentline.kind of + 0 = @singlelinecomment +| 1 = @xmldoccomment +| 2 = @multilinecomment; + +commentline_location( + unique int id: @commentline ref, + int loc: @location ref); + +commentblock( + unique int id : @commentblock); + +commentblock_location( + unique int id: @commentblock ref, + int loc: @location ref); + +commentblock_binding( + int id: @commentblock ref, + int entity: @element ref, + int bindtype: int ref); /* 0: Parent, 1: Best, 2: Before, 3: After */ + +commentblock_child( + int id: @commentblock ref, + int commentline: @commentline ref, + int index: int ref); + +/* ASP.NET */ + +case @asp_element.kind of + 0=@asp_close_tag +| 1=@asp_code +| 2=@asp_comment +| 3=@asp_data_binding +| 4=@asp_directive +| 5=@asp_open_tag +| 6=@asp_quoted_string +| 7=@asp_text +| 8=@asp_xml_directive; + +@asp_attribute = @asp_code | @asp_data_binding | @asp_quoted_string; + +asp_elements( + unique int id: @asp_element, + int kind: int ref, + int loc: @location ref); + +asp_comment_server(unique int comment: @asp_comment ref); +asp_code_inline(unique int code: @asp_code ref); +asp_directive_attribute( + int directive: @asp_directive ref, + int index: int ref, + string name: string ref, + int value: @asp_quoted_string ref); +asp_directive_name( + unique int directive: @asp_directive ref, + string name: string ref); +asp_element_body( + unique int element: @asp_element ref, + string body: string ref); +asp_tag_attribute( + int tag: @asp_open_tag ref, + int index: int ref, + string name: string ref, + int attribute: @asp_attribute ref); +asp_tag_name( + unique int tag: @asp_open_tag ref, + string name: string ref); +asp_tag_isempty(int tag: @asp_open_tag ref); + +/* Common Intermediate Language - CIL */ + +case @cil_instruction.opcode of + 0 = @cil_nop +| 1 = @cil_break +| 2 = @cil_ldarg_0 +| 3 = @cil_ldarg_1 +| 4 = @cil_ldarg_2 +| 5 = @cil_ldarg_3 +| 6 = @cil_ldloc_0 +| 7 = @cil_ldloc_1 +| 8 = @cil_ldloc_2 +| 9 = @cil_ldloc_3 +| 10 = @cil_stloc_0 +| 11 = @cil_stloc_1 +| 12 = @cil_stloc_2 +| 13 = @cil_stloc_3 +| 14 = @cil_ldarg_s +| 15 = @cil_ldarga_s +| 16 = @cil_starg_s +| 17 = @cil_ldloc_s +| 18 = @cil_ldloca_s +| 19 = @cil_stloc_s +| 20 = @cil_ldnull +| 21 = @cil_ldc_i4_m1 +| 22 = @cil_ldc_i4_0 +| 23 = @cil_ldc_i4_1 +| 24 = @cil_ldc_i4_2 +| 25 = @cil_ldc_i4_3 +| 26 = @cil_ldc_i4_4 +| 27 = @cil_ldc_i4_5 +| 28 = @cil_ldc_i4_6 +| 29 = @cil_ldc_i4_7 +| 30 = @cil_ldc_i4_8 +| 31 = @cil_ldc_i4_s +| 32 = @cil_ldc_i4 +| 33 = @cil_ldc_i8 +| 34 = @cil_ldc_r4 +| 35 = @cil_ldc_r8 +| 37 = @cil_dup +| 38 = @cil_pop +| 39 = @cil_jmp +| 40 = @cil_call +| 41 = @cil_calli +| 42 = @cil_ret +| 43 = @cil_br_s +| 44 = @cil_brfalse_s +| 45 = @cil_brtrue_s +| 46 = @cil_beq_s +| 47 = @cil_bge_s +| 48 = @cil_bgt_s +| 49 = @cil_ble_s +| 50 = @cil_blt_s +| 51 = @cil_bne_un_s +| 52 = @cil_bge_un_s +| 53 = @cil_bgt_un_s +| 54 = @cil_ble_un_s +| 55 = @cil_blt_un_s +| 56 = @cil_br +| 57 = @cil_brfalse +| 58 = @cil_brtrue +| 59 = @cil_beq +| 60 = @cil_bge +| 61 = @cil_bgt +| 62 = @cil_ble +| 63 = @cil_blt +| 64 = @cil_bne_un +| 65 = @cil_bge_un +| 66 = @cil_bgt_un +| 67 = @cil_ble_un +| 68 = @cil_blt_un +| 69 = @cil_switch +| 70 = @cil_ldind_i1 +| 71 = @cil_ldind_u1 +| 72 = @cil_ldind_i2 +| 73 = @cil_ldind_u2 +| 74 = @cil_ldind_i4 +| 75 = @cil_ldind_u4 +| 76 = @cil_ldind_i8 +| 77 = @cil_ldind_i +| 78 = @cil_ldind_r4 +| 79 = @cil_ldind_r8 +| 80 = @cil_ldind_ref +| 81 = @cil_stind_ref +| 82 = @cil_stind_i1 +| 83 = @cil_stind_i2 +| 84 = @cil_stind_i4 +| 85 = @cil_stind_i8 +| 86 = @cil_stind_r4 +| 87 = @cil_stind_r8 +| 88 = @cil_add +| 89 = @cil_sub +| 90 = @cil_mul +| 91 = @cil_div +| 92 = @cil_div_un +| 93 = @cil_rem +| 94 = @cil_rem_un +| 95 = @cil_and +| 96 = @cil_or +| 97 = @cil_xor +| 98 = @cil_shl +| 99 = @cil_shr +| 100 = @cil_shr_un +| 101 = @cil_neg +| 102 = @cil_not +| 103 = @cil_conv_i1 +| 104 = @cil_conv_i2 +| 105 = @cil_conv_i4 +| 106 = @cil_conv_i8 +| 107 = @cil_conv_r4 +| 108 = @cil_conv_r8 +| 109 = @cil_conv_u4 +| 110 = @cil_conv_u8 +| 111 = @cil_callvirt +| 112 = @cil_cpobj +| 113 = @cil_ldobj +| 114 = @cil_ldstr +| 115 = @cil_newobj +| 116 = @cil_castclass +| 117 = @cil_isinst +| 118 = @cil_conv_r_un +| 121 = @cil_unbox +| 122 = @cil_throw +| 123 = @cil_ldfld +| 124 = @cil_ldflda +| 125 = @cil_stfld +| 126 = @cil_ldsfld +| 127 = @cil_ldsflda +| 128 = @cil_stsfld +| 129 = @cil_stobj +| 130 = @cil_conv_ovf_i1_un +| 131 = @cil_conv_ovf_i2_un +| 132 = @cil_conv_ovf_i4_un +| 133 = @cil_conv_ovf_i8_un +| 134 = @cil_conv_ovf_u1_un +| 135 = @cil_conv_ovf_u2_un +| 136 = @cil_conv_ovf_u4_un +| 137 = @cil_conv_ovf_u8_un +| 138 = @cil_conv_ovf_i_un +| 139 = @cil_conv_ovf_u_un +| 140 = @cil_box +| 141 = @cil_newarr +| 142 = @cil_ldlen +| 143 = @cil_ldelema +| 144 = @cil_ldelem_i1 +| 145 = @cil_ldelem_u1 +| 146 = @cil_ldelem_i2 +| 147 = @cil_ldelem_u2 +| 148 = @cil_ldelem_i4 +| 149 = @cil_ldelem_u4 +| 150 = @cil_ldelem_i8 +| 151 = @cil_ldelem_i +| 152 = @cil_ldelem_r4 +| 153 = @cil_ldelem_r8 +| 154 = @cil_ldelem_ref +| 155 = @cil_stelem_i +| 156 = @cil_stelem_i1 +| 157 = @cil_stelem_i2 +| 158 = @cil_stelem_i4 +| 159 = @cil_stelem_i8 +| 160 = @cil_stelem_r4 +| 161 = @cil_stelem_r8 +| 162 = @cil_stelem_ref +| 163 = @cil_ldelem +| 164 = @cil_stelem +| 165 = @cil_unbox_any +| 179 = @cil_conv_ovf_i1 +| 180 = @cil_conv_ovf_u1 +| 181 = @cil_conv_ovf_i2 +| 182 = @cil_conv_ovf_u2 +| 183 = @cil_conv_ovf_i4 +| 184 = @cil_conv_ovf_u4 +| 185 = @cil_conv_ovf_i8 +| 186 = @cil_conv_ovf_u8 +| 194 = @cil_refanyval +| 195 = @cil_ckinfinite +| 198 = @cil_mkrefany +| 208 = @cil_ldtoken +| 209 = @cil_conv_u2 +| 210 = @cil_conv_u1 +| 211 = @cil_conv_i +| 212 = @cil_conv_ovf_i +| 213 = @cil_conv_ovf_u +| 214 = @cil_add_ovf +| 215 = @cil_add_ovf_un +| 216 = @cil_mul_ovf +| 217 = @cil_mul_ovf_un +| 218 = @cil_sub_ovf +| 219 = @cil_sub_ovf_un +| 220 = @cil_endfinally +| 221 = @cil_leave +| 222 = @cil_leave_s +| 223 = @cil_stind_i +| 224 = @cil_conv_u +| 65024 = @cil_arglist +| 65025 = @cil_ceq +| 65026 = @cil_cgt +| 65027 = @cil_cgt_un +| 65028 = @cil_clt +| 65029 = @cil_clt_un +| 65030 = @cil_ldftn +| 65031 = @cil_ldvirtftn +| 65033 = @cil_ldarg +| 65034 = @cil_ldarga +| 65035 = @cil_starg +| 65036 = @cil_ldloc +| 65037 = @cil_ldloca +| 65038 = @cil_stloc +| 65039 = @cil_localloc +| 65041 = @cil_endfilter +| 65042 = @cil_unaligned +| 65043 = @cil_volatile +| 65044 = @cil_tail +| 65045 = @cil_initobj +| 65046 = @cil_constrained +| 65047 = @cil_cpblk +| 65048 = @cil_initblk +| 65050 = @cil_rethrow +| 65052 = @cil_sizeof +| 65053 = @cil_refanytype +| 65054 = @cil_readonly +; + +// CIL ignored instructions + +@cil_ignore = @cil_nop | @cil_break | @cil_volatile | @cil_unaligned; + +// CIL local/parameter/field access + +@cil_ldarg_any = @cil_ldarg_0 | @cil_ldarg_1 | @cil_ldarg_2 | @cil_ldarg_3 | @cil_ldarg_s | @cil_ldarga_s | @cil_ldarg | @cil_ldarga; +@cil_starg_any = @cil_starg | @cil_starg_s; + +@cil_ldloc_any = @cil_ldloc_0 | @cil_ldloc_1 | @cil_ldloc_2 | @cil_ldloc_3 | @cil_ldloc_s | @cil_ldloca_s | @cil_ldloc | @cil_ldloca; +@cil_stloc_any = @cil_stloc_0 | @cil_stloc_1 | @cil_stloc_2 | @cil_stloc_3 | @cil_stloc_s | @cil_stloc; + +@cil_ldfld_any = @cil_ldfld | @cil_ldsfld | @cil_ldsflda | @cil_ldflda; +@cil_stfld_any = @cil_stfld | @cil_stsfld; + +@cil_local_access = @cil_stloc_any | @cil_ldloc_any; +@cil_arg_access = @cil_starg_any | @cil_ldarg_any; +@cil_read_access = @cil_ldloc_any | @cil_ldarg_any | @cil_ldfld_any; +@cil_write_access = @cil_stloc_any | @cil_starg_any | @cil_stfld_any; + +@cil_stack_access = @cil_local_access | @cil_arg_access; +@cil_field_access = @cil_ldfld_any | @cil_stfld_any; + +@cil_access = @cil_read_access | @cil_write_access; + +// CIL constant/literal instructions + +@cil_ldc_i = @cil_ldc_i4_any | @cil_ldc_i8; + +@cil_ldc_i4_any = @cil_ldc_i4_m1 | @cil_ldc_i4_0 | @cil_ldc_i4_1 | @cil_ldc_i4_2 | @cil_ldc_i4_3 | + @cil_ldc_i4_4 | @cil_ldc_i4_5 | @cil_ldc_i4_6 | @cil_ldc_i4_7 | @cil_ldc_i4_8 | @cil_ldc_i4_s | @cil_ldc_i4; + +@cil_ldc_r = @cil_ldc_r4 | @cil_ldc_r8; + +@cil_literal = @cil_ldnull | @cil_ldc_i | @cil_ldc_r | @cil_ldstr; + +// Control flow + +@cil_conditional_jump = @cil_binary_jump | @cil_unary_jump; +@cil_binary_jump = @cil_beq_s | @cil_bge_s | @cil_bgt_s | @cil_ble_s | @cil_blt_s | + @cil_bne_un_s | @cil_bge_un_s | @cil_bgt_un_s | @cil_ble_un_s | @cil_blt_un_s | + @cil_beq | @cil_bge | @cil_bgt | @cil_ble | @cil_blt | + @cil_bne_un | @cil_bge_un | @cil_bgt_un | @cil_ble_un | @cil_blt_un; +@cil_unary_jump = @cil_brfalse_s | @cil_brtrue_s | @cil_brfalse | @cil_brtrue | @cil_switch; +@cil_unconditional_jump = @cil_br | @cil_br_s | @cil_leave_any; +@cil_leave_any = @cil_leave | @cil_leave_s; +@cil_jump = @cil_unconditional_jump | @cil_conditional_jump; + +// CIL call instructions + +@cil_call_any = @cil_jmp | @cil_call | @cil_calli | @cil_tail | @cil_callvirt | @cil_newobj; + +// CIL expression instructions + +@cil_expr = @cil_literal | @cil_binary_expr | @cil_unary_expr | @cil_call_any | @cil_read_access | + @cil_newarr | @cil_ldtoken | @cil_sizeof | + @cil_ldftn | @cil_ldvirtftn | @cil_localloc | @cil_mkrefany | @cil_refanytype | @cil_arglist | @cil_dup; + +@cil_unary_expr = + @cil_conversion_operation | @cil_unary_arithmetic_operation | @cil_unary_bitwise_operation| + @cil_ldlen | @cil_isinst | @cil_box | @cil_ldobj | @cil_castclass | @cil_unbox_any | + @cil_ldind | @cil_unbox; + +@cil_conversion_operation = + @cil_conv_i1 | @cil_conv_i2 | @cil_conv_i4 | @cil_conv_i8 | + @cil_conv_u1 | @cil_conv_u2 | @cil_conv_u4 | @cil_conv_u8 | + @cil_conv_ovf_i | @cil_conv_ovf_i_un | @cil_conv_ovf_i1 | @cil_conv_ovf_i1_un | + @cil_conv_ovf_i2 | @cil_conv_ovf_i2_un | @cil_conv_ovf_i4 | @cil_conv_ovf_i4_un | + @cil_conv_ovf_i8 | @cil_conv_ovf_i8_un | @cil_conv_ovf_u | @cil_conv_ovf_u_un | + @cil_conv_ovf_u1 | @cil_conv_ovf_u1_un | @cil_conv_ovf_u2 | @cil_conv_ovf_u2_un | + @cil_conv_ovf_u4 | @cil_conv_ovf_u4_un | @cil_conv_ovf_u8 | @cil_conv_ovf_u8_un | + @cil_conv_r4 | @cil_conv_r8 | @cil_conv_ovf_u2 | @cil_conv_ovf_u2_un | + @cil_conv_i | @cil_conv_u | @cil_conv_r_un; + +@cil_ldind = @cil_ldind_i | @cil_ldind_i1 | @cil_ldind_i2 | @cil_ldind_i4 | @cil_ldind_i8 | + @cil_ldind_r4 | @cil_ldind_r8 | @cil_ldind_ref | @cil_ldind_u1 | @cil_ldind_u2 | @cil_ldind_u4; + +@cil_stind = @cil_stind_i | @cil_stind_i1 | @cil_stind_i2 | @cil_stind_i4 | @cil_stind_i8 | + @cil_stind_r4 | @cil_stind_r8 | @cil_stind_ref; + +@cil_bitwise_operation = @cil_binary_bitwise_operation | @cil_unary_bitwise_operation; + +@cil_binary_bitwise_operation = @cil_and | @cil_or | @cil_xor | @cil_shr | @cil_shr | @cil_shr_un | @cil_shl; + +@cil_binary_arithmetic_operation = @cil_add | @cil_sub | @cil_mul | @cil_div | @cil_div_un | + @cil_rem | @cil_rem_un | @cil_add_ovf | @cil_add_ovf_un | @cil_mul_ovf | @cil_mul_ovf_un | + @cil_sub_ovf | @cil_sub_ovf_un; + +@cil_unary_bitwise_operation = @cil_not; + +@cil_binary_expr = @cil_binary_arithmetic_operation | @cil_binary_bitwise_operation | @cil_read_array | @cil_comparison_operation; + +@cil_unary_arithmetic_operation = @cil_neg; + +@cil_comparison_operation = @cil_cgt_un | @cil_ceq | @cil_cgt | @cil_clt | @cil_clt_un; + +// Elements that retrieve an address of something +@cil_read_ref = @cil_ldloca_s | @cil_ldarga_s | @cil_ldflda | @cil_ldsflda | @cil_ldelema; + +// CIL array instructions + +@cil_read_array = + @cil_ldelem | @cil_ldelema | @cil_ldelem_i1 | @cil_ldelem_ref | @cil_ldelem_i | + @cil_ldelem_i1 | @cil_ldelem_i2 | @cil_ldelem_i4 | @cil_ldelem_i8 | @cil_ldelem_r4 | + @cil_ldelem_r8 | @cil_ldelem_u1 | @cil_ldelem_u2 | @cil_ldelem_u4; + +@cil_write_array = @cil_stelem | @cil_stelem_ref | + @cil_stelem_i | @cil_stelem_i1 | @cil_stelem_i2 | @cil_stelem_i4 | @cil_stelem_i8 | + @cil_stelem_r4 | @cil_stelem_r8; + +@cil_throw_any = @cil_throw | @cil_rethrow; + +#keyset[impl, index] +cil_instruction( + unique int id: @cil_instruction, + int opcode: int ref, + int index: int ref, + int impl: @cil_method_implementation ref); + +cil_jump( + unique int instruction: @cil_jump ref, + int target: @cil_instruction ref); + +cil_access( + unique int instruction: @cil_instruction ref, + int target: @cil_accessible ref); + +cil_value( + unique int instruction: @cil_literal ref, + string value: string ref); + +#keyset[instruction, index] +cil_switch( + int instruction: @cil_switch ref, + int index: int ref, + int target: @cil_instruction ref); + +cil_instruction_location( + unique int id: @cil_instruction ref, + int loc: @location ref); + +cil_type_location( + int id: @cil_type ref, + int loc: @location ref); + +cil_method_location( + int id: @cil_method ref, + int loc: @location ref); + +@cil_namespace = @namespace; + +@cil_type_container = @cil_type | @cil_namespace | @cil_method; + +case @cil_type.kind of + 0 = @cil_valueorreftype +| 1 = @cil_typeparameter +| 2 = @cil_array_type +| 3 = @cil_pointer_type +; + +cil_type( + unique int id: @cil_type, + string name: string ref, + int kind: int ref, + int parent: @cil_type_container ref, + int sourceDecl: @cil_type ref); + +cil_pointer_type( + unique int id: @cil_pointer_type ref, + int pointee: @cil_type ref); + +cil_array_type( + unique int id: @cil_array_type ref, + int element_type: @cil_type ref, + int rank: int ref); + +cil_method( + unique int id: @cil_method, + string name: string ref, + int parent: @cil_type ref, + int return_type: @cil_type ref); + +cil_method_source_declaration( + unique int method: @cil_method ref, + int source: @cil_method ref); + +cil_method_implementation( + unique int id: @cil_method_implementation, + int method: @cil_method ref, + int location: @assembly ref); + +cil_implements( + int id: @cil_method ref, + int decl: @cil_method ref); + +#keyset[parent, name] +cil_field( + unique int id: @cil_field, + int parent: @cil_type ref, + string name: string ref, + int field_type: @cil_type ref); + +@cil_element = @cil_instruction | @cil_declaration | @cil_handler | @cil_attribute | @cil_namespace; +@cil_named_element = @cil_declaration | @cil_namespace; +@cil_declaration = @cil_variable | @cil_method | @cil_type | @cil_member; +@cil_accessible = @cil_declaration; +@cil_variable = @cil_field | @cil_stack_variable; +@cil_stack_variable = @cil_local_variable | @cil_parameter; +@cil_member = @cil_method | @cil_type | @cil_field | @cil_property | @cil_event; +@cil_custom_modifier_receiver = @cil_method | @cil_property | @cil_parameter | @cil_field; // todo: add function pointer type + +#keyset[method, index] +cil_parameter( + unique int id: @cil_parameter, + int method: @cil_method ref, + int index: int ref, + int param_type: @cil_type ref); + +cil_parameter_in(unique int id: @cil_parameter ref); +cil_parameter_out(unique int id: @cil_parameter ref); + +cil_setter(unique int prop: @cil_property ref, + int method: @cil_method ref); + +#keyset[id, modifier] +cil_custom_modifiers( + int id: @cil_custom_modifier_receiver ref, + int modifier: @cil_type ref, + int kind: int ref); // modreq: 1, modopt: 0 + +cil_getter(unique int prop: @cil_property ref, + int method: @cil_method ref); + +cil_adder(unique int event: @cil_event ref, + int method: @cil_method ref); + +cil_remover(unique int event: @cil_event ref, int method: @cil_method ref); + +cil_raiser(unique int event: @cil_event ref, int method: @cil_method ref); + +cil_property( + unique int id: @cil_property, + int parent: @cil_type ref, + string name: string ref, + int property_type: @cil_type ref); + +#keyset[parent, name] +cil_event(unique int id: @cil_event, + int parent: @cil_type ref, + string name: string ref, + int event_type: @cil_type ref); + +#keyset[impl, index] +cil_local_variable( + unique int id: @cil_local_variable, + int impl: @cil_method_implementation ref, + int index: int ref, + int var_type: @cil_type ref); + +// CIL handlers (exception handlers etc). + +case @cil_handler.kind of + 0 = @cil_catch_handler +| 1 = @cil_filter_handler +| 2 = @cil_finally_handler +| 4 = @cil_fault_handler +; + +#keyset[impl, index] +cil_handler( + unique int id: @cil_handler, + int impl: @cil_method_implementation ref, + int index: int ref, + int kind: int ref, + int try_start: @cil_instruction ref, + int try_end: @cil_instruction ref, + int handler_start: @cil_instruction ref); + +cil_handler_filter( + unique int id: @cil_handler ref, + int filter_start: @cil_instruction ref); + +cil_handler_type( + unique int id: @cil_handler ref, + int catch_type: @cil_type ref); + +@cil_controlflow_node = @cil_entry_point | @cil_instruction; + +@cil_entry_point = @cil_method_implementation | @cil_handler; + +@cil_dataflow_node = @cil_instruction | @cil_variable | @cil_method; + +cil_method_stack_size( + unique int method: @cil_method_implementation ref, + int size: int ref); + +// CIL modifiers + +cil_public(int id: @cil_member ref); +cil_private(int id: @cil_member ref); +cil_protected(int id: @cil_member ref); +cil_internal(int id: @cil_member ref); +cil_static(int id: @cil_member ref); +cil_sealed(int id: @cil_member ref); +cil_virtual(int id: @cil_method ref); +cil_abstract(int id: @cil_member ref); +cil_class(int id: @cil_type ref); +cil_interface(int id: @cil_type ref); +cil_security(int id: @cil_member ref); +cil_requiresecobject(int id: @cil_method ref); +cil_specialname(int id: @cil_method ref); +cil_newslot(int id: @cil_method ref); + +cil_base_class(unique int id: @cil_type ref, int base: @cil_type ref); +cil_base_interface(int id: @cil_type ref, int base: @cil_type ref); +cil_enum_underlying_type(unique int id: @cil_type ref, int underlying: @cil_type ref); + +#keyset[unbound, index] +cil_type_parameter( + int unbound: @cil_member ref, + int index: int ref, + int param: @cil_typeparameter ref); + +#keyset[bound, index] +cil_type_argument( + int bound: @cil_member ref, + int index: int ref, + int t: @cil_type ref); + +// CIL type parameter constraints + +cil_typeparam_covariant(int tp: @cil_typeparameter ref); +cil_typeparam_contravariant(int tp: @cil_typeparameter ref); +cil_typeparam_class(int tp: @cil_typeparameter ref); +cil_typeparam_struct(int tp: @cil_typeparameter ref); +cil_typeparam_new(int tp: @cil_typeparameter ref); +cil_typeparam_constraint(int tp: @cil_typeparameter ref, int supertype: @cil_type ref); + +// CIL attributes + +cil_attribute( + unique int attributeid: @cil_attribute, + int element: @cil_declaration ref, + int constructor: @cil_method ref); + +#keyset[attribute_id, param] +cil_attribute_named_argument( + int attribute_id: @cil_attribute ref, + string param: string ref, + string value: string ref); + +#keyset[attribute_id, index] +cil_attribute_positional_argument( + int attribute_id: @cil_attribute ref, + int index: int ref, + string value: string ref); + + +// Common .Net data model covering both C# and CIL + +// Common elements +@dotnet_element = @element | @cil_element; +@dotnet_named_element = @named_element | @cil_named_element; +@dotnet_callable = @callable | @cil_method; +@dotnet_variable = @variable | @cil_variable; +@dotnet_field = @field | @cil_field; +@dotnet_parameter = @parameter | @cil_parameter; +@dotnet_declaration = @declaration | @cil_declaration; +@dotnet_member = @member | @cil_member; +@dotnet_event = @event | @cil_event; +@dotnet_property = @property | @cil_property | @indexer; + +// Common types +@dotnet_type = @type | @cil_type; +@dotnet_call = @call | @cil_call_any; +@dotnet_throw = @throw_element | @cil_throw_any; +@dotnet_valueorreftype = @cil_valueorreftype | @value_or_ref_type | @cil_array_type | @void_type; +@dotnet_typeparameter = @type_parameter | @cil_typeparameter; +@dotnet_array_type = @array_type | @cil_array_type; +@dotnet_pointer_type = @pointer_type | @cil_pointer_type; +@dotnet_type_parameter = @type_parameter | @cil_typeparameter; +@dotnet_generic = @dotnet_valueorreftype | @dotnet_callable; + +// Attributes +@dotnet_attribute = @attribute | @cil_attribute; + +// Expressions +@dotnet_expr = @expr | @cil_expr; + +// Literals +@dotnet_literal = @literal_expr | @cil_literal; +@dotnet_string_literal = @string_literal_expr | @cil_ldstr; +@dotnet_int_literal = @integer_literal_expr | @cil_ldc_i; +@dotnet_float_literal = @float_literal_expr | @cil_ldc_r; +@dotnet_null_literal = @null_literal_expr | @cil_ldnull; + +@metadata_entity = @cil_method | @cil_type | @cil_field | @cil_property | @field | @property | + @callable | @value_or_ref_type | @void_type; + +#keyset[entity, location] +metadata_handle(int entity : @metadata_entity ref, int location: @assembly ref, int handle: int ref) diff --git a/csharp/upgrades/26249c105a81c61ef8738a198928de2d4b763c37/semmlecode.csharp.dbscheme b/csharp/upgrades/26249c105a81c61ef8738a198928de2d4b763c37/semmlecode.csharp.dbscheme new file mode 100644 index 00000000000..e6442d16b7e --- /dev/null +++ b/csharp/upgrades/26249c105a81c61ef8738a198928de2d4b763c37/semmlecode.csharp.dbscheme @@ -0,0 +1,1914 @@ + +/** + * An invocation of the compiler. Note that more than one file may be + * compiled per invocation. For example, this command compiles three + * source files: + * + * csc f1.cs f2.cs f3.cs + * + * The `id` simply identifies the invocation, while `cwd` is the working + * directory from which the compiler was invoked. + */ +compilations( + unique int id : @compilation, + string cwd : string ref +); + +/** + * The arguments that were passed to the extractor for a compiler + * invocation. If `id` is for the compiler invocation + * + * csc f1.cs f2.cs f3.cs + * + * then typically there will be rows for + * + * num | arg + * --- | --- + * 0 | --compiler + * 1 | *path to compiler* + * 2 | --cil + * 3 | f1.cs + * 4 | f2.cs + * 5 | f3.cs + */ +#keyset[id, num] +compilation_args( + int id : @compilation ref, + int num : int ref, + string arg : string ref +); + +/** + * The source files that are compiled by a compiler invocation. + * If `id` is for the compiler invocation + * + * csc f1.cs f2.cs f3.cs + * + * then there will be rows for + * + * num | arg + * --- | --- + * 0 | f1.cs + * 1 | f2.cs + * 2 | f3.cs + */ +#keyset[id, num] +compilation_compiling_files( + int id : @compilation ref, + int num : int ref, + int file : @file ref +); + +/** + * The references used by a compiler invocation. + * If `id` is for the compiler invocation + * + * csc f1.cs f2.cs f3.cs /r:ref1.dll /r:ref2.dll /r:ref3.dll + * + * then there will be rows for + * + * num | arg + * --- | --- + * 0 | ref1.dll + * 1 | ref2.dll + * 2 | ref3.dll + */ +#keyset[id, num] +compilation_referencing_files( + int id : @compilation ref, + int num : int ref, + int file : @file ref +); + +/** + * The time taken by the extractor for a compiler invocation. + * + * For each file `num`, there will be rows for + * + * kind | seconds + * ---- | --- + * 1 | CPU seconds used by the extractor frontend + * 2 | Elapsed seconds during the extractor frontend + * 3 | CPU seconds used by the extractor backend + * 4 | Elapsed seconds during the extractor backend + */ +#keyset[id, num, kind] +compilation_time( + int id : @compilation ref, + int num : int ref, + /* kind: + 1 = frontend_cpu_seconds + 2 = frontend_elapsed_seconds + 3 = extractor_cpu_seconds + 4 = extractor_elapsed_seconds + */ + int kind : int ref, + float seconds : float ref +); + +/** + * An error or warning generated by the extractor. + * The diagnostic message `diagnostic` was generated during compiler + * invocation `compilation`, and is the `file_number_diagnostic_number`th + * message generated while extracting the `file_number`th file of that + * invocation. + */ +#keyset[compilation, file_number, file_number_diagnostic_number] +diagnostic_for( + unique int diagnostic : @diagnostic ref, + int compilation : @compilation ref, + int file_number : int ref, + int file_number_diagnostic_number : int ref +); + +diagnostics( + unique int id: @diagnostic, + int severity: int ref, + string error_tag: string ref, + string error_message: string ref, + string full_error_message: string ref, + int location: @location_default ref +); + +extractor_messages( + unique int id: @extractor_message, + int severity: int ref, + string origin : string ref, + string text : string ref, + string entity : string ref, + int location: @location_default ref, + string stack_trace : string ref +); + +/** + * If extraction was successful, then `cpu_seconds` and + * `elapsed_seconds` are the CPU time and elapsed time (respectively) + * that extraction took for compiler invocation `id`. + */ +compilation_finished( + unique int id : @compilation ref, + float cpu_seconds : float ref, + float elapsed_seconds : float ref +); + +compilation_assembly( + unique int id : @compilation ref, + int assembly: @assembly ref +) + +/* + * External artifacts + */ + +externalDefects( + unique int id: @externalDefect, + string queryPath: string ref, + int location: @location ref, + string message: string ref, + float severity: float ref); + +externalMetrics( + unique int id: @externalMetric, + string queryPath: string ref, + int location: @location ref, + float value: float ref); + +externalData( + int id: @externalDataElement, + string path: string ref, + int column: int ref, + string value: string ref); + +snapshotDate( + unique date snapshotDate: date ref); + +sourceLocationPrefix( + string prefix: string ref); + +/* + * Duplicate code + */ + +duplicateCode( + unique int id: @duplication, + string relativePath: string ref, + int equivClass: int ref); + +similarCode( + unique int id: @similarity, + string relativePath: string ref, + int equivClass: int ref); + +@duplication_or_similarity = @duplication | @similarity + +tokens( + int id: @duplication_or_similarity ref, + int offset: int ref, + int beginLine: int ref, + int beginColumn: int ref, + int endLine: int ref, + int endColumn: int ref); + +/* + * C# dbscheme + */ + +/** ELEMENTS **/ + +@element = @declaration | @stmt | @expr | @modifier | @attribute | @namespace_declaration + | @using_directive | @type_parameter_constraints | @external_element + | @xmllocatable | @asp_element | @namespace; + +@declaration = @callable | @generic | @assignable | @namespace; + +@named_element = @namespace | @declaration; + +@declaration_with_accessors = @property | @indexer | @event; + +@assignable = @variable | @assignable_with_accessors | @event; + +@assignable_with_accessors = @property | @indexer; + +@external_element = @externalMetric | @externalDefect | @externalDataElement; + +@attributable = @assembly | @field | @parameter | @operator | @method | @constructor + | @destructor | @callable_accessor | @value_or_ref_type | @declaration_with_accessors + | @local_function; + +/** LOCATIONS, ASEMMBLIES, MODULES, FILES and FOLDERS **/ + +@location = @location_default | @assembly; + +locations_default( + unique int id: @location_default, + int file: @file ref, + int beginLine: int ref, + int beginColumn: int ref, + int endLine: int ref, + int endColumn: int ref); + +@sourceline = @file | @callable | @xmllocatable; + +numlines( + int element_id: @sourceline ref, + int num_lines: int ref, + int num_code: int ref, + int num_comment: int ref); + +assemblies( + unique int id: @assembly, + int file: @file ref, + string fullname: string ref, + string name: string ref, + string version: string ref); + +/* + fromSource(0) = unknown, + fromSource(1) = from source, + fromSource(2) = from library +*/ +files( + unique int id: @file, + string name: string ref, + string simple: string ref, + string ext: string ref, + int fromSource: int ref); + +folders( + unique int id: @folder, + string name: string ref, + string simple: string ref); + +@container = @folder | @file ; + +containerparent( + int parent: @container ref, + unique int child: @container ref); + +file_extraction_mode( + unique int file: @file ref, + int mode: int ref + /* 0 = normal, 1 = standalone extractor */ + ); + +/** NAMESPACES **/ + +@type_container = @namespace | @type; + +namespaces( + unique int id: @namespace, + string name: string ref); + +namespace_declarations( + unique int id: @namespace_declaration, + int namespace_id: @namespace ref); + +namespace_declaration_location( + unique int id: @namespace_declaration ref, + int loc: @location ref); + +parent_namespace( + unique int child_id: @type_container ref, + int namespace_id: @namespace ref); + +@declaration_or_directive = @namespace_declaration | @type | @using_directive; + +parent_namespace_declaration( + int child_id: @declaration_or_directive ref, // cannot be unique because of partial classes + int namespace_id: @namespace_declaration ref); + +@using_directive = @using_namespace_directive | @using_static_directive; + +using_namespace_directives( + unique int id: @using_namespace_directive, + int namespace_id: @namespace ref); + +using_static_directives( + unique int id: @using_static_directive, + int type_id: @type_or_ref ref); + +using_directive_location( + unique int id: @using_directive ref, + int loc: @location ref); + +/** TYPES **/ + +types( + unique int id: @type, + int kind: int ref, + string name: string ref); + +case @type.kind of + 1 = @bool_type +| 2 = @char_type +| 3 = @decimal_type +| 4 = @sbyte_type +| 5 = @short_type +| 6 = @int_type +| 7 = @long_type +| 8 = @byte_type +| 9 = @ushort_type +| 10 = @uint_type +| 11 = @ulong_type +| 12 = @float_type +| 13 = @double_type +| 14 = @enum_type +| 15 = @struct_type +| 17 = @class_type +| 19 = @interface_type +| 20 = @delegate_type +| 21 = @null_type +| 22 = @type_parameter +| 23 = @pointer_type +| 24 = @nullable_type +| 25 = @array_type +| 26 = @void_type +| 27 = @int_ptr_type +| 28 = @uint_ptr_type +| 29 = @dynamic_type +| 30 = @arglist_type +| 31 = @unknown_type +| 32 = @tuple_type + ; + +@simple_type = @bool_type | @char_type | @integral_type | @floating_point_type | @decimal_type; +@integral_type = @signed_integral_type | @unsigned_integral_type; +@signed_integral_type = @sbyte_type | @short_type | @int_type | @long_type; +@unsigned_integral_type = @byte_type | @ushort_type | @uint_type | @ulong_type; +@floating_point_type = @float_type | @double_type; +@value_type = @simple_type | @enum_type | @struct_type | @nullable_type | @int_ptr_type + | @uint_ptr_type | @tuple_type; +@ref_type = @class_type | @interface_type | @array_type | @delegate_type | @null_type + | @dynamic_type; +@value_or_ref_type = @value_type | @ref_type; + +typerefs( + unique int id: @typeref, + string name: string ref); + +typeref_type( + int id: @typeref ref, + unique int typeId: @type ref); + +@type_or_ref = @type | @typeref; + +array_element_type( + unique int array: @array_type ref, + int dimension: int ref, + int rank: int ref, + int element: @type_or_ref ref); + +nullable_underlying_type( + unique int nullable: @nullable_type ref, + int underlying: @type_or_ref ref); + +pointer_referent_type( + unique int pointer: @pointer_type ref, + int referent: @type_or_ref ref); + +enum_underlying_type( + unique int enum_id: @enum_type ref, + int underlying_type_id: @type_or_ref ref); + +delegate_return_type( + unique int delegate_id: @delegate_type ref, + int return_type_id: @type_or_ref ref); + +extend( + unique int sub: @type ref, + int super: @type_or_ref ref); + +anonymous_types( + unique int id: @type ref); + +@interface_or_ref = @interface_type | @typeref; + +implement( + int sub: @type ref, + int super: @type_or_ref ref); + +type_location( + int id: @type ref, + int loc: @location ref); + +tuple_underlying_type( + unique int tuple: @tuple_type ref, + int struct: @type_or_ref ref); + +#keyset[tuple, index] +tuple_element( + int tuple: @tuple_type ref, + int index: int ref, + unique int field: @field ref); + +attributes( + unique int id: @attribute, + int type_id: @type_or_ref ref, + int target: @attributable ref); + +attribute_location( + int id: @attribute ref, + int loc: @location ref); + +@type_mention_parent = @element | @type_mention; + +type_mention( + unique int id: @type_mention, + int type_id: @type_or_ref ref, + int parent: @type_mention_parent ref); + +type_mention_location( + unique int id: @type_mention ref, + int loc: @location ref); + +@has_type_annotation = @assignable | @type_parameter | @callable | @expr | @delegate_type | @generic; + +/** + * A direct annotation on an entity, for example `string? x;`. + * + * Annotations: + * 2 = reftype is not annotated "!" + * 3 = reftype is annotated "?" + * 4 = readonly ref type / in parameter + * 5 = ref type parameter, return or local variable + * 6 = out parameter + * + * Note that the annotation depends on the element it annotates. + * @assignable: The annotation is on the type of the assignable, for example the variable type. + * @type_parameter: The annotation is on the reftype constraint + * @callable: The annotation is on the return type + * @array_type: The annotation is on the element type + */ +type_annotation(int id: @has_type_annotation ref, int annotation: int ref); + +nullability(unique int nullability: @nullability, int kind: int ref); + +case @nullability.kind of + 0 = @oblivious +| 1 = @not_annotated +| 2 = @annotated +; + +#keyset[parent, index] +nullability_parent(int nullability: @nullability ref, int index: int ref, int parent: @nullability ref) + +type_nullability(int id: @has_type_annotation ref, int nullability: @nullability ref); + +/** + * The nullable flow state of an expression, as determined by Roslyn. + * 0 = none (default, not populated) + * 1 = not null + * 2 = maybe null + */ +expr_flowstate(unique int id: @expr ref, int state: int ref); + +/** GENERICS **/ + +@generic = @type | @method | @local_function; + +type_parameters( + unique int id: @type_parameter ref, + int index: int ref, + int generic_id: @generic ref, + int variance: int ref /* none = 0, out = 1, in = 2 */); + +#keyset[constructed_id, index] +type_arguments( + int id: @type_or_ref ref, + int index: int ref, + int constructed_id: @generic_or_ref ref); + +@generic_or_ref = @generic | @typeref; + +constructed_generic( + unique int constructed: @generic ref, + int generic: @generic_or_ref ref); + +type_parameter_constraints( + unique int id: @type_parameter_constraints, + int param_id: @type_parameter ref); + +type_parameter_constraints_location( + int id: @type_parameter_constraints ref, + int loc: @location ref); + +general_type_parameter_constraints( + int id: @type_parameter_constraints ref, + int kind: int ref /* class = 1, struct = 2, new = 3 */); + +specific_type_parameter_constraints( + int id: @type_parameter_constraints ref, + int base_id: @type_or_ref ref); + +specific_type_parameter_nullability( + int id: @type_parameter_constraints ref, + int base_id: @type_or_ref ref, + int nullability: @nullability ref); + +/** MODIFIERS */ + +@modifiable = @modifiable_direct | @event_accessor; + +@modifiable_direct = @member | @accessor | @local_function | @anonymous_function_expr; + +modifiers( + unique int id: @modifier, + string name: string ref); + +has_modifiers( + int id: @modifiable_direct ref, + int mod_id: @modifier ref); + +compiler_generated(unique int id: @modifiable_direct ref); + +/** MEMBERS **/ + +@member = @method | @constructor | @destructor | @field | @property | @event | @operator | @indexer | @type; + +@named_exprorstmt = @goto_stmt | @labeled_stmt | @expr; + +@virtualizable = @method | @property | @indexer | @event; + +exprorstmt_name( + unique int parent_id: @named_exprorstmt ref, + string name: string ref); + +nested_types( + unique int id: @type ref, + int declaring_type_id: @type ref, + int unbound_id: @type ref); + +properties( + unique int id: @property, + string name: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @property ref); + +property_location( + int id: @property ref, + int loc: @location ref); + +indexers( + unique int id: @indexer, + string name: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @indexer ref); + +indexer_location( + int id: @indexer ref, + int loc: @location ref); + +accessors( + unique int id: @accessor, + int kind: int ref, + string name: string ref, + int declaring_member_id: @member ref, + int unbound_id: @accessor ref); + +case @accessor.kind of + 1 = @getter +| 2 = @setter + ; + +init_only_accessors( + unique int id: @accessor ref); + +accessor_location( + int id: @accessor ref, + int loc: @location ref); + +events( + unique int id: @event, + string name: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @event ref); + +event_location( + int id: @event ref, + int loc: @location ref); + +event_accessors( + unique int id: @event_accessor, + int kind: int ref, + string name: string ref, + int declaring_event_id: @event ref, + int unbound_id: @event_accessor ref); + +case @event_accessor.kind of + 1 = @add_event_accessor +| 2 = @remove_event_accessor + ; + +event_accessor_location( + int id: @event_accessor ref, + int loc: @location ref); + +operators( + unique int id: @operator, + string name: string ref, + string symbol: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @operator ref); + +operator_location( + int id: @operator ref, + int loc: @location ref); + +constant_value( + int id: @variable ref, + string value: string ref); + +/** CALLABLES **/ + +@callable = @method | @constructor | @destructor | @operator | @callable_accessor | @anonymous_function_expr | @local_function; + +@callable_accessor = @accessor | @event_accessor; + +methods( + unique int id: @method, + string name: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @method ref); + +method_location( + int id: @method ref, + int loc: @location ref); + +constructors( + unique int id: @constructor, + string name: string ref, + int declaring_type_id: @type ref, + int unbound_id: @constructor ref); + +constructor_location( + int id: @constructor ref, + int loc: @location ref); + +destructors( + unique int id: @destructor, + string name: string ref, + int declaring_type_id: @type ref, + int unbound_id: @destructor ref); + +destructor_location( + int id: @destructor ref, + int loc: @location ref); + +overrides( + int id: @callable ref, + int base_id: @callable ref); + +explicitly_implements( + int id: @member ref, + int interface_id: @interface_or_ref ref); + +local_functions( + unique int id: @local_function, + string name: string ref, + int return_type: @type ref, + int unbound_id: @local_function ref); + +local_function_stmts( + unique int fn: @local_function_stmt ref, + int stmt: @local_function ref); + +/** VARIABLES **/ + +@variable = @local_scope_variable | @field; + +@local_scope_variable = @local_variable | @parameter; + +fields( + unique int id: @field, + int kind: int ref, + string name: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @field ref); + +case @field.kind of + 1 = @addressable_field +| 2 = @constant + ; + +field_location( + int id: @field ref, + int loc: @location ref); + +localvars( + unique int id: @local_variable, + int kind: int ref, + string name: string ref, + int implicitly_typed: int ref /* 0 = no, 1 = yes */, + int type_id: @type_or_ref ref, + int parent_id: @local_var_decl_expr ref); + +case @local_variable.kind of + 1 = @addressable_local_variable +| 2 = @local_constant +| 3 = @local_variable_ref + ; + +localvar_location( + unique int id: @local_variable ref, + int loc: @location ref); + +@parameterizable = @callable | @delegate_type | @indexer; + +#keyset[name, parent_id] +#keyset[index, parent_id] +params( + unique int id: @parameter, + string name: string ref, + int type_id: @type_or_ref ref, + int index: int ref, + int mode: int ref, /* value = 0, ref = 1, out = 2, array = 3, this = 4 */ + int parent_id: @parameterizable ref, + int unbound_id: @parameter ref); + +param_location( + int id: @parameter ref, + int loc: @location ref); + +/** STATEMENTS **/ + +@exprorstmt_parent = @control_flow_element | @top_level_exprorstmt_parent; + +statements( + unique int id: @stmt, + int kind: int ref); + +#keyset[index, parent] +stmt_parent( + unique int stmt: @stmt ref, + int index: int ref, + int parent: @control_flow_element ref); + +@top_level_stmt_parent = @callable; + +// [index, parent] is not a keyset because the same parent may be compiled multiple times +stmt_parent_top_level( + unique int stmt: @stmt ref, + int index: int ref, + int parent: @top_level_stmt_parent ref); + +case @stmt.kind of + 1 = @block_stmt +| 2 = @expr_stmt +| 3 = @if_stmt +| 4 = @switch_stmt +| 5 = @while_stmt +| 6 = @do_stmt +| 7 = @for_stmt +| 8 = @foreach_stmt +| 9 = @break_stmt +| 10 = @continue_stmt +| 11 = @goto_stmt +| 12 = @goto_case_stmt +| 13 = @goto_default_stmt +| 14 = @throw_stmt +| 15 = @return_stmt +| 16 = @yield_stmt +| 17 = @try_stmt +| 18 = @checked_stmt +| 19 = @unchecked_stmt +| 20 = @lock_stmt +| 21 = @using_block_stmt +| 22 = @var_decl_stmt +| 23 = @const_decl_stmt +| 24 = @empty_stmt +| 25 = @unsafe_stmt +| 26 = @fixed_stmt +| 27 = @label_stmt +| 28 = @catch +| 29 = @case_stmt +| 30 = @local_function_stmt +| 31 = @using_decl_stmt + ; + +@using_stmt = @using_block_stmt | @using_decl_stmt; + +@labeled_stmt = @label_stmt | @case; + +@decl_stmt = @var_decl_stmt | @const_decl_stmt | @using_decl_stmt; + +@cond_stmt = @if_stmt | @switch_stmt; + +@loop_stmt = @while_stmt | @do_stmt | @for_stmt | @foreach_stmt; + +@jump_stmt = @break_stmt | @goto_any_stmt | @continue_stmt | @throw_stmt | @return_stmt + | @yield_stmt; + +@goto_any_stmt = @goto_default_stmt | @goto_case_stmt | @goto_stmt; + + +stmt_location( + unique int id: @stmt ref, + int loc: @location ref); + +catch_type( + unique int catch_id: @catch ref, + int type_id: @type_or_ref ref, + int kind: int ref /* explicit = 1, implicit = 2 */); + +/** EXPRESSIONS **/ + +expressions( + unique int id: @expr, + int kind: int ref, + int type_id: @type_or_ref ref); + +#keyset[index, parent] +expr_parent( + unique int expr: @expr ref, + int index: int ref, + int parent: @control_flow_element ref); + +@top_level_expr_parent = @attribute | @field | @property | @indexer | @parameter; + +@top_level_exprorstmt_parent = @top_level_expr_parent | @top_level_stmt_parent; + +// [index, parent] is not a keyset because the same parent may be compiled multiple times +expr_parent_top_level( + unique int expr: @expr ref, + int index: int ref, + int parent: @top_level_exprorstmt_parent ref); + +case @expr.kind of +/* literal */ + 1 = @bool_literal_expr +| 2 = @char_literal_expr +| 3 = @decimal_literal_expr +| 4 = @int_literal_expr +| 5 = @long_literal_expr +| 6 = @uint_literal_expr +| 7 = @ulong_literal_expr +| 8 = @float_literal_expr +| 9 = @double_literal_expr +| 10 = @string_literal_expr +| 11 = @null_literal_expr +/* primary & unary */ +| 12 = @this_access_expr +| 13 = @base_access_expr +| 14 = @local_variable_access_expr +| 15 = @parameter_access_expr +| 16 = @field_access_expr +| 17 = @property_access_expr +| 18 = @method_access_expr +| 19 = @event_access_expr +| 20 = @indexer_access_expr +| 21 = @array_access_expr +| 22 = @type_access_expr +| 23 = @typeof_expr +| 24 = @method_invocation_expr +| 25 = @delegate_invocation_expr +| 26 = @operator_invocation_expr +| 27 = @cast_expr +| 28 = @object_creation_expr +| 29 = @explicit_delegate_creation_expr +| 30 = @implicit_delegate_creation_expr +| 31 = @array_creation_expr +| 32 = @default_expr +| 33 = @plus_expr +| 34 = @minus_expr +| 35 = @bit_not_expr +| 36 = @log_not_expr +| 37 = @post_incr_expr +| 38 = @post_decr_expr +| 39 = @pre_incr_expr +| 40 = @pre_decr_expr +/* multiplicative */ +| 41 = @mul_expr +| 42 = @div_expr +| 43 = @rem_expr +/* additive */ +| 44 = @add_expr +| 45 = @sub_expr +/* shift */ +| 46 = @lshift_expr +| 47 = @rshift_expr +/* relational */ +| 48 = @lt_expr +| 49 = @gt_expr +| 50 = @le_expr +| 51 = @ge_expr +/* equality */ +| 52 = @eq_expr +| 53 = @ne_expr +/* logical */ +| 54 = @bit_and_expr +| 55 = @bit_xor_expr +| 56 = @bit_or_expr +| 57 = @log_and_expr +| 58 = @log_or_expr +/* type testing */ +| 59 = @is_expr +| 60 = @as_expr +/* null coalescing */ +| 61 = @null_coalescing_expr +/* conditional */ +| 62 = @conditional_expr +/* assignment */ +| 63 = @simple_assign_expr +| 64 = @assign_add_expr +| 65 = @assign_sub_expr +| 66 = @assign_mul_expr +| 67 = @assign_div_expr +| 68 = @assign_rem_expr +| 69 = @assign_and_expr +| 70 = @assign_xor_expr +| 71 = @assign_or_expr +| 72 = @assign_lshift_expr +| 73 = @assign_rshift_expr +/* more */ +| 74 = @object_init_expr +| 75 = @collection_init_expr +| 76 = @array_init_expr +| 77 = @checked_expr +| 78 = @unchecked_expr +| 79 = @constructor_init_expr +| 80 = @add_event_expr +| 81 = @remove_event_expr +| 82 = @par_expr +| 83 = @local_var_decl_expr +| 84 = @lambda_expr +| 85 = @anonymous_method_expr +| 86 = @namespace_expr +/* dynamic */ +| 92 = @dynamic_element_access_expr +| 93 = @dynamic_member_access_expr +/* unsafe */ +| 100 = @pointer_indirection_expr +| 101 = @address_of_expr +| 102 = @sizeof_expr +/* async */ +| 103 = @await_expr +/* C# 6.0 */ +| 104 = @nameof_expr +| 105 = @interpolated_string_expr +| 106 = @unknown_expr +/* C# 7.0 */ +| 107 = @throw_expr +| 108 = @tuple_expr +| 109 = @local_function_invocation_expr +| 110 = @ref_expr +| 111 = @discard_expr +/* C# 8.0 */ +| 112 = @range_expr +| 113 = @index_expr +| 114 = @switch_expr +| 115 = @recursive_pattern_expr +| 116 = @property_pattern_expr +| 117 = @positional_pattern_expr +| 118 = @switch_case_expr +| 119 = @assign_coalesce_expr +| 120 = @suppress_nullable_warning_expr +| 121 = @namespace_access_expr +; + +@switch = @switch_stmt | @switch_expr; +@case = @case_stmt | @switch_case_expr; +@pattern_match = @case | @is_expr; + +@integer_literal_expr = @int_literal_expr | @long_literal_expr | @uint_literal_expr | @ulong_literal_expr; +@real_literal_expr = @float_literal_expr | @double_literal_expr | @decimal_literal_expr; +@literal_expr = @bool_literal_expr | @char_literal_expr | @integer_literal_expr | @real_literal_expr + | @string_literal_expr | @null_literal_expr; + +@assign_expr = @simple_assign_expr | @assign_op_expr | @local_var_decl_expr; +@assign_op_expr = @assign_arith_expr | @assign_bitwise_expr | @assign_event_expr | @assign_coalesce_expr; +@assign_event_expr = @add_event_expr | @remove_event_expr; + +@assign_arith_expr = @assign_add_expr | @assign_sub_expr | @assign_mul_expr | @assign_div_expr + | @assign_rem_expr +@assign_bitwise_expr = @assign_and_expr | @assign_or_expr | @assign_xor_expr + | @assign_lshift_expr | @assign_rshift_expr; + +@member_access_expr = @field_access_expr | @property_access_expr | @indexer_access_expr | @event_access_expr + | @method_access_expr | @type_access_expr | @dynamic_member_access_expr; +@access_expr = @member_access_expr | @this_access_expr | @base_access_expr | @assignable_access_expr | @namespace_access_expr; +@element_access_expr = @indexer_access_expr | @array_access_expr | @dynamic_element_access_expr; + +@local_variable_access = @local_variable_access_expr | @local_var_decl_expr; +@local_scope_variable_access_expr = @parameter_access_expr | @local_variable_access; +@variable_access_expr = @local_scope_variable_access_expr | @field_access_expr; + +@assignable_access_expr = @variable_access_expr | @property_access_expr | @element_access_expr + | @event_access_expr | @dynamic_member_access_expr; + +@objectorcollection_init_expr = @object_init_expr | @collection_init_expr; + +@delegate_creation_expr = @explicit_delegate_creation_expr | @implicit_delegate_creation_expr; + +@bin_arith_op_expr = @mul_expr | @div_expr | @rem_expr | @add_expr | @sub_expr; +@incr_op_expr = @pre_incr_expr | @post_incr_expr; +@decr_op_expr = @pre_decr_expr | @post_decr_expr; +@mut_op_expr = @incr_op_expr | @decr_op_expr; +@un_arith_op_expr = @plus_expr | @minus_expr | @mut_op_expr; +@arith_op_expr = @bin_arith_op_expr | @un_arith_op_expr; + +@ternary_log_op_expr = @conditional_expr; +@bin_log_op_expr = @log_and_expr | @log_or_expr | @null_coalescing_expr; +@un_log_op_expr = @log_not_expr; +@log_expr = @un_log_op_expr | @bin_log_op_expr | @ternary_log_op_expr; + +@bin_bit_op_expr = @bit_and_expr | @bit_or_expr | @bit_xor_expr | @lshift_expr + | @rshift_expr; +@un_bit_op_expr = @bit_not_expr; +@bit_expr = @un_bit_op_expr | @bin_bit_op_expr; + +@equality_op_expr = @eq_expr | @ne_expr; +@rel_op_expr = @gt_expr | @lt_expr| @ge_expr | @le_expr; +@comp_expr = @equality_op_expr | @rel_op_expr; + +@op_expr = @assign_expr | @un_op | @bin_op | @ternary_op; + +@ternary_op = @ternary_log_op_expr; +@bin_op = @bin_arith_op_expr | @bin_log_op_expr | @bin_bit_op_expr | @comp_expr; +@un_op = @un_arith_op_expr | @un_log_op_expr | @un_bit_op_expr | @sizeof_expr + | @pointer_indirection_expr | @address_of_expr; + +@anonymous_function_expr = @lambda_expr | @anonymous_method_expr; + +@call = @method_invocation_expr | @constructor_init_expr | @operator_invocation_expr + | @delegate_invocation_expr | @object_creation_expr | @call_access_expr + | @local_function_invocation_expr; + +@call_access_expr = @property_access_expr | @event_access_expr | @indexer_access_expr; + +@late_bindable_expr = @dynamic_element_access_expr | @dynamic_member_access_expr + | @object_creation_expr | @method_invocation_expr | @operator_invocation_expr; + +@throw_element = @throw_expr | @throw_stmt; + +@implicitly_typeable_object_creation_expr = @object_creation_expr | @explicit_delegate_creation_expr; + +implicitly_typed_array_creation( + unique int id: @array_creation_expr ref); + +explicitly_sized_array_creation( + unique int id: @array_creation_expr ref); + +stackalloc_array_creation( + unique int id: @array_creation_expr ref); + +implicitly_typed_object_creation( + unique int id: @implicitly_typeable_object_creation_expr ref); + +mutator_invocation_mode( + unique int id: @operator_invocation_expr ref, + int mode: int ref /* prefix = 1, postfix = 2*/); + +expr_compiler_generated( + unique int id: @expr ref); + +expr_value( + unique int id: @expr ref, + string value: string ref); + +expr_call( + unique int caller_id: @expr ref, + int target_id: @callable ref); + +expr_access( + unique int accesser_id: @access_expr ref, + int target_id: @accessible ref); + +@accessible = @method | @assignable | @local_function | @namespace; + +expr_location( + unique int id: @expr ref, + int loc: @location ref); + +dynamic_member_name( + unique int id: @late_bindable_expr ref, + string name: string ref); + +@qualifiable_expr = @member_access_expr + | @method_invocation_expr + | @element_access_expr; + +conditional_access( + unique int id: @qualifiable_expr ref); + +expr_argument( + unique int id: @expr ref, + int mode: int ref); + /* mode is the same as params: value = 0, ref = 1, out = 2 */ + +expr_argument_name( + unique int id: @expr ref, + string name: string ref); + +/** CONTROL/DATA FLOW **/ + +@control_flow_element = @stmt | @expr; + +/* XML Files */ + +xmlEncoding ( + unique int id: @file ref, + string encoding: string ref); + +xmlDTDs( + unique int id: @xmldtd, + string root: string ref, + string publicId: string ref, + string systemId: string ref, + int fileid: @file ref); + +xmlElements( + unique int id: @xmlelement, + string name: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int fileid: @file ref); + +xmlAttrs( + unique int id: @xmlattribute, + int elementid: @xmlelement ref, + string name: string ref, + string value: string ref, + int idx: int ref, + int fileid: @file ref); + +xmlNs( + int id: @xmlnamespace, + string prefixName: string ref, + string URI: string ref, + int fileid: @file ref); + +xmlHasNs( + int elementId: @xmlnamespaceable ref, + int nsId: @xmlnamespace ref, + int fileid: @file ref); + +xmlComments( + unique int id: @xmlcomment, + string text: string ref, + int parentid: @xmlparent ref, + int fileid: @file ref); + +xmlChars( + unique int id: @xmlcharacters, + string text: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int isCDATA: int ref, + int fileid: @file ref); + +@xmlparent = @file | @xmlelement; +@xmlnamespaceable = @xmlelement | @xmlattribute; + +xmllocations( + int xmlElement: @xmllocatable ref, + int location: @location_default ref); + +@xmllocatable = @xmlcharacters | @xmlelement | @xmlcomment | @xmlattribute | @xmldtd | @file | @xmlnamespace; + +/* Comments */ + +commentline( + unique int id: @commentline, + int kind: int ref, + string text: string ref, + string rawtext: string ref); + +case @commentline.kind of + 0 = @singlelinecomment +| 1 = @xmldoccomment +| 2 = @multilinecomment; + +commentline_location( + unique int id: @commentline ref, + int loc: @location ref); + +commentblock( + unique int id : @commentblock); + +commentblock_location( + unique int id: @commentblock ref, + int loc: @location ref); + +commentblock_binding( + int id: @commentblock ref, + int entity: @element ref, + int bindtype: int ref); /* 0: Parent, 1: Best, 2: Before, 3: After */ + +commentblock_child( + int id: @commentblock ref, + int commentline: @commentline ref, + int index: int ref); + +/* ASP.NET */ + +case @asp_element.kind of + 0=@asp_close_tag +| 1=@asp_code +| 2=@asp_comment +| 3=@asp_data_binding +| 4=@asp_directive +| 5=@asp_open_tag +| 6=@asp_quoted_string +| 7=@asp_text +| 8=@asp_xml_directive; + +@asp_attribute = @asp_code | @asp_data_binding | @asp_quoted_string; + +asp_elements( + unique int id: @asp_element, + int kind: int ref, + int loc: @location ref); + +asp_comment_server(unique int comment: @asp_comment ref); +asp_code_inline(unique int code: @asp_code ref); +asp_directive_attribute( + int directive: @asp_directive ref, + int index: int ref, + string name: string ref, + int value: @asp_quoted_string ref); +asp_directive_name( + unique int directive: @asp_directive ref, + string name: string ref); +asp_element_body( + unique int element: @asp_element ref, + string body: string ref); +asp_tag_attribute( + int tag: @asp_open_tag ref, + int index: int ref, + string name: string ref, + int attribute: @asp_attribute ref); +asp_tag_name( + unique int tag: @asp_open_tag ref, + string name: string ref); +asp_tag_isempty(int tag: @asp_open_tag ref); + +/* Common Intermediate Language - CIL */ + +case @cil_instruction.opcode of + 0 = @cil_nop +| 1 = @cil_break +| 2 = @cil_ldarg_0 +| 3 = @cil_ldarg_1 +| 4 = @cil_ldarg_2 +| 5 = @cil_ldarg_3 +| 6 = @cil_ldloc_0 +| 7 = @cil_ldloc_1 +| 8 = @cil_ldloc_2 +| 9 = @cil_ldloc_3 +| 10 = @cil_stloc_0 +| 11 = @cil_stloc_1 +| 12 = @cil_stloc_2 +| 13 = @cil_stloc_3 +| 14 = @cil_ldarg_s +| 15 = @cil_ldarga_s +| 16 = @cil_starg_s +| 17 = @cil_ldloc_s +| 18 = @cil_ldloca_s +| 19 = @cil_stloc_s +| 20 = @cil_ldnull +| 21 = @cil_ldc_i4_m1 +| 22 = @cil_ldc_i4_0 +| 23 = @cil_ldc_i4_1 +| 24 = @cil_ldc_i4_2 +| 25 = @cil_ldc_i4_3 +| 26 = @cil_ldc_i4_4 +| 27 = @cil_ldc_i4_5 +| 28 = @cil_ldc_i4_6 +| 29 = @cil_ldc_i4_7 +| 30 = @cil_ldc_i4_8 +| 31 = @cil_ldc_i4_s +| 32 = @cil_ldc_i4 +| 33 = @cil_ldc_i8 +| 34 = @cil_ldc_r4 +| 35 = @cil_ldc_r8 +| 37 = @cil_dup +| 38 = @cil_pop +| 39 = @cil_jmp +| 40 = @cil_call +| 41 = @cil_calli +| 42 = @cil_ret +| 43 = @cil_br_s +| 44 = @cil_brfalse_s +| 45 = @cil_brtrue_s +| 46 = @cil_beq_s +| 47 = @cil_bge_s +| 48 = @cil_bgt_s +| 49 = @cil_ble_s +| 50 = @cil_blt_s +| 51 = @cil_bne_un_s +| 52 = @cil_bge_un_s +| 53 = @cil_bgt_un_s +| 54 = @cil_ble_un_s +| 55 = @cil_blt_un_s +| 56 = @cil_br +| 57 = @cil_brfalse +| 58 = @cil_brtrue +| 59 = @cil_beq +| 60 = @cil_bge +| 61 = @cil_bgt +| 62 = @cil_ble +| 63 = @cil_blt +| 64 = @cil_bne_un +| 65 = @cil_bge_un +| 66 = @cil_bgt_un +| 67 = @cil_ble_un +| 68 = @cil_blt_un +| 69 = @cil_switch +| 70 = @cil_ldind_i1 +| 71 = @cil_ldind_u1 +| 72 = @cil_ldind_i2 +| 73 = @cil_ldind_u2 +| 74 = @cil_ldind_i4 +| 75 = @cil_ldind_u4 +| 76 = @cil_ldind_i8 +| 77 = @cil_ldind_i +| 78 = @cil_ldind_r4 +| 79 = @cil_ldind_r8 +| 80 = @cil_ldind_ref +| 81 = @cil_stind_ref +| 82 = @cil_stind_i1 +| 83 = @cil_stind_i2 +| 84 = @cil_stind_i4 +| 85 = @cil_stind_i8 +| 86 = @cil_stind_r4 +| 87 = @cil_stind_r8 +| 88 = @cil_add +| 89 = @cil_sub +| 90 = @cil_mul +| 91 = @cil_div +| 92 = @cil_div_un +| 93 = @cil_rem +| 94 = @cil_rem_un +| 95 = @cil_and +| 96 = @cil_or +| 97 = @cil_xor +| 98 = @cil_shl +| 99 = @cil_shr +| 100 = @cil_shr_un +| 101 = @cil_neg +| 102 = @cil_not +| 103 = @cil_conv_i1 +| 104 = @cil_conv_i2 +| 105 = @cil_conv_i4 +| 106 = @cil_conv_i8 +| 107 = @cil_conv_r4 +| 108 = @cil_conv_r8 +| 109 = @cil_conv_u4 +| 110 = @cil_conv_u8 +| 111 = @cil_callvirt +| 112 = @cil_cpobj +| 113 = @cil_ldobj +| 114 = @cil_ldstr +| 115 = @cil_newobj +| 116 = @cil_castclass +| 117 = @cil_isinst +| 118 = @cil_conv_r_un +| 121 = @cil_unbox +| 122 = @cil_throw +| 123 = @cil_ldfld +| 124 = @cil_ldflda +| 125 = @cil_stfld +| 126 = @cil_ldsfld +| 127 = @cil_ldsflda +| 128 = @cil_stsfld +| 129 = @cil_stobj +| 130 = @cil_conv_ovf_i1_un +| 131 = @cil_conv_ovf_i2_un +| 132 = @cil_conv_ovf_i4_un +| 133 = @cil_conv_ovf_i8_un +| 134 = @cil_conv_ovf_u1_un +| 135 = @cil_conv_ovf_u2_un +| 136 = @cil_conv_ovf_u4_un +| 137 = @cil_conv_ovf_u8_un +| 138 = @cil_conv_ovf_i_un +| 139 = @cil_conv_ovf_u_un +| 140 = @cil_box +| 141 = @cil_newarr +| 142 = @cil_ldlen +| 143 = @cil_ldelema +| 144 = @cil_ldelem_i1 +| 145 = @cil_ldelem_u1 +| 146 = @cil_ldelem_i2 +| 147 = @cil_ldelem_u2 +| 148 = @cil_ldelem_i4 +| 149 = @cil_ldelem_u4 +| 150 = @cil_ldelem_i8 +| 151 = @cil_ldelem_i +| 152 = @cil_ldelem_r4 +| 153 = @cil_ldelem_r8 +| 154 = @cil_ldelem_ref +| 155 = @cil_stelem_i +| 156 = @cil_stelem_i1 +| 157 = @cil_stelem_i2 +| 158 = @cil_stelem_i4 +| 159 = @cil_stelem_i8 +| 160 = @cil_stelem_r4 +| 161 = @cil_stelem_r8 +| 162 = @cil_stelem_ref +| 163 = @cil_ldelem +| 164 = @cil_stelem +| 165 = @cil_unbox_any +| 179 = @cil_conv_ovf_i1 +| 180 = @cil_conv_ovf_u1 +| 181 = @cil_conv_ovf_i2 +| 182 = @cil_conv_ovf_u2 +| 183 = @cil_conv_ovf_i4 +| 184 = @cil_conv_ovf_u4 +| 185 = @cil_conv_ovf_i8 +| 186 = @cil_conv_ovf_u8 +| 194 = @cil_refanyval +| 195 = @cil_ckinfinite +| 198 = @cil_mkrefany +| 208 = @cil_ldtoken +| 209 = @cil_conv_u2 +| 210 = @cil_conv_u1 +| 211 = @cil_conv_i +| 212 = @cil_conv_ovf_i +| 213 = @cil_conv_ovf_u +| 214 = @cil_add_ovf +| 215 = @cil_add_ovf_un +| 216 = @cil_mul_ovf +| 217 = @cil_mul_ovf_un +| 218 = @cil_sub_ovf +| 219 = @cil_sub_ovf_un +| 220 = @cil_endfinally +| 221 = @cil_leave +| 222 = @cil_leave_s +| 223 = @cil_stind_i +| 224 = @cil_conv_u +| 65024 = @cil_arglist +| 65025 = @cil_ceq +| 65026 = @cil_cgt +| 65027 = @cil_cgt_un +| 65028 = @cil_clt +| 65029 = @cil_clt_un +| 65030 = @cil_ldftn +| 65031 = @cil_ldvirtftn +| 65033 = @cil_ldarg +| 65034 = @cil_ldarga +| 65035 = @cil_starg +| 65036 = @cil_ldloc +| 65037 = @cil_ldloca +| 65038 = @cil_stloc +| 65039 = @cil_localloc +| 65041 = @cil_endfilter +| 65042 = @cil_unaligned +| 65043 = @cil_volatile +| 65044 = @cil_tail +| 65045 = @cil_initobj +| 65046 = @cil_constrained +| 65047 = @cil_cpblk +| 65048 = @cil_initblk +| 65050 = @cil_rethrow +| 65052 = @cil_sizeof +| 65053 = @cil_refanytype +| 65054 = @cil_readonly +; + +// CIL ignored instructions + +@cil_ignore = @cil_nop | @cil_break | @cil_volatile | @cil_unaligned; + +// CIL local/parameter/field access + +@cil_ldarg_any = @cil_ldarg_0 | @cil_ldarg_1 | @cil_ldarg_2 | @cil_ldarg_3 | @cil_ldarg_s | @cil_ldarga_s | @cil_ldarg | @cil_ldarga; +@cil_starg_any = @cil_starg | @cil_starg_s; + +@cil_ldloc_any = @cil_ldloc_0 | @cil_ldloc_1 | @cil_ldloc_2 | @cil_ldloc_3 | @cil_ldloc_s | @cil_ldloca_s | @cil_ldloc | @cil_ldloca; +@cil_stloc_any = @cil_stloc_0 | @cil_stloc_1 | @cil_stloc_2 | @cil_stloc_3 | @cil_stloc_s | @cil_stloc; + +@cil_ldfld_any = @cil_ldfld | @cil_ldsfld | @cil_ldsflda | @cil_ldflda; +@cil_stfld_any = @cil_stfld | @cil_stsfld; + +@cil_local_access = @cil_stloc_any | @cil_ldloc_any; +@cil_arg_access = @cil_starg_any | @cil_ldarg_any; +@cil_read_access = @cil_ldloc_any | @cil_ldarg_any | @cil_ldfld_any; +@cil_write_access = @cil_stloc_any | @cil_starg_any | @cil_stfld_any; + +@cil_stack_access = @cil_local_access | @cil_arg_access; +@cil_field_access = @cil_ldfld_any | @cil_stfld_any; + +@cil_access = @cil_read_access | @cil_write_access; + +// CIL constant/literal instructions + +@cil_ldc_i = @cil_ldc_i4_any | @cil_ldc_i8; + +@cil_ldc_i4_any = @cil_ldc_i4_m1 | @cil_ldc_i4_0 | @cil_ldc_i4_1 | @cil_ldc_i4_2 | @cil_ldc_i4_3 | + @cil_ldc_i4_4 | @cil_ldc_i4_5 | @cil_ldc_i4_6 | @cil_ldc_i4_7 | @cil_ldc_i4_8 | @cil_ldc_i4_s | @cil_ldc_i4; + +@cil_ldc_r = @cil_ldc_r4 | @cil_ldc_r8; + +@cil_literal = @cil_ldnull | @cil_ldc_i | @cil_ldc_r | @cil_ldstr; + +// Control flow + +@cil_conditional_jump = @cil_binary_jump | @cil_unary_jump; +@cil_binary_jump = @cil_beq_s | @cil_bge_s | @cil_bgt_s | @cil_ble_s | @cil_blt_s | + @cil_bne_un_s | @cil_bge_un_s | @cil_bgt_un_s | @cil_ble_un_s | @cil_blt_un_s | + @cil_beq | @cil_bge | @cil_bgt | @cil_ble | @cil_blt | + @cil_bne_un | @cil_bge_un | @cil_bgt_un | @cil_ble_un | @cil_blt_un; +@cil_unary_jump = @cil_brfalse_s | @cil_brtrue_s | @cil_brfalse | @cil_brtrue | @cil_switch; +@cil_unconditional_jump = @cil_br | @cil_br_s | @cil_leave_any; +@cil_leave_any = @cil_leave | @cil_leave_s; +@cil_jump = @cil_unconditional_jump | @cil_conditional_jump; + +// CIL call instructions + +@cil_call_any = @cil_jmp | @cil_call | @cil_calli | @cil_tail | @cil_callvirt | @cil_newobj; + +// CIL expression instructions + +@cil_expr = @cil_literal | @cil_binary_expr | @cil_unary_expr | @cil_call_any | @cil_read_access | + @cil_newarr | @cil_ldtoken | @cil_sizeof | + @cil_ldftn | @cil_ldvirtftn | @cil_localloc | @cil_mkrefany | @cil_refanytype | @cil_arglist | @cil_dup; + +@cil_unary_expr = + @cil_conversion_operation | @cil_unary_arithmetic_operation | @cil_unary_bitwise_operation| + @cil_ldlen | @cil_isinst | @cil_box | @cil_ldobj | @cil_castclass | @cil_unbox_any | + @cil_ldind | @cil_unbox; + +@cil_conversion_operation = + @cil_conv_i1 | @cil_conv_i2 | @cil_conv_i4 | @cil_conv_i8 | + @cil_conv_u1 | @cil_conv_u2 | @cil_conv_u4 | @cil_conv_u8 | + @cil_conv_ovf_i | @cil_conv_ovf_i_un | @cil_conv_ovf_i1 | @cil_conv_ovf_i1_un | + @cil_conv_ovf_i2 | @cil_conv_ovf_i2_un | @cil_conv_ovf_i4 | @cil_conv_ovf_i4_un | + @cil_conv_ovf_i8 | @cil_conv_ovf_i8_un | @cil_conv_ovf_u | @cil_conv_ovf_u_un | + @cil_conv_ovf_u1 | @cil_conv_ovf_u1_un | @cil_conv_ovf_u2 | @cil_conv_ovf_u2_un | + @cil_conv_ovf_u4 | @cil_conv_ovf_u4_un | @cil_conv_ovf_u8 | @cil_conv_ovf_u8_un | + @cil_conv_r4 | @cil_conv_r8 | @cil_conv_ovf_u2 | @cil_conv_ovf_u2_un | + @cil_conv_i | @cil_conv_u | @cil_conv_r_un; + +@cil_ldind = @cil_ldind_i | @cil_ldind_i1 | @cil_ldind_i2 | @cil_ldind_i4 | @cil_ldind_i8 | + @cil_ldind_r4 | @cil_ldind_r8 | @cil_ldind_ref | @cil_ldind_u1 | @cil_ldind_u2 | @cil_ldind_u4; + +@cil_stind = @cil_stind_i | @cil_stind_i1 | @cil_stind_i2 | @cil_stind_i4 | @cil_stind_i8 | + @cil_stind_r4 | @cil_stind_r8 | @cil_stind_ref; + +@cil_bitwise_operation = @cil_binary_bitwise_operation | @cil_unary_bitwise_operation; + +@cil_binary_bitwise_operation = @cil_and | @cil_or | @cil_xor | @cil_shr | @cil_shr | @cil_shr_un | @cil_shl; + +@cil_binary_arithmetic_operation = @cil_add | @cil_sub | @cil_mul | @cil_div | @cil_div_un | + @cil_rem | @cil_rem_un | @cil_add_ovf | @cil_add_ovf_un | @cil_mul_ovf | @cil_mul_ovf_un | + @cil_sub_ovf | @cil_sub_ovf_un; + +@cil_unary_bitwise_operation = @cil_not; + +@cil_binary_expr = @cil_binary_arithmetic_operation | @cil_binary_bitwise_operation | @cil_read_array | @cil_comparison_operation; + +@cil_unary_arithmetic_operation = @cil_neg; + +@cil_comparison_operation = @cil_cgt_un | @cil_ceq | @cil_cgt | @cil_clt | @cil_clt_un; + +// Elements that retrieve an address of something +@cil_read_ref = @cil_ldloca_s | @cil_ldarga_s | @cil_ldflda | @cil_ldsflda | @cil_ldelema; + +// CIL array instructions + +@cil_read_array = + @cil_ldelem | @cil_ldelema | @cil_ldelem_i1 | @cil_ldelem_ref | @cil_ldelem_i | + @cil_ldelem_i1 | @cil_ldelem_i2 | @cil_ldelem_i4 | @cil_ldelem_i8 | @cil_ldelem_r4 | + @cil_ldelem_r8 | @cil_ldelem_u1 | @cil_ldelem_u2 | @cil_ldelem_u4; + +@cil_write_array = @cil_stelem | @cil_stelem_ref | + @cil_stelem_i | @cil_stelem_i1 | @cil_stelem_i2 | @cil_stelem_i4 | @cil_stelem_i8 | + @cil_stelem_r4 | @cil_stelem_r8; + +@cil_throw_any = @cil_throw | @cil_rethrow; + +#keyset[impl, index] +cil_instruction( + unique int id: @cil_instruction, + int opcode: int ref, + int index: int ref, + int impl: @cil_method_implementation ref); + +cil_jump( + unique int instruction: @cil_jump ref, + int target: @cil_instruction ref); + +cil_access( + unique int instruction: @cil_instruction ref, + int target: @cil_accessible ref); + +cil_value( + unique int instruction: @cil_literal ref, + string value: string ref); + +#keyset[instruction, index] +cil_switch( + int instruction: @cil_switch ref, + int index: int ref, + int target: @cil_instruction ref); + +cil_instruction_location( + unique int id: @cil_instruction ref, + int loc: @location ref); + +cil_type_location( + int id: @cil_type ref, + int loc: @location ref); + +cil_method_location( + int id: @cil_method ref, + int loc: @location ref); + +@cil_namespace = @namespace; + +@cil_type_container = @cil_type | @cil_namespace | @cil_method; + +case @cil_type.kind of + 0 = @cil_valueorreftype +| 1 = @cil_typeparameter +| 2 = @cil_array_type +| 3 = @cil_pointer_type +; + +cil_type( + unique int id: @cil_type, + string name: string ref, + int kind: int ref, + int parent: @cil_type_container ref, + int sourceDecl: @cil_type ref); + +cil_pointer_type( + unique int id: @cil_pointer_type ref, + int pointee: @cil_type ref); + +cil_array_type( + unique int id: @cil_array_type ref, + int element_type: @cil_type ref, + int rank: int ref); + +cil_method( + unique int id: @cil_method, + string name: string ref, + int parent: @cil_type ref, + int return_type: @cil_type ref); + +cil_method_source_declaration( + unique int method: @cil_method ref, + int source: @cil_method ref); + +cil_method_implementation( + unique int id: @cil_method_implementation, + int method: @cil_method ref, + int location: @assembly ref); + +cil_implements( + int id: @cil_method ref, + int decl: @cil_method ref); + +#keyset[parent, name] +cil_field( + unique int id: @cil_field, + int parent: @cil_type ref, + string name: string ref, + int field_type: @cil_type ref); + +@cil_element = @cil_instruction | @cil_declaration | @cil_handler | @cil_attribute | @cil_namespace; +@cil_named_element = @cil_declaration | @cil_namespace; +@cil_declaration = @cil_variable | @cil_method | @cil_type | @cil_member; +@cil_accessible = @cil_declaration; +@cil_variable = @cil_field | @cil_stack_variable; +@cil_stack_variable = @cil_local_variable | @cil_parameter; +@cil_member = @cil_method | @cil_type | @cil_field | @cil_property | @cil_event; +@cil_custom_modifier_receiver = @cil_method | @cil_property | @cil_parameter | @cil_field; // todo: add function pointer type + +#keyset[method, index] +cil_parameter( + unique int id: @cil_parameter, + int method: @cil_method ref, + int index: int ref, + int param_type: @cil_type ref); + +cil_parameter_in(unique int id: @cil_parameter ref); +cil_parameter_out(unique int id: @cil_parameter ref); + +cil_setter(unique int prop: @cil_property ref, + int method: @cil_method ref); + +#keyset[id, modifier] +cil_custom_modifiers( + int id: @cil_custom_modifier_receiver ref, + int modifier: @cil_type ref, + int kind: int ref); // modreq: 1, modopt: 0 + +cil_getter(unique int prop: @cil_property ref, + int method: @cil_method ref); + +cil_adder(unique int event: @cil_event ref, + int method: @cil_method ref); + +cil_remover(unique int event: @cil_event ref, int method: @cil_method ref); + +cil_raiser(unique int event: @cil_event ref, int method: @cil_method ref); + +cil_property( + unique int id: @cil_property, + int parent: @cil_type ref, + string name: string ref, + int property_type: @cil_type ref); + +#keyset[parent, name] +cil_event(unique int id: @cil_event, + int parent: @cil_type ref, + string name: string ref, + int event_type: @cil_type ref); + +#keyset[impl, index] +cil_local_variable( + unique int id: @cil_local_variable, + int impl: @cil_method_implementation ref, + int index: int ref, + int var_type: @cil_type ref); + +// CIL handlers (exception handlers etc). + +case @cil_handler.kind of + 0 = @cil_catch_handler +| 1 = @cil_filter_handler +| 2 = @cil_finally_handler +| 4 = @cil_fault_handler +; + +#keyset[impl, index] +cil_handler( + unique int id: @cil_handler, + int impl: @cil_method_implementation ref, + int index: int ref, + int kind: int ref, + int try_start: @cil_instruction ref, + int try_end: @cil_instruction ref, + int handler_start: @cil_instruction ref); + +cil_handler_filter( + unique int id: @cil_handler ref, + int filter_start: @cil_instruction ref); + +cil_handler_type( + unique int id: @cil_handler ref, + int catch_type: @cil_type ref); + +@cil_controlflow_node = @cil_entry_point | @cil_instruction; + +@cil_entry_point = @cil_method_implementation | @cil_handler; + +@cil_dataflow_node = @cil_instruction | @cil_variable | @cil_method; + +cil_method_stack_size( + unique int method: @cil_method_implementation ref, + int size: int ref); + +// CIL modifiers + +cil_public(int id: @cil_member ref); +cil_private(int id: @cil_member ref); +cil_protected(int id: @cil_member ref); +cil_internal(int id: @cil_member ref); +cil_static(int id: @cil_member ref); +cil_sealed(int id: @cil_member ref); +cil_virtual(int id: @cil_method ref); +cil_abstract(int id: @cil_member ref); +cil_class(int id: @cil_type ref); +cil_interface(int id: @cil_type ref); +cil_security(int id: @cil_member ref); +cil_requiresecobject(int id: @cil_method ref); +cil_specialname(int id: @cil_method ref); +cil_newslot(int id: @cil_method ref); + +cil_base_class(unique int id: @cil_type ref, int base: @cil_type ref); +cil_base_interface(int id: @cil_type ref, int base: @cil_type ref); +cil_enum_underlying_type(unique int id: @cil_type ref, int underlying: @cil_type ref); + +#keyset[unbound, index] +cil_type_parameter( + int unbound: @cil_member ref, + int index: int ref, + int param: @cil_typeparameter ref); + +#keyset[bound, index] +cil_type_argument( + int bound: @cil_member ref, + int index: int ref, + int t: @cil_type ref); + +// CIL type parameter constraints + +cil_typeparam_covariant(int tp: @cil_typeparameter ref); +cil_typeparam_contravariant(int tp: @cil_typeparameter ref); +cil_typeparam_class(int tp: @cil_typeparameter ref); +cil_typeparam_struct(int tp: @cil_typeparameter ref); +cil_typeparam_new(int tp: @cil_typeparameter ref); +cil_typeparam_constraint(int tp: @cil_typeparameter ref, int supertype: @cil_type ref); + +// CIL attributes + +cil_attribute( + unique int attributeid: @cil_attribute, + int element: @cil_declaration ref, + int constructor: @cil_method ref); + +#keyset[attribute_id, param] +cil_attribute_named_argument( + int attribute_id: @cil_attribute ref, + string param: string ref, + string value: string ref); + +#keyset[attribute_id, index] +cil_attribute_positional_argument( + int attribute_id: @cil_attribute ref, + int index: int ref, + string value: string ref); + + +// Common .Net data model covering both C# and CIL + +// Common elements +@dotnet_element = @element | @cil_element; +@dotnet_named_element = @named_element | @cil_named_element; +@dotnet_callable = @callable | @cil_method; +@dotnet_variable = @variable | @cil_variable; +@dotnet_field = @field | @cil_field; +@dotnet_parameter = @parameter | @cil_parameter; +@dotnet_declaration = @declaration | @cil_declaration; +@dotnet_member = @member | @cil_member; +@dotnet_event = @event | @cil_event; +@dotnet_property = @property | @cil_property | @indexer; + +// Common types +@dotnet_type = @type | @cil_type; +@dotnet_call = @call | @cil_call_any; +@dotnet_throw = @throw_element | @cil_throw_any; +@dotnet_valueorreftype = @cil_valueorreftype | @value_or_ref_type | @cil_array_type | @void_type; +@dotnet_typeparameter = @type_parameter | @cil_typeparameter; +@dotnet_array_type = @array_type | @cil_array_type; +@dotnet_pointer_type = @pointer_type | @cil_pointer_type; +@dotnet_type_parameter = @type_parameter | @cil_typeparameter; +@dotnet_generic = @dotnet_valueorreftype | @dotnet_callable; + +// Attributes +@dotnet_attribute = @attribute | @cil_attribute; + +// Expressions +@dotnet_expr = @expr | @cil_expr; + +// Literals +@dotnet_literal = @literal_expr | @cil_literal; +@dotnet_string_literal = @string_literal_expr | @cil_ldstr; +@dotnet_int_literal = @integer_literal_expr | @cil_ldc_i; +@dotnet_float_literal = @float_literal_expr | @cil_ldc_r; +@dotnet_null_literal = @null_literal_expr | @cil_ldnull; + +@metadata_entity = @cil_method | @cil_type | @cil_field | @cil_property | @field | @property | + @callable | @value_or_ref_type | @void_type; + +#keyset[entity, location] +metadata_handle(int entity : @metadata_entity ref, int location: @assembly ref, int handle: int ref) diff --git a/csharp/upgrades/26249c105a81c61ef8738a198928de2d4b763c37/upgrade.properties b/csharp/upgrades/26249c105a81c61ef8738a198928de2d4b763c37/upgrade.properties new file mode 100644 index 00000000000..3ee4f62265f --- /dev/null +++ b/csharp/upgrades/26249c105a81c61ef8738a198928de2d4b763c37/upgrade.properties @@ -0,0 +1,2 @@ +description: Added 'compilation_assembly' to store the output assemblies of compilations. +compatibility: backwards diff --git a/csharp/upgrades/2fb07f0b8c65f6c89437c28caf5d99fdbcdbef2d/old.dbscheme b/csharp/upgrades/2fb07f0b8c65f6c89437c28caf5d99fdbcdbef2d/old.dbscheme new file mode 100644 index 00000000000..2fb07f0b8c6 --- /dev/null +++ b/csharp/upgrades/2fb07f0b8c65f6c89437c28caf5d99fdbcdbef2d/old.dbscheme @@ -0,0 +1,1956 @@ + +/** + * An invocation of the compiler. Note that more than one file may be + * compiled per invocation. For example, this command compiles three + * source files: + * + * csc f1.cs f2.cs f3.cs + * + * The `id` simply identifies the invocation, while `cwd` is the working + * directory from which the compiler was invoked. + */ +compilations( + unique int id : @compilation, + string cwd : string ref +); + +/** + * The arguments that were passed to the extractor for a compiler + * invocation. If `id` is for the compiler invocation + * + * csc f1.cs f2.cs f3.cs + * + * then typically there will be rows for + * + * num | arg + * --- | --- + * 0 | --compiler + * 1 | *path to compiler* + * 2 | --cil + * 3 | f1.cs + * 4 | f2.cs + * 5 | f3.cs + */ +#keyset[id, num] +compilation_args( + int id : @compilation ref, + int num : int ref, + string arg : string ref +); + +/** + * The source files that are compiled by a compiler invocation. + * If `id` is for the compiler invocation + * + * csc f1.cs f2.cs f3.cs + * + * then there will be rows for + * + * num | arg + * --- | --- + * 0 | f1.cs + * 1 | f2.cs + * 2 | f3.cs + */ +#keyset[id, num] +compilation_compiling_files( + int id : @compilation ref, + int num : int ref, + int file : @file ref +); + +/** + * The references used by a compiler invocation. + * If `id` is for the compiler invocation + * + * csc f1.cs f2.cs f3.cs /r:ref1.dll /r:ref2.dll /r:ref3.dll + * + * then there will be rows for + * + * num | arg + * --- | --- + * 0 | ref1.dll + * 1 | ref2.dll + * 2 | ref3.dll + */ +#keyset[id, num] +compilation_referencing_files( + int id : @compilation ref, + int num : int ref, + int file : @file ref +); + +/** + * The time taken by the extractor for a compiler invocation. + * + * For each file `num`, there will be rows for + * + * kind | seconds + * ---- | --- + * 1 | CPU seconds used by the extractor frontend + * 2 | Elapsed seconds during the extractor frontend + * 3 | CPU seconds used by the extractor backend + * 4 | Elapsed seconds during the extractor backend + */ +#keyset[id, num, kind] +compilation_time( + int id : @compilation ref, + int num : int ref, + /* kind: + 1 = frontend_cpu_seconds + 2 = frontend_elapsed_seconds + 3 = extractor_cpu_seconds + 4 = extractor_elapsed_seconds + */ + int kind : int ref, + float seconds : float ref +); + +/** + * An error or warning generated by the extractor. + * The diagnostic message `diagnostic` was generated during compiler + * invocation `compilation`, and is the `file_number_diagnostic_number`th + * message generated while extracting the `file_number`th file of that + * invocation. + */ +#keyset[compilation, file_number, file_number_diagnostic_number] +diagnostic_for( + unique int diagnostic : @diagnostic ref, + int compilation : @compilation ref, + int file_number : int ref, + int file_number_diagnostic_number : int ref +); + +diagnostics( + unique int id: @diagnostic, + int severity: int ref, + string error_tag: string ref, + string error_message: string ref, + string full_error_message: string ref, + int location: @location_default ref +); + +extractor_messages( + unique int id: @extractor_message, + int severity: int ref, + string origin : string ref, + string text : string ref, + string entity : string ref, + int location: @location_default ref, + string stack_trace : string ref +); + +/** + * If extraction was successful, then `cpu_seconds` and + * `elapsed_seconds` are the CPU time and elapsed time (respectively) + * that extraction took for compiler invocation `id`. + */ +compilation_finished( + unique int id : @compilation ref, + float cpu_seconds : float ref, + float elapsed_seconds : float ref +); + +compilation_assembly( + unique int id : @compilation ref, + int assembly: @assembly ref +) + +/* + * External artifacts + */ + +externalDefects( + unique int id: @externalDefect, + string queryPath: string ref, + int location: @location ref, + string message: string ref, + float severity: float ref); + +externalMetrics( + unique int id: @externalMetric, + string queryPath: string ref, + int location: @location ref, + float value: float ref); + +externalData( + int id: @externalDataElement, + string path: string ref, + int column: int ref, + string value: string ref); + +snapshotDate( + unique date snapshotDate: date ref); + +sourceLocationPrefix( + string prefix: string ref); + +/* + * Duplicate code + */ + +duplicateCode( + unique int id: @duplication, + string relativePath: string ref, + int equivClass: int ref); + +similarCode( + unique int id: @similarity, + string relativePath: string ref, + int equivClass: int ref); + +@duplication_or_similarity = @duplication | @similarity + +tokens( + int id: @duplication_or_similarity ref, + int offset: int ref, + int beginLine: int ref, + int beginColumn: int ref, + int endLine: int ref, + int endColumn: int ref); + +/* + * C# dbscheme + */ + +/** ELEMENTS **/ + +@element = @declaration | @stmt | @expr | @modifier | @attribute | @namespace_declaration + | @using_directive | @type_parameter_constraints | @external_element + | @xmllocatable | @asp_element | @namespace; + +@declaration = @callable | @generic | @assignable | @namespace; + +@named_element = @namespace | @declaration; + +@declaration_with_accessors = @property | @indexer | @event; + +@assignable = @variable | @assignable_with_accessors | @event; + +@assignable_with_accessors = @property | @indexer; + +@external_element = @externalMetric | @externalDefect | @externalDataElement; + +@attributable = @assembly | @field | @parameter | @operator | @method | @constructor + | @destructor | @callable_accessor | @value_or_ref_type | @declaration_with_accessors + | @local_function; + +/** LOCATIONS, ASEMMBLIES, MODULES, FILES and FOLDERS **/ + +@location = @location_default | @assembly; + +locations_default( + unique int id: @location_default, + int file: @file ref, + int beginLine: int ref, + int beginColumn: int ref, + int endLine: int ref, + int endColumn: int ref); + +@sourceline = @file | @callable | @xmllocatable; + +numlines( + int element_id: @sourceline ref, + int num_lines: int ref, + int num_code: int ref, + int num_comment: int ref); + +assemblies( + unique int id: @assembly, + int file: @file ref, + string fullname: string ref, + string name: string ref, + string version: string ref); + +/* + fromSource(0) = unknown, + fromSource(1) = from source, + fromSource(2) = from library +*/ +files( + unique int id: @file, + string name: string ref, + string simple: string ref, + string ext: string ref, + int fromSource: int ref); + +folders( + unique int id: @folder, + string name: string ref, + string simple: string ref); + +@container = @folder | @file ; + +containerparent( + int parent: @container ref, + unique int child: @container ref); + +file_extraction_mode( + unique int file: @file ref, + int mode: int ref + /* 0 = normal, 1 = standalone extractor */ + ); + +/** NAMESPACES **/ + +@type_container = @namespace | @type; + +namespaces( + unique int id: @namespace, + string name: string ref); + +namespace_declarations( + unique int id: @namespace_declaration, + int namespace_id: @namespace ref); + +namespace_declaration_location( + unique int id: @namespace_declaration ref, + int loc: @location ref); + +parent_namespace( + unique int child_id: @type_container ref, + int namespace_id: @namespace ref); + +@declaration_or_directive = @namespace_declaration | @type | @using_directive; + +parent_namespace_declaration( + int child_id: @declaration_or_directive ref, // cannot be unique because of partial classes + int namespace_id: @namespace_declaration ref); + +@using_directive = @using_namespace_directive | @using_static_directive; + +using_namespace_directives( + unique int id: @using_namespace_directive, + int namespace_id: @namespace ref); + +using_static_directives( + unique int id: @using_static_directive, + int type_id: @type_or_ref ref); + +using_directive_location( + unique int id: @using_directive ref, + int loc: @location ref); + +/** TYPES **/ + +types( + unique int id: @type, + int kind: int ref, + string name: string ref); + +case @type.kind of + 1 = @bool_type +| 2 = @char_type +| 3 = @decimal_type +| 4 = @sbyte_type +| 5 = @short_type +| 6 = @int_type +| 7 = @long_type +| 8 = @byte_type +| 9 = @ushort_type +| 10 = @uint_type +| 11 = @ulong_type +| 12 = @float_type +| 13 = @double_type +| 14 = @enum_type +| 15 = @struct_type +| 17 = @class_type +| 19 = @interface_type +| 20 = @delegate_type +| 21 = @null_type +| 22 = @type_parameter +| 23 = @pointer_type +| 24 = @nullable_type +| 25 = @array_type +| 26 = @void_type +| 27 = @int_ptr_type +| 28 = @uint_ptr_type +| 29 = @dynamic_type +| 30 = @arglist_type +| 31 = @unknown_type +| 32 = @tuple_type +| 33 = @function_pointer_type + ; + +@simple_type = @bool_type | @char_type | @integral_type | @floating_point_type | @decimal_type; +@integral_type = @signed_integral_type | @unsigned_integral_type; +@signed_integral_type = @sbyte_type | @short_type | @int_type | @long_type; +@unsigned_integral_type = @byte_type | @ushort_type | @uint_type | @ulong_type; +@floating_point_type = @float_type | @double_type; +@value_type = @simple_type | @enum_type | @struct_type | @nullable_type | @int_ptr_type + | @uint_ptr_type | @tuple_type; +@ref_type = @class_type | @interface_type | @array_type | @delegate_type | @null_type + | @dynamic_type; +@value_or_ref_type = @value_type | @ref_type; + +typerefs( + unique int id: @typeref, + string name: string ref); + +typeref_type( + int id: @typeref ref, + unique int typeId: @type ref); + +@type_or_ref = @type | @typeref; + +array_element_type( + unique int array: @array_type ref, + int dimension: int ref, + int rank: int ref, + int element: @type_or_ref ref); + +nullable_underlying_type( + unique int nullable: @nullable_type ref, + int underlying: @type_or_ref ref); + +pointer_referent_type( + unique int pointer: @pointer_type ref, + int referent: @type_or_ref ref); + +enum_underlying_type( + unique int enum_id: @enum_type ref, + int underlying_type_id: @type_or_ref ref); + +delegate_return_type( + unique int delegate_id: @delegate_type ref, + int return_type_id: @type_or_ref ref); + +function_pointer_return_type( + unique int function_pointer_id: @function_pointer_type ref, + int return_type_id: @type_or_ref ref); + +extend( + unique int sub: @type ref, + int super: @type_or_ref ref); + +anonymous_types( + unique int id: @type ref); + +@interface_or_ref = @interface_type | @typeref; + +implement( + int sub: @type ref, + int super: @type_or_ref ref); + +type_location( + int id: @type ref, + int loc: @location ref); + +tuple_underlying_type( + unique int tuple: @tuple_type ref, + int struct: @type_or_ref ref); + +#keyset[tuple, index] +tuple_element( + int tuple: @tuple_type ref, + int index: int ref, + unique int field: @field ref); + +attributes( + unique int id: @attribute, + int type_id: @type_or_ref ref, + int target: @attributable ref); + +attribute_location( + int id: @attribute ref, + int loc: @location ref); + +@type_mention_parent = @element | @type_mention; + +type_mention( + unique int id: @type_mention, + int type_id: @type_or_ref ref, + int parent: @type_mention_parent ref); + +type_mention_location( + unique int id: @type_mention ref, + int loc: @location ref); + +@has_type_annotation = @assignable | @type_parameter | @callable | @expr | @delegate_type | @generic | @function_pointer_type; + +/** + * A direct annotation on an entity, for example `string? x;`. + * + * Annotations: + * 2 = reftype is not annotated "!" + * 3 = reftype is annotated "?" + * 4 = readonly ref type / in parameter + * 5 = ref type parameter, return or local variable + * 6 = out parameter + * + * Note that the annotation depends on the element it annotates. + * @assignable: The annotation is on the type of the assignable, for example the variable type. + * @type_parameter: The annotation is on the reftype constraint + * @callable: The annotation is on the return type + * @array_type: The annotation is on the element type + */ +type_annotation(int id: @has_type_annotation ref, int annotation: int ref); + +nullability(unique int nullability: @nullability, int kind: int ref); + +case @nullability.kind of + 0 = @oblivious +| 1 = @not_annotated +| 2 = @annotated +; + +#keyset[parent, index] +nullability_parent(int nullability: @nullability ref, int index: int ref, int parent: @nullability ref) + +type_nullability(int id: @has_type_annotation ref, int nullability: @nullability ref); + +/** + * The nullable flow state of an expression, as determined by Roslyn. + * 0 = none (default, not populated) + * 1 = not null + * 2 = maybe null + */ +expr_flowstate(unique int id: @expr ref, int state: int ref); + +/** GENERICS **/ + +@generic = @type | @method | @local_function; + +type_parameters( + unique int id: @type_parameter ref, + int index: int ref, + int generic_id: @generic ref, + int variance: int ref /* none = 0, out = 1, in = 2 */); + +#keyset[constructed_id, index] +type_arguments( + int id: @type_or_ref ref, + int index: int ref, + int constructed_id: @generic_or_ref ref); + +@generic_or_ref = @generic | @typeref; + +constructed_generic( + unique int constructed: @generic ref, + int generic: @generic_or_ref ref); + +type_parameter_constraints( + unique int id: @type_parameter_constraints, + int param_id: @type_parameter ref); + +type_parameter_constraints_location( + int id: @type_parameter_constraints ref, + int loc: @location ref); + +general_type_parameter_constraints( + int id: @type_parameter_constraints ref, + int kind: int ref /* class = 1, struct = 2, new = 3 */); + +specific_type_parameter_constraints( + int id: @type_parameter_constraints ref, + int base_id: @type_or_ref ref); + +specific_type_parameter_nullability( + int id: @type_parameter_constraints ref, + int base_id: @type_or_ref ref, + int nullability: @nullability ref); + +/** FUNCTION POINTERS */ + +function_pointer_calling_conventions( + int id: @function_pointer_type ref, + int kind: int ref); + +#keyset[id, index] +has_unmanaged_calling_conventions( + int id: @function_pointer_type ref, + int index: int ref, + int conv_id: @type_or_ref ref); + +/** MODIFIERS */ + +@modifiable = @modifiable_direct | @event_accessor; + +@modifiable_direct = @member | @accessor | @local_function | @anonymous_function_expr; + +modifiers( + unique int id: @modifier, + string name: string ref); + +has_modifiers( + int id: @modifiable_direct ref, + int mod_id: @modifier ref); + +compiler_generated(unique int id: @modifiable_direct ref); + +/** MEMBERS **/ + +@member = @method | @constructor | @destructor | @field | @property | @event | @operator | @indexer | @type; + +@named_exprorstmt = @goto_stmt | @labeled_stmt | @expr; + +@virtualizable = @method | @property | @indexer | @event; + +exprorstmt_name( + unique int parent_id: @named_exprorstmt ref, + string name: string ref); + +nested_types( + unique int id: @type ref, + int declaring_type_id: @type ref, + int unbound_id: @type ref); + +properties( + unique int id: @property, + string name: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @property ref); + +property_location( + int id: @property ref, + int loc: @location ref); + +indexers( + unique int id: @indexer, + string name: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @indexer ref); + +indexer_location( + int id: @indexer ref, + int loc: @location ref); + +accessors( + unique int id: @accessor, + int kind: int ref, + string name: string ref, + int declaring_member_id: @member ref, + int unbound_id: @accessor ref); + +case @accessor.kind of + 1 = @getter +| 2 = @setter + ; + +init_only_accessors( + unique int id: @accessor ref); + +accessor_location( + int id: @accessor ref, + int loc: @location ref); + +events( + unique int id: @event, + string name: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @event ref); + +event_location( + int id: @event ref, + int loc: @location ref); + +event_accessors( + unique int id: @event_accessor, + int kind: int ref, + string name: string ref, + int declaring_event_id: @event ref, + int unbound_id: @event_accessor ref); + +case @event_accessor.kind of + 1 = @add_event_accessor +| 2 = @remove_event_accessor + ; + +event_accessor_location( + int id: @event_accessor ref, + int loc: @location ref); + +operators( + unique int id: @operator, + string name: string ref, + string symbol: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @operator ref); + +operator_location( + int id: @operator ref, + int loc: @location ref); + +constant_value( + int id: @variable ref, + string value: string ref); + +/** CALLABLES **/ + +@callable = @method | @constructor | @destructor | @operator | @callable_accessor | @anonymous_function_expr | @local_function; + +@callable_accessor = @accessor | @event_accessor; + +methods( + unique int id: @method, + string name: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @method ref); + +method_location( + int id: @method ref, + int loc: @location ref); + +constructors( + unique int id: @constructor, + string name: string ref, + int declaring_type_id: @type ref, + int unbound_id: @constructor ref); + +constructor_location( + int id: @constructor ref, + int loc: @location ref); + +destructors( + unique int id: @destructor, + string name: string ref, + int declaring_type_id: @type ref, + int unbound_id: @destructor ref); + +destructor_location( + int id: @destructor ref, + int loc: @location ref); + +overrides( + int id: @callable ref, + int base_id: @callable ref); + +explicitly_implements( + int id: @member ref, + int interface_id: @interface_or_ref ref); + +local_functions( + unique int id: @local_function, + string name: string ref, + int return_type: @type ref, + int unbound_id: @local_function ref); + +local_function_stmts( + unique int fn: @local_function_stmt ref, + int stmt: @local_function ref); + +/** VARIABLES **/ + +@variable = @local_scope_variable | @field; + +@local_scope_variable = @local_variable | @parameter; + +fields( + unique int id: @field, + int kind: int ref, + string name: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @field ref); + +case @field.kind of + 1 = @addressable_field +| 2 = @constant + ; + +field_location( + int id: @field ref, + int loc: @location ref); + +localvars( + unique int id: @local_variable, + int kind: int ref, + string name: string ref, + int implicitly_typed: int ref /* 0 = no, 1 = yes */, + int type_id: @type_or_ref ref, + int parent_id: @local_var_decl_expr ref); + +case @local_variable.kind of + 1 = @addressable_local_variable +| 2 = @local_constant +| 3 = @local_variable_ref + ; + +localvar_location( + unique int id: @local_variable ref, + int loc: @location ref); + +@parameterizable = @callable | @delegate_type | @indexer | @function_pointer_type; + +#keyset[name, parent_id] +#keyset[index, parent_id] +params( + unique int id: @parameter, + string name: string ref, + int type_id: @type_or_ref ref, + int index: int ref, + int mode: int ref, /* value = 0, ref = 1, out = 2, array = 3, this = 4 */ + int parent_id: @parameterizable ref, + int unbound_id: @parameter ref); + +param_location( + int id: @parameter ref, + int loc: @location ref); + +/** STATEMENTS **/ + +@exprorstmt_parent = @control_flow_element | @top_level_exprorstmt_parent; + +statements( + unique int id: @stmt, + int kind: int ref); + +#keyset[index, parent] +stmt_parent( + unique int stmt: @stmt ref, + int index: int ref, + int parent: @control_flow_element ref); + +@top_level_stmt_parent = @callable; + +// [index, parent] is not a keyset because the same parent may be compiled multiple times +stmt_parent_top_level( + unique int stmt: @stmt ref, + int index: int ref, + int parent: @top_level_stmt_parent ref); + +case @stmt.kind of + 1 = @block_stmt +| 2 = @expr_stmt +| 3 = @if_stmt +| 4 = @switch_stmt +| 5 = @while_stmt +| 6 = @do_stmt +| 7 = @for_stmt +| 8 = @foreach_stmt +| 9 = @break_stmt +| 10 = @continue_stmt +| 11 = @goto_stmt +| 12 = @goto_case_stmt +| 13 = @goto_default_stmt +| 14 = @throw_stmt +| 15 = @return_stmt +| 16 = @yield_stmt +| 17 = @try_stmt +| 18 = @checked_stmt +| 19 = @unchecked_stmt +| 20 = @lock_stmt +| 21 = @using_block_stmt +| 22 = @var_decl_stmt +| 23 = @const_decl_stmt +| 24 = @empty_stmt +| 25 = @unsafe_stmt +| 26 = @fixed_stmt +| 27 = @label_stmt +| 28 = @catch +| 29 = @case_stmt +| 30 = @local_function_stmt +| 31 = @using_decl_stmt + ; + +@using_stmt = @using_block_stmt | @using_decl_stmt; + +@labeled_stmt = @label_stmt | @case; + +@decl_stmt = @var_decl_stmt | @const_decl_stmt | @using_decl_stmt; + +@cond_stmt = @if_stmt | @switch_stmt; + +@loop_stmt = @while_stmt | @do_stmt | @for_stmt | @foreach_stmt; + +@jump_stmt = @break_stmt | @goto_any_stmt | @continue_stmt | @throw_stmt | @return_stmt + | @yield_stmt; + +@goto_any_stmt = @goto_default_stmt | @goto_case_stmt | @goto_stmt; + + +stmt_location( + unique int id: @stmt ref, + int loc: @location ref); + +catch_type( + unique int catch_id: @catch ref, + int type_id: @type_or_ref ref, + int kind: int ref /* explicit = 1, implicit = 2 */); + +/** EXPRESSIONS **/ + +expressions( + unique int id: @expr, + int kind: int ref, + int type_id: @type_or_ref ref); + +#keyset[index, parent] +expr_parent( + unique int expr: @expr ref, + int index: int ref, + int parent: @control_flow_element ref); + +@top_level_expr_parent = @attribute | @field | @property | @indexer | @parameter; + +@top_level_exprorstmt_parent = @top_level_expr_parent | @top_level_stmt_parent; + +// [index, parent] is not a keyset because the same parent may be compiled multiple times +expr_parent_top_level( + unique int expr: @expr ref, + int index: int ref, + int parent: @top_level_exprorstmt_parent ref); + +case @expr.kind of +/* literal */ + 1 = @bool_literal_expr +| 2 = @char_literal_expr +| 3 = @decimal_literal_expr +| 4 = @int_literal_expr +| 5 = @long_literal_expr +| 6 = @uint_literal_expr +| 7 = @ulong_literal_expr +| 8 = @float_literal_expr +| 9 = @double_literal_expr +| 10 = @string_literal_expr +| 11 = @null_literal_expr +/* primary & unary */ +| 12 = @this_access_expr +| 13 = @base_access_expr +| 14 = @local_variable_access_expr +| 15 = @parameter_access_expr +| 16 = @field_access_expr +| 17 = @property_access_expr +| 18 = @method_access_expr +| 19 = @event_access_expr +| 20 = @indexer_access_expr +| 21 = @array_access_expr +| 22 = @type_access_expr +| 23 = @typeof_expr +| 24 = @method_invocation_expr +| 25 = @delegate_invocation_expr +| 26 = @operator_invocation_expr +| 27 = @cast_expr +| 28 = @object_creation_expr +| 29 = @explicit_delegate_creation_expr +| 30 = @implicit_delegate_creation_expr +| 31 = @array_creation_expr +| 32 = @default_expr +| 33 = @plus_expr +| 34 = @minus_expr +| 35 = @bit_not_expr +| 36 = @log_not_expr +| 37 = @post_incr_expr +| 38 = @post_decr_expr +| 39 = @pre_incr_expr +| 40 = @pre_decr_expr +/* multiplicative */ +| 41 = @mul_expr +| 42 = @div_expr +| 43 = @rem_expr +/* additive */ +| 44 = @add_expr +| 45 = @sub_expr +/* shift */ +| 46 = @lshift_expr +| 47 = @rshift_expr +/* relational */ +| 48 = @lt_expr +| 49 = @gt_expr +| 50 = @le_expr +| 51 = @ge_expr +/* equality */ +| 52 = @eq_expr +| 53 = @ne_expr +/* logical */ +| 54 = @bit_and_expr +| 55 = @bit_xor_expr +| 56 = @bit_or_expr +| 57 = @log_and_expr +| 58 = @log_or_expr +/* type testing */ +| 59 = @is_expr +| 60 = @as_expr +/* null coalescing */ +| 61 = @null_coalescing_expr +/* conditional */ +| 62 = @conditional_expr +/* assignment */ +| 63 = @simple_assign_expr +| 64 = @assign_add_expr +| 65 = @assign_sub_expr +| 66 = @assign_mul_expr +| 67 = @assign_div_expr +| 68 = @assign_rem_expr +| 69 = @assign_and_expr +| 70 = @assign_xor_expr +| 71 = @assign_or_expr +| 72 = @assign_lshift_expr +| 73 = @assign_rshift_expr +/* more */ +| 74 = @object_init_expr +| 75 = @collection_init_expr +| 76 = @array_init_expr +| 77 = @checked_expr +| 78 = @unchecked_expr +| 79 = @constructor_init_expr +| 80 = @add_event_expr +| 81 = @remove_event_expr +| 82 = @par_expr +| 83 = @local_var_decl_expr +| 84 = @lambda_expr +| 85 = @anonymous_method_expr +| 86 = @namespace_expr +/* dynamic */ +| 92 = @dynamic_element_access_expr +| 93 = @dynamic_member_access_expr +/* unsafe */ +| 100 = @pointer_indirection_expr +| 101 = @address_of_expr +| 102 = @sizeof_expr +/* async */ +| 103 = @await_expr +/* C# 6.0 */ +| 104 = @nameof_expr +| 105 = @interpolated_string_expr +| 106 = @unknown_expr +/* C# 7.0 */ +| 107 = @throw_expr +| 108 = @tuple_expr +| 109 = @local_function_invocation_expr +| 110 = @ref_expr +| 111 = @discard_expr +/* C# 8.0 */ +| 112 = @range_expr +| 113 = @index_expr +| 114 = @switch_expr +| 115 = @recursive_pattern_expr +| 116 = @property_pattern_expr +| 117 = @positional_pattern_expr +| 118 = @switch_case_expr +| 119 = @assign_coalesce_expr +| 120 = @suppress_nullable_warning_expr +| 121 = @namespace_access_expr +/* C# 9.0 */ +| 122 = @lt_pattern_expr +| 123 = @gt_pattern_expr +| 124 = @le_pattern_expr +| 125 = @ge_pattern_expr +| 126 = @not_pattern_expr +| 129 = @function_pointer_invocation_expr +; + +@switch = @switch_stmt | @switch_expr; +@case = @case_stmt | @switch_case_expr; +@pattern_match = @case | @is_expr; +@unary_pattern_expr = @not_pattern_expr; +@relational_pattern_expr = @gt_pattern_expr | @lt_pattern_expr | @ge_pattern_expr | @le_pattern_expr; + +@integer_literal_expr = @int_literal_expr | @long_literal_expr | @uint_literal_expr | @ulong_literal_expr; +@real_literal_expr = @float_literal_expr | @double_literal_expr | @decimal_literal_expr; +@literal_expr = @bool_literal_expr | @char_literal_expr | @integer_literal_expr | @real_literal_expr + | @string_literal_expr | @null_literal_expr; + +@assign_expr = @simple_assign_expr | @assign_op_expr | @local_var_decl_expr; +@assign_op_expr = @assign_arith_expr | @assign_bitwise_expr | @assign_event_expr | @assign_coalesce_expr; +@assign_event_expr = @add_event_expr | @remove_event_expr; + +@assign_arith_expr = @assign_add_expr | @assign_sub_expr | @assign_mul_expr | @assign_div_expr + | @assign_rem_expr +@assign_bitwise_expr = @assign_and_expr | @assign_or_expr | @assign_xor_expr + | @assign_lshift_expr | @assign_rshift_expr; + +@member_access_expr = @field_access_expr | @property_access_expr | @indexer_access_expr | @event_access_expr + | @method_access_expr | @type_access_expr | @dynamic_member_access_expr; +@access_expr = @member_access_expr | @this_access_expr | @base_access_expr | @assignable_access_expr | @namespace_access_expr; +@element_access_expr = @indexer_access_expr | @array_access_expr | @dynamic_element_access_expr; + +@local_variable_access = @local_variable_access_expr | @local_var_decl_expr; +@local_scope_variable_access_expr = @parameter_access_expr | @local_variable_access; +@variable_access_expr = @local_scope_variable_access_expr | @field_access_expr; + +@assignable_access_expr = @variable_access_expr | @property_access_expr | @element_access_expr + | @event_access_expr | @dynamic_member_access_expr; + +@objectorcollection_init_expr = @object_init_expr | @collection_init_expr; + +@delegate_creation_expr = @explicit_delegate_creation_expr | @implicit_delegate_creation_expr; + +@bin_arith_op_expr = @mul_expr | @div_expr | @rem_expr | @add_expr | @sub_expr; +@incr_op_expr = @pre_incr_expr | @post_incr_expr; +@decr_op_expr = @pre_decr_expr | @post_decr_expr; +@mut_op_expr = @incr_op_expr | @decr_op_expr; +@un_arith_op_expr = @plus_expr | @minus_expr | @mut_op_expr; +@arith_op_expr = @bin_arith_op_expr | @un_arith_op_expr; + +@ternary_log_op_expr = @conditional_expr; +@bin_log_op_expr = @log_and_expr | @log_or_expr | @null_coalescing_expr; +@un_log_op_expr = @log_not_expr; +@log_expr = @un_log_op_expr | @bin_log_op_expr | @ternary_log_op_expr; + +@bin_bit_op_expr = @bit_and_expr | @bit_or_expr | @bit_xor_expr | @lshift_expr + | @rshift_expr; +@un_bit_op_expr = @bit_not_expr; +@bit_expr = @un_bit_op_expr | @bin_bit_op_expr; + +@equality_op_expr = @eq_expr | @ne_expr; +@rel_op_expr = @gt_expr | @lt_expr| @ge_expr | @le_expr; +@comp_expr = @equality_op_expr | @rel_op_expr; + +@op_expr = @assign_expr | @un_op | @bin_op | @ternary_op; + +@ternary_op = @ternary_log_op_expr; +@bin_op = @bin_arith_op_expr | @bin_log_op_expr | @bin_bit_op_expr | @comp_expr; +@un_op = @un_arith_op_expr | @un_log_op_expr | @un_bit_op_expr | @sizeof_expr + | @pointer_indirection_expr | @address_of_expr; + +@anonymous_function_expr = @lambda_expr | @anonymous_method_expr; + +@call = @method_invocation_expr | @constructor_init_expr | @operator_invocation_expr + | @delegate_invocation_expr | @object_creation_expr | @call_access_expr + | @local_function_invocation_expr | @function_pointer_invocation_expr; + +@call_access_expr = @property_access_expr | @event_access_expr | @indexer_access_expr; + +@late_bindable_expr = @dynamic_element_access_expr | @dynamic_member_access_expr + | @object_creation_expr | @method_invocation_expr | @operator_invocation_expr; + +@throw_element = @throw_expr | @throw_stmt; + +@implicitly_typeable_object_creation_expr = @object_creation_expr | @explicit_delegate_creation_expr; + +implicitly_typed_array_creation( + unique int id: @array_creation_expr ref); + +explicitly_sized_array_creation( + unique int id: @array_creation_expr ref); + +stackalloc_array_creation( + unique int id: @array_creation_expr ref); + +implicitly_typed_object_creation( + unique int id: @implicitly_typeable_object_creation_expr ref); + +mutator_invocation_mode( + unique int id: @operator_invocation_expr ref, + int mode: int ref /* prefix = 1, postfix = 2*/); + +expr_compiler_generated( + unique int id: @expr ref); + +expr_value( + unique int id: @expr ref, + string value: string ref); + +expr_call( + unique int caller_id: @expr ref, + int target_id: @callable ref); + +expr_access( + unique int accesser_id: @access_expr ref, + int target_id: @accessible ref); + +@accessible = @method | @assignable | @local_function | @namespace; + +expr_location( + unique int id: @expr ref, + int loc: @location ref); + +dynamic_member_name( + unique int id: @late_bindable_expr ref, + string name: string ref); + +@qualifiable_expr = @member_access_expr + | @method_invocation_expr + | @element_access_expr; + +conditional_access( + unique int id: @qualifiable_expr ref); + +expr_argument( + unique int id: @expr ref, + int mode: int ref); + /* mode is the same as params: value = 0, ref = 1, out = 2 */ + +expr_argument_name( + unique int id: @expr ref, + string name: string ref); + +/** CONTROL/DATA FLOW **/ + +@control_flow_element = @stmt | @expr; + +/* XML Files */ + +xmlEncoding ( + unique int id: @file ref, + string encoding: string ref); + +xmlDTDs( + unique int id: @xmldtd, + string root: string ref, + string publicId: string ref, + string systemId: string ref, + int fileid: @file ref); + +xmlElements( + unique int id: @xmlelement, + string name: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int fileid: @file ref); + +xmlAttrs( + unique int id: @xmlattribute, + int elementid: @xmlelement ref, + string name: string ref, + string value: string ref, + int idx: int ref, + int fileid: @file ref); + +xmlNs( + int id: @xmlnamespace, + string prefixName: string ref, + string URI: string ref, + int fileid: @file ref); + +xmlHasNs( + int elementId: @xmlnamespaceable ref, + int nsId: @xmlnamespace ref, + int fileid: @file ref); + +xmlComments( + unique int id: @xmlcomment, + string text: string ref, + int parentid: @xmlparent ref, + int fileid: @file ref); + +xmlChars( + unique int id: @xmlcharacters, + string text: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int isCDATA: int ref, + int fileid: @file ref); + +@xmlparent = @file | @xmlelement; +@xmlnamespaceable = @xmlelement | @xmlattribute; + +xmllocations( + int xmlElement: @xmllocatable ref, + int location: @location_default ref); + +@xmllocatable = @xmlcharacters | @xmlelement | @xmlcomment | @xmlattribute | @xmldtd | @file | @xmlnamespace; + +/* Comments */ + +commentline( + unique int id: @commentline, + int kind: int ref, + string text: string ref, + string rawtext: string ref); + +case @commentline.kind of + 0 = @singlelinecomment +| 1 = @xmldoccomment +| 2 = @multilinecomment; + +commentline_location( + unique int id: @commentline ref, + int loc: @location ref); + +commentblock( + unique int id : @commentblock); + +commentblock_location( + unique int id: @commentblock ref, + int loc: @location ref); + +commentblock_binding( + int id: @commentblock ref, + int entity: @element ref, + int bindtype: int ref); /* 0: Parent, 1: Best, 2: Before, 3: After */ + +commentblock_child( + int id: @commentblock ref, + int commentline: @commentline ref, + int index: int ref); + +/* ASP.NET */ + +case @asp_element.kind of + 0=@asp_close_tag +| 1=@asp_code +| 2=@asp_comment +| 3=@asp_data_binding +| 4=@asp_directive +| 5=@asp_open_tag +| 6=@asp_quoted_string +| 7=@asp_text +| 8=@asp_xml_directive; + +@asp_attribute = @asp_code | @asp_data_binding | @asp_quoted_string; + +asp_elements( + unique int id: @asp_element, + int kind: int ref, + int loc: @location ref); + +asp_comment_server(unique int comment: @asp_comment ref); +asp_code_inline(unique int code: @asp_code ref); +asp_directive_attribute( + int directive: @asp_directive ref, + int index: int ref, + string name: string ref, + int value: @asp_quoted_string ref); +asp_directive_name( + unique int directive: @asp_directive ref, + string name: string ref); +asp_element_body( + unique int element: @asp_element ref, + string body: string ref); +asp_tag_attribute( + int tag: @asp_open_tag ref, + int index: int ref, + string name: string ref, + int attribute: @asp_attribute ref); +asp_tag_name( + unique int tag: @asp_open_tag ref, + string name: string ref); +asp_tag_isempty(int tag: @asp_open_tag ref); + +/* Common Intermediate Language - CIL */ + +case @cil_instruction.opcode of + 0 = @cil_nop +| 1 = @cil_break +| 2 = @cil_ldarg_0 +| 3 = @cil_ldarg_1 +| 4 = @cil_ldarg_2 +| 5 = @cil_ldarg_3 +| 6 = @cil_ldloc_0 +| 7 = @cil_ldloc_1 +| 8 = @cil_ldloc_2 +| 9 = @cil_ldloc_3 +| 10 = @cil_stloc_0 +| 11 = @cil_stloc_1 +| 12 = @cil_stloc_2 +| 13 = @cil_stloc_3 +| 14 = @cil_ldarg_s +| 15 = @cil_ldarga_s +| 16 = @cil_starg_s +| 17 = @cil_ldloc_s +| 18 = @cil_ldloca_s +| 19 = @cil_stloc_s +| 20 = @cil_ldnull +| 21 = @cil_ldc_i4_m1 +| 22 = @cil_ldc_i4_0 +| 23 = @cil_ldc_i4_1 +| 24 = @cil_ldc_i4_2 +| 25 = @cil_ldc_i4_3 +| 26 = @cil_ldc_i4_4 +| 27 = @cil_ldc_i4_5 +| 28 = @cil_ldc_i4_6 +| 29 = @cil_ldc_i4_7 +| 30 = @cil_ldc_i4_8 +| 31 = @cil_ldc_i4_s +| 32 = @cil_ldc_i4 +| 33 = @cil_ldc_i8 +| 34 = @cil_ldc_r4 +| 35 = @cil_ldc_r8 +| 37 = @cil_dup +| 38 = @cil_pop +| 39 = @cil_jmp +| 40 = @cil_call +| 41 = @cil_calli +| 42 = @cil_ret +| 43 = @cil_br_s +| 44 = @cil_brfalse_s +| 45 = @cil_brtrue_s +| 46 = @cil_beq_s +| 47 = @cil_bge_s +| 48 = @cil_bgt_s +| 49 = @cil_ble_s +| 50 = @cil_blt_s +| 51 = @cil_bne_un_s +| 52 = @cil_bge_un_s +| 53 = @cil_bgt_un_s +| 54 = @cil_ble_un_s +| 55 = @cil_blt_un_s +| 56 = @cil_br +| 57 = @cil_brfalse +| 58 = @cil_brtrue +| 59 = @cil_beq +| 60 = @cil_bge +| 61 = @cil_bgt +| 62 = @cil_ble +| 63 = @cil_blt +| 64 = @cil_bne_un +| 65 = @cil_bge_un +| 66 = @cil_bgt_un +| 67 = @cil_ble_un +| 68 = @cil_blt_un +| 69 = @cil_switch +| 70 = @cil_ldind_i1 +| 71 = @cil_ldind_u1 +| 72 = @cil_ldind_i2 +| 73 = @cil_ldind_u2 +| 74 = @cil_ldind_i4 +| 75 = @cil_ldind_u4 +| 76 = @cil_ldind_i8 +| 77 = @cil_ldind_i +| 78 = @cil_ldind_r4 +| 79 = @cil_ldind_r8 +| 80 = @cil_ldind_ref +| 81 = @cil_stind_ref +| 82 = @cil_stind_i1 +| 83 = @cil_stind_i2 +| 84 = @cil_stind_i4 +| 85 = @cil_stind_i8 +| 86 = @cil_stind_r4 +| 87 = @cil_stind_r8 +| 88 = @cil_add +| 89 = @cil_sub +| 90 = @cil_mul +| 91 = @cil_div +| 92 = @cil_div_un +| 93 = @cil_rem +| 94 = @cil_rem_un +| 95 = @cil_and +| 96 = @cil_or +| 97 = @cil_xor +| 98 = @cil_shl +| 99 = @cil_shr +| 100 = @cil_shr_un +| 101 = @cil_neg +| 102 = @cil_not +| 103 = @cil_conv_i1 +| 104 = @cil_conv_i2 +| 105 = @cil_conv_i4 +| 106 = @cil_conv_i8 +| 107 = @cil_conv_r4 +| 108 = @cil_conv_r8 +| 109 = @cil_conv_u4 +| 110 = @cil_conv_u8 +| 111 = @cil_callvirt +| 112 = @cil_cpobj +| 113 = @cil_ldobj +| 114 = @cil_ldstr +| 115 = @cil_newobj +| 116 = @cil_castclass +| 117 = @cil_isinst +| 118 = @cil_conv_r_un +| 121 = @cil_unbox +| 122 = @cil_throw +| 123 = @cil_ldfld +| 124 = @cil_ldflda +| 125 = @cil_stfld +| 126 = @cil_ldsfld +| 127 = @cil_ldsflda +| 128 = @cil_stsfld +| 129 = @cil_stobj +| 130 = @cil_conv_ovf_i1_un +| 131 = @cil_conv_ovf_i2_un +| 132 = @cil_conv_ovf_i4_un +| 133 = @cil_conv_ovf_i8_un +| 134 = @cil_conv_ovf_u1_un +| 135 = @cil_conv_ovf_u2_un +| 136 = @cil_conv_ovf_u4_un +| 137 = @cil_conv_ovf_u8_un +| 138 = @cil_conv_ovf_i_un +| 139 = @cil_conv_ovf_u_un +| 140 = @cil_box +| 141 = @cil_newarr +| 142 = @cil_ldlen +| 143 = @cil_ldelema +| 144 = @cil_ldelem_i1 +| 145 = @cil_ldelem_u1 +| 146 = @cil_ldelem_i2 +| 147 = @cil_ldelem_u2 +| 148 = @cil_ldelem_i4 +| 149 = @cil_ldelem_u4 +| 150 = @cil_ldelem_i8 +| 151 = @cil_ldelem_i +| 152 = @cil_ldelem_r4 +| 153 = @cil_ldelem_r8 +| 154 = @cil_ldelem_ref +| 155 = @cil_stelem_i +| 156 = @cil_stelem_i1 +| 157 = @cil_stelem_i2 +| 158 = @cil_stelem_i4 +| 159 = @cil_stelem_i8 +| 160 = @cil_stelem_r4 +| 161 = @cil_stelem_r8 +| 162 = @cil_stelem_ref +| 163 = @cil_ldelem +| 164 = @cil_stelem +| 165 = @cil_unbox_any +| 179 = @cil_conv_ovf_i1 +| 180 = @cil_conv_ovf_u1 +| 181 = @cil_conv_ovf_i2 +| 182 = @cil_conv_ovf_u2 +| 183 = @cil_conv_ovf_i4 +| 184 = @cil_conv_ovf_u4 +| 185 = @cil_conv_ovf_i8 +| 186 = @cil_conv_ovf_u8 +| 194 = @cil_refanyval +| 195 = @cil_ckinfinite +| 198 = @cil_mkrefany +| 208 = @cil_ldtoken +| 209 = @cil_conv_u2 +| 210 = @cil_conv_u1 +| 211 = @cil_conv_i +| 212 = @cil_conv_ovf_i +| 213 = @cil_conv_ovf_u +| 214 = @cil_add_ovf +| 215 = @cil_add_ovf_un +| 216 = @cil_mul_ovf +| 217 = @cil_mul_ovf_un +| 218 = @cil_sub_ovf +| 219 = @cil_sub_ovf_un +| 220 = @cil_endfinally +| 221 = @cil_leave +| 222 = @cil_leave_s +| 223 = @cil_stind_i +| 224 = @cil_conv_u +| 65024 = @cil_arglist +| 65025 = @cil_ceq +| 65026 = @cil_cgt +| 65027 = @cil_cgt_un +| 65028 = @cil_clt +| 65029 = @cil_clt_un +| 65030 = @cil_ldftn +| 65031 = @cil_ldvirtftn +| 65033 = @cil_ldarg +| 65034 = @cil_ldarga +| 65035 = @cil_starg +| 65036 = @cil_ldloc +| 65037 = @cil_ldloca +| 65038 = @cil_stloc +| 65039 = @cil_localloc +| 65041 = @cil_endfilter +| 65042 = @cil_unaligned +| 65043 = @cil_volatile +| 65044 = @cil_tail +| 65045 = @cil_initobj +| 65046 = @cil_constrained +| 65047 = @cil_cpblk +| 65048 = @cil_initblk +| 65050 = @cil_rethrow +| 65052 = @cil_sizeof +| 65053 = @cil_refanytype +| 65054 = @cil_readonly +; + +// CIL ignored instructions + +@cil_ignore = @cil_nop | @cil_break | @cil_volatile | @cil_unaligned; + +// CIL local/parameter/field access + +@cil_ldarg_any = @cil_ldarg_0 | @cil_ldarg_1 | @cil_ldarg_2 | @cil_ldarg_3 | @cil_ldarg_s | @cil_ldarga_s | @cil_ldarg | @cil_ldarga; +@cil_starg_any = @cil_starg | @cil_starg_s; + +@cil_ldloc_any = @cil_ldloc_0 | @cil_ldloc_1 | @cil_ldloc_2 | @cil_ldloc_3 | @cil_ldloc_s | @cil_ldloca_s | @cil_ldloc | @cil_ldloca; +@cil_stloc_any = @cil_stloc_0 | @cil_stloc_1 | @cil_stloc_2 | @cil_stloc_3 | @cil_stloc_s | @cil_stloc; + +@cil_ldfld_any = @cil_ldfld | @cil_ldsfld | @cil_ldsflda | @cil_ldflda; +@cil_stfld_any = @cil_stfld | @cil_stsfld; + +@cil_local_access = @cil_stloc_any | @cil_ldloc_any; +@cil_arg_access = @cil_starg_any | @cil_ldarg_any; +@cil_read_access = @cil_ldloc_any | @cil_ldarg_any | @cil_ldfld_any; +@cil_write_access = @cil_stloc_any | @cil_starg_any | @cil_stfld_any; + +@cil_stack_access = @cil_local_access | @cil_arg_access; +@cil_field_access = @cil_ldfld_any | @cil_stfld_any; + +@cil_access = @cil_read_access | @cil_write_access; + +// CIL constant/literal instructions + +@cil_ldc_i = @cil_ldc_i4_any | @cil_ldc_i8; + +@cil_ldc_i4_any = @cil_ldc_i4_m1 | @cil_ldc_i4_0 | @cil_ldc_i4_1 | @cil_ldc_i4_2 | @cil_ldc_i4_3 | + @cil_ldc_i4_4 | @cil_ldc_i4_5 | @cil_ldc_i4_6 | @cil_ldc_i4_7 | @cil_ldc_i4_8 | @cil_ldc_i4_s | @cil_ldc_i4; + +@cil_ldc_r = @cil_ldc_r4 | @cil_ldc_r8; + +@cil_literal = @cil_ldnull | @cil_ldc_i | @cil_ldc_r | @cil_ldstr; + +// Control flow + +@cil_conditional_jump = @cil_binary_jump | @cil_unary_jump; +@cil_binary_jump = @cil_beq_s | @cil_bge_s | @cil_bgt_s | @cil_ble_s | @cil_blt_s | + @cil_bne_un_s | @cil_bge_un_s | @cil_bgt_un_s | @cil_ble_un_s | @cil_blt_un_s | + @cil_beq | @cil_bge | @cil_bgt | @cil_ble | @cil_blt | + @cil_bne_un | @cil_bge_un | @cil_bgt_un | @cil_ble_un | @cil_blt_un; +@cil_unary_jump = @cil_brfalse_s | @cil_brtrue_s | @cil_brfalse | @cil_brtrue | @cil_switch; +@cil_unconditional_jump = @cil_br | @cil_br_s | @cil_leave_any; +@cil_leave_any = @cil_leave | @cil_leave_s; +@cil_jump = @cil_unconditional_jump | @cil_conditional_jump; + +// CIL call instructions + +@cil_call_any = @cil_jmp | @cil_call | @cil_calli | @cil_tail | @cil_callvirt | @cil_newobj; + +// CIL expression instructions + +@cil_expr = @cil_literal | @cil_binary_expr | @cil_unary_expr | @cil_call_any | @cil_read_access | + @cil_newarr | @cil_ldtoken | @cil_sizeof | + @cil_ldftn | @cil_ldvirtftn | @cil_localloc | @cil_mkrefany | @cil_refanytype | @cil_arglist | @cil_dup; + +@cil_unary_expr = + @cil_conversion_operation | @cil_unary_arithmetic_operation | @cil_unary_bitwise_operation| + @cil_ldlen | @cil_isinst | @cil_box | @cil_ldobj | @cil_castclass | @cil_unbox_any | + @cil_ldind | @cil_unbox; + +@cil_conversion_operation = + @cil_conv_i1 | @cil_conv_i2 | @cil_conv_i4 | @cil_conv_i8 | + @cil_conv_u1 | @cil_conv_u2 | @cil_conv_u4 | @cil_conv_u8 | + @cil_conv_ovf_i | @cil_conv_ovf_i_un | @cil_conv_ovf_i1 | @cil_conv_ovf_i1_un | + @cil_conv_ovf_i2 | @cil_conv_ovf_i2_un | @cil_conv_ovf_i4 | @cil_conv_ovf_i4_un | + @cil_conv_ovf_i8 | @cil_conv_ovf_i8_un | @cil_conv_ovf_u | @cil_conv_ovf_u_un | + @cil_conv_ovf_u1 | @cil_conv_ovf_u1_un | @cil_conv_ovf_u2 | @cil_conv_ovf_u2_un | + @cil_conv_ovf_u4 | @cil_conv_ovf_u4_un | @cil_conv_ovf_u8 | @cil_conv_ovf_u8_un | + @cil_conv_r4 | @cil_conv_r8 | @cil_conv_ovf_u2 | @cil_conv_ovf_u2_un | + @cil_conv_i | @cil_conv_u | @cil_conv_r_un; + +@cil_ldind = @cil_ldind_i | @cil_ldind_i1 | @cil_ldind_i2 | @cil_ldind_i4 | @cil_ldind_i8 | + @cil_ldind_r4 | @cil_ldind_r8 | @cil_ldind_ref | @cil_ldind_u1 | @cil_ldind_u2 | @cil_ldind_u4; + +@cil_stind = @cil_stind_i | @cil_stind_i1 | @cil_stind_i2 | @cil_stind_i4 | @cil_stind_i8 | + @cil_stind_r4 | @cil_stind_r8 | @cil_stind_ref; + +@cil_bitwise_operation = @cil_binary_bitwise_operation | @cil_unary_bitwise_operation; + +@cil_binary_bitwise_operation = @cil_and | @cil_or | @cil_xor | @cil_shr | @cil_shr | @cil_shr_un | @cil_shl; + +@cil_binary_arithmetic_operation = @cil_add | @cil_sub | @cil_mul | @cil_div | @cil_div_un | + @cil_rem | @cil_rem_un | @cil_add_ovf | @cil_add_ovf_un | @cil_mul_ovf | @cil_mul_ovf_un | + @cil_sub_ovf | @cil_sub_ovf_un; + +@cil_unary_bitwise_operation = @cil_not; + +@cil_binary_expr = @cil_binary_arithmetic_operation | @cil_binary_bitwise_operation | @cil_read_array | @cil_comparison_operation; + +@cil_unary_arithmetic_operation = @cil_neg; + +@cil_comparison_operation = @cil_cgt_un | @cil_ceq | @cil_cgt | @cil_clt | @cil_clt_un; + +// Elements that retrieve an address of something +@cil_read_ref = @cil_ldloca_s | @cil_ldarga_s | @cil_ldflda | @cil_ldsflda | @cil_ldelema; + +// CIL array instructions + +@cil_read_array = + @cil_ldelem | @cil_ldelema | @cil_ldelem_i1 | @cil_ldelem_ref | @cil_ldelem_i | + @cil_ldelem_i1 | @cil_ldelem_i2 | @cil_ldelem_i4 | @cil_ldelem_i8 | @cil_ldelem_r4 | + @cil_ldelem_r8 | @cil_ldelem_u1 | @cil_ldelem_u2 | @cil_ldelem_u4; + +@cil_write_array = @cil_stelem | @cil_stelem_ref | + @cil_stelem_i | @cil_stelem_i1 | @cil_stelem_i2 | @cil_stelem_i4 | @cil_stelem_i8 | + @cil_stelem_r4 | @cil_stelem_r8; + +@cil_throw_any = @cil_throw | @cil_rethrow; + +#keyset[impl, index] +cil_instruction( + unique int id: @cil_instruction, + int opcode: int ref, + int index: int ref, + int impl: @cil_method_implementation ref); + +cil_jump( + unique int instruction: @cil_jump ref, + int target: @cil_instruction ref); + +cil_access( + unique int instruction: @cil_instruction ref, + int target: @cil_accessible ref); + +cil_value( + unique int instruction: @cil_literal ref, + string value: string ref); + +#keyset[instruction, index] +cil_switch( + int instruction: @cil_switch ref, + int index: int ref, + int target: @cil_instruction ref); + +cil_instruction_location( + unique int id: @cil_instruction ref, + int loc: @location ref); + +cil_type_location( + int id: @cil_type ref, + int loc: @location ref); + +cil_method_location( + int id: @cil_method ref, + int loc: @location ref); + +@cil_namespace = @namespace; + +@cil_type_container = @cil_type | @cil_namespace | @cil_method; + +case @cil_type.kind of + 0 = @cil_valueorreftype +| 1 = @cil_typeparameter +| 2 = @cil_array_type +| 3 = @cil_pointer_type +| 4 = @cil_function_pointer_type +; + +cil_type( + unique int id: @cil_type, + string name: string ref, + int kind: int ref, + int parent: @cil_type_container ref, + int sourceDecl: @cil_type ref); + +cil_pointer_type( + unique int id: @cil_pointer_type ref, + int pointee: @cil_type ref); + +cil_array_type( + unique int id: @cil_array_type ref, + int element_type: @cil_type ref, + int rank: int ref); + +cil_function_pointer_return_type( + unique int id: @cil_function_pointer_type ref, + int return_type: @cil_type ref); + +cil_method( + unique int id: @cil_method, + string name: string ref, + int parent: @cil_type ref, + int return_type: @cil_type ref); + +cil_method_source_declaration( + unique int method: @cil_method ref, + int source: @cil_method ref); + +cil_method_implementation( + unique int id: @cil_method_implementation, + int method: @cil_method ref, + int location: @assembly ref); + +cil_implements( + int id: @cil_method ref, + int decl: @cil_method ref); + +#keyset[parent, name] +cil_field( + unique int id: @cil_field, + int parent: @cil_type ref, + string name: string ref, + int field_type: @cil_type ref); + +@cil_element = @cil_instruction | @cil_declaration | @cil_handler | @cil_attribute | @cil_namespace; +@cil_named_element = @cil_declaration | @cil_namespace; +@cil_declaration = @cil_variable | @cil_method | @cil_type | @cil_member; +@cil_accessible = @cil_declaration; +@cil_variable = @cil_field | @cil_stack_variable; +@cil_stack_variable = @cil_local_variable | @cil_parameter; +@cil_member = @cil_method | @cil_type | @cil_field | @cil_property | @cil_event; +@cil_custom_modifier_receiver = @cil_method | @cil_property | @cil_parameter | @cil_field | @cil_function_pointer_type; +@cil_parameterizable = @cil_method | @cil_function_pointer_type; +@cil_has_type_annotation = @cil_stack_variable | @cil_property | @cil_method | @cil_function_pointer_type; + +#keyset[parameterizable, index] +cil_parameter( + unique int id: @cil_parameter, + int parameterizable: @cil_parameterizable ref, + int index: int ref, + int param_type: @cil_type ref); + +cil_parameter_in(unique int id: @cil_parameter ref); +cil_parameter_out(unique int id: @cil_parameter ref); + +cil_setter(unique int prop: @cil_property ref, + int method: @cil_method ref); + +#keyset[id, modifier] +cil_custom_modifiers( + int id: @cil_custom_modifier_receiver ref, + int modifier: @cil_type ref, + int kind: int ref); // modreq: 1, modopt: 0 + +cil_type_annotation( + int id: @cil_has_type_annotation ref, + int annotation: int ref); + +cil_getter(unique int prop: @cil_property ref, + int method: @cil_method ref); + +cil_adder(unique int event: @cil_event ref, + int method: @cil_method ref); + +cil_remover(unique int event: @cil_event ref, int method: @cil_method ref); + +cil_raiser(unique int event: @cil_event ref, int method: @cil_method ref); + +cil_property( + unique int id: @cil_property, + int parent: @cil_type ref, + string name: string ref, + int property_type: @cil_type ref); + +#keyset[parent, name] +cil_event(unique int id: @cil_event, + int parent: @cil_type ref, + string name: string ref, + int event_type: @cil_type ref); + +#keyset[impl, index] +cil_local_variable( + unique int id: @cil_local_variable, + int impl: @cil_method_implementation ref, + int index: int ref, + int var_type: @cil_type ref); + +cil_function_pointer_calling_conventions( + int id: @cil_function_pointer_type ref, + int kind: int ref); + +// CIL handlers (exception handlers etc). + +case @cil_handler.kind of + 0 = @cil_catch_handler +| 1 = @cil_filter_handler +| 2 = @cil_finally_handler +| 4 = @cil_fault_handler +; + +#keyset[impl, index] +cil_handler( + unique int id: @cil_handler, + int impl: @cil_method_implementation ref, + int index: int ref, + int kind: int ref, + int try_start: @cil_instruction ref, + int try_end: @cil_instruction ref, + int handler_start: @cil_instruction ref); + +cil_handler_filter( + unique int id: @cil_handler ref, + int filter_start: @cil_instruction ref); + +cil_handler_type( + unique int id: @cil_handler ref, + int catch_type: @cil_type ref); + +@cil_controlflow_node = @cil_entry_point | @cil_instruction; + +@cil_entry_point = @cil_method_implementation | @cil_handler; + +@cil_dataflow_node = @cil_instruction | @cil_variable | @cil_method; + +cil_method_stack_size( + unique int method: @cil_method_implementation ref, + int size: int ref); + +// CIL modifiers + +cil_public(int id: @cil_member ref); +cil_private(int id: @cil_member ref); +cil_protected(int id: @cil_member ref); +cil_internal(int id: @cil_member ref); +cil_static(int id: @cil_member ref); +cil_sealed(int id: @cil_member ref); +cil_virtual(int id: @cil_method ref); +cil_abstract(int id: @cil_member ref); +cil_class(int id: @cil_type ref); +cil_interface(int id: @cil_type ref); +cil_security(int id: @cil_member ref); +cil_requiresecobject(int id: @cil_method ref); +cil_specialname(int id: @cil_method ref); +cil_newslot(int id: @cil_method ref); + +cil_base_class(unique int id: @cil_type ref, int base: @cil_type ref); +cil_base_interface(int id: @cil_type ref, int base: @cil_type ref); +cil_enum_underlying_type(unique int id: @cil_type ref, int underlying: @cil_type ref); + +#keyset[unbound, index] +cil_type_parameter( + int unbound: @cil_member ref, + int index: int ref, + int param: @cil_typeparameter ref); + +#keyset[bound, index] +cil_type_argument( + int bound: @cil_member ref, + int index: int ref, + int t: @cil_type ref); + +// CIL type parameter constraints + +cil_typeparam_covariant(int tp: @cil_typeparameter ref); +cil_typeparam_contravariant(int tp: @cil_typeparameter ref); +cil_typeparam_class(int tp: @cil_typeparameter ref); +cil_typeparam_struct(int tp: @cil_typeparameter ref); +cil_typeparam_new(int tp: @cil_typeparameter ref); +cil_typeparam_constraint(int tp: @cil_typeparameter ref, int supertype: @cil_type ref); + +// CIL attributes + +cil_attribute( + unique int attributeid: @cil_attribute, + int element: @cil_declaration ref, + int constructor: @cil_method ref); + +#keyset[attribute_id, param] +cil_attribute_named_argument( + int attribute_id: @cil_attribute ref, + string param: string ref, + string value: string ref); + +#keyset[attribute_id, index] +cil_attribute_positional_argument( + int attribute_id: @cil_attribute ref, + int index: int ref, + string value: string ref); + + +// Common .Net data model covering both C# and CIL + +// Common elements +@dotnet_element = @element | @cil_element; +@dotnet_named_element = @named_element | @cil_named_element; +@dotnet_callable = @callable | @cil_method; +@dotnet_variable = @variable | @cil_variable; +@dotnet_field = @field | @cil_field; +@dotnet_parameter = @parameter | @cil_parameter; +@dotnet_declaration = @declaration | @cil_declaration; +@dotnet_member = @member | @cil_member; +@dotnet_event = @event | @cil_event; +@dotnet_property = @property | @cil_property | @indexer; +@dotnet_parameterizable = @parameterizable | @cil_parameterizable; + +// Common types +@dotnet_type = @type | @cil_type; +@dotnet_call = @call | @cil_call_any; +@dotnet_throw = @throw_element | @cil_throw_any; +@dotnet_valueorreftype = @cil_valueorreftype | @value_or_ref_type | @cil_array_type | @void_type; +@dotnet_typeparameter = @type_parameter | @cil_typeparameter; +@dotnet_array_type = @array_type | @cil_array_type; +@dotnet_pointer_type = @pointer_type | @cil_pointer_type; +@dotnet_type_parameter = @type_parameter | @cil_typeparameter; +@dotnet_generic = @dotnet_valueorreftype | @dotnet_callable; + +// Attributes +@dotnet_attribute = @attribute | @cil_attribute; + +// Expressions +@dotnet_expr = @expr | @cil_expr; + +// Literals +@dotnet_literal = @literal_expr | @cil_literal; +@dotnet_string_literal = @string_literal_expr | @cil_ldstr; +@dotnet_int_literal = @integer_literal_expr | @cil_ldc_i; +@dotnet_float_literal = @float_literal_expr | @cil_ldc_r; +@dotnet_null_literal = @null_literal_expr | @cil_ldnull; + +@metadata_entity = @cil_method | @cil_type | @cil_field | @cil_property | @field | @property | + @callable | @value_or_ref_type | @void_type; + +#keyset[entity, location] +metadata_handle(int entity : @metadata_entity ref, int location: @assembly ref, int handle: int ref) diff --git a/csharp/upgrades/2fb07f0b8c65f6c89437c28caf5d99fdbcdbef2d/semmlecode.csharp.dbscheme b/csharp/upgrades/2fb07f0b8c65f6c89437c28caf5d99fdbcdbef2d/semmlecode.csharp.dbscheme new file mode 100644 index 00000000000..efcd69e086a --- /dev/null +++ b/csharp/upgrades/2fb07f0b8c65f6c89437c28caf5d99fdbcdbef2d/semmlecode.csharp.dbscheme @@ -0,0 +1,1959 @@ + +/** + * An invocation of the compiler. Note that more than one file may be + * compiled per invocation. For example, this command compiles three + * source files: + * + * csc f1.cs f2.cs f3.cs + * + * The `id` simply identifies the invocation, while `cwd` is the working + * directory from which the compiler was invoked. + */ +compilations( + unique int id : @compilation, + string cwd : string ref +); + +/** + * The arguments that were passed to the extractor for a compiler + * invocation. If `id` is for the compiler invocation + * + * csc f1.cs f2.cs f3.cs + * + * then typically there will be rows for + * + * num | arg + * --- | --- + * 0 | --compiler + * 1 | *path to compiler* + * 2 | --cil + * 3 | f1.cs + * 4 | f2.cs + * 5 | f3.cs + */ +#keyset[id, num] +compilation_args( + int id : @compilation ref, + int num : int ref, + string arg : string ref +); + +/** + * The source files that are compiled by a compiler invocation. + * If `id` is for the compiler invocation + * + * csc f1.cs f2.cs f3.cs + * + * then there will be rows for + * + * num | arg + * --- | --- + * 0 | f1.cs + * 1 | f2.cs + * 2 | f3.cs + */ +#keyset[id, num] +compilation_compiling_files( + int id : @compilation ref, + int num : int ref, + int file : @file ref +); + +/** + * The references used by a compiler invocation. + * If `id` is for the compiler invocation + * + * csc f1.cs f2.cs f3.cs /r:ref1.dll /r:ref2.dll /r:ref3.dll + * + * then there will be rows for + * + * num | arg + * --- | --- + * 0 | ref1.dll + * 1 | ref2.dll + * 2 | ref3.dll + */ +#keyset[id, num] +compilation_referencing_files( + int id : @compilation ref, + int num : int ref, + int file : @file ref +); + +/** + * The time taken by the extractor for a compiler invocation. + * + * For each file `num`, there will be rows for + * + * kind | seconds + * ---- | --- + * 1 | CPU seconds used by the extractor frontend + * 2 | Elapsed seconds during the extractor frontend + * 3 | CPU seconds used by the extractor backend + * 4 | Elapsed seconds during the extractor backend + */ +#keyset[id, num, kind] +compilation_time( + int id : @compilation ref, + int num : int ref, + /* kind: + 1 = frontend_cpu_seconds + 2 = frontend_elapsed_seconds + 3 = extractor_cpu_seconds + 4 = extractor_elapsed_seconds + */ + int kind : int ref, + float seconds : float ref +); + +/** + * An error or warning generated by the extractor. + * The diagnostic message `diagnostic` was generated during compiler + * invocation `compilation`, and is the `file_number_diagnostic_number`th + * message generated while extracting the `file_number`th file of that + * invocation. + */ +#keyset[compilation, file_number, file_number_diagnostic_number] +diagnostic_for( + unique int diagnostic : @diagnostic ref, + int compilation : @compilation ref, + int file_number : int ref, + int file_number_diagnostic_number : int ref +); + +diagnostics( + unique int id: @diagnostic, + int severity: int ref, + string error_tag: string ref, + string error_message: string ref, + string full_error_message: string ref, + int location: @location_default ref +); + +extractor_messages( + unique int id: @extractor_message, + int severity: int ref, + string origin : string ref, + string text : string ref, + string entity : string ref, + int location: @location_default ref, + string stack_trace : string ref +); + +/** + * If extraction was successful, then `cpu_seconds` and + * `elapsed_seconds` are the CPU time and elapsed time (respectively) + * that extraction took for compiler invocation `id`. + */ +compilation_finished( + unique int id : @compilation ref, + float cpu_seconds : float ref, + float elapsed_seconds : float ref +); + +compilation_assembly( + unique int id : @compilation ref, + int assembly: @assembly ref +) + +/* + * External artifacts + */ + +externalDefects( + unique int id: @externalDefect, + string queryPath: string ref, + int location: @location ref, + string message: string ref, + float severity: float ref); + +externalMetrics( + unique int id: @externalMetric, + string queryPath: string ref, + int location: @location ref, + float value: float ref); + +externalData( + int id: @externalDataElement, + string path: string ref, + int column: int ref, + string value: string ref); + +snapshotDate( + unique date snapshotDate: date ref); + +sourceLocationPrefix( + string prefix: string ref); + +/* + * Duplicate code + */ + +duplicateCode( + unique int id: @duplication, + string relativePath: string ref, + int equivClass: int ref); + +similarCode( + unique int id: @similarity, + string relativePath: string ref, + int equivClass: int ref); + +@duplication_or_similarity = @duplication | @similarity + +tokens( + int id: @duplication_or_similarity ref, + int offset: int ref, + int beginLine: int ref, + int beginColumn: int ref, + int endLine: int ref, + int endColumn: int ref); + +/* + * C# dbscheme + */ + +/** ELEMENTS **/ + +@element = @declaration | @stmt | @expr | @modifier | @attribute | @namespace_declaration + | @using_directive | @type_parameter_constraints | @external_element + | @xmllocatable | @asp_element | @namespace; + +@declaration = @callable | @generic | @assignable | @namespace; + +@named_element = @namespace | @declaration; + +@declaration_with_accessors = @property | @indexer | @event; + +@assignable = @variable | @assignable_with_accessors | @event; + +@assignable_with_accessors = @property | @indexer; + +@external_element = @externalMetric | @externalDefect | @externalDataElement; + +@attributable = @assembly | @field | @parameter | @operator | @method | @constructor + | @destructor | @callable_accessor | @value_or_ref_type | @declaration_with_accessors + | @local_function; + +/** LOCATIONS, ASEMMBLIES, MODULES, FILES and FOLDERS **/ + +@location = @location_default | @assembly; + +locations_default( + unique int id: @location_default, + int file: @file ref, + int beginLine: int ref, + int beginColumn: int ref, + int endLine: int ref, + int endColumn: int ref); + +@sourceline = @file | @callable | @xmllocatable; + +numlines( + int element_id: @sourceline ref, + int num_lines: int ref, + int num_code: int ref, + int num_comment: int ref); + +assemblies( + unique int id: @assembly, + int file: @file ref, + string fullname: string ref, + string name: string ref, + string version: string ref); + +/* + fromSource(0) = unknown, + fromSource(1) = from source, + fromSource(2) = from library +*/ +files( + unique int id: @file, + string name: string ref, + string simple: string ref, + string ext: string ref, + int fromSource: int ref); + +folders( + unique int id: @folder, + string name: string ref, + string simple: string ref); + +@container = @folder | @file ; + +containerparent( + int parent: @container ref, + unique int child: @container ref); + +file_extraction_mode( + unique int file: @file ref, + int mode: int ref + /* 0 = normal, 1 = standalone extractor */ + ); + +/** NAMESPACES **/ + +@type_container = @namespace | @type; + +namespaces( + unique int id: @namespace, + string name: string ref); + +namespace_declarations( + unique int id: @namespace_declaration, + int namespace_id: @namespace ref); + +namespace_declaration_location( + unique int id: @namespace_declaration ref, + int loc: @location ref); + +parent_namespace( + unique int child_id: @type_container ref, + int namespace_id: @namespace ref); + +@declaration_or_directive = @namespace_declaration | @type | @using_directive; + +parent_namespace_declaration( + int child_id: @declaration_or_directive ref, // cannot be unique because of partial classes + int namespace_id: @namespace_declaration ref); + +@using_directive = @using_namespace_directive | @using_static_directive; + +using_namespace_directives( + unique int id: @using_namespace_directive, + int namespace_id: @namespace ref); + +using_static_directives( + unique int id: @using_static_directive, + int type_id: @type_or_ref ref); + +using_directive_location( + unique int id: @using_directive ref, + int loc: @location ref); + +/** TYPES **/ + +types( + unique int id: @type, + int kind: int ref, + string name: string ref); + +case @type.kind of + 1 = @bool_type +| 2 = @char_type +| 3 = @decimal_type +| 4 = @sbyte_type +| 5 = @short_type +| 6 = @int_type +| 7 = @long_type +| 8 = @byte_type +| 9 = @ushort_type +| 10 = @uint_type +| 11 = @ulong_type +| 12 = @float_type +| 13 = @double_type +| 14 = @enum_type +| 15 = @struct_type +| 17 = @class_type +| 19 = @interface_type +| 20 = @delegate_type +| 21 = @null_type +| 22 = @type_parameter +| 23 = @pointer_type +| 24 = @nullable_type +| 25 = @array_type +| 26 = @void_type +| 27 = @int_ptr_type +| 28 = @uint_ptr_type +| 29 = @dynamic_type +| 30 = @arglist_type +| 31 = @unknown_type +| 32 = @tuple_type +| 33 = @function_pointer_type + ; + +@simple_type = @bool_type | @char_type | @integral_type | @floating_point_type | @decimal_type; +@integral_type = @signed_integral_type | @unsigned_integral_type; +@signed_integral_type = @sbyte_type | @short_type | @int_type | @long_type; +@unsigned_integral_type = @byte_type | @ushort_type | @uint_type | @ulong_type; +@floating_point_type = @float_type | @double_type; +@value_type = @simple_type | @enum_type | @struct_type | @nullable_type | @int_ptr_type + | @uint_ptr_type | @tuple_type; +@ref_type = @class_type | @interface_type | @array_type | @delegate_type | @null_type + | @dynamic_type; +@value_or_ref_type = @value_type | @ref_type; + +typerefs( + unique int id: @typeref, + string name: string ref); + +typeref_type( + int id: @typeref ref, + unique int typeId: @type ref); + +@type_or_ref = @type | @typeref; + +array_element_type( + unique int array: @array_type ref, + int dimension: int ref, + int rank: int ref, + int element: @type_or_ref ref); + +nullable_underlying_type( + unique int nullable: @nullable_type ref, + int underlying: @type_or_ref ref); + +pointer_referent_type( + unique int pointer: @pointer_type ref, + int referent: @type_or_ref ref); + +enum_underlying_type( + unique int enum_id: @enum_type ref, + int underlying_type_id: @type_or_ref ref); + +delegate_return_type( + unique int delegate_id: @delegate_type ref, + int return_type_id: @type_or_ref ref); + +function_pointer_return_type( + unique int function_pointer_id: @function_pointer_type ref, + int return_type_id: @type_or_ref ref); + +extend( + unique int sub: @type ref, + int super: @type_or_ref ref); + +anonymous_types( + unique int id: @type ref); + +@interface_or_ref = @interface_type | @typeref; + +implement( + int sub: @type ref, + int super: @type_or_ref ref); + +type_location( + int id: @type ref, + int loc: @location ref); + +tuple_underlying_type( + unique int tuple: @tuple_type ref, + int struct: @type_or_ref ref); + +#keyset[tuple, index] +tuple_element( + int tuple: @tuple_type ref, + int index: int ref, + unique int field: @field ref); + +attributes( + unique int id: @attribute, + int type_id: @type_or_ref ref, + int target: @attributable ref); + +attribute_location( + int id: @attribute ref, + int loc: @location ref); + +@type_mention_parent = @element | @type_mention; + +type_mention( + unique int id: @type_mention, + int type_id: @type_or_ref ref, + int parent: @type_mention_parent ref); + +type_mention_location( + unique int id: @type_mention ref, + int loc: @location ref); + +@has_type_annotation = @assignable | @type_parameter | @callable | @expr | @delegate_type | @generic | @function_pointer_type; + +/** + * A direct annotation on an entity, for example `string? x;`. + * + * Annotations: + * 2 = reftype is not annotated "!" + * 3 = reftype is annotated "?" + * 4 = readonly ref type / in parameter + * 5 = ref type parameter, return or local variable + * 6 = out parameter + * + * Note that the annotation depends on the element it annotates. + * @assignable: The annotation is on the type of the assignable, for example the variable type. + * @type_parameter: The annotation is on the reftype constraint + * @callable: The annotation is on the return type + * @array_type: The annotation is on the element type + */ +type_annotation(int id: @has_type_annotation ref, int annotation: int ref); + +nullability(unique int nullability: @nullability, int kind: int ref); + +case @nullability.kind of + 0 = @oblivious +| 1 = @not_annotated +| 2 = @annotated +; + +#keyset[parent, index] +nullability_parent(int nullability: @nullability ref, int index: int ref, int parent: @nullability ref) + +type_nullability(int id: @has_type_annotation ref, int nullability: @nullability ref); + +/** + * The nullable flow state of an expression, as determined by Roslyn. + * 0 = none (default, not populated) + * 1 = not null + * 2 = maybe null + */ +expr_flowstate(unique int id: @expr ref, int state: int ref); + +/** GENERICS **/ + +@generic = @type | @method | @local_function; + +type_parameters( + unique int id: @type_parameter ref, + int index: int ref, + int generic_id: @generic ref, + int variance: int ref /* none = 0, out = 1, in = 2 */); + +#keyset[constructed_id, index] +type_arguments( + int id: @type_or_ref ref, + int index: int ref, + int constructed_id: @generic_or_ref ref); + +@generic_or_ref = @generic | @typeref; + +constructed_generic( + unique int constructed: @generic ref, + int generic: @generic_or_ref ref); + +type_parameter_constraints( + unique int id: @type_parameter_constraints, + int param_id: @type_parameter ref); + +type_parameter_constraints_location( + int id: @type_parameter_constraints ref, + int loc: @location ref); + +general_type_parameter_constraints( + int id: @type_parameter_constraints ref, + int kind: int ref /* class = 1, struct = 2, new = 3 */); + +specific_type_parameter_constraints( + int id: @type_parameter_constraints ref, + int base_id: @type_or_ref ref); + +specific_type_parameter_nullability( + int id: @type_parameter_constraints ref, + int base_id: @type_or_ref ref, + int nullability: @nullability ref); + +/** FUNCTION POINTERS */ + +function_pointer_calling_conventions( + int id: @function_pointer_type ref, + int kind: int ref); + +#keyset[id, index] +has_unmanaged_calling_conventions( + int id: @function_pointer_type ref, + int index: int ref, + int conv_id: @type_or_ref ref); + +/** MODIFIERS */ + +@modifiable = @modifiable_direct | @event_accessor; + +@modifiable_direct = @member | @accessor | @local_function | @anonymous_function_expr; + +modifiers( + unique int id: @modifier, + string name: string ref); + +has_modifiers( + int id: @modifiable_direct ref, + int mod_id: @modifier ref); + +compiler_generated(unique int id: @modifiable_direct ref); + +/** MEMBERS **/ + +@member = @method | @constructor | @destructor | @field | @property | @event | @operator | @indexer | @type; + +@named_exprorstmt = @goto_stmt | @labeled_stmt | @expr; + +@virtualizable = @method | @property | @indexer | @event; + +exprorstmt_name( + unique int parent_id: @named_exprorstmt ref, + string name: string ref); + +nested_types( + unique int id: @type ref, + int declaring_type_id: @type ref, + int unbound_id: @type ref); + +properties( + unique int id: @property, + string name: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @property ref); + +property_location( + int id: @property ref, + int loc: @location ref); + +indexers( + unique int id: @indexer, + string name: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @indexer ref); + +indexer_location( + int id: @indexer ref, + int loc: @location ref); + +accessors( + unique int id: @accessor, + int kind: int ref, + string name: string ref, + int declaring_member_id: @member ref, + int unbound_id: @accessor ref); + +case @accessor.kind of + 1 = @getter +| 2 = @setter + ; + +init_only_accessors( + unique int id: @accessor ref); + +accessor_location( + int id: @accessor ref, + int loc: @location ref); + +events( + unique int id: @event, + string name: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @event ref); + +event_location( + int id: @event ref, + int loc: @location ref); + +event_accessors( + unique int id: @event_accessor, + int kind: int ref, + string name: string ref, + int declaring_event_id: @event ref, + int unbound_id: @event_accessor ref); + +case @event_accessor.kind of + 1 = @add_event_accessor +| 2 = @remove_event_accessor + ; + +event_accessor_location( + int id: @event_accessor ref, + int loc: @location ref); + +operators( + unique int id: @operator, + string name: string ref, + string symbol: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @operator ref); + +operator_location( + int id: @operator ref, + int loc: @location ref); + +constant_value( + int id: @variable ref, + string value: string ref); + +/** CALLABLES **/ + +@callable = @method | @constructor | @destructor | @operator | @callable_accessor | @anonymous_function_expr | @local_function; + +@callable_accessor = @accessor | @event_accessor; + +methods( + unique int id: @method, + string name: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @method ref); + +method_location( + int id: @method ref, + int loc: @location ref); + +constructors( + unique int id: @constructor, + string name: string ref, + int declaring_type_id: @type ref, + int unbound_id: @constructor ref); + +constructor_location( + int id: @constructor ref, + int loc: @location ref); + +destructors( + unique int id: @destructor, + string name: string ref, + int declaring_type_id: @type ref, + int unbound_id: @destructor ref); + +destructor_location( + int id: @destructor ref, + int loc: @location ref); + +overrides( + int id: @callable ref, + int base_id: @callable ref); + +explicitly_implements( + int id: @member ref, + int interface_id: @interface_or_ref ref); + +local_functions( + unique int id: @local_function, + string name: string ref, + int return_type: @type ref, + int unbound_id: @local_function ref); + +local_function_stmts( + unique int fn: @local_function_stmt ref, + int stmt: @local_function ref); + +/** VARIABLES **/ + +@variable = @local_scope_variable | @field; + +@local_scope_variable = @local_variable | @parameter; + +fields( + unique int id: @field, + int kind: int ref, + string name: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @field ref); + +case @field.kind of + 1 = @addressable_field +| 2 = @constant + ; + +field_location( + int id: @field ref, + int loc: @location ref); + +localvars( + unique int id: @local_variable, + int kind: int ref, + string name: string ref, + int implicitly_typed: int ref /* 0 = no, 1 = yes */, + int type_id: @type_or_ref ref, + int parent_id: @local_var_decl_expr ref); + +case @local_variable.kind of + 1 = @addressable_local_variable +| 2 = @local_constant +| 3 = @local_variable_ref + ; + +localvar_location( + unique int id: @local_variable ref, + int loc: @location ref); + +@parameterizable = @callable | @delegate_type | @indexer | @function_pointer_type; + +#keyset[name, parent_id] +#keyset[index, parent_id] +params( + unique int id: @parameter, + string name: string ref, + int type_id: @type_or_ref ref, + int index: int ref, + int mode: int ref, /* value = 0, ref = 1, out = 2, array = 3, this = 4 */ + int parent_id: @parameterizable ref, + int unbound_id: @parameter ref); + +param_location( + int id: @parameter ref, + int loc: @location ref); + +/** STATEMENTS **/ + +@exprorstmt_parent = @control_flow_element | @top_level_exprorstmt_parent; + +statements( + unique int id: @stmt, + int kind: int ref); + +#keyset[index, parent] +stmt_parent( + unique int stmt: @stmt ref, + int index: int ref, + int parent: @control_flow_element ref); + +@top_level_stmt_parent = @callable; + +// [index, parent] is not a keyset because the same parent may be compiled multiple times +stmt_parent_top_level( + unique int stmt: @stmt ref, + int index: int ref, + int parent: @top_level_stmt_parent ref); + +case @stmt.kind of + 1 = @block_stmt +| 2 = @expr_stmt +| 3 = @if_stmt +| 4 = @switch_stmt +| 5 = @while_stmt +| 6 = @do_stmt +| 7 = @for_stmt +| 8 = @foreach_stmt +| 9 = @break_stmt +| 10 = @continue_stmt +| 11 = @goto_stmt +| 12 = @goto_case_stmt +| 13 = @goto_default_stmt +| 14 = @throw_stmt +| 15 = @return_stmt +| 16 = @yield_stmt +| 17 = @try_stmt +| 18 = @checked_stmt +| 19 = @unchecked_stmt +| 20 = @lock_stmt +| 21 = @using_block_stmt +| 22 = @var_decl_stmt +| 23 = @const_decl_stmt +| 24 = @empty_stmt +| 25 = @unsafe_stmt +| 26 = @fixed_stmt +| 27 = @label_stmt +| 28 = @catch +| 29 = @case_stmt +| 30 = @local_function_stmt +| 31 = @using_decl_stmt + ; + +@using_stmt = @using_block_stmt | @using_decl_stmt; + +@labeled_stmt = @label_stmt | @case; + +@decl_stmt = @var_decl_stmt | @const_decl_stmt | @using_decl_stmt; + +@cond_stmt = @if_stmt | @switch_stmt; + +@loop_stmt = @while_stmt | @do_stmt | @for_stmt | @foreach_stmt; + +@jump_stmt = @break_stmt | @goto_any_stmt | @continue_stmt | @throw_stmt | @return_stmt + | @yield_stmt; + +@goto_any_stmt = @goto_default_stmt | @goto_case_stmt | @goto_stmt; + + +stmt_location( + unique int id: @stmt ref, + int loc: @location ref); + +catch_type( + unique int catch_id: @catch ref, + int type_id: @type_or_ref ref, + int kind: int ref /* explicit = 1, implicit = 2 */); + +/** EXPRESSIONS **/ + +expressions( + unique int id: @expr, + int kind: int ref, + int type_id: @type_or_ref ref); + +#keyset[index, parent] +expr_parent( + unique int expr: @expr ref, + int index: int ref, + int parent: @control_flow_element ref); + +@top_level_expr_parent = @attribute | @field | @property | @indexer | @parameter; + +@top_level_exprorstmt_parent = @top_level_expr_parent | @top_level_stmt_parent; + +// [index, parent] is not a keyset because the same parent may be compiled multiple times +expr_parent_top_level( + unique int expr: @expr ref, + int index: int ref, + int parent: @top_level_exprorstmt_parent ref); + +case @expr.kind of +/* literal */ + 1 = @bool_literal_expr +| 2 = @char_literal_expr +| 3 = @decimal_literal_expr +| 4 = @int_literal_expr +| 5 = @long_literal_expr +| 6 = @uint_literal_expr +| 7 = @ulong_literal_expr +| 8 = @float_literal_expr +| 9 = @double_literal_expr +| 10 = @string_literal_expr +| 11 = @null_literal_expr +/* primary & unary */ +| 12 = @this_access_expr +| 13 = @base_access_expr +| 14 = @local_variable_access_expr +| 15 = @parameter_access_expr +| 16 = @field_access_expr +| 17 = @property_access_expr +| 18 = @method_access_expr +| 19 = @event_access_expr +| 20 = @indexer_access_expr +| 21 = @array_access_expr +| 22 = @type_access_expr +| 23 = @typeof_expr +| 24 = @method_invocation_expr +| 25 = @delegate_invocation_expr +| 26 = @operator_invocation_expr +| 27 = @cast_expr +| 28 = @object_creation_expr +| 29 = @explicit_delegate_creation_expr +| 30 = @implicit_delegate_creation_expr +| 31 = @array_creation_expr +| 32 = @default_expr +| 33 = @plus_expr +| 34 = @minus_expr +| 35 = @bit_not_expr +| 36 = @log_not_expr +| 37 = @post_incr_expr +| 38 = @post_decr_expr +| 39 = @pre_incr_expr +| 40 = @pre_decr_expr +/* multiplicative */ +| 41 = @mul_expr +| 42 = @div_expr +| 43 = @rem_expr +/* additive */ +| 44 = @add_expr +| 45 = @sub_expr +/* shift */ +| 46 = @lshift_expr +| 47 = @rshift_expr +/* relational */ +| 48 = @lt_expr +| 49 = @gt_expr +| 50 = @le_expr +| 51 = @ge_expr +/* equality */ +| 52 = @eq_expr +| 53 = @ne_expr +/* logical */ +| 54 = @bit_and_expr +| 55 = @bit_xor_expr +| 56 = @bit_or_expr +| 57 = @log_and_expr +| 58 = @log_or_expr +/* type testing */ +| 59 = @is_expr +| 60 = @as_expr +/* null coalescing */ +| 61 = @null_coalescing_expr +/* conditional */ +| 62 = @conditional_expr +/* assignment */ +| 63 = @simple_assign_expr +| 64 = @assign_add_expr +| 65 = @assign_sub_expr +| 66 = @assign_mul_expr +| 67 = @assign_div_expr +| 68 = @assign_rem_expr +| 69 = @assign_and_expr +| 70 = @assign_xor_expr +| 71 = @assign_or_expr +| 72 = @assign_lshift_expr +| 73 = @assign_rshift_expr +/* more */ +| 74 = @object_init_expr +| 75 = @collection_init_expr +| 76 = @array_init_expr +| 77 = @checked_expr +| 78 = @unchecked_expr +| 79 = @constructor_init_expr +| 80 = @add_event_expr +| 81 = @remove_event_expr +| 82 = @par_expr +| 83 = @local_var_decl_expr +| 84 = @lambda_expr +| 85 = @anonymous_method_expr +| 86 = @namespace_expr +/* dynamic */ +| 92 = @dynamic_element_access_expr +| 93 = @dynamic_member_access_expr +/* unsafe */ +| 100 = @pointer_indirection_expr +| 101 = @address_of_expr +| 102 = @sizeof_expr +/* async */ +| 103 = @await_expr +/* C# 6.0 */ +| 104 = @nameof_expr +| 105 = @interpolated_string_expr +| 106 = @unknown_expr +/* C# 7.0 */ +| 107 = @throw_expr +| 108 = @tuple_expr +| 109 = @local_function_invocation_expr +| 110 = @ref_expr +| 111 = @discard_expr +/* C# 8.0 */ +| 112 = @range_expr +| 113 = @index_expr +| 114 = @switch_expr +| 115 = @recursive_pattern_expr +| 116 = @property_pattern_expr +| 117 = @positional_pattern_expr +| 118 = @switch_case_expr +| 119 = @assign_coalesce_expr +| 120 = @suppress_nullable_warning_expr +| 121 = @namespace_access_expr +/* C# 9.0 */ +| 122 = @lt_pattern_expr +| 123 = @gt_pattern_expr +| 124 = @le_pattern_expr +| 125 = @ge_pattern_expr +| 126 = @not_pattern_expr +| 127 = @and_pattern_expr +| 128 = @or_pattern_expr +| 129 = @function_pointer_invocation_expr +; + +@switch = @switch_stmt | @switch_expr; +@case = @case_stmt | @switch_case_expr; +@pattern_match = @case | @is_expr; +@unary_pattern_expr = @not_pattern_expr; +@relational_pattern_expr = @gt_pattern_expr | @lt_pattern_expr | @ge_pattern_expr | @le_pattern_expr; +@binary_pattern_expr = @and_pattern_expr | @or_pattern_expr; + +@integer_literal_expr = @int_literal_expr | @long_literal_expr | @uint_literal_expr | @ulong_literal_expr; +@real_literal_expr = @float_literal_expr | @double_literal_expr | @decimal_literal_expr; +@literal_expr = @bool_literal_expr | @char_literal_expr | @integer_literal_expr | @real_literal_expr + | @string_literal_expr | @null_literal_expr; + +@assign_expr = @simple_assign_expr | @assign_op_expr | @local_var_decl_expr; +@assign_op_expr = @assign_arith_expr | @assign_bitwise_expr | @assign_event_expr | @assign_coalesce_expr; +@assign_event_expr = @add_event_expr | @remove_event_expr; + +@assign_arith_expr = @assign_add_expr | @assign_sub_expr | @assign_mul_expr | @assign_div_expr + | @assign_rem_expr +@assign_bitwise_expr = @assign_and_expr | @assign_or_expr | @assign_xor_expr + | @assign_lshift_expr | @assign_rshift_expr; + +@member_access_expr = @field_access_expr | @property_access_expr | @indexer_access_expr | @event_access_expr + | @method_access_expr | @type_access_expr | @dynamic_member_access_expr; +@access_expr = @member_access_expr | @this_access_expr | @base_access_expr | @assignable_access_expr | @namespace_access_expr; +@element_access_expr = @indexer_access_expr | @array_access_expr | @dynamic_element_access_expr; + +@local_variable_access = @local_variable_access_expr | @local_var_decl_expr; +@local_scope_variable_access_expr = @parameter_access_expr | @local_variable_access; +@variable_access_expr = @local_scope_variable_access_expr | @field_access_expr; + +@assignable_access_expr = @variable_access_expr | @property_access_expr | @element_access_expr + | @event_access_expr | @dynamic_member_access_expr; + +@objectorcollection_init_expr = @object_init_expr | @collection_init_expr; + +@delegate_creation_expr = @explicit_delegate_creation_expr | @implicit_delegate_creation_expr; + +@bin_arith_op_expr = @mul_expr | @div_expr | @rem_expr | @add_expr | @sub_expr; +@incr_op_expr = @pre_incr_expr | @post_incr_expr; +@decr_op_expr = @pre_decr_expr | @post_decr_expr; +@mut_op_expr = @incr_op_expr | @decr_op_expr; +@un_arith_op_expr = @plus_expr | @minus_expr | @mut_op_expr; +@arith_op_expr = @bin_arith_op_expr | @un_arith_op_expr; + +@ternary_log_op_expr = @conditional_expr; +@bin_log_op_expr = @log_and_expr | @log_or_expr | @null_coalescing_expr; +@un_log_op_expr = @log_not_expr; +@log_expr = @un_log_op_expr | @bin_log_op_expr | @ternary_log_op_expr; + +@bin_bit_op_expr = @bit_and_expr | @bit_or_expr | @bit_xor_expr | @lshift_expr + | @rshift_expr; +@un_bit_op_expr = @bit_not_expr; +@bit_expr = @un_bit_op_expr | @bin_bit_op_expr; + +@equality_op_expr = @eq_expr | @ne_expr; +@rel_op_expr = @gt_expr | @lt_expr| @ge_expr | @le_expr; +@comp_expr = @equality_op_expr | @rel_op_expr; + +@op_expr = @assign_expr | @un_op | @bin_op | @ternary_op; + +@ternary_op = @ternary_log_op_expr; +@bin_op = @bin_arith_op_expr | @bin_log_op_expr | @bin_bit_op_expr | @comp_expr; +@un_op = @un_arith_op_expr | @un_log_op_expr | @un_bit_op_expr | @sizeof_expr + | @pointer_indirection_expr | @address_of_expr; + +@anonymous_function_expr = @lambda_expr | @anonymous_method_expr; + +@call = @method_invocation_expr | @constructor_init_expr | @operator_invocation_expr + | @delegate_invocation_expr | @object_creation_expr | @call_access_expr + | @local_function_invocation_expr | @function_pointer_invocation_expr; + +@call_access_expr = @property_access_expr | @event_access_expr | @indexer_access_expr; + +@late_bindable_expr = @dynamic_element_access_expr | @dynamic_member_access_expr + | @object_creation_expr | @method_invocation_expr | @operator_invocation_expr; + +@throw_element = @throw_expr | @throw_stmt; + +@implicitly_typeable_object_creation_expr = @object_creation_expr | @explicit_delegate_creation_expr; + +implicitly_typed_array_creation( + unique int id: @array_creation_expr ref); + +explicitly_sized_array_creation( + unique int id: @array_creation_expr ref); + +stackalloc_array_creation( + unique int id: @array_creation_expr ref); + +implicitly_typed_object_creation( + unique int id: @implicitly_typeable_object_creation_expr ref); + +mutator_invocation_mode( + unique int id: @operator_invocation_expr ref, + int mode: int ref /* prefix = 1, postfix = 2*/); + +expr_compiler_generated( + unique int id: @expr ref); + +expr_value( + unique int id: @expr ref, + string value: string ref); + +expr_call( + unique int caller_id: @expr ref, + int target_id: @callable ref); + +expr_access( + unique int accesser_id: @access_expr ref, + int target_id: @accessible ref); + +@accessible = @method | @assignable | @local_function | @namespace; + +expr_location( + unique int id: @expr ref, + int loc: @location ref); + +dynamic_member_name( + unique int id: @late_bindable_expr ref, + string name: string ref); + +@qualifiable_expr = @member_access_expr + | @method_invocation_expr + | @element_access_expr; + +conditional_access( + unique int id: @qualifiable_expr ref); + +expr_argument( + unique int id: @expr ref, + int mode: int ref); + /* mode is the same as params: value = 0, ref = 1, out = 2 */ + +expr_argument_name( + unique int id: @expr ref, + string name: string ref); + +/** CONTROL/DATA FLOW **/ + +@control_flow_element = @stmt | @expr; + +/* XML Files */ + +xmlEncoding ( + unique int id: @file ref, + string encoding: string ref); + +xmlDTDs( + unique int id: @xmldtd, + string root: string ref, + string publicId: string ref, + string systemId: string ref, + int fileid: @file ref); + +xmlElements( + unique int id: @xmlelement, + string name: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int fileid: @file ref); + +xmlAttrs( + unique int id: @xmlattribute, + int elementid: @xmlelement ref, + string name: string ref, + string value: string ref, + int idx: int ref, + int fileid: @file ref); + +xmlNs( + int id: @xmlnamespace, + string prefixName: string ref, + string URI: string ref, + int fileid: @file ref); + +xmlHasNs( + int elementId: @xmlnamespaceable ref, + int nsId: @xmlnamespace ref, + int fileid: @file ref); + +xmlComments( + unique int id: @xmlcomment, + string text: string ref, + int parentid: @xmlparent ref, + int fileid: @file ref); + +xmlChars( + unique int id: @xmlcharacters, + string text: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int isCDATA: int ref, + int fileid: @file ref); + +@xmlparent = @file | @xmlelement; +@xmlnamespaceable = @xmlelement | @xmlattribute; + +xmllocations( + int xmlElement: @xmllocatable ref, + int location: @location_default ref); + +@xmllocatable = @xmlcharacters | @xmlelement | @xmlcomment | @xmlattribute | @xmldtd | @file | @xmlnamespace; + +/* Comments */ + +commentline( + unique int id: @commentline, + int kind: int ref, + string text: string ref, + string rawtext: string ref); + +case @commentline.kind of + 0 = @singlelinecomment +| 1 = @xmldoccomment +| 2 = @multilinecomment; + +commentline_location( + unique int id: @commentline ref, + int loc: @location ref); + +commentblock( + unique int id : @commentblock); + +commentblock_location( + unique int id: @commentblock ref, + int loc: @location ref); + +commentblock_binding( + int id: @commentblock ref, + int entity: @element ref, + int bindtype: int ref); /* 0: Parent, 1: Best, 2: Before, 3: After */ + +commentblock_child( + int id: @commentblock ref, + int commentline: @commentline ref, + int index: int ref); + +/* ASP.NET */ + +case @asp_element.kind of + 0=@asp_close_tag +| 1=@asp_code +| 2=@asp_comment +| 3=@asp_data_binding +| 4=@asp_directive +| 5=@asp_open_tag +| 6=@asp_quoted_string +| 7=@asp_text +| 8=@asp_xml_directive; + +@asp_attribute = @asp_code | @asp_data_binding | @asp_quoted_string; + +asp_elements( + unique int id: @asp_element, + int kind: int ref, + int loc: @location ref); + +asp_comment_server(unique int comment: @asp_comment ref); +asp_code_inline(unique int code: @asp_code ref); +asp_directive_attribute( + int directive: @asp_directive ref, + int index: int ref, + string name: string ref, + int value: @asp_quoted_string ref); +asp_directive_name( + unique int directive: @asp_directive ref, + string name: string ref); +asp_element_body( + unique int element: @asp_element ref, + string body: string ref); +asp_tag_attribute( + int tag: @asp_open_tag ref, + int index: int ref, + string name: string ref, + int attribute: @asp_attribute ref); +asp_tag_name( + unique int tag: @asp_open_tag ref, + string name: string ref); +asp_tag_isempty(int tag: @asp_open_tag ref); + +/* Common Intermediate Language - CIL */ + +case @cil_instruction.opcode of + 0 = @cil_nop +| 1 = @cil_break +| 2 = @cil_ldarg_0 +| 3 = @cil_ldarg_1 +| 4 = @cil_ldarg_2 +| 5 = @cil_ldarg_3 +| 6 = @cil_ldloc_0 +| 7 = @cil_ldloc_1 +| 8 = @cil_ldloc_2 +| 9 = @cil_ldloc_3 +| 10 = @cil_stloc_0 +| 11 = @cil_stloc_1 +| 12 = @cil_stloc_2 +| 13 = @cil_stloc_3 +| 14 = @cil_ldarg_s +| 15 = @cil_ldarga_s +| 16 = @cil_starg_s +| 17 = @cil_ldloc_s +| 18 = @cil_ldloca_s +| 19 = @cil_stloc_s +| 20 = @cil_ldnull +| 21 = @cil_ldc_i4_m1 +| 22 = @cil_ldc_i4_0 +| 23 = @cil_ldc_i4_1 +| 24 = @cil_ldc_i4_2 +| 25 = @cil_ldc_i4_3 +| 26 = @cil_ldc_i4_4 +| 27 = @cil_ldc_i4_5 +| 28 = @cil_ldc_i4_6 +| 29 = @cil_ldc_i4_7 +| 30 = @cil_ldc_i4_8 +| 31 = @cil_ldc_i4_s +| 32 = @cil_ldc_i4 +| 33 = @cil_ldc_i8 +| 34 = @cil_ldc_r4 +| 35 = @cil_ldc_r8 +| 37 = @cil_dup +| 38 = @cil_pop +| 39 = @cil_jmp +| 40 = @cil_call +| 41 = @cil_calli +| 42 = @cil_ret +| 43 = @cil_br_s +| 44 = @cil_brfalse_s +| 45 = @cil_brtrue_s +| 46 = @cil_beq_s +| 47 = @cil_bge_s +| 48 = @cil_bgt_s +| 49 = @cil_ble_s +| 50 = @cil_blt_s +| 51 = @cil_bne_un_s +| 52 = @cil_bge_un_s +| 53 = @cil_bgt_un_s +| 54 = @cil_ble_un_s +| 55 = @cil_blt_un_s +| 56 = @cil_br +| 57 = @cil_brfalse +| 58 = @cil_brtrue +| 59 = @cil_beq +| 60 = @cil_bge +| 61 = @cil_bgt +| 62 = @cil_ble +| 63 = @cil_blt +| 64 = @cil_bne_un +| 65 = @cil_bge_un +| 66 = @cil_bgt_un +| 67 = @cil_ble_un +| 68 = @cil_blt_un +| 69 = @cil_switch +| 70 = @cil_ldind_i1 +| 71 = @cil_ldind_u1 +| 72 = @cil_ldind_i2 +| 73 = @cil_ldind_u2 +| 74 = @cil_ldind_i4 +| 75 = @cil_ldind_u4 +| 76 = @cil_ldind_i8 +| 77 = @cil_ldind_i +| 78 = @cil_ldind_r4 +| 79 = @cil_ldind_r8 +| 80 = @cil_ldind_ref +| 81 = @cil_stind_ref +| 82 = @cil_stind_i1 +| 83 = @cil_stind_i2 +| 84 = @cil_stind_i4 +| 85 = @cil_stind_i8 +| 86 = @cil_stind_r4 +| 87 = @cil_stind_r8 +| 88 = @cil_add +| 89 = @cil_sub +| 90 = @cil_mul +| 91 = @cil_div +| 92 = @cil_div_un +| 93 = @cil_rem +| 94 = @cil_rem_un +| 95 = @cil_and +| 96 = @cil_or +| 97 = @cil_xor +| 98 = @cil_shl +| 99 = @cil_shr +| 100 = @cil_shr_un +| 101 = @cil_neg +| 102 = @cil_not +| 103 = @cil_conv_i1 +| 104 = @cil_conv_i2 +| 105 = @cil_conv_i4 +| 106 = @cil_conv_i8 +| 107 = @cil_conv_r4 +| 108 = @cil_conv_r8 +| 109 = @cil_conv_u4 +| 110 = @cil_conv_u8 +| 111 = @cil_callvirt +| 112 = @cil_cpobj +| 113 = @cil_ldobj +| 114 = @cil_ldstr +| 115 = @cil_newobj +| 116 = @cil_castclass +| 117 = @cil_isinst +| 118 = @cil_conv_r_un +| 121 = @cil_unbox +| 122 = @cil_throw +| 123 = @cil_ldfld +| 124 = @cil_ldflda +| 125 = @cil_stfld +| 126 = @cil_ldsfld +| 127 = @cil_ldsflda +| 128 = @cil_stsfld +| 129 = @cil_stobj +| 130 = @cil_conv_ovf_i1_un +| 131 = @cil_conv_ovf_i2_un +| 132 = @cil_conv_ovf_i4_un +| 133 = @cil_conv_ovf_i8_un +| 134 = @cil_conv_ovf_u1_un +| 135 = @cil_conv_ovf_u2_un +| 136 = @cil_conv_ovf_u4_un +| 137 = @cil_conv_ovf_u8_un +| 138 = @cil_conv_ovf_i_un +| 139 = @cil_conv_ovf_u_un +| 140 = @cil_box +| 141 = @cil_newarr +| 142 = @cil_ldlen +| 143 = @cil_ldelema +| 144 = @cil_ldelem_i1 +| 145 = @cil_ldelem_u1 +| 146 = @cil_ldelem_i2 +| 147 = @cil_ldelem_u2 +| 148 = @cil_ldelem_i4 +| 149 = @cil_ldelem_u4 +| 150 = @cil_ldelem_i8 +| 151 = @cil_ldelem_i +| 152 = @cil_ldelem_r4 +| 153 = @cil_ldelem_r8 +| 154 = @cil_ldelem_ref +| 155 = @cil_stelem_i +| 156 = @cil_stelem_i1 +| 157 = @cil_stelem_i2 +| 158 = @cil_stelem_i4 +| 159 = @cil_stelem_i8 +| 160 = @cil_stelem_r4 +| 161 = @cil_stelem_r8 +| 162 = @cil_stelem_ref +| 163 = @cil_ldelem +| 164 = @cil_stelem +| 165 = @cil_unbox_any +| 179 = @cil_conv_ovf_i1 +| 180 = @cil_conv_ovf_u1 +| 181 = @cil_conv_ovf_i2 +| 182 = @cil_conv_ovf_u2 +| 183 = @cil_conv_ovf_i4 +| 184 = @cil_conv_ovf_u4 +| 185 = @cil_conv_ovf_i8 +| 186 = @cil_conv_ovf_u8 +| 194 = @cil_refanyval +| 195 = @cil_ckinfinite +| 198 = @cil_mkrefany +| 208 = @cil_ldtoken +| 209 = @cil_conv_u2 +| 210 = @cil_conv_u1 +| 211 = @cil_conv_i +| 212 = @cil_conv_ovf_i +| 213 = @cil_conv_ovf_u +| 214 = @cil_add_ovf +| 215 = @cil_add_ovf_un +| 216 = @cil_mul_ovf +| 217 = @cil_mul_ovf_un +| 218 = @cil_sub_ovf +| 219 = @cil_sub_ovf_un +| 220 = @cil_endfinally +| 221 = @cil_leave +| 222 = @cil_leave_s +| 223 = @cil_stind_i +| 224 = @cil_conv_u +| 65024 = @cil_arglist +| 65025 = @cil_ceq +| 65026 = @cil_cgt +| 65027 = @cil_cgt_un +| 65028 = @cil_clt +| 65029 = @cil_clt_un +| 65030 = @cil_ldftn +| 65031 = @cil_ldvirtftn +| 65033 = @cil_ldarg +| 65034 = @cil_ldarga +| 65035 = @cil_starg +| 65036 = @cil_ldloc +| 65037 = @cil_ldloca +| 65038 = @cil_stloc +| 65039 = @cil_localloc +| 65041 = @cil_endfilter +| 65042 = @cil_unaligned +| 65043 = @cil_volatile +| 65044 = @cil_tail +| 65045 = @cil_initobj +| 65046 = @cil_constrained +| 65047 = @cil_cpblk +| 65048 = @cil_initblk +| 65050 = @cil_rethrow +| 65052 = @cil_sizeof +| 65053 = @cil_refanytype +| 65054 = @cil_readonly +; + +// CIL ignored instructions + +@cil_ignore = @cil_nop | @cil_break | @cil_volatile | @cil_unaligned; + +// CIL local/parameter/field access + +@cil_ldarg_any = @cil_ldarg_0 | @cil_ldarg_1 | @cil_ldarg_2 | @cil_ldarg_3 | @cil_ldarg_s | @cil_ldarga_s | @cil_ldarg | @cil_ldarga; +@cil_starg_any = @cil_starg | @cil_starg_s; + +@cil_ldloc_any = @cil_ldloc_0 | @cil_ldloc_1 | @cil_ldloc_2 | @cil_ldloc_3 | @cil_ldloc_s | @cil_ldloca_s | @cil_ldloc | @cil_ldloca; +@cil_stloc_any = @cil_stloc_0 | @cil_stloc_1 | @cil_stloc_2 | @cil_stloc_3 | @cil_stloc_s | @cil_stloc; + +@cil_ldfld_any = @cil_ldfld | @cil_ldsfld | @cil_ldsflda | @cil_ldflda; +@cil_stfld_any = @cil_stfld | @cil_stsfld; + +@cil_local_access = @cil_stloc_any | @cil_ldloc_any; +@cil_arg_access = @cil_starg_any | @cil_ldarg_any; +@cil_read_access = @cil_ldloc_any | @cil_ldarg_any | @cil_ldfld_any; +@cil_write_access = @cil_stloc_any | @cil_starg_any | @cil_stfld_any; + +@cil_stack_access = @cil_local_access | @cil_arg_access; +@cil_field_access = @cil_ldfld_any | @cil_stfld_any; + +@cil_access = @cil_read_access | @cil_write_access; + +// CIL constant/literal instructions + +@cil_ldc_i = @cil_ldc_i4_any | @cil_ldc_i8; + +@cil_ldc_i4_any = @cil_ldc_i4_m1 | @cil_ldc_i4_0 | @cil_ldc_i4_1 | @cil_ldc_i4_2 | @cil_ldc_i4_3 | + @cil_ldc_i4_4 | @cil_ldc_i4_5 | @cil_ldc_i4_6 | @cil_ldc_i4_7 | @cil_ldc_i4_8 | @cil_ldc_i4_s | @cil_ldc_i4; + +@cil_ldc_r = @cil_ldc_r4 | @cil_ldc_r8; + +@cil_literal = @cil_ldnull | @cil_ldc_i | @cil_ldc_r | @cil_ldstr; + +// Control flow + +@cil_conditional_jump = @cil_binary_jump | @cil_unary_jump; +@cil_binary_jump = @cil_beq_s | @cil_bge_s | @cil_bgt_s | @cil_ble_s | @cil_blt_s | + @cil_bne_un_s | @cil_bge_un_s | @cil_bgt_un_s | @cil_ble_un_s | @cil_blt_un_s | + @cil_beq | @cil_bge | @cil_bgt | @cil_ble | @cil_blt | + @cil_bne_un | @cil_bge_un | @cil_bgt_un | @cil_ble_un | @cil_blt_un; +@cil_unary_jump = @cil_brfalse_s | @cil_brtrue_s | @cil_brfalse | @cil_brtrue | @cil_switch; +@cil_unconditional_jump = @cil_br | @cil_br_s | @cil_leave_any; +@cil_leave_any = @cil_leave | @cil_leave_s; +@cil_jump = @cil_unconditional_jump | @cil_conditional_jump; + +// CIL call instructions + +@cil_call_any = @cil_jmp | @cil_call | @cil_calli | @cil_tail | @cil_callvirt | @cil_newobj; + +// CIL expression instructions + +@cil_expr = @cil_literal | @cil_binary_expr | @cil_unary_expr | @cil_call_any | @cil_read_access | + @cil_newarr | @cil_ldtoken | @cil_sizeof | + @cil_ldftn | @cil_ldvirtftn | @cil_localloc | @cil_mkrefany | @cil_refanytype | @cil_arglist | @cil_dup; + +@cil_unary_expr = + @cil_conversion_operation | @cil_unary_arithmetic_operation | @cil_unary_bitwise_operation| + @cil_ldlen | @cil_isinst | @cil_box | @cil_ldobj | @cil_castclass | @cil_unbox_any | + @cil_ldind | @cil_unbox; + +@cil_conversion_operation = + @cil_conv_i1 | @cil_conv_i2 | @cil_conv_i4 | @cil_conv_i8 | + @cil_conv_u1 | @cil_conv_u2 | @cil_conv_u4 | @cil_conv_u8 | + @cil_conv_ovf_i | @cil_conv_ovf_i_un | @cil_conv_ovf_i1 | @cil_conv_ovf_i1_un | + @cil_conv_ovf_i2 | @cil_conv_ovf_i2_un | @cil_conv_ovf_i4 | @cil_conv_ovf_i4_un | + @cil_conv_ovf_i8 | @cil_conv_ovf_i8_un | @cil_conv_ovf_u | @cil_conv_ovf_u_un | + @cil_conv_ovf_u1 | @cil_conv_ovf_u1_un | @cil_conv_ovf_u2 | @cil_conv_ovf_u2_un | + @cil_conv_ovf_u4 | @cil_conv_ovf_u4_un | @cil_conv_ovf_u8 | @cil_conv_ovf_u8_un | + @cil_conv_r4 | @cil_conv_r8 | @cil_conv_ovf_u2 | @cil_conv_ovf_u2_un | + @cil_conv_i | @cil_conv_u | @cil_conv_r_un; + +@cil_ldind = @cil_ldind_i | @cil_ldind_i1 | @cil_ldind_i2 | @cil_ldind_i4 | @cil_ldind_i8 | + @cil_ldind_r4 | @cil_ldind_r8 | @cil_ldind_ref | @cil_ldind_u1 | @cil_ldind_u2 | @cil_ldind_u4; + +@cil_stind = @cil_stind_i | @cil_stind_i1 | @cil_stind_i2 | @cil_stind_i4 | @cil_stind_i8 | + @cil_stind_r4 | @cil_stind_r8 | @cil_stind_ref; + +@cil_bitwise_operation = @cil_binary_bitwise_operation | @cil_unary_bitwise_operation; + +@cil_binary_bitwise_operation = @cil_and | @cil_or | @cil_xor | @cil_shr | @cil_shr | @cil_shr_un | @cil_shl; + +@cil_binary_arithmetic_operation = @cil_add | @cil_sub | @cil_mul | @cil_div | @cil_div_un | + @cil_rem | @cil_rem_un | @cil_add_ovf | @cil_add_ovf_un | @cil_mul_ovf | @cil_mul_ovf_un | + @cil_sub_ovf | @cil_sub_ovf_un; + +@cil_unary_bitwise_operation = @cil_not; + +@cil_binary_expr = @cil_binary_arithmetic_operation | @cil_binary_bitwise_operation | @cil_read_array | @cil_comparison_operation; + +@cil_unary_arithmetic_operation = @cil_neg; + +@cil_comparison_operation = @cil_cgt_un | @cil_ceq | @cil_cgt | @cil_clt | @cil_clt_un; + +// Elements that retrieve an address of something +@cil_read_ref = @cil_ldloca_s | @cil_ldarga_s | @cil_ldflda | @cil_ldsflda | @cil_ldelema; + +// CIL array instructions + +@cil_read_array = + @cil_ldelem | @cil_ldelema | @cil_ldelem_i1 | @cil_ldelem_ref | @cil_ldelem_i | + @cil_ldelem_i1 | @cil_ldelem_i2 | @cil_ldelem_i4 | @cil_ldelem_i8 | @cil_ldelem_r4 | + @cil_ldelem_r8 | @cil_ldelem_u1 | @cil_ldelem_u2 | @cil_ldelem_u4; + +@cil_write_array = @cil_stelem | @cil_stelem_ref | + @cil_stelem_i | @cil_stelem_i1 | @cil_stelem_i2 | @cil_stelem_i4 | @cil_stelem_i8 | + @cil_stelem_r4 | @cil_stelem_r8; + +@cil_throw_any = @cil_throw | @cil_rethrow; + +#keyset[impl, index] +cil_instruction( + unique int id: @cil_instruction, + int opcode: int ref, + int index: int ref, + int impl: @cil_method_implementation ref); + +cil_jump( + unique int instruction: @cil_jump ref, + int target: @cil_instruction ref); + +cil_access( + unique int instruction: @cil_instruction ref, + int target: @cil_accessible ref); + +cil_value( + unique int instruction: @cil_literal ref, + string value: string ref); + +#keyset[instruction, index] +cil_switch( + int instruction: @cil_switch ref, + int index: int ref, + int target: @cil_instruction ref); + +cil_instruction_location( + unique int id: @cil_instruction ref, + int loc: @location ref); + +cil_type_location( + int id: @cil_type ref, + int loc: @location ref); + +cil_method_location( + int id: @cil_method ref, + int loc: @location ref); + +@cil_namespace = @namespace; + +@cil_type_container = @cil_type | @cil_namespace | @cil_method; + +case @cil_type.kind of + 0 = @cil_valueorreftype +| 1 = @cil_typeparameter +| 2 = @cil_array_type +| 3 = @cil_pointer_type +| 4 = @cil_function_pointer_type +; + +cil_type( + unique int id: @cil_type, + string name: string ref, + int kind: int ref, + int parent: @cil_type_container ref, + int sourceDecl: @cil_type ref); + +cil_pointer_type( + unique int id: @cil_pointer_type ref, + int pointee: @cil_type ref); + +cil_array_type( + unique int id: @cil_array_type ref, + int element_type: @cil_type ref, + int rank: int ref); + +cil_function_pointer_return_type( + unique int id: @cil_function_pointer_type ref, + int return_type: @cil_type ref); + +cil_method( + unique int id: @cil_method, + string name: string ref, + int parent: @cil_type ref, + int return_type: @cil_type ref); + +cil_method_source_declaration( + unique int method: @cil_method ref, + int source: @cil_method ref); + +cil_method_implementation( + unique int id: @cil_method_implementation, + int method: @cil_method ref, + int location: @assembly ref); + +cil_implements( + int id: @cil_method ref, + int decl: @cil_method ref); + +#keyset[parent, name] +cil_field( + unique int id: @cil_field, + int parent: @cil_type ref, + string name: string ref, + int field_type: @cil_type ref); + +@cil_element = @cil_instruction | @cil_declaration | @cil_handler | @cil_attribute | @cil_namespace; +@cil_named_element = @cil_declaration | @cil_namespace; +@cil_declaration = @cil_variable | @cil_method | @cil_type | @cil_member; +@cil_accessible = @cil_declaration; +@cil_variable = @cil_field | @cil_stack_variable; +@cil_stack_variable = @cil_local_variable | @cil_parameter; +@cil_member = @cil_method | @cil_type | @cil_field | @cil_property | @cil_event; +@cil_custom_modifier_receiver = @cil_method | @cil_property | @cil_parameter | @cil_field | @cil_function_pointer_type; +@cil_parameterizable = @cil_method | @cil_function_pointer_type; +@cil_has_type_annotation = @cil_stack_variable | @cil_property | @cil_method | @cil_function_pointer_type; + +#keyset[parameterizable, index] +cil_parameter( + unique int id: @cil_parameter, + int parameterizable: @cil_parameterizable ref, + int index: int ref, + int param_type: @cil_type ref); + +cil_parameter_in(unique int id: @cil_parameter ref); +cil_parameter_out(unique int id: @cil_parameter ref); + +cil_setter(unique int prop: @cil_property ref, + int method: @cil_method ref); + +#keyset[id, modifier] +cil_custom_modifiers( + int id: @cil_custom_modifier_receiver ref, + int modifier: @cil_type ref, + int kind: int ref); // modreq: 1, modopt: 0 + +cil_type_annotation( + int id: @cil_has_type_annotation ref, + int annotation: int ref); + +cil_getter(unique int prop: @cil_property ref, + int method: @cil_method ref); + +cil_adder(unique int event: @cil_event ref, + int method: @cil_method ref); + +cil_remover(unique int event: @cil_event ref, int method: @cil_method ref); + +cil_raiser(unique int event: @cil_event ref, int method: @cil_method ref); + +cil_property( + unique int id: @cil_property, + int parent: @cil_type ref, + string name: string ref, + int property_type: @cil_type ref); + +#keyset[parent, name] +cil_event(unique int id: @cil_event, + int parent: @cil_type ref, + string name: string ref, + int event_type: @cil_type ref); + +#keyset[impl, index] +cil_local_variable( + unique int id: @cil_local_variable, + int impl: @cil_method_implementation ref, + int index: int ref, + int var_type: @cil_type ref); + +cil_function_pointer_calling_conventions( + int id: @cil_function_pointer_type ref, + int kind: int ref); + +// CIL handlers (exception handlers etc). + +case @cil_handler.kind of + 0 = @cil_catch_handler +| 1 = @cil_filter_handler +| 2 = @cil_finally_handler +| 4 = @cil_fault_handler +; + +#keyset[impl, index] +cil_handler( + unique int id: @cil_handler, + int impl: @cil_method_implementation ref, + int index: int ref, + int kind: int ref, + int try_start: @cil_instruction ref, + int try_end: @cil_instruction ref, + int handler_start: @cil_instruction ref); + +cil_handler_filter( + unique int id: @cil_handler ref, + int filter_start: @cil_instruction ref); + +cil_handler_type( + unique int id: @cil_handler ref, + int catch_type: @cil_type ref); + +@cil_controlflow_node = @cil_entry_point | @cil_instruction; + +@cil_entry_point = @cil_method_implementation | @cil_handler; + +@cil_dataflow_node = @cil_instruction | @cil_variable | @cil_method; + +cil_method_stack_size( + unique int method: @cil_method_implementation ref, + int size: int ref); + +// CIL modifiers + +cil_public(int id: @cil_member ref); +cil_private(int id: @cil_member ref); +cil_protected(int id: @cil_member ref); +cil_internal(int id: @cil_member ref); +cil_static(int id: @cil_member ref); +cil_sealed(int id: @cil_member ref); +cil_virtual(int id: @cil_method ref); +cil_abstract(int id: @cil_member ref); +cil_class(int id: @cil_type ref); +cil_interface(int id: @cil_type ref); +cil_security(int id: @cil_member ref); +cil_requiresecobject(int id: @cil_method ref); +cil_specialname(int id: @cil_method ref); +cil_newslot(int id: @cil_method ref); + +cil_base_class(unique int id: @cil_type ref, int base: @cil_type ref); +cil_base_interface(int id: @cil_type ref, int base: @cil_type ref); +cil_enum_underlying_type(unique int id: @cil_type ref, int underlying: @cil_type ref); + +#keyset[unbound, index] +cil_type_parameter( + int unbound: @cil_member ref, + int index: int ref, + int param: @cil_typeparameter ref); + +#keyset[bound, index] +cil_type_argument( + int bound: @cil_member ref, + int index: int ref, + int t: @cil_type ref); + +// CIL type parameter constraints + +cil_typeparam_covariant(int tp: @cil_typeparameter ref); +cil_typeparam_contravariant(int tp: @cil_typeparameter ref); +cil_typeparam_class(int tp: @cil_typeparameter ref); +cil_typeparam_struct(int tp: @cil_typeparameter ref); +cil_typeparam_new(int tp: @cil_typeparameter ref); +cil_typeparam_constraint(int tp: @cil_typeparameter ref, int supertype: @cil_type ref); + +// CIL attributes + +cil_attribute( + unique int attributeid: @cil_attribute, + int element: @cil_declaration ref, + int constructor: @cil_method ref); + +#keyset[attribute_id, param] +cil_attribute_named_argument( + int attribute_id: @cil_attribute ref, + string param: string ref, + string value: string ref); + +#keyset[attribute_id, index] +cil_attribute_positional_argument( + int attribute_id: @cil_attribute ref, + int index: int ref, + string value: string ref); + + +// Common .Net data model covering both C# and CIL + +// Common elements +@dotnet_element = @element | @cil_element; +@dotnet_named_element = @named_element | @cil_named_element; +@dotnet_callable = @callable | @cil_method; +@dotnet_variable = @variable | @cil_variable; +@dotnet_field = @field | @cil_field; +@dotnet_parameter = @parameter | @cil_parameter; +@dotnet_declaration = @declaration | @cil_declaration; +@dotnet_member = @member | @cil_member; +@dotnet_event = @event | @cil_event; +@dotnet_property = @property | @cil_property | @indexer; +@dotnet_parameterizable = @parameterizable | @cil_parameterizable; + +// Common types +@dotnet_type = @type | @cil_type; +@dotnet_call = @call | @cil_call_any; +@dotnet_throw = @throw_element | @cil_throw_any; +@dotnet_valueorreftype = @cil_valueorreftype | @value_or_ref_type | @cil_array_type | @void_type; +@dotnet_typeparameter = @type_parameter | @cil_typeparameter; +@dotnet_array_type = @array_type | @cil_array_type; +@dotnet_pointer_type = @pointer_type | @cil_pointer_type; +@dotnet_type_parameter = @type_parameter | @cil_typeparameter; +@dotnet_generic = @dotnet_valueorreftype | @dotnet_callable; + +// Attributes +@dotnet_attribute = @attribute | @cil_attribute; + +// Expressions +@dotnet_expr = @expr | @cil_expr; + +// Literals +@dotnet_literal = @literal_expr | @cil_literal; +@dotnet_string_literal = @string_literal_expr | @cil_ldstr; +@dotnet_int_literal = @integer_literal_expr | @cil_ldc_i; +@dotnet_float_literal = @float_literal_expr | @cil_ldc_r; +@dotnet_null_literal = @null_literal_expr | @cil_ldnull; + +@metadata_entity = @cil_method | @cil_type | @cil_field | @cil_property | @field | @property | + @callable | @value_or_ref_type | @void_type; + +#keyset[entity, location] +metadata_handle(int entity : @metadata_entity ref, int location: @assembly ref, int handle: int ref) diff --git a/csharp/upgrades/2fb07f0b8c65f6c89437c28caf5d99fdbcdbef2d/upgrade.properties b/csharp/upgrades/2fb07f0b8c65f6c89437c28caf5d99fdbcdbef2d/upgrade.properties new file mode 100644 index 00000000000..675c948ac4c --- /dev/null +++ b/csharp/upgrades/2fb07f0b8c65f6c89437c28caf5d99fdbcdbef2d/upgrade.properties @@ -0,0 +1,2 @@ +description: Add 'and_pattern_expr' and 'or_pattern_expr' to the list of 'expr' types. +compatibility: backwards diff --git a/csharp/upgrades/5f6770a8a174aa0b651375a847d9686533d3f528/old.dbscheme b/csharp/upgrades/5f6770a8a174aa0b651375a847d9686533d3f528/old.dbscheme new file mode 100644 index 00000000000..5f6770a8a17 --- /dev/null +++ b/csharp/upgrades/5f6770a8a174aa0b651375a847d9686533d3f528/old.dbscheme @@ -0,0 +1,1917 @@ + +/** + * An invocation of the compiler. Note that more than one file may be + * compiled per invocation. For example, this command compiles three + * source files: + * + * csc f1.cs f2.cs f3.cs + * + * The `id` simply identifies the invocation, while `cwd` is the working + * directory from which the compiler was invoked. + */ +compilations( + unique int id : @compilation, + string cwd : string ref +); + +/** + * The arguments that were passed to the extractor for a compiler + * invocation. If `id` is for the compiler invocation + * + * csc f1.cs f2.cs f3.cs + * + * then typically there will be rows for + * + * num | arg + * --- | --- + * 0 | --compiler + * 1 | *path to compiler* + * 2 | --cil + * 3 | f1.cs + * 4 | f2.cs + * 5 | f3.cs + */ +#keyset[id, num] +compilation_args( + int id : @compilation ref, + int num : int ref, + string arg : string ref +); + +/** + * The source files that are compiled by a compiler invocation. + * If `id` is for the compiler invocation + * + * csc f1.cs f2.cs f3.cs + * + * then there will be rows for + * + * num | arg + * --- | --- + * 0 | f1.cs + * 1 | f2.cs + * 2 | f3.cs + */ +#keyset[id, num] +compilation_compiling_files( + int id : @compilation ref, + int num : int ref, + int file : @file ref +); + +/** + * The references used by a compiler invocation. + * If `id` is for the compiler invocation + * + * csc f1.cs f2.cs f3.cs /r:ref1.dll /r:ref2.dll /r:ref3.dll + * + * then there will be rows for + * + * num | arg + * --- | --- + * 0 | ref1.dll + * 1 | ref2.dll + * 2 | ref3.dll + */ +#keyset[id, num] +compilation_referencing_files( + int id : @compilation ref, + int num : int ref, + int file : @file ref +); + +/** + * The time taken by the extractor for a compiler invocation. + * + * For each file `num`, there will be rows for + * + * kind | seconds + * ---- | --- + * 1 | CPU seconds used by the extractor frontend + * 2 | Elapsed seconds during the extractor frontend + * 3 | CPU seconds used by the extractor backend + * 4 | Elapsed seconds during the extractor backend + */ +#keyset[id, num, kind] +compilation_time( + int id : @compilation ref, + int num : int ref, + /* kind: + 1 = frontend_cpu_seconds + 2 = frontend_elapsed_seconds + 3 = extractor_cpu_seconds + 4 = extractor_elapsed_seconds + */ + int kind : int ref, + float seconds : float ref +); + +/** + * An error or warning generated by the extractor. + * The diagnostic message `diagnostic` was generated during compiler + * invocation `compilation`, and is the `file_number_diagnostic_number`th + * message generated while extracting the `file_number`th file of that + * invocation. + */ +#keyset[compilation, file_number, file_number_diagnostic_number] +diagnostic_for( + unique int diagnostic : @diagnostic ref, + int compilation : @compilation ref, + int file_number : int ref, + int file_number_diagnostic_number : int ref +); + +diagnostics( + unique int id: @diagnostic, + int severity: int ref, + string error_tag: string ref, + string error_message: string ref, + string full_error_message: string ref, + int location: @location_default ref +); + +extractor_messages( + unique int id: @extractor_message, + int severity: int ref, + string origin : string ref, + string text : string ref, + string entity : string ref, + int location: @location_default ref, + string stack_trace : string ref +); + +/** + * If extraction was successful, then `cpu_seconds` and + * `elapsed_seconds` are the CPU time and elapsed time (respectively) + * that extraction took for compiler invocation `id`. + */ +compilation_finished( + unique int id : @compilation ref, + float cpu_seconds : float ref, + float elapsed_seconds : float ref +); + +compilation_assembly( + unique int id : @compilation ref, + int assembly: @assembly ref +) + +/* + * External artifacts + */ + +externalDefects( + unique int id: @externalDefect, + string queryPath: string ref, + int location: @location ref, + string message: string ref, + float severity: float ref); + +externalMetrics( + unique int id: @externalMetric, + string queryPath: string ref, + int location: @location ref, + float value: float ref); + +externalData( + int id: @externalDataElement, + string path: string ref, + int column: int ref, + string value: string ref); + +snapshotDate( + unique date snapshotDate: date ref); + +sourceLocationPrefix( + string prefix: string ref); + +/* + * Duplicate code + */ + +duplicateCode( + unique int id: @duplication, + string relativePath: string ref, + int equivClass: int ref); + +similarCode( + unique int id: @similarity, + string relativePath: string ref, + int equivClass: int ref); + +@duplication_or_similarity = @duplication | @similarity + +tokens( + int id: @duplication_or_similarity ref, + int offset: int ref, + int beginLine: int ref, + int beginColumn: int ref, + int endLine: int ref, + int endColumn: int ref); + +/* + * C# dbscheme + */ + +/** ELEMENTS **/ + +@element = @declaration | @stmt | @expr | @modifier | @attribute | @namespace_declaration + | @using_directive | @type_parameter_constraints | @external_element + | @xmllocatable | @asp_element | @namespace; + +@declaration = @callable | @generic | @assignable | @namespace; + +@named_element = @namespace | @declaration; + +@declaration_with_accessors = @property | @indexer | @event; + +@assignable = @variable | @assignable_with_accessors | @event; + +@assignable_with_accessors = @property | @indexer; + +@external_element = @externalMetric | @externalDefect | @externalDataElement; + +@attributable = @assembly | @field | @parameter | @operator | @method | @constructor + | @destructor | @callable_accessor | @value_or_ref_type | @declaration_with_accessors + | @local_function; + +/** LOCATIONS, ASEMMBLIES, MODULES, FILES and FOLDERS **/ + +@location = @location_default | @assembly; + +locations_default( + unique int id: @location_default, + int file: @file ref, + int beginLine: int ref, + int beginColumn: int ref, + int endLine: int ref, + int endColumn: int ref); + +@sourceline = @file | @callable | @xmllocatable; + +numlines( + int element_id: @sourceline ref, + int num_lines: int ref, + int num_code: int ref, + int num_comment: int ref); + +assemblies( + unique int id: @assembly, + int file: @file ref, + string fullname: string ref, + string name: string ref, + string version: string ref); + +/* + fromSource(0) = unknown, + fromSource(1) = from source, + fromSource(2) = from library +*/ +files( + unique int id: @file, + string name: string ref, + string simple: string ref, + string ext: string ref, + int fromSource: int ref); + +folders( + unique int id: @folder, + string name: string ref, + string simple: string ref); + +@container = @folder | @file ; + +containerparent( + int parent: @container ref, + unique int child: @container ref); + +file_extraction_mode( + unique int file: @file ref, + int mode: int ref + /* 0 = normal, 1 = standalone extractor */ + ); + +/** NAMESPACES **/ + +@type_container = @namespace | @type; + +namespaces( + unique int id: @namespace, + string name: string ref); + +namespace_declarations( + unique int id: @namespace_declaration, + int namespace_id: @namespace ref); + +namespace_declaration_location( + unique int id: @namespace_declaration ref, + int loc: @location ref); + +parent_namespace( + unique int child_id: @type_container ref, + int namespace_id: @namespace ref); + +@declaration_or_directive = @namespace_declaration | @type | @using_directive; + +parent_namespace_declaration( + int child_id: @declaration_or_directive ref, // cannot be unique because of partial classes + int namespace_id: @namespace_declaration ref); + +@using_directive = @using_namespace_directive | @using_static_directive; + +using_namespace_directives( + unique int id: @using_namespace_directive, + int namespace_id: @namespace ref); + +using_static_directives( + unique int id: @using_static_directive, + int type_id: @type_or_ref ref); + +using_directive_location( + unique int id: @using_directive ref, + int loc: @location ref); + +/** TYPES **/ + +types( + unique int id: @type, + int kind: int ref, + string name: string ref); + +case @type.kind of + 1 = @bool_type +| 2 = @char_type +| 3 = @decimal_type +| 4 = @sbyte_type +| 5 = @short_type +| 6 = @int_type +| 7 = @long_type +| 8 = @byte_type +| 9 = @ushort_type +| 10 = @uint_type +| 11 = @ulong_type +| 12 = @float_type +| 13 = @double_type +| 14 = @enum_type +| 15 = @struct_type +| 17 = @class_type +| 19 = @interface_type +| 20 = @delegate_type +| 21 = @null_type +| 22 = @type_parameter +| 23 = @pointer_type +| 24 = @nullable_type +| 25 = @array_type +| 26 = @void_type +| 27 = @int_ptr_type +| 28 = @uint_ptr_type +| 29 = @dynamic_type +| 30 = @arglist_type +| 31 = @unknown_type +| 32 = @tuple_type + ; + +@simple_type = @bool_type | @char_type | @integral_type | @floating_point_type | @decimal_type; +@integral_type = @signed_integral_type | @unsigned_integral_type; +@signed_integral_type = @sbyte_type | @short_type | @int_type | @long_type; +@unsigned_integral_type = @byte_type | @ushort_type | @uint_type | @ulong_type; +@floating_point_type = @float_type | @double_type; +@value_type = @simple_type | @enum_type | @struct_type | @nullable_type | @int_ptr_type + | @uint_ptr_type | @tuple_type; +@ref_type = @class_type | @interface_type | @array_type | @delegate_type | @null_type + | @dynamic_type; +@value_or_ref_type = @value_type | @ref_type; + +typerefs( + unique int id: @typeref, + string name: string ref); + +typeref_type( + int id: @typeref ref, + unique int typeId: @type ref); + +@type_or_ref = @type | @typeref; + +array_element_type( + unique int array: @array_type ref, + int dimension: int ref, + int rank: int ref, + int element: @type_or_ref ref); + +nullable_underlying_type( + unique int nullable: @nullable_type ref, + int underlying: @type_or_ref ref); + +pointer_referent_type( + unique int pointer: @pointer_type ref, + int referent: @type_or_ref ref); + +enum_underlying_type( + unique int enum_id: @enum_type ref, + int underlying_type_id: @type_or_ref ref); + +delegate_return_type( + unique int delegate_id: @delegate_type ref, + int return_type_id: @type_or_ref ref); + +extend( + unique int sub: @type ref, + int super: @type_or_ref ref); + +anonymous_types( + unique int id: @type ref); + +@interface_or_ref = @interface_type | @typeref; + +implement( + int sub: @type ref, + int super: @type_or_ref ref); + +type_location( + int id: @type ref, + int loc: @location ref); + +tuple_underlying_type( + unique int tuple: @tuple_type ref, + int struct: @type_or_ref ref); + +#keyset[tuple, index] +tuple_element( + int tuple: @tuple_type ref, + int index: int ref, + unique int field: @field ref); + +attributes( + unique int id: @attribute, + int type_id: @type_or_ref ref, + int target: @attributable ref); + +attribute_location( + int id: @attribute ref, + int loc: @location ref); + +@type_mention_parent = @element | @type_mention; + +type_mention( + unique int id: @type_mention, + int type_id: @type_or_ref ref, + int parent: @type_mention_parent ref); + +type_mention_location( + unique int id: @type_mention ref, + int loc: @location ref); + +@has_type_annotation = @assignable | @type_parameter | @callable | @expr | @delegate_type | @generic; + +/** + * A direct annotation on an entity, for example `string? x;`. + * + * Annotations: + * 2 = reftype is not annotated "!" + * 3 = reftype is annotated "?" + * 4 = readonly ref type / in parameter + * 5 = ref type parameter, return or local variable + * 6 = out parameter + * + * Note that the annotation depends on the element it annotates. + * @assignable: The annotation is on the type of the assignable, for example the variable type. + * @type_parameter: The annotation is on the reftype constraint + * @callable: The annotation is on the return type + * @array_type: The annotation is on the element type + */ +type_annotation(int id: @has_type_annotation ref, int annotation: int ref); + +nullability(unique int nullability: @nullability, int kind: int ref); + +case @nullability.kind of + 0 = @oblivious +| 1 = @not_annotated +| 2 = @annotated +; + +#keyset[parent, index] +nullability_parent(int nullability: @nullability ref, int index: int ref, int parent: @nullability ref) + +type_nullability(int id: @has_type_annotation ref, int nullability: @nullability ref); + +/** + * The nullable flow state of an expression, as determined by Roslyn. + * 0 = none (default, not populated) + * 1 = not null + * 2 = maybe null + */ +expr_flowstate(unique int id: @expr ref, int state: int ref); + +/** GENERICS **/ + +@generic = @type | @method | @local_function; + +type_parameters( + unique int id: @type_parameter ref, + int index: int ref, + int generic_id: @generic ref, + int variance: int ref /* none = 0, out = 1, in = 2 */); + +#keyset[constructed_id, index] +type_arguments( + int id: @type_or_ref ref, + int index: int ref, + int constructed_id: @generic_or_ref ref); + +@generic_or_ref = @generic | @typeref; + +constructed_generic( + unique int constructed: @generic ref, + int generic: @generic_or_ref ref); + +type_parameter_constraints( + unique int id: @type_parameter_constraints, + int param_id: @type_parameter ref); + +type_parameter_constraints_location( + int id: @type_parameter_constraints ref, + int loc: @location ref); + +general_type_parameter_constraints( + int id: @type_parameter_constraints ref, + int kind: int ref /* class = 1, struct = 2, new = 3 */); + +specific_type_parameter_constraints( + int id: @type_parameter_constraints ref, + int base_id: @type_or_ref ref); + +specific_type_parameter_nullability( + int id: @type_parameter_constraints ref, + int base_id: @type_or_ref ref, + int nullability: @nullability ref); + +/** MODIFIERS */ + +@modifiable = @modifiable_direct | @event_accessor; + +@modifiable_direct = @member | @accessor | @local_function | @anonymous_function_expr; + +modifiers( + unique int id: @modifier, + string name: string ref); + +has_modifiers( + int id: @modifiable_direct ref, + int mod_id: @modifier ref); + +compiler_generated(unique int id: @modifiable_direct ref); + +/** MEMBERS **/ + +@member = @method | @constructor | @destructor | @field | @property | @event | @operator | @indexer | @type; + +@named_exprorstmt = @goto_stmt | @labeled_stmt | @expr; + +@virtualizable = @method | @property | @indexer | @event; + +exprorstmt_name( + unique int parent_id: @named_exprorstmt ref, + string name: string ref); + +nested_types( + unique int id: @type ref, + int declaring_type_id: @type ref, + int unbound_id: @type ref); + +properties( + unique int id: @property, + string name: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @property ref); + +property_location( + int id: @property ref, + int loc: @location ref); + +indexers( + unique int id: @indexer, + string name: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @indexer ref); + +indexer_location( + int id: @indexer ref, + int loc: @location ref); + +accessors( + unique int id: @accessor, + int kind: int ref, + string name: string ref, + int declaring_member_id: @member ref, + int unbound_id: @accessor ref); + +case @accessor.kind of + 1 = @getter +| 2 = @setter + ; + +init_only_accessors( + unique int id: @accessor ref); + +accessor_location( + int id: @accessor ref, + int loc: @location ref); + +events( + unique int id: @event, + string name: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @event ref); + +event_location( + int id: @event ref, + int loc: @location ref); + +event_accessors( + unique int id: @event_accessor, + int kind: int ref, + string name: string ref, + int declaring_event_id: @event ref, + int unbound_id: @event_accessor ref); + +case @event_accessor.kind of + 1 = @add_event_accessor +| 2 = @remove_event_accessor + ; + +event_accessor_location( + int id: @event_accessor ref, + int loc: @location ref); + +operators( + unique int id: @operator, + string name: string ref, + string symbol: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @operator ref); + +operator_location( + int id: @operator ref, + int loc: @location ref); + +constant_value( + int id: @variable ref, + string value: string ref); + +/** CALLABLES **/ + +@callable = @method | @constructor | @destructor | @operator | @callable_accessor | @anonymous_function_expr | @local_function; + +@callable_accessor = @accessor | @event_accessor; + +methods( + unique int id: @method, + string name: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @method ref); + +method_location( + int id: @method ref, + int loc: @location ref); + +constructors( + unique int id: @constructor, + string name: string ref, + int declaring_type_id: @type ref, + int unbound_id: @constructor ref); + +constructor_location( + int id: @constructor ref, + int loc: @location ref); + +destructors( + unique int id: @destructor, + string name: string ref, + int declaring_type_id: @type ref, + int unbound_id: @destructor ref); + +destructor_location( + int id: @destructor ref, + int loc: @location ref); + +overrides( + int id: @callable ref, + int base_id: @callable ref); + +explicitly_implements( + int id: @member ref, + int interface_id: @interface_or_ref ref); + +local_functions( + unique int id: @local_function, + string name: string ref, + int return_type: @type ref, + int unbound_id: @local_function ref); + +local_function_stmts( + unique int fn: @local_function_stmt ref, + int stmt: @local_function ref); + +/** VARIABLES **/ + +@variable = @local_scope_variable | @field; + +@local_scope_variable = @local_variable | @parameter; + +fields( + unique int id: @field, + int kind: int ref, + string name: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @field ref); + +case @field.kind of + 1 = @addressable_field +| 2 = @constant + ; + +field_location( + int id: @field ref, + int loc: @location ref); + +localvars( + unique int id: @local_variable, + int kind: int ref, + string name: string ref, + int implicitly_typed: int ref /* 0 = no, 1 = yes */, + int type_id: @type_or_ref ref, + int parent_id: @local_var_decl_expr ref); + +case @local_variable.kind of + 1 = @addressable_local_variable +| 2 = @local_constant +| 3 = @local_variable_ref + ; + +localvar_location( + unique int id: @local_variable ref, + int loc: @location ref); + +@parameterizable = @callable | @delegate_type | @indexer; + +#keyset[name, parent_id] +#keyset[index, parent_id] +params( + unique int id: @parameter, + string name: string ref, + int type_id: @type_or_ref ref, + int index: int ref, + int mode: int ref, /* value = 0, ref = 1, out = 2, array = 3, this = 4 */ + int parent_id: @parameterizable ref, + int unbound_id: @parameter ref); + +param_location( + int id: @parameter ref, + int loc: @location ref); + +/** STATEMENTS **/ + +@exprorstmt_parent = @control_flow_element | @top_level_exprorstmt_parent; + +statements( + unique int id: @stmt, + int kind: int ref); + +#keyset[index, parent] +stmt_parent( + unique int stmt: @stmt ref, + int index: int ref, + int parent: @control_flow_element ref); + +@top_level_stmt_parent = @callable; + +// [index, parent] is not a keyset because the same parent may be compiled multiple times +stmt_parent_top_level( + unique int stmt: @stmt ref, + int index: int ref, + int parent: @top_level_stmt_parent ref); + +case @stmt.kind of + 1 = @block_stmt +| 2 = @expr_stmt +| 3 = @if_stmt +| 4 = @switch_stmt +| 5 = @while_stmt +| 6 = @do_stmt +| 7 = @for_stmt +| 8 = @foreach_stmt +| 9 = @break_stmt +| 10 = @continue_stmt +| 11 = @goto_stmt +| 12 = @goto_case_stmt +| 13 = @goto_default_stmt +| 14 = @throw_stmt +| 15 = @return_stmt +| 16 = @yield_stmt +| 17 = @try_stmt +| 18 = @checked_stmt +| 19 = @unchecked_stmt +| 20 = @lock_stmt +| 21 = @using_block_stmt +| 22 = @var_decl_stmt +| 23 = @const_decl_stmt +| 24 = @empty_stmt +| 25 = @unsafe_stmt +| 26 = @fixed_stmt +| 27 = @label_stmt +| 28 = @catch +| 29 = @case_stmt +| 30 = @local_function_stmt +| 31 = @using_decl_stmt + ; + +@using_stmt = @using_block_stmt | @using_decl_stmt; + +@labeled_stmt = @label_stmt | @case; + +@decl_stmt = @var_decl_stmt | @const_decl_stmt | @using_decl_stmt; + +@cond_stmt = @if_stmt | @switch_stmt; + +@loop_stmt = @while_stmt | @do_stmt | @for_stmt | @foreach_stmt; + +@jump_stmt = @break_stmt | @goto_any_stmt | @continue_stmt | @throw_stmt | @return_stmt + | @yield_stmt; + +@goto_any_stmt = @goto_default_stmt | @goto_case_stmt | @goto_stmt; + + +stmt_location( + unique int id: @stmt ref, + int loc: @location ref); + +catch_type( + unique int catch_id: @catch ref, + int type_id: @type_or_ref ref, + int kind: int ref /* explicit = 1, implicit = 2 */); + +/** EXPRESSIONS **/ + +expressions( + unique int id: @expr, + int kind: int ref, + int type_id: @type_or_ref ref); + +#keyset[index, parent] +expr_parent( + unique int expr: @expr ref, + int index: int ref, + int parent: @control_flow_element ref); + +@top_level_expr_parent = @attribute | @field | @property | @indexer | @parameter; + +@top_level_exprorstmt_parent = @top_level_expr_parent | @top_level_stmt_parent; + +// [index, parent] is not a keyset because the same parent may be compiled multiple times +expr_parent_top_level( + unique int expr: @expr ref, + int index: int ref, + int parent: @top_level_exprorstmt_parent ref); + +case @expr.kind of +/* literal */ + 1 = @bool_literal_expr +| 2 = @char_literal_expr +| 3 = @decimal_literal_expr +| 4 = @int_literal_expr +| 5 = @long_literal_expr +| 6 = @uint_literal_expr +| 7 = @ulong_literal_expr +| 8 = @float_literal_expr +| 9 = @double_literal_expr +| 10 = @string_literal_expr +| 11 = @null_literal_expr +/* primary & unary */ +| 12 = @this_access_expr +| 13 = @base_access_expr +| 14 = @local_variable_access_expr +| 15 = @parameter_access_expr +| 16 = @field_access_expr +| 17 = @property_access_expr +| 18 = @method_access_expr +| 19 = @event_access_expr +| 20 = @indexer_access_expr +| 21 = @array_access_expr +| 22 = @type_access_expr +| 23 = @typeof_expr +| 24 = @method_invocation_expr +| 25 = @delegate_invocation_expr +| 26 = @operator_invocation_expr +| 27 = @cast_expr +| 28 = @object_creation_expr +| 29 = @explicit_delegate_creation_expr +| 30 = @implicit_delegate_creation_expr +| 31 = @array_creation_expr +| 32 = @default_expr +| 33 = @plus_expr +| 34 = @minus_expr +| 35 = @bit_not_expr +| 36 = @log_not_expr +| 37 = @post_incr_expr +| 38 = @post_decr_expr +| 39 = @pre_incr_expr +| 40 = @pre_decr_expr +/* multiplicative */ +| 41 = @mul_expr +| 42 = @div_expr +| 43 = @rem_expr +/* additive */ +| 44 = @add_expr +| 45 = @sub_expr +/* shift */ +| 46 = @lshift_expr +| 47 = @rshift_expr +/* relational */ +| 48 = @lt_expr +| 49 = @gt_expr +| 50 = @le_expr +| 51 = @ge_expr +/* equality */ +| 52 = @eq_expr +| 53 = @ne_expr +/* logical */ +| 54 = @bit_and_expr +| 55 = @bit_xor_expr +| 56 = @bit_or_expr +| 57 = @log_and_expr +| 58 = @log_or_expr +/* type testing */ +| 59 = @is_expr +| 60 = @as_expr +/* null coalescing */ +| 61 = @null_coalescing_expr +/* conditional */ +| 62 = @conditional_expr +/* assignment */ +| 63 = @simple_assign_expr +| 64 = @assign_add_expr +| 65 = @assign_sub_expr +| 66 = @assign_mul_expr +| 67 = @assign_div_expr +| 68 = @assign_rem_expr +| 69 = @assign_and_expr +| 70 = @assign_xor_expr +| 71 = @assign_or_expr +| 72 = @assign_lshift_expr +| 73 = @assign_rshift_expr +/* more */ +| 74 = @object_init_expr +| 75 = @collection_init_expr +| 76 = @array_init_expr +| 77 = @checked_expr +| 78 = @unchecked_expr +| 79 = @constructor_init_expr +| 80 = @add_event_expr +| 81 = @remove_event_expr +| 82 = @par_expr +| 83 = @local_var_decl_expr +| 84 = @lambda_expr +| 85 = @anonymous_method_expr +| 86 = @namespace_expr +/* dynamic */ +| 92 = @dynamic_element_access_expr +| 93 = @dynamic_member_access_expr +/* unsafe */ +| 100 = @pointer_indirection_expr +| 101 = @address_of_expr +| 102 = @sizeof_expr +/* async */ +| 103 = @await_expr +/* C# 6.0 */ +| 104 = @nameof_expr +| 105 = @interpolated_string_expr +| 106 = @unknown_expr +/* C# 7.0 */ +| 107 = @throw_expr +| 108 = @tuple_expr +| 109 = @local_function_invocation_expr +| 110 = @ref_expr +| 111 = @discard_expr +/* C# 8.0 */ +| 112 = @range_expr +| 113 = @index_expr +| 114 = @switch_expr +| 115 = @recursive_pattern_expr +| 116 = @property_pattern_expr +| 117 = @positional_pattern_expr +| 118 = @switch_case_expr +| 119 = @assign_coalesce_expr +| 120 = @suppress_nullable_warning_expr +| 121 = @namespace_access_expr +/* C# 9.0 */ +| 126 = @not_pattern_expr +; + +@switch = @switch_stmt | @switch_expr; +@case = @case_stmt | @switch_case_expr; +@pattern_match = @case | @is_expr; +@unary_pattern_expr = @not_pattern_expr; + +@integer_literal_expr = @int_literal_expr | @long_literal_expr | @uint_literal_expr | @ulong_literal_expr; +@real_literal_expr = @float_literal_expr | @double_literal_expr | @decimal_literal_expr; +@literal_expr = @bool_literal_expr | @char_literal_expr | @integer_literal_expr | @real_literal_expr + | @string_literal_expr | @null_literal_expr; + +@assign_expr = @simple_assign_expr | @assign_op_expr | @local_var_decl_expr; +@assign_op_expr = @assign_arith_expr | @assign_bitwise_expr | @assign_event_expr | @assign_coalesce_expr; +@assign_event_expr = @add_event_expr | @remove_event_expr; + +@assign_arith_expr = @assign_add_expr | @assign_sub_expr | @assign_mul_expr | @assign_div_expr + | @assign_rem_expr +@assign_bitwise_expr = @assign_and_expr | @assign_or_expr | @assign_xor_expr + | @assign_lshift_expr | @assign_rshift_expr; + +@member_access_expr = @field_access_expr | @property_access_expr | @indexer_access_expr | @event_access_expr + | @method_access_expr | @type_access_expr | @dynamic_member_access_expr; +@access_expr = @member_access_expr | @this_access_expr | @base_access_expr | @assignable_access_expr | @namespace_access_expr; +@element_access_expr = @indexer_access_expr | @array_access_expr | @dynamic_element_access_expr; + +@local_variable_access = @local_variable_access_expr | @local_var_decl_expr; +@local_scope_variable_access_expr = @parameter_access_expr | @local_variable_access; +@variable_access_expr = @local_scope_variable_access_expr | @field_access_expr; + +@assignable_access_expr = @variable_access_expr | @property_access_expr | @element_access_expr + | @event_access_expr | @dynamic_member_access_expr; + +@objectorcollection_init_expr = @object_init_expr | @collection_init_expr; + +@delegate_creation_expr = @explicit_delegate_creation_expr | @implicit_delegate_creation_expr; + +@bin_arith_op_expr = @mul_expr | @div_expr | @rem_expr | @add_expr | @sub_expr; +@incr_op_expr = @pre_incr_expr | @post_incr_expr; +@decr_op_expr = @pre_decr_expr | @post_decr_expr; +@mut_op_expr = @incr_op_expr | @decr_op_expr; +@un_arith_op_expr = @plus_expr | @minus_expr | @mut_op_expr; +@arith_op_expr = @bin_arith_op_expr | @un_arith_op_expr; + +@ternary_log_op_expr = @conditional_expr; +@bin_log_op_expr = @log_and_expr | @log_or_expr | @null_coalescing_expr; +@un_log_op_expr = @log_not_expr; +@log_expr = @un_log_op_expr | @bin_log_op_expr | @ternary_log_op_expr; + +@bin_bit_op_expr = @bit_and_expr | @bit_or_expr | @bit_xor_expr | @lshift_expr + | @rshift_expr; +@un_bit_op_expr = @bit_not_expr; +@bit_expr = @un_bit_op_expr | @bin_bit_op_expr; + +@equality_op_expr = @eq_expr | @ne_expr; +@rel_op_expr = @gt_expr | @lt_expr| @ge_expr | @le_expr; +@comp_expr = @equality_op_expr | @rel_op_expr; + +@op_expr = @assign_expr | @un_op | @bin_op | @ternary_op; + +@ternary_op = @ternary_log_op_expr; +@bin_op = @bin_arith_op_expr | @bin_log_op_expr | @bin_bit_op_expr | @comp_expr; +@un_op = @un_arith_op_expr | @un_log_op_expr | @un_bit_op_expr | @sizeof_expr + | @pointer_indirection_expr | @address_of_expr; + +@anonymous_function_expr = @lambda_expr | @anonymous_method_expr; + +@call = @method_invocation_expr | @constructor_init_expr | @operator_invocation_expr + | @delegate_invocation_expr | @object_creation_expr | @call_access_expr + | @local_function_invocation_expr; + +@call_access_expr = @property_access_expr | @event_access_expr | @indexer_access_expr; + +@late_bindable_expr = @dynamic_element_access_expr | @dynamic_member_access_expr + | @object_creation_expr | @method_invocation_expr | @operator_invocation_expr; + +@throw_element = @throw_expr | @throw_stmt; + +@implicitly_typeable_object_creation_expr = @object_creation_expr | @explicit_delegate_creation_expr; + +implicitly_typed_array_creation( + unique int id: @array_creation_expr ref); + +explicitly_sized_array_creation( + unique int id: @array_creation_expr ref); + +stackalloc_array_creation( + unique int id: @array_creation_expr ref); + +implicitly_typed_object_creation( + unique int id: @implicitly_typeable_object_creation_expr ref); + +mutator_invocation_mode( + unique int id: @operator_invocation_expr ref, + int mode: int ref /* prefix = 1, postfix = 2*/); + +expr_compiler_generated( + unique int id: @expr ref); + +expr_value( + unique int id: @expr ref, + string value: string ref); + +expr_call( + unique int caller_id: @expr ref, + int target_id: @callable ref); + +expr_access( + unique int accesser_id: @access_expr ref, + int target_id: @accessible ref); + +@accessible = @method | @assignable | @local_function | @namespace; + +expr_location( + unique int id: @expr ref, + int loc: @location ref); + +dynamic_member_name( + unique int id: @late_bindable_expr ref, + string name: string ref); + +@qualifiable_expr = @member_access_expr + | @method_invocation_expr + | @element_access_expr; + +conditional_access( + unique int id: @qualifiable_expr ref); + +expr_argument( + unique int id: @expr ref, + int mode: int ref); + /* mode is the same as params: value = 0, ref = 1, out = 2 */ + +expr_argument_name( + unique int id: @expr ref, + string name: string ref); + +/** CONTROL/DATA FLOW **/ + +@control_flow_element = @stmt | @expr; + +/* XML Files */ + +xmlEncoding ( + unique int id: @file ref, + string encoding: string ref); + +xmlDTDs( + unique int id: @xmldtd, + string root: string ref, + string publicId: string ref, + string systemId: string ref, + int fileid: @file ref); + +xmlElements( + unique int id: @xmlelement, + string name: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int fileid: @file ref); + +xmlAttrs( + unique int id: @xmlattribute, + int elementid: @xmlelement ref, + string name: string ref, + string value: string ref, + int idx: int ref, + int fileid: @file ref); + +xmlNs( + int id: @xmlnamespace, + string prefixName: string ref, + string URI: string ref, + int fileid: @file ref); + +xmlHasNs( + int elementId: @xmlnamespaceable ref, + int nsId: @xmlnamespace ref, + int fileid: @file ref); + +xmlComments( + unique int id: @xmlcomment, + string text: string ref, + int parentid: @xmlparent ref, + int fileid: @file ref); + +xmlChars( + unique int id: @xmlcharacters, + string text: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int isCDATA: int ref, + int fileid: @file ref); + +@xmlparent = @file | @xmlelement; +@xmlnamespaceable = @xmlelement | @xmlattribute; + +xmllocations( + int xmlElement: @xmllocatable ref, + int location: @location_default ref); + +@xmllocatable = @xmlcharacters | @xmlelement | @xmlcomment | @xmlattribute | @xmldtd | @file | @xmlnamespace; + +/* Comments */ + +commentline( + unique int id: @commentline, + int kind: int ref, + string text: string ref, + string rawtext: string ref); + +case @commentline.kind of + 0 = @singlelinecomment +| 1 = @xmldoccomment +| 2 = @multilinecomment; + +commentline_location( + unique int id: @commentline ref, + int loc: @location ref); + +commentblock( + unique int id : @commentblock); + +commentblock_location( + unique int id: @commentblock ref, + int loc: @location ref); + +commentblock_binding( + int id: @commentblock ref, + int entity: @element ref, + int bindtype: int ref); /* 0: Parent, 1: Best, 2: Before, 3: After */ + +commentblock_child( + int id: @commentblock ref, + int commentline: @commentline ref, + int index: int ref); + +/* ASP.NET */ + +case @asp_element.kind of + 0=@asp_close_tag +| 1=@asp_code +| 2=@asp_comment +| 3=@asp_data_binding +| 4=@asp_directive +| 5=@asp_open_tag +| 6=@asp_quoted_string +| 7=@asp_text +| 8=@asp_xml_directive; + +@asp_attribute = @asp_code | @asp_data_binding | @asp_quoted_string; + +asp_elements( + unique int id: @asp_element, + int kind: int ref, + int loc: @location ref); + +asp_comment_server(unique int comment: @asp_comment ref); +asp_code_inline(unique int code: @asp_code ref); +asp_directive_attribute( + int directive: @asp_directive ref, + int index: int ref, + string name: string ref, + int value: @asp_quoted_string ref); +asp_directive_name( + unique int directive: @asp_directive ref, + string name: string ref); +asp_element_body( + unique int element: @asp_element ref, + string body: string ref); +asp_tag_attribute( + int tag: @asp_open_tag ref, + int index: int ref, + string name: string ref, + int attribute: @asp_attribute ref); +asp_tag_name( + unique int tag: @asp_open_tag ref, + string name: string ref); +asp_tag_isempty(int tag: @asp_open_tag ref); + +/* Common Intermediate Language - CIL */ + +case @cil_instruction.opcode of + 0 = @cil_nop +| 1 = @cil_break +| 2 = @cil_ldarg_0 +| 3 = @cil_ldarg_1 +| 4 = @cil_ldarg_2 +| 5 = @cil_ldarg_3 +| 6 = @cil_ldloc_0 +| 7 = @cil_ldloc_1 +| 8 = @cil_ldloc_2 +| 9 = @cil_ldloc_3 +| 10 = @cil_stloc_0 +| 11 = @cil_stloc_1 +| 12 = @cil_stloc_2 +| 13 = @cil_stloc_3 +| 14 = @cil_ldarg_s +| 15 = @cil_ldarga_s +| 16 = @cil_starg_s +| 17 = @cil_ldloc_s +| 18 = @cil_ldloca_s +| 19 = @cil_stloc_s +| 20 = @cil_ldnull +| 21 = @cil_ldc_i4_m1 +| 22 = @cil_ldc_i4_0 +| 23 = @cil_ldc_i4_1 +| 24 = @cil_ldc_i4_2 +| 25 = @cil_ldc_i4_3 +| 26 = @cil_ldc_i4_4 +| 27 = @cil_ldc_i4_5 +| 28 = @cil_ldc_i4_6 +| 29 = @cil_ldc_i4_7 +| 30 = @cil_ldc_i4_8 +| 31 = @cil_ldc_i4_s +| 32 = @cil_ldc_i4 +| 33 = @cil_ldc_i8 +| 34 = @cil_ldc_r4 +| 35 = @cil_ldc_r8 +| 37 = @cil_dup +| 38 = @cil_pop +| 39 = @cil_jmp +| 40 = @cil_call +| 41 = @cil_calli +| 42 = @cil_ret +| 43 = @cil_br_s +| 44 = @cil_brfalse_s +| 45 = @cil_brtrue_s +| 46 = @cil_beq_s +| 47 = @cil_bge_s +| 48 = @cil_bgt_s +| 49 = @cil_ble_s +| 50 = @cil_blt_s +| 51 = @cil_bne_un_s +| 52 = @cil_bge_un_s +| 53 = @cil_bgt_un_s +| 54 = @cil_ble_un_s +| 55 = @cil_blt_un_s +| 56 = @cil_br +| 57 = @cil_brfalse +| 58 = @cil_brtrue +| 59 = @cil_beq +| 60 = @cil_bge +| 61 = @cil_bgt +| 62 = @cil_ble +| 63 = @cil_blt +| 64 = @cil_bne_un +| 65 = @cil_bge_un +| 66 = @cil_bgt_un +| 67 = @cil_ble_un +| 68 = @cil_blt_un +| 69 = @cil_switch +| 70 = @cil_ldind_i1 +| 71 = @cil_ldind_u1 +| 72 = @cil_ldind_i2 +| 73 = @cil_ldind_u2 +| 74 = @cil_ldind_i4 +| 75 = @cil_ldind_u4 +| 76 = @cil_ldind_i8 +| 77 = @cil_ldind_i +| 78 = @cil_ldind_r4 +| 79 = @cil_ldind_r8 +| 80 = @cil_ldind_ref +| 81 = @cil_stind_ref +| 82 = @cil_stind_i1 +| 83 = @cil_stind_i2 +| 84 = @cil_stind_i4 +| 85 = @cil_stind_i8 +| 86 = @cil_stind_r4 +| 87 = @cil_stind_r8 +| 88 = @cil_add +| 89 = @cil_sub +| 90 = @cil_mul +| 91 = @cil_div +| 92 = @cil_div_un +| 93 = @cil_rem +| 94 = @cil_rem_un +| 95 = @cil_and +| 96 = @cil_or +| 97 = @cil_xor +| 98 = @cil_shl +| 99 = @cil_shr +| 100 = @cil_shr_un +| 101 = @cil_neg +| 102 = @cil_not +| 103 = @cil_conv_i1 +| 104 = @cil_conv_i2 +| 105 = @cil_conv_i4 +| 106 = @cil_conv_i8 +| 107 = @cil_conv_r4 +| 108 = @cil_conv_r8 +| 109 = @cil_conv_u4 +| 110 = @cil_conv_u8 +| 111 = @cil_callvirt +| 112 = @cil_cpobj +| 113 = @cil_ldobj +| 114 = @cil_ldstr +| 115 = @cil_newobj +| 116 = @cil_castclass +| 117 = @cil_isinst +| 118 = @cil_conv_r_un +| 121 = @cil_unbox +| 122 = @cil_throw +| 123 = @cil_ldfld +| 124 = @cil_ldflda +| 125 = @cil_stfld +| 126 = @cil_ldsfld +| 127 = @cil_ldsflda +| 128 = @cil_stsfld +| 129 = @cil_stobj +| 130 = @cil_conv_ovf_i1_un +| 131 = @cil_conv_ovf_i2_un +| 132 = @cil_conv_ovf_i4_un +| 133 = @cil_conv_ovf_i8_un +| 134 = @cil_conv_ovf_u1_un +| 135 = @cil_conv_ovf_u2_un +| 136 = @cil_conv_ovf_u4_un +| 137 = @cil_conv_ovf_u8_un +| 138 = @cil_conv_ovf_i_un +| 139 = @cil_conv_ovf_u_un +| 140 = @cil_box +| 141 = @cil_newarr +| 142 = @cil_ldlen +| 143 = @cil_ldelema +| 144 = @cil_ldelem_i1 +| 145 = @cil_ldelem_u1 +| 146 = @cil_ldelem_i2 +| 147 = @cil_ldelem_u2 +| 148 = @cil_ldelem_i4 +| 149 = @cil_ldelem_u4 +| 150 = @cil_ldelem_i8 +| 151 = @cil_ldelem_i +| 152 = @cil_ldelem_r4 +| 153 = @cil_ldelem_r8 +| 154 = @cil_ldelem_ref +| 155 = @cil_stelem_i +| 156 = @cil_stelem_i1 +| 157 = @cil_stelem_i2 +| 158 = @cil_stelem_i4 +| 159 = @cil_stelem_i8 +| 160 = @cil_stelem_r4 +| 161 = @cil_stelem_r8 +| 162 = @cil_stelem_ref +| 163 = @cil_ldelem +| 164 = @cil_stelem +| 165 = @cil_unbox_any +| 179 = @cil_conv_ovf_i1 +| 180 = @cil_conv_ovf_u1 +| 181 = @cil_conv_ovf_i2 +| 182 = @cil_conv_ovf_u2 +| 183 = @cil_conv_ovf_i4 +| 184 = @cil_conv_ovf_u4 +| 185 = @cil_conv_ovf_i8 +| 186 = @cil_conv_ovf_u8 +| 194 = @cil_refanyval +| 195 = @cil_ckinfinite +| 198 = @cil_mkrefany +| 208 = @cil_ldtoken +| 209 = @cil_conv_u2 +| 210 = @cil_conv_u1 +| 211 = @cil_conv_i +| 212 = @cil_conv_ovf_i +| 213 = @cil_conv_ovf_u +| 214 = @cil_add_ovf +| 215 = @cil_add_ovf_un +| 216 = @cil_mul_ovf +| 217 = @cil_mul_ovf_un +| 218 = @cil_sub_ovf +| 219 = @cil_sub_ovf_un +| 220 = @cil_endfinally +| 221 = @cil_leave +| 222 = @cil_leave_s +| 223 = @cil_stind_i +| 224 = @cil_conv_u +| 65024 = @cil_arglist +| 65025 = @cil_ceq +| 65026 = @cil_cgt +| 65027 = @cil_cgt_un +| 65028 = @cil_clt +| 65029 = @cil_clt_un +| 65030 = @cil_ldftn +| 65031 = @cil_ldvirtftn +| 65033 = @cil_ldarg +| 65034 = @cil_ldarga +| 65035 = @cil_starg +| 65036 = @cil_ldloc +| 65037 = @cil_ldloca +| 65038 = @cil_stloc +| 65039 = @cil_localloc +| 65041 = @cil_endfilter +| 65042 = @cil_unaligned +| 65043 = @cil_volatile +| 65044 = @cil_tail +| 65045 = @cil_initobj +| 65046 = @cil_constrained +| 65047 = @cil_cpblk +| 65048 = @cil_initblk +| 65050 = @cil_rethrow +| 65052 = @cil_sizeof +| 65053 = @cil_refanytype +| 65054 = @cil_readonly +; + +// CIL ignored instructions + +@cil_ignore = @cil_nop | @cil_break | @cil_volatile | @cil_unaligned; + +// CIL local/parameter/field access + +@cil_ldarg_any = @cil_ldarg_0 | @cil_ldarg_1 | @cil_ldarg_2 | @cil_ldarg_3 | @cil_ldarg_s | @cil_ldarga_s | @cil_ldarg | @cil_ldarga; +@cil_starg_any = @cil_starg | @cil_starg_s; + +@cil_ldloc_any = @cil_ldloc_0 | @cil_ldloc_1 | @cil_ldloc_2 | @cil_ldloc_3 | @cil_ldloc_s | @cil_ldloca_s | @cil_ldloc | @cil_ldloca; +@cil_stloc_any = @cil_stloc_0 | @cil_stloc_1 | @cil_stloc_2 | @cil_stloc_3 | @cil_stloc_s | @cil_stloc; + +@cil_ldfld_any = @cil_ldfld | @cil_ldsfld | @cil_ldsflda | @cil_ldflda; +@cil_stfld_any = @cil_stfld | @cil_stsfld; + +@cil_local_access = @cil_stloc_any | @cil_ldloc_any; +@cil_arg_access = @cil_starg_any | @cil_ldarg_any; +@cil_read_access = @cil_ldloc_any | @cil_ldarg_any | @cil_ldfld_any; +@cil_write_access = @cil_stloc_any | @cil_starg_any | @cil_stfld_any; + +@cil_stack_access = @cil_local_access | @cil_arg_access; +@cil_field_access = @cil_ldfld_any | @cil_stfld_any; + +@cil_access = @cil_read_access | @cil_write_access; + +// CIL constant/literal instructions + +@cil_ldc_i = @cil_ldc_i4_any | @cil_ldc_i8; + +@cil_ldc_i4_any = @cil_ldc_i4_m1 | @cil_ldc_i4_0 | @cil_ldc_i4_1 | @cil_ldc_i4_2 | @cil_ldc_i4_3 | + @cil_ldc_i4_4 | @cil_ldc_i4_5 | @cil_ldc_i4_6 | @cil_ldc_i4_7 | @cil_ldc_i4_8 | @cil_ldc_i4_s | @cil_ldc_i4; + +@cil_ldc_r = @cil_ldc_r4 | @cil_ldc_r8; + +@cil_literal = @cil_ldnull | @cil_ldc_i | @cil_ldc_r | @cil_ldstr; + +// Control flow + +@cil_conditional_jump = @cil_binary_jump | @cil_unary_jump; +@cil_binary_jump = @cil_beq_s | @cil_bge_s | @cil_bgt_s | @cil_ble_s | @cil_blt_s | + @cil_bne_un_s | @cil_bge_un_s | @cil_bgt_un_s | @cil_ble_un_s | @cil_blt_un_s | + @cil_beq | @cil_bge | @cil_bgt | @cil_ble | @cil_blt | + @cil_bne_un | @cil_bge_un | @cil_bgt_un | @cil_ble_un | @cil_blt_un; +@cil_unary_jump = @cil_brfalse_s | @cil_brtrue_s | @cil_brfalse | @cil_brtrue | @cil_switch; +@cil_unconditional_jump = @cil_br | @cil_br_s | @cil_leave_any; +@cil_leave_any = @cil_leave | @cil_leave_s; +@cil_jump = @cil_unconditional_jump | @cil_conditional_jump; + +// CIL call instructions + +@cil_call_any = @cil_jmp | @cil_call | @cil_calli | @cil_tail | @cil_callvirt | @cil_newobj; + +// CIL expression instructions + +@cil_expr = @cil_literal | @cil_binary_expr | @cil_unary_expr | @cil_call_any | @cil_read_access | + @cil_newarr | @cil_ldtoken | @cil_sizeof | + @cil_ldftn | @cil_ldvirtftn | @cil_localloc | @cil_mkrefany | @cil_refanytype | @cil_arglist | @cil_dup; + +@cil_unary_expr = + @cil_conversion_operation | @cil_unary_arithmetic_operation | @cil_unary_bitwise_operation| + @cil_ldlen | @cil_isinst | @cil_box | @cil_ldobj | @cil_castclass | @cil_unbox_any | + @cil_ldind | @cil_unbox; + +@cil_conversion_operation = + @cil_conv_i1 | @cil_conv_i2 | @cil_conv_i4 | @cil_conv_i8 | + @cil_conv_u1 | @cil_conv_u2 | @cil_conv_u4 | @cil_conv_u8 | + @cil_conv_ovf_i | @cil_conv_ovf_i_un | @cil_conv_ovf_i1 | @cil_conv_ovf_i1_un | + @cil_conv_ovf_i2 | @cil_conv_ovf_i2_un | @cil_conv_ovf_i4 | @cil_conv_ovf_i4_un | + @cil_conv_ovf_i8 | @cil_conv_ovf_i8_un | @cil_conv_ovf_u | @cil_conv_ovf_u_un | + @cil_conv_ovf_u1 | @cil_conv_ovf_u1_un | @cil_conv_ovf_u2 | @cil_conv_ovf_u2_un | + @cil_conv_ovf_u4 | @cil_conv_ovf_u4_un | @cil_conv_ovf_u8 | @cil_conv_ovf_u8_un | + @cil_conv_r4 | @cil_conv_r8 | @cil_conv_ovf_u2 | @cil_conv_ovf_u2_un | + @cil_conv_i | @cil_conv_u | @cil_conv_r_un; + +@cil_ldind = @cil_ldind_i | @cil_ldind_i1 | @cil_ldind_i2 | @cil_ldind_i4 | @cil_ldind_i8 | + @cil_ldind_r4 | @cil_ldind_r8 | @cil_ldind_ref | @cil_ldind_u1 | @cil_ldind_u2 | @cil_ldind_u4; + +@cil_stind = @cil_stind_i | @cil_stind_i1 | @cil_stind_i2 | @cil_stind_i4 | @cil_stind_i8 | + @cil_stind_r4 | @cil_stind_r8 | @cil_stind_ref; + +@cil_bitwise_operation = @cil_binary_bitwise_operation | @cil_unary_bitwise_operation; + +@cil_binary_bitwise_operation = @cil_and | @cil_or | @cil_xor | @cil_shr | @cil_shr | @cil_shr_un | @cil_shl; + +@cil_binary_arithmetic_operation = @cil_add | @cil_sub | @cil_mul | @cil_div | @cil_div_un | + @cil_rem | @cil_rem_un | @cil_add_ovf | @cil_add_ovf_un | @cil_mul_ovf | @cil_mul_ovf_un | + @cil_sub_ovf | @cil_sub_ovf_un; + +@cil_unary_bitwise_operation = @cil_not; + +@cil_binary_expr = @cil_binary_arithmetic_operation | @cil_binary_bitwise_operation | @cil_read_array | @cil_comparison_operation; + +@cil_unary_arithmetic_operation = @cil_neg; + +@cil_comparison_operation = @cil_cgt_un | @cil_ceq | @cil_cgt | @cil_clt | @cil_clt_un; + +// Elements that retrieve an address of something +@cil_read_ref = @cil_ldloca_s | @cil_ldarga_s | @cil_ldflda | @cil_ldsflda | @cil_ldelema; + +// CIL array instructions + +@cil_read_array = + @cil_ldelem | @cil_ldelema | @cil_ldelem_i1 | @cil_ldelem_ref | @cil_ldelem_i | + @cil_ldelem_i1 | @cil_ldelem_i2 | @cil_ldelem_i4 | @cil_ldelem_i8 | @cil_ldelem_r4 | + @cil_ldelem_r8 | @cil_ldelem_u1 | @cil_ldelem_u2 | @cil_ldelem_u4; + +@cil_write_array = @cil_stelem | @cil_stelem_ref | + @cil_stelem_i | @cil_stelem_i1 | @cil_stelem_i2 | @cil_stelem_i4 | @cil_stelem_i8 | + @cil_stelem_r4 | @cil_stelem_r8; + +@cil_throw_any = @cil_throw | @cil_rethrow; + +#keyset[impl, index] +cil_instruction( + unique int id: @cil_instruction, + int opcode: int ref, + int index: int ref, + int impl: @cil_method_implementation ref); + +cil_jump( + unique int instruction: @cil_jump ref, + int target: @cil_instruction ref); + +cil_access( + unique int instruction: @cil_instruction ref, + int target: @cil_accessible ref); + +cil_value( + unique int instruction: @cil_literal ref, + string value: string ref); + +#keyset[instruction, index] +cil_switch( + int instruction: @cil_switch ref, + int index: int ref, + int target: @cil_instruction ref); + +cil_instruction_location( + unique int id: @cil_instruction ref, + int loc: @location ref); + +cil_type_location( + int id: @cil_type ref, + int loc: @location ref); + +cil_method_location( + int id: @cil_method ref, + int loc: @location ref); + +@cil_namespace = @namespace; + +@cil_type_container = @cil_type | @cil_namespace | @cil_method; + +case @cil_type.kind of + 0 = @cil_valueorreftype +| 1 = @cil_typeparameter +| 2 = @cil_array_type +| 3 = @cil_pointer_type +; + +cil_type( + unique int id: @cil_type, + string name: string ref, + int kind: int ref, + int parent: @cil_type_container ref, + int sourceDecl: @cil_type ref); + +cil_pointer_type( + unique int id: @cil_pointer_type ref, + int pointee: @cil_type ref); + +cil_array_type( + unique int id: @cil_array_type ref, + int element_type: @cil_type ref, + int rank: int ref); + +cil_method( + unique int id: @cil_method, + string name: string ref, + int parent: @cil_type ref, + int return_type: @cil_type ref); + +cil_method_source_declaration( + unique int method: @cil_method ref, + int source: @cil_method ref); + +cil_method_implementation( + unique int id: @cil_method_implementation, + int method: @cil_method ref, + int location: @assembly ref); + +cil_implements( + int id: @cil_method ref, + int decl: @cil_method ref); + +#keyset[parent, name] +cil_field( + unique int id: @cil_field, + int parent: @cil_type ref, + string name: string ref, + int field_type: @cil_type ref); + +@cil_element = @cil_instruction | @cil_declaration | @cil_handler | @cil_attribute | @cil_namespace; +@cil_named_element = @cil_declaration | @cil_namespace; +@cil_declaration = @cil_variable | @cil_method | @cil_type | @cil_member; +@cil_accessible = @cil_declaration; +@cil_variable = @cil_field | @cil_stack_variable; +@cil_stack_variable = @cil_local_variable | @cil_parameter; +@cil_member = @cil_method | @cil_type | @cil_field | @cil_property | @cil_event; +@cil_custom_modifier_receiver = @cil_method | @cil_property | @cil_parameter | @cil_field; // todo: add function pointer type + +#keyset[method, index] +cil_parameter( + unique int id: @cil_parameter, + int method: @cil_method ref, + int index: int ref, + int param_type: @cil_type ref); + +cil_parameter_in(unique int id: @cil_parameter ref); +cil_parameter_out(unique int id: @cil_parameter ref); + +cil_setter(unique int prop: @cil_property ref, + int method: @cil_method ref); + +#keyset[id, modifier] +cil_custom_modifiers( + int id: @cil_custom_modifier_receiver ref, + int modifier: @cil_type ref, + int kind: int ref); // modreq: 1, modopt: 0 + +cil_getter(unique int prop: @cil_property ref, + int method: @cil_method ref); + +cil_adder(unique int event: @cil_event ref, + int method: @cil_method ref); + +cil_remover(unique int event: @cil_event ref, int method: @cil_method ref); + +cil_raiser(unique int event: @cil_event ref, int method: @cil_method ref); + +cil_property( + unique int id: @cil_property, + int parent: @cil_type ref, + string name: string ref, + int property_type: @cil_type ref); + +#keyset[parent, name] +cil_event(unique int id: @cil_event, + int parent: @cil_type ref, + string name: string ref, + int event_type: @cil_type ref); + +#keyset[impl, index] +cil_local_variable( + unique int id: @cil_local_variable, + int impl: @cil_method_implementation ref, + int index: int ref, + int var_type: @cil_type ref); + +// CIL handlers (exception handlers etc). + +case @cil_handler.kind of + 0 = @cil_catch_handler +| 1 = @cil_filter_handler +| 2 = @cil_finally_handler +| 4 = @cil_fault_handler +; + +#keyset[impl, index] +cil_handler( + unique int id: @cil_handler, + int impl: @cil_method_implementation ref, + int index: int ref, + int kind: int ref, + int try_start: @cil_instruction ref, + int try_end: @cil_instruction ref, + int handler_start: @cil_instruction ref); + +cil_handler_filter( + unique int id: @cil_handler ref, + int filter_start: @cil_instruction ref); + +cil_handler_type( + unique int id: @cil_handler ref, + int catch_type: @cil_type ref); + +@cil_controlflow_node = @cil_entry_point | @cil_instruction; + +@cil_entry_point = @cil_method_implementation | @cil_handler; + +@cil_dataflow_node = @cil_instruction | @cil_variable | @cil_method; + +cil_method_stack_size( + unique int method: @cil_method_implementation ref, + int size: int ref); + +// CIL modifiers + +cil_public(int id: @cil_member ref); +cil_private(int id: @cil_member ref); +cil_protected(int id: @cil_member ref); +cil_internal(int id: @cil_member ref); +cil_static(int id: @cil_member ref); +cil_sealed(int id: @cil_member ref); +cil_virtual(int id: @cil_method ref); +cil_abstract(int id: @cil_member ref); +cil_class(int id: @cil_type ref); +cil_interface(int id: @cil_type ref); +cil_security(int id: @cil_member ref); +cil_requiresecobject(int id: @cil_method ref); +cil_specialname(int id: @cil_method ref); +cil_newslot(int id: @cil_method ref); + +cil_base_class(unique int id: @cil_type ref, int base: @cil_type ref); +cil_base_interface(int id: @cil_type ref, int base: @cil_type ref); +cil_enum_underlying_type(unique int id: @cil_type ref, int underlying: @cil_type ref); + +#keyset[unbound, index] +cil_type_parameter( + int unbound: @cil_member ref, + int index: int ref, + int param: @cil_typeparameter ref); + +#keyset[bound, index] +cil_type_argument( + int bound: @cil_member ref, + int index: int ref, + int t: @cil_type ref); + +// CIL type parameter constraints + +cil_typeparam_covariant(int tp: @cil_typeparameter ref); +cil_typeparam_contravariant(int tp: @cil_typeparameter ref); +cil_typeparam_class(int tp: @cil_typeparameter ref); +cil_typeparam_struct(int tp: @cil_typeparameter ref); +cil_typeparam_new(int tp: @cil_typeparameter ref); +cil_typeparam_constraint(int tp: @cil_typeparameter ref, int supertype: @cil_type ref); + +// CIL attributes + +cil_attribute( + unique int attributeid: @cil_attribute, + int element: @cil_declaration ref, + int constructor: @cil_method ref); + +#keyset[attribute_id, param] +cil_attribute_named_argument( + int attribute_id: @cil_attribute ref, + string param: string ref, + string value: string ref); + +#keyset[attribute_id, index] +cil_attribute_positional_argument( + int attribute_id: @cil_attribute ref, + int index: int ref, + string value: string ref); + + +// Common .Net data model covering both C# and CIL + +// Common elements +@dotnet_element = @element | @cil_element; +@dotnet_named_element = @named_element | @cil_named_element; +@dotnet_callable = @callable | @cil_method; +@dotnet_variable = @variable | @cil_variable; +@dotnet_field = @field | @cil_field; +@dotnet_parameter = @parameter | @cil_parameter; +@dotnet_declaration = @declaration | @cil_declaration; +@dotnet_member = @member | @cil_member; +@dotnet_event = @event | @cil_event; +@dotnet_property = @property | @cil_property | @indexer; + +// Common types +@dotnet_type = @type | @cil_type; +@dotnet_call = @call | @cil_call_any; +@dotnet_throw = @throw_element | @cil_throw_any; +@dotnet_valueorreftype = @cil_valueorreftype | @value_or_ref_type | @cil_array_type | @void_type; +@dotnet_typeparameter = @type_parameter | @cil_typeparameter; +@dotnet_array_type = @array_type | @cil_array_type; +@dotnet_pointer_type = @pointer_type | @cil_pointer_type; +@dotnet_type_parameter = @type_parameter | @cil_typeparameter; +@dotnet_generic = @dotnet_valueorreftype | @dotnet_callable; + +// Attributes +@dotnet_attribute = @attribute | @cil_attribute; + +// Expressions +@dotnet_expr = @expr | @cil_expr; + +// Literals +@dotnet_literal = @literal_expr | @cil_literal; +@dotnet_string_literal = @string_literal_expr | @cil_ldstr; +@dotnet_int_literal = @integer_literal_expr | @cil_ldc_i; +@dotnet_float_literal = @float_literal_expr | @cil_ldc_r; +@dotnet_null_literal = @null_literal_expr | @cil_ldnull; + +@metadata_entity = @cil_method | @cil_type | @cil_field | @cil_property | @field | @property | + @callable | @value_or_ref_type | @void_type; + +#keyset[entity, location] +metadata_handle(int entity : @metadata_entity ref, int location: @assembly ref, int handle: int ref) diff --git a/csharp/upgrades/5f6770a8a174aa0b651375a847d9686533d3f528/semmlecode.csharp.dbscheme b/csharp/upgrades/5f6770a8a174aa0b651375a847d9686533d3f528/semmlecode.csharp.dbscheme new file mode 100644 index 00000000000..98e37f65f0a --- /dev/null +++ b/csharp/upgrades/5f6770a8a174aa0b651375a847d9686533d3f528/semmlecode.csharp.dbscheme @@ -0,0 +1,1922 @@ + +/** + * An invocation of the compiler. Note that more than one file may be + * compiled per invocation. For example, this command compiles three + * source files: + * + * csc f1.cs f2.cs f3.cs + * + * The `id` simply identifies the invocation, while `cwd` is the working + * directory from which the compiler was invoked. + */ +compilations( + unique int id : @compilation, + string cwd : string ref +); + +/** + * The arguments that were passed to the extractor for a compiler + * invocation. If `id` is for the compiler invocation + * + * csc f1.cs f2.cs f3.cs + * + * then typically there will be rows for + * + * num | arg + * --- | --- + * 0 | --compiler + * 1 | *path to compiler* + * 2 | --cil + * 3 | f1.cs + * 4 | f2.cs + * 5 | f3.cs + */ +#keyset[id, num] +compilation_args( + int id : @compilation ref, + int num : int ref, + string arg : string ref +); + +/** + * The source files that are compiled by a compiler invocation. + * If `id` is for the compiler invocation + * + * csc f1.cs f2.cs f3.cs + * + * then there will be rows for + * + * num | arg + * --- | --- + * 0 | f1.cs + * 1 | f2.cs + * 2 | f3.cs + */ +#keyset[id, num] +compilation_compiling_files( + int id : @compilation ref, + int num : int ref, + int file : @file ref +); + +/** + * The references used by a compiler invocation. + * If `id` is for the compiler invocation + * + * csc f1.cs f2.cs f3.cs /r:ref1.dll /r:ref2.dll /r:ref3.dll + * + * then there will be rows for + * + * num | arg + * --- | --- + * 0 | ref1.dll + * 1 | ref2.dll + * 2 | ref3.dll + */ +#keyset[id, num] +compilation_referencing_files( + int id : @compilation ref, + int num : int ref, + int file : @file ref +); + +/** + * The time taken by the extractor for a compiler invocation. + * + * For each file `num`, there will be rows for + * + * kind | seconds + * ---- | --- + * 1 | CPU seconds used by the extractor frontend + * 2 | Elapsed seconds during the extractor frontend + * 3 | CPU seconds used by the extractor backend + * 4 | Elapsed seconds during the extractor backend + */ +#keyset[id, num, kind] +compilation_time( + int id : @compilation ref, + int num : int ref, + /* kind: + 1 = frontend_cpu_seconds + 2 = frontend_elapsed_seconds + 3 = extractor_cpu_seconds + 4 = extractor_elapsed_seconds + */ + int kind : int ref, + float seconds : float ref +); + +/** + * An error or warning generated by the extractor. + * The diagnostic message `diagnostic` was generated during compiler + * invocation `compilation`, and is the `file_number_diagnostic_number`th + * message generated while extracting the `file_number`th file of that + * invocation. + */ +#keyset[compilation, file_number, file_number_diagnostic_number] +diagnostic_for( + unique int diagnostic : @diagnostic ref, + int compilation : @compilation ref, + int file_number : int ref, + int file_number_diagnostic_number : int ref +); + +diagnostics( + unique int id: @diagnostic, + int severity: int ref, + string error_tag: string ref, + string error_message: string ref, + string full_error_message: string ref, + int location: @location_default ref +); + +extractor_messages( + unique int id: @extractor_message, + int severity: int ref, + string origin : string ref, + string text : string ref, + string entity : string ref, + int location: @location_default ref, + string stack_trace : string ref +); + +/** + * If extraction was successful, then `cpu_seconds` and + * `elapsed_seconds` are the CPU time and elapsed time (respectively) + * that extraction took for compiler invocation `id`. + */ +compilation_finished( + unique int id : @compilation ref, + float cpu_seconds : float ref, + float elapsed_seconds : float ref +); + +compilation_assembly( + unique int id : @compilation ref, + int assembly: @assembly ref +) + +/* + * External artifacts + */ + +externalDefects( + unique int id: @externalDefect, + string queryPath: string ref, + int location: @location ref, + string message: string ref, + float severity: float ref); + +externalMetrics( + unique int id: @externalMetric, + string queryPath: string ref, + int location: @location ref, + float value: float ref); + +externalData( + int id: @externalDataElement, + string path: string ref, + int column: int ref, + string value: string ref); + +snapshotDate( + unique date snapshotDate: date ref); + +sourceLocationPrefix( + string prefix: string ref); + +/* + * Duplicate code + */ + +duplicateCode( + unique int id: @duplication, + string relativePath: string ref, + int equivClass: int ref); + +similarCode( + unique int id: @similarity, + string relativePath: string ref, + int equivClass: int ref); + +@duplication_or_similarity = @duplication | @similarity + +tokens( + int id: @duplication_or_similarity ref, + int offset: int ref, + int beginLine: int ref, + int beginColumn: int ref, + int endLine: int ref, + int endColumn: int ref); + +/* + * C# dbscheme + */ + +/** ELEMENTS **/ + +@element = @declaration | @stmt | @expr | @modifier | @attribute | @namespace_declaration + | @using_directive | @type_parameter_constraints | @external_element + | @xmllocatable | @asp_element | @namespace; + +@declaration = @callable | @generic | @assignable | @namespace; + +@named_element = @namespace | @declaration; + +@declaration_with_accessors = @property | @indexer | @event; + +@assignable = @variable | @assignable_with_accessors | @event; + +@assignable_with_accessors = @property | @indexer; + +@external_element = @externalMetric | @externalDefect | @externalDataElement; + +@attributable = @assembly | @field | @parameter | @operator | @method | @constructor + | @destructor | @callable_accessor | @value_or_ref_type | @declaration_with_accessors + | @local_function; + +/** LOCATIONS, ASEMMBLIES, MODULES, FILES and FOLDERS **/ + +@location = @location_default | @assembly; + +locations_default( + unique int id: @location_default, + int file: @file ref, + int beginLine: int ref, + int beginColumn: int ref, + int endLine: int ref, + int endColumn: int ref); + +@sourceline = @file | @callable | @xmllocatable; + +numlines( + int element_id: @sourceline ref, + int num_lines: int ref, + int num_code: int ref, + int num_comment: int ref); + +assemblies( + unique int id: @assembly, + int file: @file ref, + string fullname: string ref, + string name: string ref, + string version: string ref); + +/* + fromSource(0) = unknown, + fromSource(1) = from source, + fromSource(2) = from library +*/ +files( + unique int id: @file, + string name: string ref, + string simple: string ref, + string ext: string ref, + int fromSource: int ref); + +folders( + unique int id: @folder, + string name: string ref, + string simple: string ref); + +@container = @folder | @file ; + +containerparent( + int parent: @container ref, + unique int child: @container ref); + +file_extraction_mode( + unique int file: @file ref, + int mode: int ref + /* 0 = normal, 1 = standalone extractor */ + ); + +/** NAMESPACES **/ + +@type_container = @namespace | @type; + +namespaces( + unique int id: @namespace, + string name: string ref); + +namespace_declarations( + unique int id: @namespace_declaration, + int namespace_id: @namespace ref); + +namespace_declaration_location( + unique int id: @namespace_declaration ref, + int loc: @location ref); + +parent_namespace( + unique int child_id: @type_container ref, + int namespace_id: @namespace ref); + +@declaration_or_directive = @namespace_declaration | @type | @using_directive; + +parent_namespace_declaration( + int child_id: @declaration_or_directive ref, // cannot be unique because of partial classes + int namespace_id: @namespace_declaration ref); + +@using_directive = @using_namespace_directive | @using_static_directive; + +using_namespace_directives( + unique int id: @using_namespace_directive, + int namespace_id: @namespace ref); + +using_static_directives( + unique int id: @using_static_directive, + int type_id: @type_or_ref ref); + +using_directive_location( + unique int id: @using_directive ref, + int loc: @location ref); + +/** TYPES **/ + +types( + unique int id: @type, + int kind: int ref, + string name: string ref); + +case @type.kind of + 1 = @bool_type +| 2 = @char_type +| 3 = @decimal_type +| 4 = @sbyte_type +| 5 = @short_type +| 6 = @int_type +| 7 = @long_type +| 8 = @byte_type +| 9 = @ushort_type +| 10 = @uint_type +| 11 = @ulong_type +| 12 = @float_type +| 13 = @double_type +| 14 = @enum_type +| 15 = @struct_type +| 17 = @class_type +| 19 = @interface_type +| 20 = @delegate_type +| 21 = @null_type +| 22 = @type_parameter +| 23 = @pointer_type +| 24 = @nullable_type +| 25 = @array_type +| 26 = @void_type +| 27 = @int_ptr_type +| 28 = @uint_ptr_type +| 29 = @dynamic_type +| 30 = @arglist_type +| 31 = @unknown_type +| 32 = @tuple_type + ; + +@simple_type = @bool_type | @char_type | @integral_type | @floating_point_type | @decimal_type; +@integral_type = @signed_integral_type | @unsigned_integral_type; +@signed_integral_type = @sbyte_type | @short_type | @int_type | @long_type; +@unsigned_integral_type = @byte_type | @ushort_type | @uint_type | @ulong_type; +@floating_point_type = @float_type | @double_type; +@value_type = @simple_type | @enum_type | @struct_type | @nullable_type | @int_ptr_type + | @uint_ptr_type | @tuple_type; +@ref_type = @class_type | @interface_type | @array_type | @delegate_type | @null_type + | @dynamic_type; +@value_or_ref_type = @value_type | @ref_type; + +typerefs( + unique int id: @typeref, + string name: string ref); + +typeref_type( + int id: @typeref ref, + unique int typeId: @type ref); + +@type_or_ref = @type | @typeref; + +array_element_type( + unique int array: @array_type ref, + int dimension: int ref, + int rank: int ref, + int element: @type_or_ref ref); + +nullable_underlying_type( + unique int nullable: @nullable_type ref, + int underlying: @type_or_ref ref); + +pointer_referent_type( + unique int pointer: @pointer_type ref, + int referent: @type_or_ref ref); + +enum_underlying_type( + unique int enum_id: @enum_type ref, + int underlying_type_id: @type_or_ref ref); + +delegate_return_type( + unique int delegate_id: @delegate_type ref, + int return_type_id: @type_or_ref ref); + +extend( + unique int sub: @type ref, + int super: @type_or_ref ref); + +anonymous_types( + unique int id: @type ref); + +@interface_or_ref = @interface_type | @typeref; + +implement( + int sub: @type ref, + int super: @type_or_ref ref); + +type_location( + int id: @type ref, + int loc: @location ref); + +tuple_underlying_type( + unique int tuple: @tuple_type ref, + int struct: @type_or_ref ref); + +#keyset[tuple, index] +tuple_element( + int tuple: @tuple_type ref, + int index: int ref, + unique int field: @field ref); + +attributes( + unique int id: @attribute, + int type_id: @type_or_ref ref, + int target: @attributable ref); + +attribute_location( + int id: @attribute ref, + int loc: @location ref); + +@type_mention_parent = @element | @type_mention; + +type_mention( + unique int id: @type_mention, + int type_id: @type_or_ref ref, + int parent: @type_mention_parent ref); + +type_mention_location( + unique int id: @type_mention ref, + int loc: @location ref); + +@has_type_annotation = @assignable | @type_parameter | @callable | @expr | @delegate_type | @generic; + +/** + * A direct annotation on an entity, for example `string? x;`. + * + * Annotations: + * 2 = reftype is not annotated "!" + * 3 = reftype is annotated "?" + * 4 = readonly ref type / in parameter + * 5 = ref type parameter, return or local variable + * 6 = out parameter + * + * Note that the annotation depends on the element it annotates. + * @assignable: The annotation is on the type of the assignable, for example the variable type. + * @type_parameter: The annotation is on the reftype constraint + * @callable: The annotation is on the return type + * @array_type: The annotation is on the element type + */ +type_annotation(int id: @has_type_annotation ref, int annotation: int ref); + +nullability(unique int nullability: @nullability, int kind: int ref); + +case @nullability.kind of + 0 = @oblivious +| 1 = @not_annotated +| 2 = @annotated +; + +#keyset[parent, index] +nullability_parent(int nullability: @nullability ref, int index: int ref, int parent: @nullability ref) + +type_nullability(int id: @has_type_annotation ref, int nullability: @nullability ref); + +/** + * The nullable flow state of an expression, as determined by Roslyn. + * 0 = none (default, not populated) + * 1 = not null + * 2 = maybe null + */ +expr_flowstate(unique int id: @expr ref, int state: int ref); + +/** GENERICS **/ + +@generic = @type | @method | @local_function; + +type_parameters( + unique int id: @type_parameter ref, + int index: int ref, + int generic_id: @generic ref, + int variance: int ref /* none = 0, out = 1, in = 2 */); + +#keyset[constructed_id, index] +type_arguments( + int id: @type_or_ref ref, + int index: int ref, + int constructed_id: @generic_or_ref ref); + +@generic_or_ref = @generic | @typeref; + +constructed_generic( + unique int constructed: @generic ref, + int generic: @generic_or_ref ref); + +type_parameter_constraints( + unique int id: @type_parameter_constraints, + int param_id: @type_parameter ref); + +type_parameter_constraints_location( + int id: @type_parameter_constraints ref, + int loc: @location ref); + +general_type_parameter_constraints( + int id: @type_parameter_constraints ref, + int kind: int ref /* class = 1, struct = 2, new = 3 */); + +specific_type_parameter_constraints( + int id: @type_parameter_constraints ref, + int base_id: @type_or_ref ref); + +specific_type_parameter_nullability( + int id: @type_parameter_constraints ref, + int base_id: @type_or_ref ref, + int nullability: @nullability ref); + +/** MODIFIERS */ + +@modifiable = @modifiable_direct | @event_accessor; + +@modifiable_direct = @member | @accessor | @local_function | @anonymous_function_expr; + +modifiers( + unique int id: @modifier, + string name: string ref); + +has_modifiers( + int id: @modifiable_direct ref, + int mod_id: @modifier ref); + +compiler_generated(unique int id: @modifiable_direct ref); + +/** MEMBERS **/ + +@member = @method | @constructor | @destructor | @field | @property | @event | @operator | @indexer | @type; + +@named_exprorstmt = @goto_stmt | @labeled_stmt | @expr; + +@virtualizable = @method | @property | @indexer | @event; + +exprorstmt_name( + unique int parent_id: @named_exprorstmt ref, + string name: string ref); + +nested_types( + unique int id: @type ref, + int declaring_type_id: @type ref, + int unbound_id: @type ref); + +properties( + unique int id: @property, + string name: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @property ref); + +property_location( + int id: @property ref, + int loc: @location ref); + +indexers( + unique int id: @indexer, + string name: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @indexer ref); + +indexer_location( + int id: @indexer ref, + int loc: @location ref); + +accessors( + unique int id: @accessor, + int kind: int ref, + string name: string ref, + int declaring_member_id: @member ref, + int unbound_id: @accessor ref); + +case @accessor.kind of + 1 = @getter +| 2 = @setter + ; + +init_only_accessors( + unique int id: @accessor ref); + +accessor_location( + int id: @accessor ref, + int loc: @location ref); + +events( + unique int id: @event, + string name: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @event ref); + +event_location( + int id: @event ref, + int loc: @location ref); + +event_accessors( + unique int id: @event_accessor, + int kind: int ref, + string name: string ref, + int declaring_event_id: @event ref, + int unbound_id: @event_accessor ref); + +case @event_accessor.kind of + 1 = @add_event_accessor +| 2 = @remove_event_accessor + ; + +event_accessor_location( + int id: @event_accessor ref, + int loc: @location ref); + +operators( + unique int id: @operator, + string name: string ref, + string symbol: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @operator ref); + +operator_location( + int id: @operator ref, + int loc: @location ref); + +constant_value( + int id: @variable ref, + string value: string ref); + +/** CALLABLES **/ + +@callable = @method | @constructor | @destructor | @operator | @callable_accessor | @anonymous_function_expr | @local_function; + +@callable_accessor = @accessor | @event_accessor; + +methods( + unique int id: @method, + string name: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @method ref); + +method_location( + int id: @method ref, + int loc: @location ref); + +constructors( + unique int id: @constructor, + string name: string ref, + int declaring_type_id: @type ref, + int unbound_id: @constructor ref); + +constructor_location( + int id: @constructor ref, + int loc: @location ref); + +destructors( + unique int id: @destructor, + string name: string ref, + int declaring_type_id: @type ref, + int unbound_id: @destructor ref); + +destructor_location( + int id: @destructor ref, + int loc: @location ref); + +overrides( + int id: @callable ref, + int base_id: @callable ref); + +explicitly_implements( + int id: @member ref, + int interface_id: @interface_or_ref ref); + +local_functions( + unique int id: @local_function, + string name: string ref, + int return_type: @type ref, + int unbound_id: @local_function ref); + +local_function_stmts( + unique int fn: @local_function_stmt ref, + int stmt: @local_function ref); + +/** VARIABLES **/ + +@variable = @local_scope_variable | @field; + +@local_scope_variable = @local_variable | @parameter; + +fields( + unique int id: @field, + int kind: int ref, + string name: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @field ref); + +case @field.kind of + 1 = @addressable_field +| 2 = @constant + ; + +field_location( + int id: @field ref, + int loc: @location ref); + +localvars( + unique int id: @local_variable, + int kind: int ref, + string name: string ref, + int implicitly_typed: int ref /* 0 = no, 1 = yes */, + int type_id: @type_or_ref ref, + int parent_id: @local_var_decl_expr ref); + +case @local_variable.kind of + 1 = @addressable_local_variable +| 2 = @local_constant +| 3 = @local_variable_ref + ; + +localvar_location( + unique int id: @local_variable ref, + int loc: @location ref); + +@parameterizable = @callable | @delegate_type | @indexer; + +#keyset[name, parent_id] +#keyset[index, parent_id] +params( + unique int id: @parameter, + string name: string ref, + int type_id: @type_or_ref ref, + int index: int ref, + int mode: int ref, /* value = 0, ref = 1, out = 2, array = 3, this = 4 */ + int parent_id: @parameterizable ref, + int unbound_id: @parameter ref); + +param_location( + int id: @parameter ref, + int loc: @location ref); + +/** STATEMENTS **/ + +@exprorstmt_parent = @control_flow_element | @top_level_exprorstmt_parent; + +statements( + unique int id: @stmt, + int kind: int ref); + +#keyset[index, parent] +stmt_parent( + unique int stmt: @stmt ref, + int index: int ref, + int parent: @control_flow_element ref); + +@top_level_stmt_parent = @callable; + +// [index, parent] is not a keyset because the same parent may be compiled multiple times +stmt_parent_top_level( + unique int stmt: @stmt ref, + int index: int ref, + int parent: @top_level_stmt_parent ref); + +case @stmt.kind of + 1 = @block_stmt +| 2 = @expr_stmt +| 3 = @if_stmt +| 4 = @switch_stmt +| 5 = @while_stmt +| 6 = @do_stmt +| 7 = @for_stmt +| 8 = @foreach_stmt +| 9 = @break_stmt +| 10 = @continue_stmt +| 11 = @goto_stmt +| 12 = @goto_case_stmt +| 13 = @goto_default_stmt +| 14 = @throw_stmt +| 15 = @return_stmt +| 16 = @yield_stmt +| 17 = @try_stmt +| 18 = @checked_stmt +| 19 = @unchecked_stmt +| 20 = @lock_stmt +| 21 = @using_block_stmt +| 22 = @var_decl_stmt +| 23 = @const_decl_stmt +| 24 = @empty_stmt +| 25 = @unsafe_stmt +| 26 = @fixed_stmt +| 27 = @label_stmt +| 28 = @catch +| 29 = @case_stmt +| 30 = @local_function_stmt +| 31 = @using_decl_stmt + ; + +@using_stmt = @using_block_stmt | @using_decl_stmt; + +@labeled_stmt = @label_stmt | @case; + +@decl_stmt = @var_decl_stmt | @const_decl_stmt | @using_decl_stmt; + +@cond_stmt = @if_stmt | @switch_stmt; + +@loop_stmt = @while_stmt | @do_stmt | @for_stmt | @foreach_stmt; + +@jump_stmt = @break_stmt | @goto_any_stmt | @continue_stmt | @throw_stmt | @return_stmt + | @yield_stmt; + +@goto_any_stmt = @goto_default_stmt | @goto_case_stmt | @goto_stmt; + + +stmt_location( + unique int id: @stmt ref, + int loc: @location ref); + +catch_type( + unique int catch_id: @catch ref, + int type_id: @type_or_ref ref, + int kind: int ref /* explicit = 1, implicit = 2 */); + +/** EXPRESSIONS **/ + +expressions( + unique int id: @expr, + int kind: int ref, + int type_id: @type_or_ref ref); + +#keyset[index, parent] +expr_parent( + unique int expr: @expr ref, + int index: int ref, + int parent: @control_flow_element ref); + +@top_level_expr_parent = @attribute | @field | @property | @indexer | @parameter; + +@top_level_exprorstmt_parent = @top_level_expr_parent | @top_level_stmt_parent; + +// [index, parent] is not a keyset because the same parent may be compiled multiple times +expr_parent_top_level( + unique int expr: @expr ref, + int index: int ref, + int parent: @top_level_exprorstmt_parent ref); + +case @expr.kind of +/* literal */ + 1 = @bool_literal_expr +| 2 = @char_literal_expr +| 3 = @decimal_literal_expr +| 4 = @int_literal_expr +| 5 = @long_literal_expr +| 6 = @uint_literal_expr +| 7 = @ulong_literal_expr +| 8 = @float_literal_expr +| 9 = @double_literal_expr +| 10 = @string_literal_expr +| 11 = @null_literal_expr +/* primary & unary */ +| 12 = @this_access_expr +| 13 = @base_access_expr +| 14 = @local_variable_access_expr +| 15 = @parameter_access_expr +| 16 = @field_access_expr +| 17 = @property_access_expr +| 18 = @method_access_expr +| 19 = @event_access_expr +| 20 = @indexer_access_expr +| 21 = @array_access_expr +| 22 = @type_access_expr +| 23 = @typeof_expr +| 24 = @method_invocation_expr +| 25 = @delegate_invocation_expr +| 26 = @operator_invocation_expr +| 27 = @cast_expr +| 28 = @object_creation_expr +| 29 = @explicit_delegate_creation_expr +| 30 = @implicit_delegate_creation_expr +| 31 = @array_creation_expr +| 32 = @default_expr +| 33 = @plus_expr +| 34 = @minus_expr +| 35 = @bit_not_expr +| 36 = @log_not_expr +| 37 = @post_incr_expr +| 38 = @post_decr_expr +| 39 = @pre_incr_expr +| 40 = @pre_decr_expr +/* multiplicative */ +| 41 = @mul_expr +| 42 = @div_expr +| 43 = @rem_expr +/* additive */ +| 44 = @add_expr +| 45 = @sub_expr +/* shift */ +| 46 = @lshift_expr +| 47 = @rshift_expr +/* relational */ +| 48 = @lt_expr +| 49 = @gt_expr +| 50 = @le_expr +| 51 = @ge_expr +/* equality */ +| 52 = @eq_expr +| 53 = @ne_expr +/* logical */ +| 54 = @bit_and_expr +| 55 = @bit_xor_expr +| 56 = @bit_or_expr +| 57 = @log_and_expr +| 58 = @log_or_expr +/* type testing */ +| 59 = @is_expr +| 60 = @as_expr +/* null coalescing */ +| 61 = @null_coalescing_expr +/* conditional */ +| 62 = @conditional_expr +/* assignment */ +| 63 = @simple_assign_expr +| 64 = @assign_add_expr +| 65 = @assign_sub_expr +| 66 = @assign_mul_expr +| 67 = @assign_div_expr +| 68 = @assign_rem_expr +| 69 = @assign_and_expr +| 70 = @assign_xor_expr +| 71 = @assign_or_expr +| 72 = @assign_lshift_expr +| 73 = @assign_rshift_expr +/* more */ +| 74 = @object_init_expr +| 75 = @collection_init_expr +| 76 = @array_init_expr +| 77 = @checked_expr +| 78 = @unchecked_expr +| 79 = @constructor_init_expr +| 80 = @add_event_expr +| 81 = @remove_event_expr +| 82 = @par_expr +| 83 = @local_var_decl_expr +| 84 = @lambda_expr +| 85 = @anonymous_method_expr +| 86 = @namespace_expr +/* dynamic */ +| 92 = @dynamic_element_access_expr +| 93 = @dynamic_member_access_expr +/* unsafe */ +| 100 = @pointer_indirection_expr +| 101 = @address_of_expr +| 102 = @sizeof_expr +/* async */ +| 103 = @await_expr +/* C# 6.0 */ +| 104 = @nameof_expr +| 105 = @interpolated_string_expr +| 106 = @unknown_expr +/* C# 7.0 */ +| 107 = @throw_expr +| 108 = @tuple_expr +| 109 = @local_function_invocation_expr +| 110 = @ref_expr +| 111 = @discard_expr +/* C# 8.0 */ +| 112 = @range_expr +| 113 = @index_expr +| 114 = @switch_expr +| 115 = @recursive_pattern_expr +| 116 = @property_pattern_expr +| 117 = @positional_pattern_expr +| 118 = @switch_case_expr +| 119 = @assign_coalesce_expr +| 120 = @suppress_nullable_warning_expr +| 121 = @namespace_access_expr +/* C# 9.0 */ +| 122 = @lt_pattern_expr +| 123 = @gt_pattern_expr +| 124 = @le_pattern_expr +| 125 = @ge_pattern_expr +| 126 = @not_pattern_expr +; + +@switch = @switch_stmt | @switch_expr; +@case = @case_stmt | @switch_case_expr; +@pattern_match = @case | @is_expr; +@unary_pattern_expr = @not_pattern_expr; +@relational_pattern_expr = @gt_pattern_expr | @lt_pattern_expr | @ge_pattern_expr | @le_pattern_expr; + +@integer_literal_expr = @int_literal_expr | @long_literal_expr | @uint_literal_expr | @ulong_literal_expr; +@real_literal_expr = @float_literal_expr | @double_literal_expr | @decimal_literal_expr; +@literal_expr = @bool_literal_expr | @char_literal_expr | @integer_literal_expr | @real_literal_expr + | @string_literal_expr | @null_literal_expr; + +@assign_expr = @simple_assign_expr | @assign_op_expr | @local_var_decl_expr; +@assign_op_expr = @assign_arith_expr | @assign_bitwise_expr | @assign_event_expr | @assign_coalesce_expr; +@assign_event_expr = @add_event_expr | @remove_event_expr; + +@assign_arith_expr = @assign_add_expr | @assign_sub_expr | @assign_mul_expr | @assign_div_expr + | @assign_rem_expr +@assign_bitwise_expr = @assign_and_expr | @assign_or_expr | @assign_xor_expr + | @assign_lshift_expr | @assign_rshift_expr; + +@member_access_expr = @field_access_expr | @property_access_expr | @indexer_access_expr | @event_access_expr + | @method_access_expr | @type_access_expr | @dynamic_member_access_expr; +@access_expr = @member_access_expr | @this_access_expr | @base_access_expr | @assignable_access_expr | @namespace_access_expr; +@element_access_expr = @indexer_access_expr | @array_access_expr | @dynamic_element_access_expr; + +@local_variable_access = @local_variable_access_expr | @local_var_decl_expr; +@local_scope_variable_access_expr = @parameter_access_expr | @local_variable_access; +@variable_access_expr = @local_scope_variable_access_expr | @field_access_expr; + +@assignable_access_expr = @variable_access_expr | @property_access_expr | @element_access_expr + | @event_access_expr | @dynamic_member_access_expr; + +@objectorcollection_init_expr = @object_init_expr | @collection_init_expr; + +@delegate_creation_expr = @explicit_delegate_creation_expr | @implicit_delegate_creation_expr; + +@bin_arith_op_expr = @mul_expr | @div_expr | @rem_expr | @add_expr | @sub_expr; +@incr_op_expr = @pre_incr_expr | @post_incr_expr; +@decr_op_expr = @pre_decr_expr | @post_decr_expr; +@mut_op_expr = @incr_op_expr | @decr_op_expr; +@un_arith_op_expr = @plus_expr | @minus_expr | @mut_op_expr; +@arith_op_expr = @bin_arith_op_expr | @un_arith_op_expr; + +@ternary_log_op_expr = @conditional_expr; +@bin_log_op_expr = @log_and_expr | @log_or_expr | @null_coalescing_expr; +@un_log_op_expr = @log_not_expr; +@log_expr = @un_log_op_expr | @bin_log_op_expr | @ternary_log_op_expr; + +@bin_bit_op_expr = @bit_and_expr | @bit_or_expr | @bit_xor_expr | @lshift_expr + | @rshift_expr; +@un_bit_op_expr = @bit_not_expr; +@bit_expr = @un_bit_op_expr | @bin_bit_op_expr; + +@equality_op_expr = @eq_expr | @ne_expr; +@rel_op_expr = @gt_expr | @lt_expr| @ge_expr | @le_expr; +@comp_expr = @equality_op_expr | @rel_op_expr; + +@op_expr = @assign_expr | @un_op | @bin_op | @ternary_op; + +@ternary_op = @ternary_log_op_expr; +@bin_op = @bin_arith_op_expr | @bin_log_op_expr | @bin_bit_op_expr | @comp_expr; +@un_op = @un_arith_op_expr | @un_log_op_expr | @un_bit_op_expr | @sizeof_expr + | @pointer_indirection_expr | @address_of_expr; + +@anonymous_function_expr = @lambda_expr | @anonymous_method_expr; + +@call = @method_invocation_expr | @constructor_init_expr | @operator_invocation_expr + | @delegate_invocation_expr | @object_creation_expr | @call_access_expr + | @local_function_invocation_expr; + +@call_access_expr = @property_access_expr | @event_access_expr | @indexer_access_expr; + +@late_bindable_expr = @dynamic_element_access_expr | @dynamic_member_access_expr + | @object_creation_expr | @method_invocation_expr | @operator_invocation_expr; + +@throw_element = @throw_expr | @throw_stmt; + +@implicitly_typeable_object_creation_expr = @object_creation_expr | @explicit_delegate_creation_expr; + +implicitly_typed_array_creation( + unique int id: @array_creation_expr ref); + +explicitly_sized_array_creation( + unique int id: @array_creation_expr ref); + +stackalloc_array_creation( + unique int id: @array_creation_expr ref); + +implicitly_typed_object_creation( + unique int id: @implicitly_typeable_object_creation_expr ref); + +mutator_invocation_mode( + unique int id: @operator_invocation_expr ref, + int mode: int ref /* prefix = 1, postfix = 2*/); + +expr_compiler_generated( + unique int id: @expr ref); + +expr_value( + unique int id: @expr ref, + string value: string ref); + +expr_call( + unique int caller_id: @expr ref, + int target_id: @callable ref); + +expr_access( + unique int accesser_id: @access_expr ref, + int target_id: @accessible ref); + +@accessible = @method | @assignable | @local_function | @namespace; + +expr_location( + unique int id: @expr ref, + int loc: @location ref); + +dynamic_member_name( + unique int id: @late_bindable_expr ref, + string name: string ref); + +@qualifiable_expr = @member_access_expr + | @method_invocation_expr + | @element_access_expr; + +conditional_access( + unique int id: @qualifiable_expr ref); + +expr_argument( + unique int id: @expr ref, + int mode: int ref); + /* mode is the same as params: value = 0, ref = 1, out = 2 */ + +expr_argument_name( + unique int id: @expr ref, + string name: string ref); + +/** CONTROL/DATA FLOW **/ + +@control_flow_element = @stmt | @expr; + +/* XML Files */ + +xmlEncoding ( + unique int id: @file ref, + string encoding: string ref); + +xmlDTDs( + unique int id: @xmldtd, + string root: string ref, + string publicId: string ref, + string systemId: string ref, + int fileid: @file ref); + +xmlElements( + unique int id: @xmlelement, + string name: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int fileid: @file ref); + +xmlAttrs( + unique int id: @xmlattribute, + int elementid: @xmlelement ref, + string name: string ref, + string value: string ref, + int idx: int ref, + int fileid: @file ref); + +xmlNs( + int id: @xmlnamespace, + string prefixName: string ref, + string URI: string ref, + int fileid: @file ref); + +xmlHasNs( + int elementId: @xmlnamespaceable ref, + int nsId: @xmlnamespace ref, + int fileid: @file ref); + +xmlComments( + unique int id: @xmlcomment, + string text: string ref, + int parentid: @xmlparent ref, + int fileid: @file ref); + +xmlChars( + unique int id: @xmlcharacters, + string text: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int isCDATA: int ref, + int fileid: @file ref); + +@xmlparent = @file | @xmlelement; +@xmlnamespaceable = @xmlelement | @xmlattribute; + +xmllocations( + int xmlElement: @xmllocatable ref, + int location: @location_default ref); + +@xmllocatable = @xmlcharacters | @xmlelement | @xmlcomment | @xmlattribute | @xmldtd | @file | @xmlnamespace; + +/* Comments */ + +commentline( + unique int id: @commentline, + int kind: int ref, + string text: string ref, + string rawtext: string ref); + +case @commentline.kind of + 0 = @singlelinecomment +| 1 = @xmldoccomment +| 2 = @multilinecomment; + +commentline_location( + unique int id: @commentline ref, + int loc: @location ref); + +commentblock( + unique int id : @commentblock); + +commentblock_location( + unique int id: @commentblock ref, + int loc: @location ref); + +commentblock_binding( + int id: @commentblock ref, + int entity: @element ref, + int bindtype: int ref); /* 0: Parent, 1: Best, 2: Before, 3: After */ + +commentblock_child( + int id: @commentblock ref, + int commentline: @commentline ref, + int index: int ref); + +/* ASP.NET */ + +case @asp_element.kind of + 0=@asp_close_tag +| 1=@asp_code +| 2=@asp_comment +| 3=@asp_data_binding +| 4=@asp_directive +| 5=@asp_open_tag +| 6=@asp_quoted_string +| 7=@asp_text +| 8=@asp_xml_directive; + +@asp_attribute = @asp_code | @asp_data_binding | @asp_quoted_string; + +asp_elements( + unique int id: @asp_element, + int kind: int ref, + int loc: @location ref); + +asp_comment_server(unique int comment: @asp_comment ref); +asp_code_inline(unique int code: @asp_code ref); +asp_directive_attribute( + int directive: @asp_directive ref, + int index: int ref, + string name: string ref, + int value: @asp_quoted_string ref); +asp_directive_name( + unique int directive: @asp_directive ref, + string name: string ref); +asp_element_body( + unique int element: @asp_element ref, + string body: string ref); +asp_tag_attribute( + int tag: @asp_open_tag ref, + int index: int ref, + string name: string ref, + int attribute: @asp_attribute ref); +asp_tag_name( + unique int tag: @asp_open_tag ref, + string name: string ref); +asp_tag_isempty(int tag: @asp_open_tag ref); + +/* Common Intermediate Language - CIL */ + +case @cil_instruction.opcode of + 0 = @cil_nop +| 1 = @cil_break +| 2 = @cil_ldarg_0 +| 3 = @cil_ldarg_1 +| 4 = @cil_ldarg_2 +| 5 = @cil_ldarg_3 +| 6 = @cil_ldloc_0 +| 7 = @cil_ldloc_1 +| 8 = @cil_ldloc_2 +| 9 = @cil_ldloc_3 +| 10 = @cil_stloc_0 +| 11 = @cil_stloc_1 +| 12 = @cil_stloc_2 +| 13 = @cil_stloc_3 +| 14 = @cil_ldarg_s +| 15 = @cil_ldarga_s +| 16 = @cil_starg_s +| 17 = @cil_ldloc_s +| 18 = @cil_ldloca_s +| 19 = @cil_stloc_s +| 20 = @cil_ldnull +| 21 = @cil_ldc_i4_m1 +| 22 = @cil_ldc_i4_0 +| 23 = @cil_ldc_i4_1 +| 24 = @cil_ldc_i4_2 +| 25 = @cil_ldc_i4_3 +| 26 = @cil_ldc_i4_4 +| 27 = @cil_ldc_i4_5 +| 28 = @cil_ldc_i4_6 +| 29 = @cil_ldc_i4_7 +| 30 = @cil_ldc_i4_8 +| 31 = @cil_ldc_i4_s +| 32 = @cil_ldc_i4 +| 33 = @cil_ldc_i8 +| 34 = @cil_ldc_r4 +| 35 = @cil_ldc_r8 +| 37 = @cil_dup +| 38 = @cil_pop +| 39 = @cil_jmp +| 40 = @cil_call +| 41 = @cil_calli +| 42 = @cil_ret +| 43 = @cil_br_s +| 44 = @cil_brfalse_s +| 45 = @cil_brtrue_s +| 46 = @cil_beq_s +| 47 = @cil_bge_s +| 48 = @cil_bgt_s +| 49 = @cil_ble_s +| 50 = @cil_blt_s +| 51 = @cil_bne_un_s +| 52 = @cil_bge_un_s +| 53 = @cil_bgt_un_s +| 54 = @cil_ble_un_s +| 55 = @cil_blt_un_s +| 56 = @cil_br +| 57 = @cil_brfalse +| 58 = @cil_brtrue +| 59 = @cil_beq +| 60 = @cil_bge +| 61 = @cil_bgt +| 62 = @cil_ble +| 63 = @cil_blt +| 64 = @cil_bne_un +| 65 = @cil_bge_un +| 66 = @cil_bgt_un +| 67 = @cil_ble_un +| 68 = @cil_blt_un +| 69 = @cil_switch +| 70 = @cil_ldind_i1 +| 71 = @cil_ldind_u1 +| 72 = @cil_ldind_i2 +| 73 = @cil_ldind_u2 +| 74 = @cil_ldind_i4 +| 75 = @cil_ldind_u4 +| 76 = @cil_ldind_i8 +| 77 = @cil_ldind_i +| 78 = @cil_ldind_r4 +| 79 = @cil_ldind_r8 +| 80 = @cil_ldind_ref +| 81 = @cil_stind_ref +| 82 = @cil_stind_i1 +| 83 = @cil_stind_i2 +| 84 = @cil_stind_i4 +| 85 = @cil_stind_i8 +| 86 = @cil_stind_r4 +| 87 = @cil_stind_r8 +| 88 = @cil_add +| 89 = @cil_sub +| 90 = @cil_mul +| 91 = @cil_div +| 92 = @cil_div_un +| 93 = @cil_rem +| 94 = @cil_rem_un +| 95 = @cil_and +| 96 = @cil_or +| 97 = @cil_xor +| 98 = @cil_shl +| 99 = @cil_shr +| 100 = @cil_shr_un +| 101 = @cil_neg +| 102 = @cil_not +| 103 = @cil_conv_i1 +| 104 = @cil_conv_i2 +| 105 = @cil_conv_i4 +| 106 = @cil_conv_i8 +| 107 = @cil_conv_r4 +| 108 = @cil_conv_r8 +| 109 = @cil_conv_u4 +| 110 = @cil_conv_u8 +| 111 = @cil_callvirt +| 112 = @cil_cpobj +| 113 = @cil_ldobj +| 114 = @cil_ldstr +| 115 = @cil_newobj +| 116 = @cil_castclass +| 117 = @cil_isinst +| 118 = @cil_conv_r_un +| 121 = @cil_unbox +| 122 = @cil_throw +| 123 = @cil_ldfld +| 124 = @cil_ldflda +| 125 = @cil_stfld +| 126 = @cil_ldsfld +| 127 = @cil_ldsflda +| 128 = @cil_stsfld +| 129 = @cil_stobj +| 130 = @cil_conv_ovf_i1_un +| 131 = @cil_conv_ovf_i2_un +| 132 = @cil_conv_ovf_i4_un +| 133 = @cil_conv_ovf_i8_un +| 134 = @cil_conv_ovf_u1_un +| 135 = @cil_conv_ovf_u2_un +| 136 = @cil_conv_ovf_u4_un +| 137 = @cil_conv_ovf_u8_un +| 138 = @cil_conv_ovf_i_un +| 139 = @cil_conv_ovf_u_un +| 140 = @cil_box +| 141 = @cil_newarr +| 142 = @cil_ldlen +| 143 = @cil_ldelema +| 144 = @cil_ldelem_i1 +| 145 = @cil_ldelem_u1 +| 146 = @cil_ldelem_i2 +| 147 = @cil_ldelem_u2 +| 148 = @cil_ldelem_i4 +| 149 = @cil_ldelem_u4 +| 150 = @cil_ldelem_i8 +| 151 = @cil_ldelem_i +| 152 = @cil_ldelem_r4 +| 153 = @cil_ldelem_r8 +| 154 = @cil_ldelem_ref +| 155 = @cil_stelem_i +| 156 = @cil_stelem_i1 +| 157 = @cil_stelem_i2 +| 158 = @cil_stelem_i4 +| 159 = @cil_stelem_i8 +| 160 = @cil_stelem_r4 +| 161 = @cil_stelem_r8 +| 162 = @cil_stelem_ref +| 163 = @cil_ldelem +| 164 = @cil_stelem +| 165 = @cil_unbox_any +| 179 = @cil_conv_ovf_i1 +| 180 = @cil_conv_ovf_u1 +| 181 = @cil_conv_ovf_i2 +| 182 = @cil_conv_ovf_u2 +| 183 = @cil_conv_ovf_i4 +| 184 = @cil_conv_ovf_u4 +| 185 = @cil_conv_ovf_i8 +| 186 = @cil_conv_ovf_u8 +| 194 = @cil_refanyval +| 195 = @cil_ckinfinite +| 198 = @cil_mkrefany +| 208 = @cil_ldtoken +| 209 = @cil_conv_u2 +| 210 = @cil_conv_u1 +| 211 = @cil_conv_i +| 212 = @cil_conv_ovf_i +| 213 = @cil_conv_ovf_u +| 214 = @cil_add_ovf +| 215 = @cil_add_ovf_un +| 216 = @cil_mul_ovf +| 217 = @cil_mul_ovf_un +| 218 = @cil_sub_ovf +| 219 = @cil_sub_ovf_un +| 220 = @cil_endfinally +| 221 = @cil_leave +| 222 = @cil_leave_s +| 223 = @cil_stind_i +| 224 = @cil_conv_u +| 65024 = @cil_arglist +| 65025 = @cil_ceq +| 65026 = @cil_cgt +| 65027 = @cil_cgt_un +| 65028 = @cil_clt +| 65029 = @cil_clt_un +| 65030 = @cil_ldftn +| 65031 = @cil_ldvirtftn +| 65033 = @cil_ldarg +| 65034 = @cil_ldarga +| 65035 = @cil_starg +| 65036 = @cil_ldloc +| 65037 = @cil_ldloca +| 65038 = @cil_stloc +| 65039 = @cil_localloc +| 65041 = @cil_endfilter +| 65042 = @cil_unaligned +| 65043 = @cil_volatile +| 65044 = @cil_tail +| 65045 = @cil_initobj +| 65046 = @cil_constrained +| 65047 = @cil_cpblk +| 65048 = @cil_initblk +| 65050 = @cil_rethrow +| 65052 = @cil_sizeof +| 65053 = @cil_refanytype +| 65054 = @cil_readonly +; + +// CIL ignored instructions + +@cil_ignore = @cil_nop | @cil_break | @cil_volatile | @cil_unaligned; + +// CIL local/parameter/field access + +@cil_ldarg_any = @cil_ldarg_0 | @cil_ldarg_1 | @cil_ldarg_2 | @cil_ldarg_3 | @cil_ldarg_s | @cil_ldarga_s | @cil_ldarg | @cil_ldarga; +@cil_starg_any = @cil_starg | @cil_starg_s; + +@cil_ldloc_any = @cil_ldloc_0 | @cil_ldloc_1 | @cil_ldloc_2 | @cil_ldloc_3 | @cil_ldloc_s | @cil_ldloca_s | @cil_ldloc | @cil_ldloca; +@cil_stloc_any = @cil_stloc_0 | @cil_stloc_1 | @cil_stloc_2 | @cil_stloc_3 | @cil_stloc_s | @cil_stloc; + +@cil_ldfld_any = @cil_ldfld | @cil_ldsfld | @cil_ldsflda | @cil_ldflda; +@cil_stfld_any = @cil_stfld | @cil_stsfld; + +@cil_local_access = @cil_stloc_any | @cil_ldloc_any; +@cil_arg_access = @cil_starg_any | @cil_ldarg_any; +@cil_read_access = @cil_ldloc_any | @cil_ldarg_any | @cil_ldfld_any; +@cil_write_access = @cil_stloc_any | @cil_starg_any | @cil_stfld_any; + +@cil_stack_access = @cil_local_access | @cil_arg_access; +@cil_field_access = @cil_ldfld_any | @cil_stfld_any; + +@cil_access = @cil_read_access | @cil_write_access; + +// CIL constant/literal instructions + +@cil_ldc_i = @cil_ldc_i4_any | @cil_ldc_i8; + +@cil_ldc_i4_any = @cil_ldc_i4_m1 | @cil_ldc_i4_0 | @cil_ldc_i4_1 | @cil_ldc_i4_2 | @cil_ldc_i4_3 | + @cil_ldc_i4_4 | @cil_ldc_i4_5 | @cil_ldc_i4_6 | @cil_ldc_i4_7 | @cil_ldc_i4_8 | @cil_ldc_i4_s | @cil_ldc_i4; + +@cil_ldc_r = @cil_ldc_r4 | @cil_ldc_r8; + +@cil_literal = @cil_ldnull | @cil_ldc_i | @cil_ldc_r | @cil_ldstr; + +// Control flow + +@cil_conditional_jump = @cil_binary_jump | @cil_unary_jump; +@cil_binary_jump = @cil_beq_s | @cil_bge_s | @cil_bgt_s | @cil_ble_s | @cil_blt_s | + @cil_bne_un_s | @cil_bge_un_s | @cil_bgt_un_s | @cil_ble_un_s | @cil_blt_un_s | + @cil_beq | @cil_bge | @cil_bgt | @cil_ble | @cil_blt | + @cil_bne_un | @cil_bge_un | @cil_bgt_un | @cil_ble_un | @cil_blt_un; +@cil_unary_jump = @cil_brfalse_s | @cil_brtrue_s | @cil_brfalse | @cil_brtrue | @cil_switch; +@cil_unconditional_jump = @cil_br | @cil_br_s | @cil_leave_any; +@cil_leave_any = @cil_leave | @cil_leave_s; +@cil_jump = @cil_unconditional_jump | @cil_conditional_jump; + +// CIL call instructions + +@cil_call_any = @cil_jmp | @cil_call | @cil_calli | @cil_tail | @cil_callvirt | @cil_newobj; + +// CIL expression instructions + +@cil_expr = @cil_literal | @cil_binary_expr | @cil_unary_expr | @cil_call_any | @cil_read_access | + @cil_newarr | @cil_ldtoken | @cil_sizeof | + @cil_ldftn | @cil_ldvirtftn | @cil_localloc | @cil_mkrefany | @cil_refanytype | @cil_arglist | @cil_dup; + +@cil_unary_expr = + @cil_conversion_operation | @cil_unary_arithmetic_operation | @cil_unary_bitwise_operation| + @cil_ldlen | @cil_isinst | @cil_box | @cil_ldobj | @cil_castclass | @cil_unbox_any | + @cil_ldind | @cil_unbox; + +@cil_conversion_operation = + @cil_conv_i1 | @cil_conv_i2 | @cil_conv_i4 | @cil_conv_i8 | + @cil_conv_u1 | @cil_conv_u2 | @cil_conv_u4 | @cil_conv_u8 | + @cil_conv_ovf_i | @cil_conv_ovf_i_un | @cil_conv_ovf_i1 | @cil_conv_ovf_i1_un | + @cil_conv_ovf_i2 | @cil_conv_ovf_i2_un | @cil_conv_ovf_i4 | @cil_conv_ovf_i4_un | + @cil_conv_ovf_i8 | @cil_conv_ovf_i8_un | @cil_conv_ovf_u | @cil_conv_ovf_u_un | + @cil_conv_ovf_u1 | @cil_conv_ovf_u1_un | @cil_conv_ovf_u2 | @cil_conv_ovf_u2_un | + @cil_conv_ovf_u4 | @cil_conv_ovf_u4_un | @cil_conv_ovf_u8 | @cil_conv_ovf_u8_un | + @cil_conv_r4 | @cil_conv_r8 | @cil_conv_ovf_u2 | @cil_conv_ovf_u2_un | + @cil_conv_i | @cil_conv_u | @cil_conv_r_un; + +@cil_ldind = @cil_ldind_i | @cil_ldind_i1 | @cil_ldind_i2 | @cil_ldind_i4 | @cil_ldind_i8 | + @cil_ldind_r4 | @cil_ldind_r8 | @cil_ldind_ref | @cil_ldind_u1 | @cil_ldind_u2 | @cil_ldind_u4; + +@cil_stind = @cil_stind_i | @cil_stind_i1 | @cil_stind_i2 | @cil_stind_i4 | @cil_stind_i8 | + @cil_stind_r4 | @cil_stind_r8 | @cil_stind_ref; + +@cil_bitwise_operation = @cil_binary_bitwise_operation | @cil_unary_bitwise_operation; + +@cil_binary_bitwise_operation = @cil_and | @cil_or | @cil_xor | @cil_shr | @cil_shr | @cil_shr_un | @cil_shl; + +@cil_binary_arithmetic_operation = @cil_add | @cil_sub | @cil_mul | @cil_div | @cil_div_un | + @cil_rem | @cil_rem_un | @cil_add_ovf | @cil_add_ovf_un | @cil_mul_ovf | @cil_mul_ovf_un | + @cil_sub_ovf | @cil_sub_ovf_un; + +@cil_unary_bitwise_operation = @cil_not; + +@cil_binary_expr = @cil_binary_arithmetic_operation | @cil_binary_bitwise_operation | @cil_read_array | @cil_comparison_operation; + +@cil_unary_arithmetic_operation = @cil_neg; + +@cil_comparison_operation = @cil_cgt_un | @cil_ceq | @cil_cgt | @cil_clt | @cil_clt_un; + +// Elements that retrieve an address of something +@cil_read_ref = @cil_ldloca_s | @cil_ldarga_s | @cil_ldflda | @cil_ldsflda | @cil_ldelema; + +// CIL array instructions + +@cil_read_array = + @cil_ldelem | @cil_ldelema | @cil_ldelem_i1 | @cil_ldelem_ref | @cil_ldelem_i | + @cil_ldelem_i1 | @cil_ldelem_i2 | @cil_ldelem_i4 | @cil_ldelem_i8 | @cil_ldelem_r4 | + @cil_ldelem_r8 | @cil_ldelem_u1 | @cil_ldelem_u2 | @cil_ldelem_u4; + +@cil_write_array = @cil_stelem | @cil_stelem_ref | + @cil_stelem_i | @cil_stelem_i1 | @cil_stelem_i2 | @cil_stelem_i4 | @cil_stelem_i8 | + @cil_stelem_r4 | @cil_stelem_r8; + +@cil_throw_any = @cil_throw | @cil_rethrow; + +#keyset[impl, index] +cil_instruction( + unique int id: @cil_instruction, + int opcode: int ref, + int index: int ref, + int impl: @cil_method_implementation ref); + +cil_jump( + unique int instruction: @cil_jump ref, + int target: @cil_instruction ref); + +cil_access( + unique int instruction: @cil_instruction ref, + int target: @cil_accessible ref); + +cil_value( + unique int instruction: @cil_literal ref, + string value: string ref); + +#keyset[instruction, index] +cil_switch( + int instruction: @cil_switch ref, + int index: int ref, + int target: @cil_instruction ref); + +cil_instruction_location( + unique int id: @cil_instruction ref, + int loc: @location ref); + +cil_type_location( + int id: @cil_type ref, + int loc: @location ref); + +cil_method_location( + int id: @cil_method ref, + int loc: @location ref); + +@cil_namespace = @namespace; + +@cil_type_container = @cil_type | @cil_namespace | @cil_method; + +case @cil_type.kind of + 0 = @cil_valueorreftype +| 1 = @cil_typeparameter +| 2 = @cil_array_type +| 3 = @cil_pointer_type +; + +cil_type( + unique int id: @cil_type, + string name: string ref, + int kind: int ref, + int parent: @cil_type_container ref, + int sourceDecl: @cil_type ref); + +cil_pointer_type( + unique int id: @cil_pointer_type ref, + int pointee: @cil_type ref); + +cil_array_type( + unique int id: @cil_array_type ref, + int element_type: @cil_type ref, + int rank: int ref); + +cil_method( + unique int id: @cil_method, + string name: string ref, + int parent: @cil_type ref, + int return_type: @cil_type ref); + +cil_method_source_declaration( + unique int method: @cil_method ref, + int source: @cil_method ref); + +cil_method_implementation( + unique int id: @cil_method_implementation, + int method: @cil_method ref, + int location: @assembly ref); + +cil_implements( + int id: @cil_method ref, + int decl: @cil_method ref); + +#keyset[parent, name] +cil_field( + unique int id: @cil_field, + int parent: @cil_type ref, + string name: string ref, + int field_type: @cil_type ref); + +@cil_element = @cil_instruction | @cil_declaration | @cil_handler | @cil_attribute | @cil_namespace; +@cil_named_element = @cil_declaration | @cil_namespace; +@cil_declaration = @cil_variable | @cil_method | @cil_type | @cil_member; +@cil_accessible = @cil_declaration; +@cil_variable = @cil_field | @cil_stack_variable; +@cil_stack_variable = @cil_local_variable | @cil_parameter; +@cil_member = @cil_method | @cil_type | @cil_field | @cil_property | @cil_event; +@cil_custom_modifier_receiver = @cil_method | @cil_property | @cil_parameter | @cil_field; // todo: add function pointer type + +#keyset[method, index] +cil_parameter( + unique int id: @cil_parameter, + int method: @cil_method ref, + int index: int ref, + int param_type: @cil_type ref); + +cil_parameter_in(unique int id: @cil_parameter ref); +cil_parameter_out(unique int id: @cil_parameter ref); + +cil_setter(unique int prop: @cil_property ref, + int method: @cil_method ref); + +#keyset[id, modifier] +cil_custom_modifiers( + int id: @cil_custom_modifier_receiver ref, + int modifier: @cil_type ref, + int kind: int ref); // modreq: 1, modopt: 0 + +cil_getter(unique int prop: @cil_property ref, + int method: @cil_method ref); + +cil_adder(unique int event: @cil_event ref, + int method: @cil_method ref); + +cil_remover(unique int event: @cil_event ref, int method: @cil_method ref); + +cil_raiser(unique int event: @cil_event ref, int method: @cil_method ref); + +cil_property( + unique int id: @cil_property, + int parent: @cil_type ref, + string name: string ref, + int property_type: @cil_type ref); + +#keyset[parent, name] +cil_event(unique int id: @cil_event, + int parent: @cil_type ref, + string name: string ref, + int event_type: @cil_type ref); + +#keyset[impl, index] +cil_local_variable( + unique int id: @cil_local_variable, + int impl: @cil_method_implementation ref, + int index: int ref, + int var_type: @cil_type ref); + +// CIL handlers (exception handlers etc). + +case @cil_handler.kind of + 0 = @cil_catch_handler +| 1 = @cil_filter_handler +| 2 = @cil_finally_handler +| 4 = @cil_fault_handler +; + +#keyset[impl, index] +cil_handler( + unique int id: @cil_handler, + int impl: @cil_method_implementation ref, + int index: int ref, + int kind: int ref, + int try_start: @cil_instruction ref, + int try_end: @cil_instruction ref, + int handler_start: @cil_instruction ref); + +cil_handler_filter( + unique int id: @cil_handler ref, + int filter_start: @cil_instruction ref); + +cil_handler_type( + unique int id: @cil_handler ref, + int catch_type: @cil_type ref); + +@cil_controlflow_node = @cil_entry_point | @cil_instruction; + +@cil_entry_point = @cil_method_implementation | @cil_handler; + +@cil_dataflow_node = @cil_instruction | @cil_variable | @cil_method; + +cil_method_stack_size( + unique int method: @cil_method_implementation ref, + int size: int ref); + +// CIL modifiers + +cil_public(int id: @cil_member ref); +cil_private(int id: @cil_member ref); +cil_protected(int id: @cil_member ref); +cil_internal(int id: @cil_member ref); +cil_static(int id: @cil_member ref); +cil_sealed(int id: @cil_member ref); +cil_virtual(int id: @cil_method ref); +cil_abstract(int id: @cil_member ref); +cil_class(int id: @cil_type ref); +cil_interface(int id: @cil_type ref); +cil_security(int id: @cil_member ref); +cil_requiresecobject(int id: @cil_method ref); +cil_specialname(int id: @cil_method ref); +cil_newslot(int id: @cil_method ref); + +cil_base_class(unique int id: @cil_type ref, int base: @cil_type ref); +cil_base_interface(int id: @cil_type ref, int base: @cil_type ref); +cil_enum_underlying_type(unique int id: @cil_type ref, int underlying: @cil_type ref); + +#keyset[unbound, index] +cil_type_parameter( + int unbound: @cil_member ref, + int index: int ref, + int param: @cil_typeparameter ref); + +#keyset[bound, index] +cil_type_argument( + int bound: @cil_member ref, + int index: int ref, + int t: @cil_type ref); + +// CIL type parameter constraints + +cil_typeparam_covariant(int tp: @cil_typeparameter ref); +cil_typeparam_contravariant(int tp: @cil_typeparameter ref); +cil_typeparam_class(int tp: @cil_typeparameter ref); +cil_typeparam_struct(int tp: @cil_typeparameter ref); +cil_typeparam_new(int tp: @cil_typeparameter ref); +cil_typeparam_constraint(int tp: @cil_typeparameter ref, int supertype: @cil_type ref); + +// CIL attributes + +cil_attribute( + unique int attributeid: @cil_attribute, + int element: @cil_declaration ref, + int constructor: @cil_method ref); + +#keyset[attribute_id, param] +cil_attribute_named_argument( + int attribute_id: @cil_attribute ref, + string param: string ref, + string value: string ref); + +#keyset[attribute_id, index] +cil_attribute_positional_argument( + int attribute_id: @cil_attribute ref, + int index: int ref, + string value: string ref); + + +// Common .Net data model covering both C# and CIL + +// Common elements +@dotnet_element = @element | @cil_element; +@dotnet_named_element = @named_element | @cil_named_element; +@dotnet_callable = @callable | @cil_method; +@dotnet_variable = @variable | @cil_variable; +@dotnet_field = @field | @cil_field; +@dotnet_parameter = @parameter | @cil_parameter; +@dotnet_declaration = @declaration | @cil_declaration; +@dotnet_member = @member | @cil_member; +@dotnet_event = @event | @cil_event; +@dotnet_property = @property | @cil_property | @indexer; + +// Common types +@dotnet_type = @type | @cil_type; +@dotnet_call = @call | @cil_call_any; +@dotnet_throw = @throw_element | @cil_throw_any; +@dotnet_valueorreftype = @cil_valueorreftype | @value_or_ref_type | @cil_array_type | @void_type; +@dotnet_typeparameter = @type_parameter | @cil_typeparameter; +@dotnet_array_type = @array_type | @cil_array_type; +@dotnet_pointer_type = @pointer_type | @cil_pointer_type; +@dotnet_type_parameter = @type_parameter | @cil_typeparameter; +@dotnet_generic = @dotnet_valueorreftype | @dotnet_callable; + +// Attributes +@dotnet_attribute = @attribute | @cil_attribute; + +// Expressions +@dotnet_expr = @expr | @cil_expr; + +// Literals +@dotnet_literal = @literal_expr | @cil_literal; +@dotnet_string_literal = @string_literal_expr | @cil_ldstr; +@dotnet_int_literal = @integer_literal_expr | @cil_ldc_i; +@dotnet_float_literal = @float_literal_expr | @cil_ldc_r; +@dotnet_null_literal = @null_literal_expr | @cil_ldnull; + +@metadata_entity = @cil_method | @cil_type | @cil_field | @cil_property | @field | @property | + @callable | @value_or_ref_type | @void_type; + +#keyset[entity, location] +metadata_handle(int entity : @metadata_entity ref, int location: @assembly ref, int handle: int ref) diff --git a/csharp/upgrades/5f6770a8a174aa0b651375a847d9686533d3f528/upgrade.properties b/csharp/upgrades/5f6770a8a174aa0b651375a847d9686533d3f528/upgrade.properties new file mode 100644 index 00000000000..87219db2b0a --- /dev/null +++ b/csharp/upgrades/5f6770a8a174aa0b651375a847d9686533d3f528/upgrade.properties @@ -0,0 +1,2 @@ +description: Add relational patterns to the list of 'expr' types. +compatibility: backwards diff --git a/csharp/upgrades/68db341c2ed1693c2ae6e20ad533c84138cb275a/old.dbscheme b/csharp/upgrades/68db341c2ed1693c2ae6e20ad533c84138cb275a/old.dbscheme new file mode 100644 index 00000000000..68db341c2ed --- /dev/null +++ b/csharp/upgrades/68db341c2ed1693c2ae6e20ad533c84138cb275a/old.dbscheme @@ -0,0 +1,2070 @@ + +/** + * An invocation of the compiler. Note that more than one file may be + * compiled per invocation. For example, this command compiles three + * source files: + * + * csc f1.cs f2.cs f3.cs + * + * The `id` simply identifies the invocation, while `cwd` is the working + * directory from which the compiler was invoked. + */ +compilations( + unique int id : @compilation, + string cwd : string ref +); + +/** + * The arguments that were passed to the extractor for a compiler + * invocation. If `id` is for the compiler invocation + * + * csc f1.cs f2.cs f3.cs + * + * then typically there will be rows for + * + * num | arg + * --- | --- + * 0 | --compiler + * 1 | *path to compiler* + * 2 | --cil + * 3 | f1.cs + * 4 | f2.cs + * 5 | f3.cs + */ +#keyset[id, num] +compilation_args( + int id : @compilation ref, + int num : int ref, + string arg : string ref +); + +/** + * The source files that are compiled by a compiler invocation. + * If `id` is for the compiler invocation + * + * csc f1.cs f2.cs f3.cs + * + * then there will be rows for + * + * num | arg + * --- | --- + * 0 | f1.cs + * 1 | f2.cs + * 2 | f3.cs + */ +#keyset[id, num] +compilation_compiling_files( + int id : @compilation ref, + int num : int ref, + int file : @file ref +); + +/** + * The references used by a compiler invocation. + * If `id` is for the compiler invocation + * + * csc f1.cs f2.cs f3.cs /r:ref1.dll /r:ref2.dll /r:ref3.dll + * + * then there will be rows for + * + * num | arg + * --- | --- + * 0 | ref1.dll + * 1 | ref2.dll + * 2 | ref3.dll + */ +#keyset[id, num] +compilation_referencing_files( + int id : @compilation ref, + int num : int ref, + int file : @file ref +); + +/** + * The time taken by the extractor for a compiler invocation. + * + * For each file `num`, there will be rows for + * + * kind | seconds + * ---- | --- + * 1 | CPU seconds used by the extractor frontend + * 2 | Elapsed seconds during the extractor frontend + * 3 | CPU seconds used by the extractor backend + * 4 | Elapsed seconds during the extractor backend + */ +#keyset[id, num, kind] +compilation_time( + int id : @compilation ref, + int num : int ref, + /* kind: + 1 = frontend_cpu_seconds + 2 = frontend_elapsed_seconds + 3 = extractor_cpu_seconds + 4 = extractor_elapsed_seconds + */ + int kind : int ref, + float seconds : float ref +); + +/** + * An error or warning generated by the extractor. + * The diagnostic message `diagnostic` was generated during compiler + * invocation `compilation`, and is the `file_number_diagnostic_number`th + * message generated while extracting the `file_number`th file of that + * invocation. + */ +#keyset[compilation, file_number, file_number_diagnostic_number] +diagnostic_for( + unique int diagnostic : @diagnostic ref, + int compilation : @compilation ref, + int file_number : int ref, + int file_number_diagnostic_number : int ref +); + +diagnostics( + unique int id: @diagnostic, + int severity: int ref, + string error_tag: string ref, + string error_message: string ref, + string full_error_message: string ref, + int location: @location_default ref +); + +extractor_messages( + unique int id: @extractor_message, + int severity: int ref, + string origin : string ref, + string text : string ref, + string entity : string ref, + int location: @location_default ref, + string stack_trace : string ref +); + +/** + * If extraction was successful, then `cpu_seconds` and + * `elapsed_seconds` are the CPU time and elapsed time (respectively) + * that extraction took for compiler invocation `id`. + */ +compilation_finished( + unique int id : @compilation ref, + float cpu_seconds : float ref, + float elapsed_seconds : float ref +); + +compilation_assembly( + unique int id : @compilation ref, + int assembly: @assembly ref +) + +/* + * External artifacts + */ + +externalDefects( + unique int id: @externalDefect, + string queryPath: string ref, + int location: @location ref, + string message: string ref, + float severity: float ref); + +externalMetrics( + unique int id: @externalMetric, + string queryPath: string ref, + int location: @location ref, + float value: float ref); + +externalData( + int id: @externalDataElement, + string path: string ref, + int column: int ref, + string value: string ref); + +snapshotDate( + unique date snapshotDate: date ref); + +sourceLocationPrefix( + string prefix: string ref); + +/* + * Duplicate code + */ + +duplicateCode( + unique int id: @duplication, + string relativePath: string ref, + int equivClass: int ref); + +similarCode( + unique int id: @similarity, + string relativePath: string ref, + int equivClass: int ref); + +@duplication_or_similarity = @duplication | @similarity + +tokens( + int id: @duplication_or_similarity ref, + int offset: int ref, + int beginLine: int ref, + int beginColumn: int ref, + int endLine: int ref, + int endColumn: int ref); + +/* + * C# dbscheme + */ + +/** ELEMENTS **/ + +@element = @declaration | @stmt | @expr | @modifier | @attribute | @namespace_declaration + | @using_directive | @type_parameter_constraints | @external_element + | @xmllocatable | @asp_element | @namespace | @preprocessor_directive; + +@declaration = @callable | @generic | @assignable | @namespace; + +@named_element = @namespace | @declaration; + +@declaration_with_accessors = @property | @indexer | @event; + +@assignable = @variable | @assignable_with_accessors | @event; + +@assignable_with_accessors = @property | @indexer; + +@external_element = @externalMetric | @externalDefect | @externalDataElement; + +@attributable = @assembly | @field | @parameter | @operator | @method | @constructor + | @destructor | @callable_accessor | @value_or_ref_type | @declaration_with_accessors + | @local_function; + +/** LOCATIONS, ASEMMBLIES, MODULES, FILES and FOLDERS **/ + +@location = @location_default | @assembly; + +locations_default( + unique int id: @location_default, + int file: @file ref, + int beginLine: int ref, + int beginColumn: int ref, + int endLine: int ref, + int endColumn: int ref); + +locations_mapped( + unique int id: @location_default ref, + int mapped_to: @location_default ref); + +@sourceline = @file | @callable | @xmllocatable; + +numlines( + int element_id: @sourceline ref, + int num_lines: int ref, + int num_code: int ref, + int num_comment: int ref); + +assemblies( + unique int id: @assembly, + int file: @file ref, + string fullname: string ref, + string name: string ref, + string version: string ref); + +/* + fromSource(0) = unknown, + fromSource(1) = from source, + fromSource(2) = from library +*/ +files( + unique int id: @file, + string name: string ref, + string simple: string ref, + string ext: string ref, + int fromSource: int ref); + +folders( + unique int id: @folder, + string name: string ref, + string simple: string ref); + +@container = @folder | @file ; + +containerparent( + int parent: @container ref, + unique int child: @container ref); + +file_extraction_mode( + unique int file: @file ref, + int mode: int ref + /* 0 = normal, 1 = standalone extractor */ + ); + +/** NAMESPACES **/ + +@type_container = @namespace | @type; + +namespaces( + unique int id: @namespace, + string name: string ref); + +namespace_declarations( + unique int id: @namespace_declaration, + int namespace_id: @namespace ref); + +namespace_declaration_location( + unique int id: @namespace_declaration ref, + int loc: @location ref); + +parent_namespace( + unique int child_id: @type_container ref, + int namespace_id: @namespace ref); + +@declaration_or_directive = @namespace_declaration | @type | @using_directive; + +parent_namespace_declaration( + int child_id: @declaration_or_directive ref, // cannot be unique because of partial classes + int namespace_id: @namespace_declaration ref); + +@using_directive = @using_namespace_directive | @using_static_directive; + +using_namespace_directives( + unique int id: @using_namespace_directive, + int namespace_id: @namespace ref); + +using_static_directives( + unique int id: @using_static_directive, + int type_id: @type_or_ref ref); + +using_directive_location( + unique int id: @using_directive ref, + int loc: @location ref); + +@preprocessor_directive = @pragma_warning | @pragma_checksum | @directive_define | @directive_undefine | @directive_warning + | @directive_error | @directive_nullable | @directive_line | @directive_region | @directive_endregion | @directive_if + | @directive_elif | @directive_else | @directive_endif; + +@conditional_directive = @directive_if | @directive_elif; +@branch_directive = @directive_if | @directive_elif | @directive_else; + +directive_ifs( + unique int id: @directive_if, + int branchTaken: int ref, /* 0: false, 1: true */ + int conditionValue: int ref); /* 0: false, 1: true */ + +directive_elifs( + unique int id: @directive_elif, + int branchTaken: int ref, /* 0: false, 1: true */ + int conditionValue: int ref, /* 0: false, 1: true */ + int parent: @directive_if ref, + int index: int ref); + +directive_elses( + unique int id: @directive_else, + int branchTaken: int ref, /* 0: false, 1: true */ + int parent: @directive_if ref, + int index: int ref); + +#keyset[id, start] +directive_endifs( + unique int id: @directive_endif, + unique int start: @directive_if ref); + +directive_define_symbols( + unique int id: @define_symbol_expr ref, + string name: string ref); + +directive_regions( + unique int id: @directive_region, + string name: string ref); + +#keyset[id, start] +directive_endregions( + unique int id: @directive_endregion, + unique int start: @directive_region ref); + +directive_lines( + unique int id: @directive_line, + int kind: int ref); /* 0: default, 1: hidden, 2: numeric */ + +directive_line_value( + unique int id: @directive_line ref, + int line: int ref); + +directive_line_file( + unique int id: @directive_line ref, + int file: @file ref +) + +directive_nullables( + unique int id: @directive_nullable, + int setting: int ref, /* 0: disable, 1: enable, 2: restore */ + int target: int ref); /* 0: none, 1: annotations, 2: warnings */ + +directive_warnings( + unique int id: @directive_warning, + string message: string ref); + +directive_errors( + unique int id: @directive_error, + string message: string ref); + +directive_undefines( + unique int id: @directive_undefine, + string name: string ref); + +directive_defines( + unique int id: @directive_define, + string name: string ref); + +pragma_checksums( + unique int id: @pragma_checksum, + int file: @file ref, + string guid: string ref, + string bytes: string ref); + +pragma_warnings( + unique int id: @pragma_warning, + int kind: int ref /* 0 = disable, 1 = restore */); + +#keyset[id, index] +pragma_warning_error_codes( + int id: @pragma_warning ref, + string errorCode: string ref, + int index: int ref); + +preprocessor_directive_location( + unique int id: @preprocessor_directive ref, + int loc: @location ref); + +preprocessor_directive_compilation( + unique int id: @preprocessor_directive ref, + int compilation: @compilation ref); + +preprocessor_directive_active( + unique int id: @preprocessor_directive ref, + int active: int ref); /* 0: false, 1: true */ + +/** TYPES **/ + +types( + unique int id: @type, + int kind: int ref, + string name: string ref); + +case @type.kind of + 1 = @bool_type +| 2 = @char_type +| 3 = @decimal_type +| 4 = @sbyte_type +| 5 = @short_type +| 6 = @int_type +| 7 = @long_type +| 8 = @byte_type +| 9 = @ushort_type +| 10 = @uint_type +| 11 = @ulong_type +| 12 = @float_type +| 13 = @double_type +| 14 = @enum_type +| 15 = @struct_type +| 17 = @class_type +| 19 = @interface_type +| 20 = @delegate_type +| 21 = @null_type +| 22 = @type_parameter +| 23 = @pointer_type +| 24 = @nullable_type +| 25 = @array_type +| 26 = @void_type +| 27 = @int_ptr_type +| 28 = @uint_ptr_type +| 29 = @dynamic_type +| 30 = @arglist_type +| 31 = @unknown_type +| 32 = @tuple_type +| 33 = @function_pointer_type + ; + +@simple_type = @bool_type | @char_type | @integral_type | @floating_point_type | @decimal_type; +@integral_type = @signed_integral_type | @unsigned_integral_type; +@signed_integral_type = @sbyte_type | @short_type | @int_type | @long_type; +@unsigned_integral_type = @byte_type | @ushort_type | @uint_type | @ulong_type; +@floating_point_type = @float_type | @double_type; +@value_type = @simple_type | @enum_type | @struct_type | @nullable_type | @int_ptr_type + | @uint_ptr_type | @tuple_type; +@ref_type = @class_type | @interface_type | @array_type | @delegate_type | @null_type + | @dynamic_type; +@value_or_ref_type = @value_type | @ref_type; + +typerefs( + unique int id: @typeref, + string name: string ref); + +typeref_type( + int id: @typeref ref, + unique int typeId: @type ref); + +@type_or_ref = @type | @typeref; + +array_element_type( + unique int array: @array_type ref, + int dimension: int ref, + int rank: int ref, + int element: @type_or_ref ref); + +nullable_underlying_type( + unique int nullable: @nullable_type ref, + int underlying: @type_or_ref ref); + +pointer_referent_type( + unique int pointer: @pointer_type ref, + int referent: @type_or_ref ref); + +enum_underlying_type( + unique int enum_id: @enum_type ref, + int underlying_type_id: @type_or_ref ref); + +delegate_return_type( + unique int delegate_id: @delegate_type ref, + int return_type_id: @type_or_ref ref); + +function_pointer_return_type( + unique int function_pointer_id: @function_pointer_type ref, + int return_type_id: @type_or_ref ref); + +extend( + unique int sub: @type ref, + int super: @type_or_ref ref); + +anonymous_types( + unique int id: @type ref); + +@interface_or_ref = @interface_type | @typeref; + +implement( + int sub: @type ref, + int super: @type_or_ref ref); + +type_location( + int id: @type ref, + int loc: @location ref); + +tuple_underlying_type( + unique int tuple: @tuple_type ref, + int struct: @type_or_ref ref); + +#keyset[tuple, index] +tuple_element( + int tuple: @tuple_type ref, + int index: int ref, + unique int field: @field ref); + +attributes( + unique int id: @attribute, + int type_id: @type_or_ref ref, + int target: @attributable ref); + +attribute_location( + int id: @attribute ref, + int loc: @location ref); + +@type_mention_parent = @element | @type_mention; + +type_mention( + unique int id: @type_mention, + int type_id: @type_or_ref ref, + int parent: @type_mention_parent ref); + +type_mention_location( + unique int id: @type_mention ref, + int loc: @location ref); + +@has_type_annotation = @assignable | @type_parameter | @callable | @expr | @delegate_type | @generic | @function_pointer_type; + +/** + * A direct annotation on an entity, for example `string? x;`. + * + * Annotations: + * 2 = reftype is not annotated "!" + * 3 = reftype is annotated "?" + * 4 = readonly ref type / in parameter + * 5 = ref type parameter, return or local variable + * 6 = out parameter + * + * Note that the annotation depends on the element it annotates. + * @assignable: The annotation is on the type of the assignable, for example the variable type. + * @type_parameter: The annotation is on the reftype constraint + * @callable: The annotation is on the return type + * @array_type: The annotation is on the element type + */ +type_annotation(int id: @has_type_annotation ref, int annotation: int ref); + +nullability(unique int nullability: @nullability, int kind: int ref); + +case @nullability.kind of + 0 = @oblivious +| 1 = @not_annotated +| 2 = @annotated +; + +#keyset[parent, index] +nullability_parent(int nullability: @nullability ref, int index: int ref, int parent: @nullability ref) + +type_nullability(int id: @has_type_annotation ref, int nullability: @nullability ref); + +/** + * The nullable flow state of an expression, as determined by Roslyn. + * 0 = none (default, not populated) + * 1 = not null + * 2 = maybe null + */ +expr_flowstate(unique int id: @expr ref, int state: int ref); + +/** GENERICS **/ + +@generic = @type | @method | @local_function; + +type_parameters( + unique int id: @type_parameter ref, + int index: int ref, + int generic_id: @generic ref, + int variance: int ref /* none = 0, out = 1, in = 2 */); + +#keyset[constructed_id, index] +type_arguments( + int id: @type_or_ref ref, + int index: int ref, + int constructed_id: @generic_or_ref ref); + +@generic_or_ref = @generic | @typeref; + +constructed_generic( + unique int constructed: @generic ref, + int generic: @generic_or_ref ref); + +type_parameter_constraints( + unique int id: @type_parameter_constraints, + int param_id: @type_parameter ref); + +type_parameter_constraints_location( + int id: @type_parameter_constraints ref, + int loc: @location ref); + +general_type_parameter_constraints( + int id: @type_parameter_constraints ref, + int kind: int ref /* class = 1, struct = 2, new = 3 */); + +specific_type_parameter_constraints( + int id: @type_parameter_constraints ref, + int base_id: @type_or_ref ref); + +specific_type_parameter_nullability( + int id: @type_parameter_constraints ref, + int base_id: @type_or_ref ref, + int nullability: @nullability ref); + +/** FUNCTION POINTERS */ + +function_pointer_calling_conventions( + int id: @function_pointer_type ref, + int kind: int ref); + +#keyset[id, index] +has_unmanaged_calling_conventions( + int id: @function_pointer_type ref, + int index: int ref, + int conv_id: @type_or_ref ref); + +/** MODIFIERS */ + +@modifiable = @modifiable_direct | @event_accessor; + +@modifiable_direct = @member | @accessor | @local_function | @anonymous_function_expr; + +modifiers( + unique int id: @modifier, + string name: string ref); + +has_modifiers( + int id: @modifiable_direct ref, + int mod_id: @modifier ref); + +compiler_generated(unique int id: @modifiable_direct ref); + +/** MEMBERS **/ + +@member = @method | @constructor | @destructor | @field | @property | @event | @operator | @indexer | @type; + +@named_exprorstmt = @goto_stmt | @labeled_stmt | @expr; + +@virtualizable = @method | @property | @indexer | @event; + +exprorstmt_name( + unique int parent_id: @named_exprorstmt ref, + string name: string ref); + +nested_types( + unique int id: @type ref, + int declaring_type_id: @type ref, + int unbound_id: @type ref); + +properties( + unique int id: @property, + string name: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @property ref); + +property_location( + int id: @property ref, + int loc: @location ref); + +indexers( + unique int id: @indexer, + string name: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @indexer ref); + +indexer_location( + int id: @indexer ref, + int loc: @location ref); + +accessors( + unique int id: @accessor, + int kind: int ref, + string name: string ref, + int declaring_member_id: @member ref, + int unbound_id: @accessor ref); + +case @accessor.kind of + 1 = @getter +| 2 = @setter + ; + +init_only_accessors( + unique int id: @accessor ref); + +accessor_location( + int id: @accessor ref, + int loc: @location ref); + +events( + unique int id: @event, + string name: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @event ref); + +event_location( + int id: @event ref, + int loc: @location ref); + +event_accessors( + unique int id: @event_accessor, + int kind: int ref, + string name: string ref, + int declaring_event_id: @event ref, + int unbound_id: @event_accessor ref); + +case @event_accessor.kind of + 1 = @add_event_accessor +| 2 = @remove_event_accessor + ; + +event_accessor_location( + int id: @event_accessor ref, + int loc: @location ref); + +operators( + unique int id: @operator, + string name: string ref, + string symbol: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @operator ref); + +operator_location( + int id: @operator ref, + int loc: @location ref); + +constant_value( + int id: @variable ref, + string value: string ref); + +/** CALLABLES **/ + +@callable = @method | @constructor | @destructor | @operator | @callable_accessor | @anonymous_function_expr | @local_function; + +@callable_accessor = @accessor | @event_accessor; + +methods( + unique int id: @method, + string name: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @method ref); + +method_location( + int id: @method ref, + int loc: @location ref); + +constructors( + unique int id: @constructor, + string name: string ref, + int declaring_type_id: @type ref, + int unbound_id: @constructor ref); + +constructor_location( + int id: @constructor ref, + int loc: @location ref); + +destructors( + unique int id: @destructor, + string name: string ref, + int declaring_type_id: @type ref, + int unbound_id: @destructor ref); + +destructor_location( + int id: @destructor ref, + int loc: @location ref); + +overrides( + int id: @callable ref, + int base_id: @callable ref); + +explicitly_implements( + int id: @member ref, + int interface_id: @interface_or_ref ref); + +local_functions( + unique int id: @local_function, + string name: string ref, + int return_type: @type ref, + int unbound_id: @local_function ref); + +local_function_stmts( + unique int fn: @local_function_stmt ref, + int stmt: @local_function ref); + +/** VARIABLES **/ + +@variable = @local_scope_variable | @field; + +@local_scope_variable = @local_variable | @parameter; + +fields( + unique int id: @field, + int kind: int ref, + string name: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @field ref); + +case @field.kind of + 1 = @addressable_field +| 2 = @constant + ; + +field_location( + int id: @field ref, + int loc: @location ref); + +localvars( + unique int id: @local_variable, + int kind: int ref, + string name: string ref, + int implicitly_typed: int ref /* 0 = no, 1 = yes */, + int type_id: @type_or_ref ref, + int parent_id: @local_var_decl_expr ref); + +case @local_variable.kind of + 1 = @addressable_local_variable +| 2 = @local_constant +| 3 = @local_variable_ref + ; + +localvar_location( + unique int id: @local_variable ref, + int loc: @location ref); + +@parameterizable = @callable | @delegate_type | @indexer | @function_pointer_type; + +#keyset[name, parent_id] +#keyset[index, parent_id] +params( + unique int id: @parameter, + string name: string ref, + int type_id: @type_or_ref ref, + int index: int ref, + int mode: int ref, /* value = 0, ref = 1, out = 2, array = 3, this = 4 */ + int parent_id: @parameterizable ref, + int unbound_id: @parameter ref); + +param_location( + int id: @parameter ref, + int loc: @location ref); + +/** STATEMENTS **/ + +@exprorstmt_parent = @control_flow_element | @top_level_exprorstmt_parent; + +statements( + unique int id: @stmt, + int kind: int ref); + +#keyset[index, parent] +stmt_parent( + unique int stmt: @stmt ref, + int index: int ref, + int parent: @control_flow_element ref); + +@top_level_stmt_parent = @callable; + +// [index, parent] is not a keyset because the same parent may be compiled multiple times +stmt_parent_top_level( + unique int stmt: @stmt ref, + int index: int ref, + int parent: @top_level_stmt_parent ref); + +case @stmt.kind of + 1 = @block_stmt +| 2 = @expr_stmt +| 3 = @if_stmt +| 4 = @switch_stmt +| 5 = @while_stmt +| 6 = @do_stmt +| 7 = @for_stmt +| 8 = @foreach_stmt +| 9 = @break_stmt +| 10 = @continue_stmt +| 11 = @goto_stmt +| 12 = @goto_case_stmt +| 13 = @goto_default_stmt +| 14 = @throw_stmt +| 15 = @return_stmt +| 16 = @yield_stmt +| 17 = @try_stmt +| 18 = @checked_stmt +| 19 = @unchecked_stmt +| 20 = @lock_stmt +| 21 = @using_block_stmt +| 22 = @var_decl_stmt +| 23 = @const_decl_stmt +| 24 = @empty_stmt +| 25 = @unsafe_stmt +| 26 = @fixed_stmt +| 27 = @label_stmt +| 28 = @catch +| 29 = @case_stmt +| 30 = @local_function_stmt +| 31 = @using_decl_stmt + ; + +@using_stmt = @using_block_stmt | @using_decl_stmt; + +@labeled_stmt = @label_stmt | @case; + +@decl_stmt = @var_decl_stmt | @const_decl_stmt | @using_decl_stmt; + +@cond_stmt = @if_stmt | @switch_stmt; + +@loop_stmt = @while_stmt | @do_stmt | @for_stmt | @foreach_stmt; + +@jump_stmt = @break_stmt | @goto_any_stmt | @continue_stmt | @throw_stmt | @return_stmt + | @yield_stmt; + +@goto_any_stmt = @goto_default_stmt | @goto_case_stmt | @goto_stmt; + + +stmt_location( + unique int id: @stmt ref, + int loc: @location ref); + +catch_type( + unique int catch_id: @catch ref, + int type_id: @type_or_ref ref, + int kind: int ref /* explicit = 1, implicit = 2 */); + +/** EXPRESSIONS **/ + +expressions( + unique int id: @expr, + int kind: int ref, + int type_id: @type_or_ref ref); + +#keyset[index, parent] +expr_parent( + unique int expr: @expr ref, + int index: int ref, + int parent: @control_flow_element ref); + +@top_level_expr_parent = @attribute | @field | @property | @indexer | @parameter | @directive_if | @directive_elif; + +@top_level_exprorstmt_parent = @top_level_expr_parent | @top_level_stmt_parent; + +// [index, parent] is not a keyset because the same parent may be compiled multiple times +expr_parent_top_level( + unique int expr: @expr ref, + int index: int ref, + int parent: @top_level_exprorstmt_parent ref); + +case @expr.kind of +/* literal */ + 1 = @bool_literal_expr +| 2 = @char_literal_expr +| 3 = @decimal_literal_expr +| 4 = @int_literal_expr +| 5 = @long_literal_expr +| 6 = @uint_literal_expr +| 7 = @ulong_literal_expr +| 8 = @float_literal_expr +| 9 = @double_literal_expr +| 10 = @string_literal_expr +| 11 = @null_literal_expr +/* primary & unary */ +| 12 = @this_access_expr +| 13 = @base_access_expr +| 14 = @local_variable_access_expr +| 15 = @parameter_access_expr +| 16 = @field_access_expr +| 17 = @property_access_expr +| 18 = @method_access_expr +| 19 = @event_access_expr +| 20 = @indexer_access_expr +| 21 = @array_access_expr +| 22 = @type_access_expr +| 23 = @typeof_expr +| 24 = @method_invocation_expr +| 25 = @delegate_invocation_expr +| 26 = @operator_invocation_expr +| 27 = @cast_expr +| 28 = @object_creation_expr +| 29 = @explicit_delegate_creation_expr +| 30 = @implicit_delegate_creation_expr +| 31 = @array_creation_expr +| 32 = @default_expr +| 33 = @plus_expr +| 34 = @minus_expr +| 35 = @bit_not_expr +| 36 = @log_not_expr +| 37 = @post_incr_expr +| 38 = @post_decr_expr +| 39 = @pre_incr_expr +| 40 = @pre_decr_expr +/* multiplicative */ +| 41 = @mul_expr +| 42 = @div_expr +| 43 = @rem_expr +/* additive */ +| 44 = @add_expr +| 45 = @sub_expr +/* shift */ +| 46 = @lshift_expr +| 47 = @rshift_expr +/* relational */ +| 48 = @lt_expr +| 49 = @gt_expr +| 50 = @le_expr +| 51 = @ge_expr +/* equality */ +| 52 = @eq_expr +| 53 = @ne_expr +/* logical */ +| 54 = @bit_and_expr +| 55 = @bit_xor_expr +| 56 = @bit_or_expr +| 57 = @log_and_expr +| 58 = @log_or_expr +/* type testing */ +| 59 = @is_expr +| 60 = @as_expr +/* null coalescing */ +| 61 = @null_coalescing_expr +/* conditional */ +| 62 = @conditional_expr +/* assignment */ +| 63 = @simple_assign_expr +| 64 = @assign_add_expr +| 65 = @assign_sub_expr +| 66 = @assign_mul_expr +| 67 = @assign_div_expr +| 68 = @assign_rem_expr +| 69 = @assign_and_expr +| 70 = @assign_xor_expr +| 71 = @assign_or_expr +| 72 = @assign_lshift_expr +| 73 = @assign_rshift_expr +/* more */ +| 74 = @object_init_expr +| 75 = @collection_init_expr +| 76 = @array_init_expr +| 77 = @checked_expr +| 78 = @unchecked_expr +| 79 = @constructor_init_expr +| 80 = @add_event_expr +| 81 = @remove_event_expr +| 82 = @par_expr +| 83 = @local_var_decl_expr +| 84 = @lambda_expr +| 85 = @anonymous_method_expr +| 86 = @namespace_expr +/* dynamic */ +| 92 = @dynamic_element_access_expr +| 93 = @dynamic_member_access_expr +/* unsafe */ +| 100 = @pointer_indirection_expr +| 101 = @address_of_expr +| 102 = @sizeof_expr +/* async */ +| 103 = @await_expr +/* C# 6.0 */ +| 104 = @nameof_expr +| 105 = @interpolated_string_expr +| 106 = @unknown_expr +/* C# 7.0 */ +| 107 = @throw_expr +| 108 = @tuple_expr +| 109 = @local_function_invocation_expr +| 110 = @ref_expr +| 111 = @discard_expr +/* C# 8.0 */ +| 112 = @range_expr +| 113 = @index_expr +| 114 = @switch_expr +| 115 = @recursive_pattern_expr +| 116 = @property_pattern_expr +| 117 = @positional_pattern_expr +| 118 = @switch_case_expr +| 119 = @assign_coalesce_expr +| 120 = @suppress_nullable_warning_expr +| 121 = @namespace_access_expr +/* C# 9.0 */ +| 122 = @lt_pattern_expr +| 123 = @gt_pattern_expr +| 124 = @le_pattern_expr +| 125 = @ge_pattern_expr +| 126 = @not_pattern_expr +| 127 = @and_pattern_expr +| 128 = @or_pattern_expr +| 129 = @function_pointer_invocation_expr +/* Preprocessor */ +| 999 = @define_symbol_expr +; + +@switch = @switch_stmt | @switch_expr; +@case = @case_stmt | @switch_case_expr; +@pattern_match = @case | @is_expr; +@unary_pattern_expr = @not_pattern_expr; +@relational_pattern_expr = @gt_pattern_expr | @lt_pattern_expr | @ge_pattern_expr | @le_pattern_expr; +@binary_pattern_expr = @and_pattern_expr | @or_pattern_expr; + +@integer_literal_expr = @int_literal_expr | @long_literal_expr | @uint_literal_expr | @ulong_literal_expr; +@real_literal_expr = @float_literal_expr | @double_literal_expr | @decimal_literal_expr; +@literal_expr = @bool_literal_expr | @char_literal_expr | @integer_literal_expr | @real_literal_expr + | @string_literal_expr | @null_literal_expr; + +@assign_expr = @simple_assign_expr | @assign_op_expr | @local_var_decl_expr; +@assign_op_expr = @assign_arith_expr | @assign_bitwise_expr | @assign_event_expr | @assign_coalesce_expr; +@assign_event_expr = @add_event_expr | @remove_event_expr; + +@assign_arith_expr = @assign_add_expr | @assign_sub_expr | @assign_mul_expr | @assign_div_expr + | @assign_rem_expr +@assign_bitwise_expr = @assign_and_expr | @assign_or_expr | @assign_xor_expr + | @assign_lshift_expr | @assign_rshift_expr; + +@member_access_expr = @field_access_expr | @property_access_expr | @indexer_access_expr | @event_access_expr + | @method_access_expr | @type_access_expr | @dynamic_member_access_expr; +@access_expr = @member_access_expr | @this_access_expr | @base_access_expr | @assignable_access_expr | @namespace_access_expr; +@element_access_expr = @indexer_access_expr | @array_access_expr | @dynamic_element_access_expr; + +@local_variable_access = @local_variable_access_expr | @local_var_decl_expr; +@local_scope_variable_access_expr = @parameter_access_expr | @local_variable_access; +@variable_access_expr = @local_scope_variable_access_expr | @field_access_expr; + +@assignable_access_expr = @variable_access_expr | @property_access_expr | @element_access_expr + | @event_access_expr | @dynamic_member_access_expr; + +@objectorcollection_init_expr = @object_init_expr | @collection_init_expr; + +@delegate_creation_expr = @explicit_delegate_creation_expr | @implicit_delegate_creation_expr; + +@bin_arith_op_expr = @mul_expr | @div_expr | @rem_expr | @add_expr | @sub_expr; +@incr_op_expr = @pre_incr_expr | @post_incr_expr; +@decr_op_expr = @pre_decr_expr | @post_decr_expr; +@mut_op_expr = @incr_op_expr | @decr_op_expr; +@un_arith_op_expr = @plus_expr | @minus_expr | @mut_op_expr; +@arith_op_expr = @bin_arith_op_expr | @un_arith_op_expr; + +@ternary_log_op_expr = @conditional_expr; +@bin_log_op_expr = @log_and_expr | @log_or_expr | @null_coalescing_expr; +@un_log_op_expr = @log_not_expr; +@log_expr = @un_log_op_expr | @bin_log_op_expr | @ternary_log_op_expr; + +@bin_bit_op_expr = @bit_and_expr | @bit_or_expr | @bit_xor_expr | @lshift_expr + | @rshift_expr; +@un_bit_op_expr = @bit_not_expr; +@bit_expr = @un_bit_op_expr | @bin_bit_op_expr; + +@equality_op_expr = @eq_expr | @ne_expr; +@rel_op_expr = @gt_expr | @lt_expr| @ge_expr | @le_expr; +@comp_expr = @equality_op_expr | @rel_op_expr; + +@op_expr = @assign_expr | @un_op | @bin_op | @ternary_op; + +@ternary_op = @ternary_log_op_expr; +@bin_op = @bin_arith_op_expr | @bin_log_op_expr | @bin_bit_op_expr | @comp_expr; +@un_op = @un_arith_op_expr | @un_log_op_expr | @un_bit_op_expr | @sizeof_expr + | @pointer_indirection_expr | @address_of_expr; + +@anonymous_function_expr = @lambda_expr | @anonymous_method_expr; + +@call = @method_invocation_expr | @constructor_init_expr | @operator_invocation_expr + | @delegate_invocation_expr | @object_creation_expr | @call_access_expr + | @local_function_invocation_expr | @function_pointer_invocation_expr; + +@call_access_expr = @property_access_expr | @event_access_expr | @indexer_access_expr; + +@late_bindable_expr = @dynamic_element_access_expr | @dynamic_member_access_expr + | @object_creation_expr | @method_invocation_expr | @operator_invocation_expr; + +@throw_element = @throw_expr | @throw_stmt; + +@implicitly_typeable_object_creation_expr = @object_creation_expr | @explicit_delegate_creation_expr; + +implicitly_typed_array_creation( + unique int id: @array_creation_expr ref); + +explicitly_sized_array_creation( + unique int id: @array_creation_expr ref); + +stackalloc_array_creation( + unique int id: @array_creation_expr ref); + +implicitly_typed_object_creation( + unique int id: @implicitly_typeable_object_creation_expr ref); + +mutator_invocation_mode( + unique int id: @operator_invocation_expr ref, + int mode: int ref /* prefix = 1, postfix = 2*/); + +expr_compiler_generated( + unique int id: @expr ref); + +expr_value( + unique int id: @expr ref, + string value: string ref); + +expr_call( + unique int caller_id: @expr ref, + int target_id: @callable ref); + +expr_access( + unique int accesser_id: @access_expr ref, + int target_id: @accessible ref); + +@accessible = @method | @assignable | @local_function | @namespace; + +expr_location( + unique int id: @expr ref, + int loc: @location ref); + +dynamic_member_name( + unique int id: @late_bindable_expr ref, + string name: string ref); + +@qualifiable_expr = @member_access_expr + | @method_invocation_expr + | @element_access_expr; + +conditional_access( + unique int id: @qualifiable_expr ref); + +expr_argument( + unique int id: @expr ref, + int mode: int ref); + /* mode is the same as params: value = 0, ref = 1, out = 2 */ + +expr_argument_name( + unique int id: @expr ref, + string name: string ref); + +/** CONTROL/DATA FLOW **/ + +@control_flow_element = @stmt | @expr; + +/* XML Files */ + +xmlEncoding ( + unique int id: @file ref, + string encoding: string ref); + +xmlDTDs( + unique int id: @xmldtd, + string root: string ref, + string publicId: string ref, + string systemId: string ref, + int fileid: @file ref); + +xmlElements( + unique int id: @xmlelement, + string name: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int fileid: @file ref); + +xmlAttrs( + unique int id: @xmlattribute, + int elementid: @xmlelement ref, + string name: string ref, + string value: string ref, + int idx: int ref, + int fileid: @file ref); + +xmlNs( + int id: @xmlnamespace, + string prefixName: string ref, + string URI: string ref, + int fileid: @file ref); + +xmlHasNs( + int elementId: @xmlnamespaceable ref, + int nsId: @xmlnamespace ref, + int fileid: @file ref); + +xmlComments( + unique int id: @xmlcomment, + string text: string ref, + int parentid: @xmlparent ref, + int fileid: @file ref); + +xmlChars( + unique int id: @xmlcharacters, + string text: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int isCDATA: int ref, + int fileid: @file ref); + +@xmlparent = @file | @xmlelement; +@xmlnamespaceable = @xmlelement | @xmlattribute; + +xmllocations( + int xmlElement: @xmllocatable ref, + int location: @location_default ref); + +@xmllocatable = @xmlcharacters | @xmlelement | @xmlcomment | @xmlattribute | @xmldtd | @file | @xmlnamespace; + +/* Comments */ + +commentline( + unique int id: @commentline, + int kind: int ref, + string text: string ref, + string rawtext: string ref); + +case @commentline.kind of + 0 = @singlelinecomment +| 1 = @xmldoccomment +| 2 = @multilinecomment; + +commentline_location( + unique int id: @commentline ref, + int loc: @location ref); + +commentblock( + unique int id : @commentblock); + +commentblock_location( + unique int id: @commentblock ref, + int loc: @location ref); + +commentblock_binding( + int id: @commentblock ref, + int entity: @element ref, + int bindtype: int ref); /* 0: Parent, 1: Best, 2: Before, 3: After */ + +commentblock_child( + int id: @commentblock ref, + int commentline: @commentline ref, + int index: int ref); + +/* ASP.NET */ + +case @asp_element.kind of + 0=@asp_close_tag +| 1=@asp_code +| 2=@asp_comment +| 3=@asp_data_binding +| 4=@asp_directive +| 5=@asp_open_tag +| 6=@asp_quoted_string +| 7=@asp_text +| 8=@asp_xml_directive; + +@asp_attribute = @asp_code | @asp_data_binding | @asp_quoted_string; + +asp_elements( + unique int id: @asp_element, + int kind: int ref, + int loc: @location ref); + +asp_comment_server(unique int comment: @asp_comment ref); +asp_code_inline(unique int code: @asp_code ref); +asp_directive_attribute( + int directive: @asp_directive ref, + int index: int ref, + string name: string ref, + int value: @asp_quoted_string ref); +asp_directive_name( + unique int directive: @asp_directive ref, + string name: string ref); +asp_element_body( + unique int element: @asp_element ref, + string body: string ref); +asp_tag_attribute( + int tag: @asp_open_tag ref, + int index: int ref, + string name: string ref, + int attribute: @asp_attribute ref); +asp_tag_name( + unique int tag: @asp_open_tag ref, + string name: string ref); +asp_tag_isempty(int tag: @asp_open_tag ref); + +/* Common Intermediate Language - CIL */ + +case @cil_instruction.opcode of + 0 = @cil_nop +| 1 = @cil_break +| 2 = @cil_ldarg_0 +| 3 = @cil_ldarg_1 +| 4 = @cil_ldarg_2 +| 5 = @cil_ldarg_3 +| 6 = @cil_ldloc_0 +| 7 = @cil_ldloc_1 +| 8 = @cil_ldloc_2 +| 9 = @cil_ldloc_3 +| 10 = @cil_stloc_0 +| 11 = @cil_stloc_1 +| 12 = @cil_stloc_2 +| 13 = @cil_stloc_3 +| 14 = @cil_ldarg_s +| 15 = @cil_ldarga_s +| 16 = @cil_starg_s +| 17 = @cil_ldloc_s +| 18 = @cil_ldloca_s +| 19 = @cil_stloc_s +| 20 = @cil_ldnull +| 21 = @cil_ldc_i4_m1 +| 22 = @cil_ldc_i4_0 +| 23 = @cil_ldc_i4_1 +| 24 = @cil_ldc_i4_2 +| 25 = @cil_ldc_i4_3 +| 26 = @cil_ldc_i4_4 +| 27 = @cil_ldc_i4_5 +| 28 = @cil_ldc_i4_6 +| 29 = @cil_ldc_i4_7 +| 30 = @cil_ldc_i4_8 +| 31 = @cil_ldc_i4_s +| 32 = @cil_ldc_i4 +| 33 = @cil_ldc_i8 +| 34 = @cil_ldc_r4 +| 35 = @cil_ldc_r8 +| 37 = @cil_dup +| 38 = @cil_pop +| 39 = @cil_jmp +| 40 = @cil_call +| 41 = @cil_calli +| 42 = @cil_ret +| 43 = @cil_br_s +| 44 = @cil_brfalse_s +| 45 = @cil_brtrue_s +| 46 = @cil_beq_s +| 47 = @cil_bge_s +| 48 = @cil_bgt_s +| 49 = @cil_ble_s +| 50 = @cil_blt_s +| 51 = @cil_bne_un_s +| 52 = @cil_bge_un_s +| 53 = @cil_bgt_un_s +| 54 = @cil_ble_un_s +| 55 = @cil_blt_un_s +| 56 = @cil_br +| 57 = @cil_brfalse +| 58 = @cil_brtrue +| 59 = @cil_beq +| 60 = @cil_bge +| 61 = @cil_bgt +| 62 = @cil_ble +| 63 = @cil_blt +| 64 = @cil_bne_un +| 65 = @cil_bge_un +| 66 = @cil_bgt_un +| 67 = @cil_ble_un +| 68 = @cil_blt_un +| 69 = @cil_switch +| 70 = @cil_ldind_i1 +| 71 = @cil_ldind_u1 +| 72 = @cil_ldind_i2 +| 73 = @cil_ldind_u2 +| 74 = @cil_ldind_i4 +| 75 = @cil_ldind_u4 +| 76 = @cil_ldind_i8 +| 77 = @cil_ldind_i +| 78 = @cil_ldind_r4 +| 79 = @cil_ldind_r8 +| 80 = @cil_ldind_ref +| 81 = @cil_stind_ref +| 82 = @cil_stind_i1 +| 83 = @cil_stind_i2 +| 84 = @cil_stind_i4 +| 85 = @cil_stind_i8 +| 86 = @cil_stind_r4 +| 87 = @cil_stind_r8 +| 88 = @cil_add +| 89 = @cil_sub +| 90 = @cil_mul +| 91 = @cil_div +| 92 = @cil_div_un +| 93 = @cil_rem +| 94 = @cil_rem_un +| 95 = @cil_and +| 96 = @cil_or +| 97 = @cil_xor +| 98 = @cil_shl +| 99 = @cil_shr +| 100 = @cil_shr_un +| 101 = @cil_neg +| 102 = @cil_not +| 103 = @cil_conv_i1 +| 104 = @cil_conv_i2 +| 105 = @cil_conv_i4 +| 106 = @cil_conv_i8 +| 107 = @cil_conv_r4 +| 108 = @cil_conv_r8 +| 109 = @cil_conv_u4 +| 110 = @cil_conv_u8 +| 111 = @cil_callvirt +| 112 = @cil_cpobj +| 113 = @cil_ldobj +| 114 = @cil_ldstr +| 115 = @cil_newobj +| 116 = @cil_castclass +| 117 = @cil_isinst +| 118 = @cil_conv_r_un +| 121 = @cil_unbox +| 122 = @cil_throw +| 123 = @cil_ldfld +| 124 = @cil_ldflda +| 125 = @cil_stfld +| 126 = @cil_ldsfld +| 127 = @cil_ldsflda +| 128 = @cil_stsfld +| 129 = @cil_stobj +| 130 = @cil_conv_ovf_i1_un +| 131 = @cil_conv_ovf_i2_un +| 132 = @cil_conv_ovf_i4_un +| 133 = @cil_conv_ovf_i8_un +| 134 = @cil_conv_ovf_u1_un +| 135 = @cil_conv_ovf_u2_un +| 136 = @cil_conv_ovf_u4_un +| 137 = @cil_conv_ovf_u8_un +| 138 = @cil_conv_ovf_i_un +| 139 = @cil_conv_ovf_u_un +| 140 = @cil_box +| 141 = @cil_newarr +| 142 = @cil_ldlen +| 143 = @cil_ldelema +| 144 = @cil_ldelem_i1 +| 145 = @cil_ldelem_u1 +| 146 = @cil_ldelem_i2 +| 147 = @cil_ldelem_u2 +| 148 = @cil_ldelem_i4 +| 149 = @cil_ldelem_u4 +| 150 = @cil_ldelem_i8 +| 151 = @cil_ldelem_i +| 152 = @cil_ldelem_r4 +| 153 = @cil_ldelem_r8 +| 154 = @cil_ldelem_ref +| 155 = @cil_stelem_i +| 156 = @cil_stelem_i1 +| 157 = @cil_stelem_i2 +| 158 = @cil_stelem_i4 +| 159 = @cil_stelem_i8 +| 160 = @cil_stelem_r4 +| 161 = @cil_stelem_r8 +| 162 = @cil_stelem_ref +| 163 = @cil_ldelem +| 164 = @cil_stelem +| 165 = @cil_unbox_any +| 179 = @cil_conv_ovf_i1 +| 180 = @cil_conv_ovf_u1 +| 181 = @cil_conv_ovf_i2 +| 182 = @cil_conv_ovf_u2 +| 183 = @cil_conv_ovf_i4 +| 184 = @cil_conv_ovf_u4 +| 185 = @cil_conv_ovf_i8 +| 186 = @cil_conv_ovf_u8 +| 194 = @cil_refanyval +| 195 = @cil_ckinfinite +| 198 = @cil_mkrefany +| 208 = @cil_ldtoken +| 209 = @cil_conv_u2 +| 210 = @cil_conv_u1 +| 211 = @cil_conv_i +| 212 = @cil_conv_ovf_i +| 213 = @cil_conv_ovf_u +| 214 = @cil_add_ovf +| 215 = @cil_add_ovf_un +| 216 = @cil_mul_ovf +| 217 = @cil_mul_ovf_un +| 218 = @cil_sub_ovf +| 219 = @cil_sub_ovf_un +| 220 = @cil_endfinally +| 221 = @cil_leave +| 222 = @cil_leave_s +| 223 = @cil_stind_i +| 224 = @cil_conv_u +| 65024 = @cil_arglist +| 65025 = @cil_ceq +| 65026 = @cil_cgt +| 65027 = @cil_cgt_un +| 65028 = @cil_clt +| 65029 = @cil_clt_un +| 65030 = @cil_ldftn +| 65031 = @cil_ldvirtftn +| 65033 = @cil_ldarg +| 65034 = @cil_ldarga +| 65035 = @cil_starg +| 65036 = @cil_ldloc +| 65037 = @cil_ldloca +| 65038 = @cil_stloc +| 65039 = @cil_localloc +| 65041 = @cil_endfilter +| 65042 = @cil_unaligned +| 65043 = @cil_volatile +| 65044 = @cil_tail +| 65045 = @cil_initobj +| 65046 = @cil_constrained +| 65047 = @cil_cpblk +| 65048 = @cil_initblk +| 65050 = @cil_rethrow +| 65052 = @cil_sizeof +| 65053 = @cil_refanytype +| 65054 = @cil_readonly +; + +// CIL ignored instructions + +@cil_ignore = @cil_nop | @cil_break | @cil_volatile | @cil_unaligned; + +// CIL local/parameter/field access + +@cil_ldarg_any = @cil_ldarg_0 | @cil_ldarg_1 | @cil_ldarg_2 | @cil_ldarg_3 | @cil_ldarg_s | @cil_ldarga_s | @cil_ldarg | @cil_ldarga; +@cil_starg_any = @cil_starg | @cil_starg_s; + +@cil_ldloc_any = @cil_ldloc_0 | @cil_ldloc_1 | @cil_ldloc_2 | @cil_ldloc_3 | @cil_ldloc_s | @cil_ldloca_s | @cil_ldloc | @cil_ldloca; +@cil_stloc_any = @cil_stloc_0 | @cil_stloc_1 | @cil_stloc_2 | @cil_stloc_3 | @cil_stloc_s | @cil_stloc; + +@cil_ldfld_any = @cil_ldfld | @cil_ldsfld | @cil_ldsflda | @cil_ldflda; +@cil_stfld_any = @cil_stfld | @cil_stsfld; + +@cil_local_access = @cil_stloc_any | @cil_ldloc_any; +@cil_arg_access = @cil_starg_any | @cil_ldarg_any; +@cil_read_access = @cil_ldloc_any | @cil_ldarg_any | @cil_ldfld_any; +@cil_write_access = @cil_stloc_any | @cil_starg_any | @cil_stfld_any; + +@cil_stack_access = @cil_local_access | @cil_arg_access; +@cil_field_access = @cil_ldfld_any | @cil_stfld_any; + +@cil_access = @cil_read_access | @cil_write_access; + +// CIL constant/literal instructions + +@cil_ldc_i = @cil_ldc_i4_any | @cil_ldc_i8; + +@cil_ldc_i4_any = @cil_ldc_i4_m1 | @cil_ldc_i4_0 | @cil_ldc_i4_1 | @cil_ldc_i4_2 | @cil_ldc_i4_3 | + @cil_ldc_i4_4 | @cil_ldc_i4_5 | @cil_ldc_i4_6 | @cil_ldc_i4_7 | @cil_ldc_i4_8 | @cil_ldc_i4_s | @cil_ldc_i4; + +@cil_ldc_r = @cil_ldc_r4 | @cil_ldc_r8; + +@cil_literal = @cil_ldnull | @cil_ldc_i | @cil_ldc_r | @cil_ldstr; + +// Control flow + +@cil_conditional_jump = @cil_binary_jump | @cil_unary_jump; +@cil_binary_jump = @cil_beq_s | @cil_bge_s | @cil_bgt_s | @cil_ble_s | @cil_blt_s | + @cil_bne_un_s | @cil_bge_un_s | @cil_bgt_un_s | @cil_ble_un_s | @cil_blt_un_s | + @cil_beq | @cil_bge | @cil_bgt | @cil_ble | @cil_blt | + @cil_bne_un | @cil_bge_un | @cil_bgt_un | @cil_ble_un | @cil_blt_un; +@cil_unary_jump = @cil_brfalse_s | @cil_brtrue_s | @cil_brfalse | @cil_brtrue | @cil_switch; +@cil_unconditional_jump = @cil_br | @cil_br_s | @cil_leave_any; +@cil_leave_any = @cil_leave | @cil_leave_s; +@cil_jump = @cil_unconditional_jump | @cil_conditional_jump; + +// CIL call instructions + +@cil_call_any = @cil_jmp | @cil_call | @cil_calli | @cil_tail | @cil_callvirt | @cil_newobj; + +// CIL expression instructions + +@cil_expr = @cil_literal | @cil_binary_expr | @cil_unary_expr | @cil_call_any | @cil_read_access | + @cil_newarr | @cil_ldtoken | @cil_sizeof | + @cil_ldftn | @cil_ldvirtftn | @cil_localloc | @cil_mkrefany | @cil_refanytype | @cil_arglist | @cil_dup; + +@cil_unary_expr = + @cil_conversion_operation | @cil_unary_arithmetic_operation | @cil_unary_bitwise_operation| + @cil_ldlen | @cil_isinst | @cil_box | @cil_ldobj | @cil_castclass | @cil_unbox_any | + @cil_ldind | @cil_unbox; + +@cil_conversion_operation = + @cil_conv_i1 | @cil_conv_i2 | @cil_conv_i4 | @cil_conv_i8 | + @cil_conv_u1 | @cil_conv_u2 | @cil_conv_u4 | @cil_conv_u8 | + @cil_conv_ovf_i | @cil_conv_ovf_i_un | @cil_conv_ovf_i1 | @cil_conv_ovf_i1_un | + @cil_conv_ovf_i2 | @cil_conv_ovf_i2_un | @cil_conv_ovf_i4 | @cil_conv_ovf_i4_un | + @cil_conv_ovf_i8 | @cil_conv_ovf_i8_un | @cil_conv_ovf_u | @cil_conv_ovf_u_un | + @cil_conv_ovf_u1 | @cil_conv_ovf_u1_un | @cil_conv_ovf_u2 | @cil_conv_ovf_u2_un | + @cil_conv_ovf_u4 | @cil_conv_ovf_u4_un | @cil_conv_ovf_u8 | @cil_conv_ovf_u8_un | + @cil_conv_r4 | @cil_conv_r8 | @cil_conv_ovf_u2 | @cil_conv_ovf_u2_un | + @cil_conv_i | @cil_conv_u | @cil_conv_r_un; + +@cil_ldind = @cil_ldind_i | @cil_ldind_i1 | @cil_ldind_i2 | @cil_ldind_i4 | @cil_ldind_i8 | + @cil_ldind_r4 | @cil_ldind_r8 | @cil_ldind_ref | @cil_ldind_u1 | @cil_ldind_u2 | @cil_ldind_u4; + +@cil_stind = @cil_stind_i | @cil_stind_i1 | @cil_stind_i2 | @cil_stind_i4 | @cil_stind_i8 | + @cil_stind_r4 | @cil_stind_r8 | @cil_stind_ref; + +@cil_bitwise_operation = @cil_binary_bitwise_operation | @cil_unary_bitwise_operation; + +@cil_binary_bitwise_operation = @cil_and | @cil_or | @cil_xor | @cil_shr | @cil_shr | @cil_shr_un | @cil_shl; + +@cil_binary_arithmetic_operation = @cil_add | @cil_sub | @cil_mul | @cil_div | @cil_div_un | + @cil_rem | @cil_rem_un | @cil_add_ovf | @cil_add_ovf_un | @cil_mul_ovf | @cil_mul_ovf_un | + @cil_sub_ovf | @cil_sub_ovf_un; + +@cil_unary_bitwise_operation = @cil_not; + +@cil_binary_expr = @cil_binary_arithmetic_operation | @cil_binary_bitwise_operation | @cil_read_array | @cil_comparison_operation; + +@cil_unary_arithmetic_operation = @cil_neg; + +@cil_comparison_operation = @cil_cgt_un | @cil_ceq | @cil_cgt | @cil_clt | @cil_clt_un; + +// Elements that retrieve an address of something +@cil_read_ref = @cil_ldloca_s | @cil_ldarga_s | @cil_ldflda | @cil_ldsflda | @cil_ldelema; + +// CIL array instructions + +@cil_read_array = + @cil_ldelem | @cil_ldelema | @cil_ldelem_i1 | @cil_ldelem_ref | @cil_ldelem_i | + @cil_ldelem_i1 | @cil_ldelem_i2 | @cil_ldelem_i4 | @cil_ldelem_i8 | @cil_ldelem_r4 | + @cil_ldelem_r8 | @cil_ldelem_u1 | @cil_ldelem_u2 | @cil_ldelem_u4; + +@cil_write_array = @cil_stelem | @cil_stelem_ref | + @cil_stelem_i | @cil_stelem_i1 | @cil_stelem_i2 | @cil_stelem_i4 | @cil_stelem_i8 | + @cil_stelem_r4 | @cil_stelem_r8; + +@cil_throw_any = @cil_throw | @cil_rethrow; + +#keyset[impl, index] +cil_instruction( + unique int id: @cil_instruction, + int opcode: int ref, + int index: int ref, + int impl: @cil_method_implementation ref); + +cil_jump( + unique int instruction: @cil_jump ref, + int target: @cil_instruction ref); + +cil_access( + unique int instruction: @cil_instruction ref, + int target: @cil_accessible ref); + +cil_value( + unique int instruction: @cil_literal ref, + string value: string ref); + +#keyset[instruction, index] +cil_switch( + int instruction: @cil_switch ref, + int index: int ref, + int target: @cil_instruction ref); + +cil_instruction_location( + unique int id: @cil_instruction ref, + int loc: @location ref); + +cil_type_location( + int id: @cil_type ref, + int loc: @location ref); + +cil_method_location( + int id: @cil_method ref, + int loc: @location ref); + +@cil_namespace = @namespace; + +@cil_type_container = @cil_type | @cil_namespace | @cil_method; + +case @cil_type.kind of + 0 = @cil_valueorreftype +| 1 = @cil_typeparameter +| 2 = @cil_array_type +| 3 = @cil_pointer_type +| 4 = @cil_function_pointer_type +; + +cil_type( + unique int id: @cil_type, + string name: string ref, + int kind: int ref, + int parent: @cil_type_container ref, + int sourceDecl: @cil_type ref); + +cil_pointer_type( + unique int id: @cil_pointer_type ref, + int pointee: @cil_type ref); + +cil_array_type( + unique int id: @cil_array_type ref, + int element_type: @cil_type ref, + int rank: int ref); + +cil_function_pointer_return_type( + unique int id: @cil_function_pointer_type ref, + int return_type: @cil_type ref); + +cil_method( + unique int id: @cil_method, + string name: string ref, + int parent: @cil_type ref, + int return_type: @cil_type ref); + +cil_method_source_declaration( + unique int method: @cil_method ref, + int source: @cil_method ref); + +cil_method_implementation( + unique int id: @cil_method_implementation, + int method: @cil_method ref, + int location: @assembly ref); + +cil_implements( + int id: @cil_method ref, + int decl: @cil_method ref); + +#keyset[parent, name] +cil_field( + unique int id: @cil_field, + int parent: @cil_type ref, + string name: string ref, + int field_type: @cil_type ref); + +@cil_element = @cil_instruction | @cil_declaration | @cil_handler | @cil_attribute | @cil_namespace; +@cil_named_element = @cil_declaration | @cil_namespace; +@cil_declaration = @cil_variable | @cil_method | @cil_type | @cil_member; +@cil_accessible = @cil_declaration; +@cil_variable = @cil_field | @cil_stack_variable; +@cil_stack_variable = @cil_local_variable | @cil_parameter; +@cil_member = @cil_method | @cil_type | @cil_field | @cil_property | @cil_event; +@cil_custom_modifier_receiver = @cil_method | @cil_property | @cil_parameter | @cil_field | @cil_function_pointer_type; +@cil_parameterizable = @cil_method | @cil_function_pointer_type; +@cil_has_type_annotation = @cil_stack_variable | @cil_property | @cil_method | @cil_function_pointer_type; + +#keyset[parameterizable, index] +cil_parameter( + unique int id: @cil_parameter, + int parameterizable: @cil_parameterizable ref, + int index: int ref, + int param_type: @cil_type ref); + +cil_parameter_in(unique int id: @cil_parameter ref); +cil_parameter_out(unique int id: @cil_parameter ref); + +cil_setter(unique int prop: @cil_property ref, + int method: @cil_method ref); + +#keyset[id, modifier] +cil_custom_modifiers( + int id: @cil_custom_modifier_receiver ref, + int modifier: @cil_type ref, + int kind: int ref); // modreq: 1, modopt: 0 + +cil_type_annotation( + int id: @cil_has_type_annotation ref, + int annotation: int ref); + +cil_getter(unique int prop: @cil_property ref, + int method: @cil_method ref); + +cil_adder(unique int event: @cil_event ref, + int method: @cil_method ref); + +cil_remover(unique int event: @cil_event ref, int method: @cil_method ref); + +cil_raiser(unique int event: @cil_event ref, int method: @cil_method ref); + +cil_property( + unique int id: @cil_property, + int parent: @cil_type ref, + string name: string ref, + int property_type: @cil_type ref); + +#keyset[parent, name] +cil_event(unique int id: @cil_event, + int parent: @cil_type ref, + string name: string ref, + int event_type: @cil_type ref); + +#keyset[impl, index] +cil_local_variable( + unique int id: @cil_local_variable, + int impl: @cil_method_implementation ref, + int index: int ref, + int var_type: @cil_type ref); + +cil_function_pointer_calling_conventions( + int id: @cil_function_pointer_type ref, + int kind: int ref); + +// CIL handlers (exception handlers etc). + +case @cil_handler.kind of + 0 = @cil_catch_handler +| 1 = @cil_filter_handler +| 2 = @cil_finally_handler +| 4 = @cil_fault_handler +; + +#keyset[impl, index] +cil_handler( + unique int id: @cil_handler, + int impl: @cil_method_implementation ref, + int index: int ref, + int kind: int ref, + int try_start: @cil_instruction ref, + int try_end: @cil_instruction ref, + int handler_start: @cil_instruction ref); + +cil_handler_filter( + unique int id: @cil_handler ref, + int filter_start: @cil_instruction ref); + +cil_handler_type( + unique int id: @cil_handler ref, + int catch_type: @cil_type ref); + +@cil_controlflow_node = @cil_entry_point | @cil_instruction; + +@cil_entry_point = @cil_method_implementation | @cil_handler; + +@cil_dataflow_node = @cil_instruction | @cil_variable | @cil_method; + +cil_method_stack_size( + unique int method: @cil_method_implementation ref, + int size: int ref); + +// CIL modifiers + +cil_public(int id: @cil_member ref); +cil_private(int id: @cil_member ref); +cil_protected(int id: @cil_member ref); +cil_internal(int id: @cil_member ref); +cil_static(int id: @cil_member ref); +cil_sealed(int id: @cil_member ref); +cil_virtual(int id: @cil_method ref); +cil_abstract(int id: @cil_member ref); +cil_class(int id: @cil_type ref); +cil_interface(int id: @cil_type ref); +cil_security(int id: @cil_member ref); +cil_requiresecobject(int id: @cil_method ref); +cil_specialname(int id: @cil_method ref); +cil_newslot(int id: @cil_method ref); + +cil_base_class(unique int id: @cil_type ref, int base: @cil_type ref); +cil_base_interface(int id: @cil_type ref, int base: @cil_type ref); +cil_enum_underlying_type(unique int id: @cil_type ref, int underlying: @cil_type ref); + +#keyset[unbound, index] +cil_type_parameter( + int unbound: @cil_member ref, + int index: int ref, + int param: @cil_typeparameter ref); + +#keyset[bound, index] +cil_type_argument( + int bound: @cil_member ref, + int index: int ref, + int t: @cil_type ref); + +// CIL type parameter constraints + +cil_typeparam_covariant(int tp: @cil_typeparameter ref); +cil_typeparam_contravariant(int tp: @cil_typeparameter ref); +cil_typeparam_class(int tp: @cil_typeparameter ref); +cil_typeparam_struct(int tp: @cil_typeparameter ref); +cil_typeparam_new(int tp: @cil_typeparameter ref); +cil_typeparam_constraint(int tp: @cil_typeparameter ref, int supertype: @cil_type ref); + +// CIL attributes + +cil_attribute( + unique int attributeid: @cil_attribute, + int element: @cil_declaration ref, + int constructor: @cil_method ref); + +#keyset[attribute_id, param] +cil_attribute_named_argument( + int attribute_id: @cil_attribute ref, + string param: string ref, + string value: string ref); + +#keyset[attribute_id, index] +cil_attribute_positional_argument( + int attribute_id: @cil_attribute ref, + int index: int ref, + string value: string ref); + + +// Common .Net data model covering both C# and CIL + +// Common elements +@dotnet_element = @element | @cil_element; +@dotnet_named_element = @named_element | @cil_named_element; +@dotnet_callable = @callable | @cil_method; +@dotnet_variable = @variable | @cil_variable; +@dotnet_field = @field | @cil_field; +@dotnet_parameter = @parameter | @cil_parameter; +@dotnet_declaration = @declaration | @cil_declaration; +@dotnet_member = @member | @cil_member; +@dotnet_event = @event | @cil_event; +@dotnet_property = @property | @cil_property | @indexer; +@dotnet_parameterizable = @parameterizable | @cil_parameterizable; + +// Common types +@dotnet_type = @type | @cil_type; +@dotnet_call = @call | @cil_call_any; +@dotnet_throw = @throw_element | @cil_throw_any; +@dotnet_valueorreftype = @cil_valueorreftype | @value_or_ref_type | @cil_array_type | @void_type; +@dotnet_typeparameter = @type_parameter | @cil_typeparameter; +@dotnet_array_type = @array_type | @cil_array_type; +@dotnet_pointer_type = @pointer_type | @cil_pointer_type; +@dotnet_type_parameter = @type_parameter | @cil_typeparameter; +@dotnet_generic = @dotnet_valueorreftype | @dotnet_callable; + +// Attributes +@dotnet_attribute = @attribute | @cil_attribute; + +// Expressions +@dotnet_expr = @expr | @cil_expr; + +// Literals +@dotnet_literal = @literal_expr | @cil_literal; +@dotnet_string_literal = @string_literal_expr | @cil_ldstr; +@dotnet_int_literal = @integer_literal_expr | @cil_ldc_i; +@dotnet_float_literal = @float_literal_expr | @cil_ldc_r; +@dotnet_null_literal = @null_literal_expr | @cil_ldnull; + +@metadata_entity = @cil_method | @cil_type | @cil_field | @cil_property | @field | @property | + @callable | @value_or_ref_type | @void_type; + +#keyset[entity, location] +metadata_handle(int entity : @metadata_entity ref, int location: @assembly ref, int handle: int ref) diff --git a/csharp/upgrades/68db341c2ed1693c2ae6e20ad533c84138cb275a/semmlecode.csharp.dbscheme b/csharp/upgrades/68db341c2ed1693c2ae6e20ad533c84138cb275a/semmlecode.csharp.dbscheme new file mode 100644 index 00000000000..16936565fbe --- /dev/null +++ b/csharp/upgrades/68db341c2ed1693c2ae6e20ad533c84138cb275a/semmlecode.csharp.dbscheme @@ -0,0 +1,2082 @@ + +/** + * An invocation of the compiler. Note that more than one file may be + * compiled per invocation. For example, this command compiles three + * source files: + * + * csc f1.cs f2.cs f3.cs + * + * The `id` simply identifies the invocation, while `cwd` is the working + * directory from which the compiler was invoked. + */ +compilations( + unique int id : @compilation, + string cwd : string ref +); + +/** + * The arguments that were passed to the extractor for a compiler + * invocation. If `id` is for the compiler invocation + * + * csc f1.cs f2.cs f3.cs + * + * then typically there will be rows for + * + * num | arg + * --- | --- + * 0 | --compiler + * 1 | *path to compiler* + * 2 | --cil + * 3 | f1.cs + * 4 | f2.cs + * 5 | f3.cs + */ +#keyset[id, num] +compilation_args( + int id : @compilation ref, + int num : int ref, + string arg : string ref +); + +/** + * The source files that are compiled by a compiler invocation. + * If `id` is for the compiler invocation + * + * csc f1.cs f2.cs f3.cs + * + * then there will be rows for + * + * num | arg + * --- | --- + * 0 | f1.cs + * 1 | f2.cs + * 2 | f3.cs + */ +#keyset[id, num] +compilation_compiling_files( + int id : @compilation ref, + int num : int ref, + int file : @file ref +); + +/** + * The references used by a compiler invocation. + * If `id` is for the compiler invocation + * + * csc f1.cs f2.cs f3.cs /r:ref1.dll /r:ref2.dll /r:ref3.dll + * + * then there will be rows for + * + * num | arg + * --- | --- + * 0 | ref1.dll + * 1 | ref2.dll + * 2 | ref3.dll + */ +#keyset[id, num] +compilation_referencing_files( + int id : @compilation ref, + int num : int ref, + int file : @file ref +); + +/** + * The time taken by the extractor for a compiler invocation. + * + * For each file `num`, there will be rows for + * + * kind | seconds + * ---- | --- + * 1 | CPU seconds used by the extractor frontend + * 2 | Elapsed seconds during the extractor frontend + * 3 | CPU seconds used by the extractor backend + * 4 | Elapsed seconds during the extractor backend + */ +#keyset[id, num, kind] +compilation_time( + int id : @compilation ref, + int num : int ref, + /* kind: + 1 = frontend_cpu_seconds + 2 = frontend_elapsed_seconds + 3 = extractor_cpu_seconds + 4 = extractor_elapsed_seconds + */ + int kind : int ref, + float seconds : float ref +); + +/** + * An error or warning generated by the extractor. + * The diagnostic message `diagnostic` was generated during compiler + * invocation `compilation`, and is the `file_number_diagnostic_number`th + * message generated while extracting the `file_number`th file of that + * invocation. + */ +#keyset[compilation, file_number, file_number_diagnostic_number] +diagnostic_for( + unique int diagnostic : @diagnostic ref, + int compilation : @compilation ref, + int file_number : int ref, + int file_number_diagnostic_number : int ref +); + +diagnostics( + unique int id: @diagnostic, + int severity: int ref, + string error_tag: string ref, + string error_message: string ref, + string full_error_message: string ref, + int location: @location_default ref +); + +extractor_messages( + unique int id: @extractor_message, + int severity: int ref, + string origin : string ref, + string text : string ref, + string entity : string ref, + int location: @location_default ref, + string stack_trace : string ref +); + +/** + * If extraction was successful, then `cpu_seconds` and + * `elapsed_seconds` are the CPU time and elapsed time (respectively) + * that extraction took for compiler invocation `id`. + */ +compilation_finished( + unique int id : @compilation ref, + float cpu_seconds : float ref, + float elapsed_seconds : float ref +); + +compilation_assembly( + unique int id : @compilation ref, + int assembly: @assembly ref +) + +/* + * External artifacts + */ + +externalDefects( + unique int id: @externalDefect, + string queryPath: string ref, + int location: @location ref, + string message: string ref, + float severity: float ref); + +externalMetrics( + unique int id: @externalMetric, + string queryPath: string ref, + int location: @location ref, + float value: float ref); + +externalData( + int id: @externalDataElement, + string path: string ref, + int column: int ref, + string value: string ref); + +snapshotDate( + unique date snapshotDate: date ref); + +sourceLocationPrefix( + string prefix: string ref); + +/* + * Duplicate code + */ + +duplicateCode( + unique int id: @duplication, + string relativePath: string ref, + int equivClass: int ref); + +similarCode( + unique int id: @similarity, + string relativePath: string ref, + int equivClass: int ref); + +@duplication_or_similarity = @duplication | @similarity + +tokens( + int id: @duplication_or_similarity ref, + int offset: int ref, + int beginLine: int ref, + int beginColumn: int ref, + int endLine: int ref, + int endColumn: int ref); + +/* + * C# dbscheme + */ + +/** ELEMENTS **/ + +@element = @declaration | @stmt | @expr | @modifier | @attribute | @namespace_declaration + | @using_directive | @type_parameter_constraints | @external_element + | @xmllocatable | @asp_element | @namespace | @preprocessor_directive; + +@declaration = @callable | @generic | @assignable | @namespace; + +@named_element = @namespace | @declaration; + +@declaration_with_accessors = @property | @indexer | @event; + +@assignable = @variable | @assignable_with_accessors | @event; + +@assignable_with_accessors = @property | @indexer; + +@external_element = @externalMetric | @externalDefect | @externalDataElement; + +@attributable = @assembly | @field | @parameter | @operator | @method | @constructor + | @destructor | @callable_accessor | @value_or_ref_type | @declaration_with_accessors + | @local_function; + +/** LOCATIONS, ASEMMBLIES, MODULES, FILES and FOLDERS **/ + +@location = @location_default | @assembly; + +locations_default( + unique int id: @location_default, + int file: @file ref, + int beginLine: int ref, + int beginColumn: int ref, + int endLine: int ref, + int endColumn: int ref); + +locations_mapped( + unique int id: @location_default ref, + int mapped_to: @location_default ref); + +@sourceline = @file | @callable | @xmllocatable; + +numlines( + int element_id: @sourceline ref, + int num_lines: int ref, + int num_code: int ref, + int num_comment: int ref); + +assemblies( + unique int id: @assembly, + int file: @file ref, + string fullname: string ref, + string name: string ref, + string version: string ref); + +/* + fromSource(0) = unknown, + fromSource(1) = from source, + fromSource(2) = from library +*/ +files( + unique int id: @file, + string name: string ref, + string simple: string ref, + string ext: string ref, + int fromSource: int ref); + +folders( + unique int id: @folder, + string name: string ref, + string simple: string ref); + +@container = @folder | @file ; + +containerparent( + int parent: @container ref, + unique int child: @container ref); + +file_extraction_mode( + unique int file: @file ref, + int mode: int ref + /* 0 = normal, 1 = standalone extractor */ + ); + +/** NAMESPACES **/ + +@type_container = @namespace | @type; + +namespaces( + unique int id: @namespace, + string name: string ref); + +namespace_declarations( + unique int id: @namespace_declaration, + int namespace_id: @namespace ref); + +namespace_declaration_location( + unique int id: @namespace_declaration ref, + int loc: @location ref); + +parent_namespace( + unique int child_id: @type_container ref, + int namespace_id: @namespace ref); + +@declaration_or_directive = @namespace_declaration | @type | @using_directive; + +parent_namespace_declaration( + int child_id: @declaration_or_directive ref, // cannot be unique because of partial classes + int namespace_id: @namespace_declaration ref); + +@using_directive = @using_namespace_directive | @using_static_directive; + +using_namespace_directives( + unique int id: @using_namespace_directive, + int namespace_id: @namespace ref); + +using_static_directives( + unique int id: @using_static_directive, + int type_id: @type_or_ref ref); + +using_directive_location( + unique int id: @using_directive ref, + int loc: @location ref); + +@preprocessor_directive = @pragma_warning | @pragma_checksum | @directive_define | @directive_undefine | @directive_warning + | @directive_error | @directive_nullable | @directive_line | @directive_region | @directive_endregion | @directive_if + | @directive_elif | @directive_else | @directive_endif; + +@conditional_directive = @directive_if | @directive_elif; +@branch_directive = @directive_if | @directive_elif | @directive_else; + +directive_ifs( + unique int id: @directive_if, + int branchTaken: int ref, /* 0: false, 1: true */ + int conditionValue: int ref); /* 0: false, 1: true */ + +directive_elifs( + unique int id: @directive_elif, + int branchTaken: int ref, /* 0: false, 1: true */ + int conditionValue: int ref, /* 0: false, 1: true */ + int parent: @directive_if ref, + int index: int ref); + +directive_elses( + unique int id: @directive_else, + int branchTaken: int ref, /* 0: false, 1: true */ + int parent: @directive_if ref, + int index: int ref); + +#keyset[id, start] +directive_endifs( + unique int id: @directive_endif, + unique int start: @directive_if ref); + +directive_define_symbols( + unique int id: @define_symbol_expr ref, + string name: string ref); + +directive_regions( + unique int id: @directive_region, + string name: string ref); + +#keyset[id, start] +directive_endregions( + unique int id: @directive_endregion, + unique int start: @directive_region ref); + +directive_lines( + unique int id: @directive_line, + int kind: int ref); /* 0: default, 1: hidden, 2: numeric */ + +directive_line_value( + unique int id: @directive_line ref, + int line: int ref); + +directive_line_file( + unique int id: @directive_line ref, + int file: @file ref +) + +directive_nullables( + unique int id: @directive_nullable, + int setting: int ref, /* 0: disable, 1: enable, 2: restore */ + int target: int ref); /* 0: none, 1: annotations, 2: warnings */ + +directive_warnings( + unique int id: @directive_warning, + string message: string ref); + +directive_errors( + unique int id: @directive_error, + string message: string ref); + +directive_undefines( + unique int id: @directive_undefine, + string name: string ref); + +directive_defines( + unique int id: @directive_define, + string name: string ref); + +pragma_checksums( + unique int id: @pragma_checksum, + int file: @file ref, + string guid: string ref, + string bytes: string ref); + +pragma_warnings( + unique int id: @pragma_warning, + int kind: int ref /* 0 = disable, 1 = restore */); + +#keyset[id, index] +pragma_warning_error_codes( + int id: @pragma_warning ref, + string errorCode: string ref, + int index: int ref); + +preprocessor_directive_location( + unique int id: @preprocessor_directive ref, + int loc: @location ref); + +preprocessor_directive_compilation( + unique int id: @preprocessor_directive ref, + int compilation: @compilation ref); + +preprocessor_directive_active( + unique int id: @preprocessor_directive ref, + int active: int ref); /* 0: false, 1: true */ + +/** TYPES **/ + +types( + unique int id: @type, + int kind: int ref, + string name: string ref); + +case @type.kind of + 1 = @bool_type +| 2 = @char_type +| 3 = @decimal_type +| 4 = @sbyte_type +| 5 = @short_type +| 6 = @int_type +| 7 = @long_type +| 8 = @byte_type +| 9 = @ushort_type +| 10 = @uint_type +| 11 = @ulong_type +| 12 = @float_type +| 13 = @double_type +| 14 = @enum_type +| 15 = @struct_type +| 17 = @class_type +| 19 = @interface_type +| 20 = @delegate_type +| 21 = @null_type +| 22 = @type_parameter +| 23 = @pointer_type +| 24 = @nullable_type +| 25 = @array_type +| 26 = @void_type +| 27 = @int_ptr_type +| 28 = @uint_ptr_type +| 29 = @dynamic_type +| 30 = @arglist_type +| 31 = @unknown_type +| 32 = @tuple_type +| 33 = @function_pointer_type + ; + +@simple_type = @bool_type | @char_type | @integral_type | @floating_point_type | @decimal_type; +@integral_type = @signed_integral_type | @unsigned_integral_type; +@signed_integral_type = @sbyte_type | @short_type | @int_type | @long_type; +@unsigned_integral_type = @byte_type | @ushort_type | @uint_type | @ulong_type; +@floating_point_type = @float_type | @double_type; +@value_type = @simple_type | @enum_type | @struct_type | @nullable_type | @int_ptr_type + | @uint_ptr_type | @tuple_type; +@ref_type = @class_type | @interface_type | @array_type | @delegate_type | @null_type + | @dynamic_type; +@value_or_ref_type = @value_type | @ref_type; + +typerefs( + unique int id: @typeref, + string name: string ref); + +typeref_type( + int id: @typeref ref, + unique int typeId: @type ref); + +@type_or_ref = @type | @typeref; + +array_element_type( + unique int array: @array_type ref, + int dimension: int ref, + int rank: int ref, + int element: @type_or_ref ref); + +nullable_underlying_type( + unique int nullable: @nullable_type ref, + int underlying: @type_or_ref ref); + +pointer_referent_type( + unique int pointer: @pointer_type ref, + int referent: @type_or_ref ref); + +enum_underlying_type( + unique int enum_id: @enum_type ref, + int underlying_type_id: @type_or_ref ref); + +delegate_return_type( + unique int delegate_id: @delegate_type ref, + int return_type_id: @type_or_ref ref); + +function_pointer_return_type( + unique int function_pointer_id: @function_pointer_type ref, + int return_type_id: @type_or_ref ref); + +extend( + unique int sub: @type ref, + int super: @type_or_ref ref); + +anonymous_types( + unique int id: @type ref); + +@interface_or_ref = @interface_type | @typeref; + +implement( + int sub: @type ref, + int super: @type_or_ref ref); + +type_location( + int id: @type ref, + int loc: @location ref); + +tuple_underlying_type( + unique int tuple: @tuple_type ref, + int struct: @type_or_ref ref); + +#keyset[tuple, index] +tuple_element( + int tuple: @tuple_type ref, + int index: int ref, + unique int field: @field ref); + +attributes( + unique int id: @attribute, + int type_id: @type_or_ref ref, + int target: @attributable ref); + +attribute_location( + int id: @attribute ref, + int loc: @location ref); + +@type_mention_parent = @element | @type_mention; + +type_mention( + unique int id: @type_mention, + int type_id: @type_or_ref ref, + int parent: @type_mention_parent ref); + +type_mention_location( + unique int id: @type_mention ref, + int loc: @location ref); + +@has_type_annotation = @assignable | @type_parameter | @callable | @expr | @delegate_type | @generic | @function_pointer_type; + +/** + * A direct annotation on an entity, for example `string? x;`. + * + * Annotations: + * 2 = reftype is not annotated "!" + * 3 = reftype is annotated "?" + * 4 = readonly ref type / in parameter + * 5 = ref type parameter, return or local variable + * 6 = out parameter + * + * Note that the annotation depends on the element it annotates. + * @assignable: The annotation is on the type of the assignable, for example the variable type. + * @type_parameter: The annotation is on the reftype constraint + * @callable: The annotation is on the return type + * @array_type: The annotation is on the element type + */ +type_annotation(int id: @has_type_annotation ref, int annotation: int ref); + +nullability(unique int nullability: @nullability, int kind: int ref); + +case @nullability.kind of + 0 = @oblivious +| 1 = @not_annotated +| 2 = @annotated +; + +#keyset[parent, index] +nullability_parent(int nullability: @nullability ref, int index: int ref, int parent: @nullability ref) + +type_nullability(int id: @has_type_annotation ref, int nullability: @nullability ref); + +/** + * The nullable flow state of an expression, as determined by Roslyn. + * 0 = none (default, not populated) + * 1 = not null + * 2 = maybe null + */ +expr_flowstate(unique int id: @expr ref, int state: int ref); + +/** GENERICS **/ + +@generic = @type | @method | @local_function; + +type_parameters( + unique int id: @type_parameter ref, + int index: int ref, + int generic_id: @generic ref, + int variance: int ref /* none = 0, out = 1, in = 2 */); + +#keyset[constructed_id, index] +type_arguments( + int id: @type_or_ref ref, + int index: int ref, + int constructed_id: @generic_or_ref ref); + +@generic_or_ref = @generic | @typeref; + +constructed_generic( + unique int constructed: @generic ref, + int generic: @generic_or_ref ref); + +type_parameter_constraints( + unique int id: @type_parameter_constraints, + int param_id: @type_parameter ref); + +type_parameter_constraints_location( + int id: @type_parameter_constraints ref, + int loc: @location ref); + +general_type_parameter_constraints( + int id: @type_parameter_constraints ref, + int kind: int ref /* class = 1, struct = 2, new = 3 */); + +specific_type_parameter_constraints( + int id: @type_parameter_constraints ref, + int base_id: @type_or_ref ref); + +specific_type_parameter_nullability( + int id: @type_parameter_constraints ref, + int base_id: @type_or_ref ref, + int nullability: @nullability ref); + +/** FUNCTION POINTERS */ + +function_pointer_calling_conventions( + int id: @function_pointer_type ref, + int kind: int ref); + +#keyset[id, index] +has_unmanaged_calling_conventions( + int id: @function_pointer_type ref, + int index: int ref, + int conv_id: @type_or_ref ref); + +/** MODIFIERS */ + +@modifiable = @modifiable_direct | @event_accessor; + +@modifiable_direct = @member | @accessor | @local_function | @anonymous_function_expr; + +modifiers( + unique int id: @modifier, + string name: string ref); + +has_modifiers( + int id: @modifiable_direct ref, + int mod_id: @modifier ref); + +compiler_generated(unique int id: @modifiable_direct ref); + +/** MEMBERS **/ + +@member = @method | @constructor | @destructor | @field | @property | @event | @operator | @indexer | @type; + +@named_exprorstmt = @goto_stmt | @labeled_stmt | @expr; + +@virtualizable = @method | @property | @indexer | @event; + +exprorstmt_name( + unique int parent_id: @named_exprorstmt ref, + string name: string ref); + +nested_types( + unique int id: @type ref, + int declaring_type_id: @type ref, + int unbound_id: @type ref); + +properties( + unique int id: @property, + string name: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @property ref); + +property_location( + int id: @property ref, + int loc: @location ref); + +indexers( + unique int id: @indexer, + string name: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @indexer ref); + +indexer_location( + int id: @indexer ref, + int loc: @location ref); + +accessors( + unique int id: @accessor, + int kind: int ref, + string name: string ref, + int declaring_member_id: @member ref, + int unbound_id: @accessor ref); + +case @accessor.kind of + 1 = @getter +| 2 = @setter + ; + +init_only_accessors( + unique int id: @accessor ref); + +accessor_location( + int id: @accessor ref, + int loc: @location ref); + +events( + unique int id: @event, + string name: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @event ref); + +event_location( + int id: @event ref, + int loc: @location ref); + +event_accessors( + unique int id: @event_accessor, + int kind: int ref, + string name: string ref, + int declaring_event_id: @event ref, + int unbound_id: @event_accessor ref); + +case @event_accessor.kind of + 1 = @add_event_accessor +| 2 = @remove_event_accessor + ; + +event_accessor_location( + int id: @event_accessor ref, + int loc: @location ref); + +operators( + unique int id: @operator, + string name: string ref, + string symbol: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @operator ref); + +operator_location( + int id: @operator ref, + int loc: @location ref); + +constant_value( + int id: @variable ref, + string value: string ref); + +/** CALLABLES **/ + +@callable = @method | @constructor | @destructor | @operator | @callable_accessor | @anonymous_function_expr | @local_function; + +@callable_accessor = @accessor | @event_accessor; + +methods( + unique int id: @method, + string name: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @method ref); + +method_location( + int id: @method ref, + int loc: @location ref); + +constructors( + unique int id: @constructor, + string name: string ref, + int declaring_type_id: @type ref, + int unbound_id: @constructor ref); + +constructor_location( + int id: @constructor ref, + int loc: @location ref); + +destructors( + unique int id: @destructor, + string name: string ref, + int declaring_type_id: @type ref, + int unbound_id: @destructor ref); + +destructor_location( + int id: @destructor ref, + int loc: @location ref); + +overrides( + int id: @callable ref, + int base_id: @callable ref); + +explicitly_implements( + int id: @member ref, + int interface_id: @interface_or_ref ref); + +local_functions( + unique int id: @local_function, + string name: string ref, + int return_type: @type ref, + int unbound_id: @local_function ref); + +local_function_stmts( + unique int fn: @local_function_stmt ref, + int stmt: @local_function ref); + +/** VARIABLES **/ + +@variable = @local_scope_variable | @field; + +@local_scope_variable = @local_variable | @parameter; + +fields( + unique int id: @field, + int kind: int ref, + string name: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @field ref); + +case @field.kind of + 1 = @addressable_field +| 2 = @constant + ; + +field_location( + int id: @field ref, + int loc: @location ref); + +localvars( + unique int id: @local_variable, + int kind: int ref, + string name: string ref, + int implicitly_typed: int ref /* 0 = no, 1 = yes */, + int type_id: @type_or_ref ref, + int parent_id: @local_var_decl_expr ref); + +case @local_variable.kind of + 1 = @addressable_local_variable +| 2 = @local_constant +| 3 = @local_variable_ref + ; + +localvar_location( + unique int id: @local_variable ref, + int loc: @location ref); + +@parameterizable = @callable | @delegate_type | @indexer | @function_pointer_type; + +#keyset[name, parent_id] +#keyset[index, parent_id] +params( + unique int id: @parameter, + string name: string ref, + int type_id: @type_or_ref ref, + int index: int ref, + int mode: int ref, /* value = 0, ref = 1, out = 2, array = 3, this = 4 */ + int parent_id: @parameterizable ref, + int unbound_id: @parameter ref); + +param_location( + int id: @parameter ref, + int loc: @location ref); + +/** STATEMENTS **/ + +@exprorstmt_parent = @control_flow_element | @top_level_exprorstmt_parent; + +statements( + unique int id: @stmt, + int kind: int ref); + +#keyset[index, parent] +stmt_parent( + unique int stmt: @stmt ref, + int index: int ref, + int parent: @control_flow_element ref); + +@top_level_stmt_parent = @callable; + +// [index, parent] is not a keyset because the same parent may be compiled multiple times +stmt_parent_top_level( + unique int stmt: @stmt ref, + int index: int ref, + int parent: @top_level_stmt_parent ref); + +case @stmt.kind of + 1 = @block_stmt +| 2 = @expr_stmt +| 3 = @if_stmt +| 4 = @switch_stmt +| 5 = @while_stmt +| 6 = @do_stmt +| 7 = @for_stmt +| 8 = @foreach_stmt +| 9 = @break_stmt +| 10 = @continue_stmt +| 11 = @goto_stmt +| 12 = @goto_case_stmt +| 13 = @goto_default_stmt +| 14 = @throw_stmt +| 15 = @return_stmt +| 16 = @yield_stmt +| 17 = @try_stmt +| 18 = @checked_stmt +| 19 = @unchecked_stmt +| 20 = @lock_stmt +| 21 = @using_block_stmt +| 22 = @var_decl_stmt +| 23 = @const_decl_stmt +| 24 = @empty_stmt +| 25 = @unsafe_stmt +| 26 = @fixed_stmt +| 27 = @label_stmt +| 28 = @catch +| 29 = @case_stmt +| 30 = @local_function_stmt +| 31 = @using_decl_stmt + ; + +@using_stmt = @using_block_stmt | @using_decl_stmt; + +@labeled_stmt = @label_stmt | @case; + +@decl_stmt = @var_decl_stmt | @const_decl_stmt | @using_decl_stmt; + +@cond_stmt = @if_stmt | @switch_stmt; + +@loop_stmt = @while_stmt | @do_stmt | @for_stmt | @foreach_stmt; + +@jump_stmt = @break_stmt | @goto_any_stmt | @continue_stmt | @throw_stmt | @return_stmt + | @yield_stmt; + +@goto_any_stmt = @goto_default_stmt | @goto_case_stmt | @goto_stmt; + + +stmt_location( + unique int id: @stmt ref, + int loc: @location ref); + +catch_type( + unique int catch_id: @catch ref, + int type_id: @type_or_ref ref, + int kind: int ref /* explicit = 1, implicit = 2 */); + +foreach_stmt_info( + unique int id: @foreach_stmt ref, + int kind: int ref /* non-async = 1, async = 2 */); + +@foreach_symbol = @method | @property | @type_or_ref; + +#keyset[id, kind] +foreach_stmt_desugar( + int id: @foreach_stmt ref, + int symbol: @foreach_symbol ref, + int kind: int ref /* GetEnumeratorMethod = 1, CurrentProperty = 2, MoveNextMethod = 3, DisposeMethod = 4, ElementType = 5 */); + +/** EXPRESSIONS **/ + +expressions( + unique int id: @expr, + int kind: int ref, + int type_id: @type_or_ref ref); + +#keyset[index, parent] +expr_parent( + unique int expr: @expr ref, + int index: int ref, + int parent: @control_flow_element ref); + +@top_level_expr_parent = @attribute | @field | @property | @indexer | @parameter | @directive_if | @directive_elif; + +@top_level_exprorstmt_parent = @top_level_expr_parent | @top_level_stmt_parent; + +// [index, parent] is not a keyset because the same parent may be compiled multiple times +expr_parent_top_level( + unique int expr: @expr ref, + int index: int ref, + int parent: @top_level_exprorstmt_parent ref); + +case @expr.kind of +/* literal */ + 1 = @bool_literal_expr +| 2 = @char_literal_expr +| 3 = @decimal_literal_expr +| 4 = @int_literal_expr +| 5 = @long_literal_expr +| 6 = @uint_literal_expr +| 7 = @ulong_literal_expr +| 8 = @float_literal_expr +| 9 = @double_literal_expr +| 10 = @string_literal_expr +| 11 = @null_literal_expr +/* primary & unary */ +| 12 = @this_access_expr +| 13 = @base_access_expr +| 14 = @local_variable_access_expr +| 15 = @parameter_access_expr +| 16 = @field_access_expr +| 17 = @property_access_expr +| 18 = @method_access_expr +| 19 = @event_access_expr +| 20 = @indexer_access_expr +| 21 = @array_access_expr +| 22 = @type_access_expr +| 23 = @typeof_expr +| 24 = @method_invocation_expr +| 25 = @delegate_invocation_expr +| 26 = @operator_invocation_expr +| 27 = @cast_expr +| 28 = @object_creation_expr +| 29 = @explicit_delegate_creation_expr +| 30 = @implicit_delegate_creation_expr +| 31 = @array_creation_expr +| 32 = @default_expr +| 33 = @plus_expr +| 34 = @minus_expr +| 35 = @bit_not_expr +| 36 = @log_not_expr +| 37 = @post_incr_expr +| 38 = @post_decr_expr +| 39 = @pre_incr_expr +| 40 = @pre_decr_expr +/* multiplicative */ +| 41 = @mul_expr +| 42 = @div_expr +| 43 = @rem_expr +/* additive */ +| 44 = @add_expr +| 45 = @sub_expr +/* shift */ +| 46 = @lshift_expr +| 47 = @rshift_expr +/* relational */ +| 48 = @lt_expr +| 49 = @gt_expr +| 50 = @le_expr +| 51 = @ge_expr +/* equality */ +| 52 = @eq_expr +| 53 = @ne_expr +/* logical */ +| 54 = @bit_and_expr +| 55 = @bit_xor_expr +| 56 = @bit_or_expr +| 57 = @log_and_expr +| 58 = @log_or_expr +/* type testing */ +| 59 = @is_expr +| 60 = @as_expr +/* null coalescing */ +| 61 = @null_coalescing_expr +/* conditional */ +| 62 = @conditional_expr +/* assignment */ +| 63 = @simple_assign_expr +| 64 = @assign_add_expr +| 65 = @assign_sub_expr +| 66 = @assign_mul_expr +| 67 = @assign_div_expr +| 68 = @assign_rem_expr +| 69 = @assign_and_expr +| 70 = @assign_xor_expr +| 71 = @assign_or_expr +| 72 = @assign_lshift_expr +| 73 = @assign_rshift_expr +/* more */ +| 74 = @object_init_expr +| 75 = @collection_init_expr +| 76 = @array_init_expr +| 77 = @checked_expr +| 78 = @unchecked_expr +| 79 = @constructor_init_expr +| 80 = @add_event_expr +| 81 = @remove_event_expr +| 82 = @par_expr +| 83 = @local_var_decl_expr +| 84 = @lambda_expr +| 85 = @anonymous_method_expr +| 86 = @namespace_expr +/* dynamic */ +| 92 = @dynamic_element_access_expr +| 93 = @dynamic_member_access_expr +/* unsafe */ +| 100 = @pointer_indirection_expr +| 101 = @address_of_expr +| 102 = @sizeof_expr +/* async */ +| 103 = @await_expr +/* C# 6.0 */ +| 104 = @nameof_expr +| 105 = @interpolated_string_expr +| 106 = @unknown_expr +/* C# 7.0 */ +| 107 = @throw_expr +| 108 = @tuple_expr +| 109 = @local_function_invocation_expr +| 110 = @ref_expr +| 111 = @discard_expr +/* C# 8.0 */ +| 112 = @range_expr +| 113 = @index_expr +| 114 = @switch_expr +| 115 = @recursive_pattern_expr +| 116 = @property_pattern_expr +| 117 = @positional_pattern_expr +| 118 = @switch_case_expr +| 119 = @assign_coalesce_expr +| 120 = @suppress_nullable_warning_expr +| 121 = @namespace_access_expr +/* C# 9.0 */ +| 122 = @lt_pattern_expr +| 123 = @gt_pattern_expr +| 124 = @le_pattern_expr +| 125 = @ge_pattern_expr +| 126 = @not_pattern_expr +| 127 = @and_pattern_expr +| 128 = @or_pattern_expr +| 129 = @function_pointer_invocation_expr +/* Preprocessor */ +| 999 = @define_symbol_expr +; + +@switch = @switch_stmt | @switch_expr; +@case = @case_stmt | @switch_case_expr; +@pattern_match = @case | @is_expr; +@unary_pattern_expr = @not_pattern_expr; +@relational_pattern_expr = @gt_pattern_expr | @lt_pattern_expr | @ge_pattern_expr | @le_pattern_expr; +@binary_pattern_expr = @and_pattern_expr | @or_pattern_expr; + +@integer_literal_expr = @int_literal_expr | @long_literal_expr | @uint_literal_expr | @ulong_literal_expr; +@real_literal_expr = @float_literal_expr | @double_literal_expr | @decimal_literal_expr; +@literal_expr = @bool_literal_expr | @char_literal_expr | @integer_literal_expr | @real_literal_expr + | @string_literal_expr | @null_literal_expr; + +@assign_expr = @simple_assign_expr | @assign_op_expr | @local_var_decl_expr; +@assign_op_expr = @assign_arith_expr | @assign_bitwise_expr | @assign_event_expr | @assign_coalesce_expr; +@assign_event_expr = @add_event_expr | @remove_event_expr; + +@assign_arith_expr = @assign_add_expr | @assign_sub_expr | @assign_mul_expr | @assign_div_expr + | @assign_rem_expr +@assign_bitwise_expr = @assign_and_expr | @assign_or_expr | @assign_xor_expr + | @assign_lshift_expr | @assign_rshift_expr; + +@member_access_expr = @field_access_expr | @property_access_expr | @indexer_access_expr | @event_access_expr + | @method_access_expr | @type_access_expr | @dynamic_member_access_expr; +@access_expr = @member_access_expr | @this_access_expr | @base_access_expr | @assignable_access_expr | @namespace_access_expr; +@element_access_expr = @indexer_access_expr | @array_access_expr | @dynamic_element_access_expr; + +@local_variable_access = @local_variable_access_expr | @local_var_decl_expr; +@local_scope_variable_access_expr = @parameter_access_expr | @local_variable_access; +@variable_access_expr = @local_scope_variable_access_expr | @field_access_expr; + +@assignable_access_expr = @variable_access_expr | @property_access_expr | @element_access_expr + | @event_access_expr | @dynamic_member_access_expr; + +@objectorcollection_init_expr = @object_init_expr | @collection_init_expr; + +@delegate_creation_expr = @explicit_delegate_creation_expr | @implicit_delegate_creation_expr; + +@bin_arith_op_expr = @mul_expr | @div_expr | @rem_expr | @add_expr | @sub_expr; +@incr_op_expr = @pre_incr_expr | @post_incr_expr; +@decr_op_expr = @pre_decr_expr | @post_decr_expr; +@mut_op_expr = @incr_op_expr | @decr_op_expr; +@un_arith_op_expr = @plus_expr | @minus_expr | @mut_op_expr; +@arith_op_expr = @bin_arith_op_expr | @un_arith_op_expr; + +@ternary_log_op_expr = @conditional_expr; +@bin_log_op_expr = @log_and_expr | @log_or_expr | @null_coalescing_expr; +@un_log_op_expr = @log_not_expr; +@log_expr = @un_log_op_expr | @bin_log_op_expr | @ternary_log_op_expr; + +@bin_bit_op_expr = @bit_and_expr | @bit_or_expr | @bit_xor_expr | @lshift_expr + | @rshift_expr; +@un_bit_op_expr = @bit_not_expr; +@bit_expr = @un_bit_op_expr | @bin_bit_op_expr; + +@equality_op_expr = @eq_expr | @ne_expr; +@rel_op_expr = @gt_expr | @lt_expr| @ge_expr | @le_expr; +@comp_expr = @equality_op_expr | @rel_op_expr; + +@op_expr = @assign_expr | @un_op | @bin_op | @ternary_op; + +@ternary_op = @ternary_log_op_expr; +@bin_op = @bin_arith_op_expr | @bin_log_op_expr | @bin_bit_op_expr | @comp_expr; +@un_op = @un_arith_op_expr | @un_log_op_expr | @un_bit_op_expr | @sizeof_expr + | @pointer_indirection_expr | @address_of_expr; + +@anonymous_function_expr = @lambda_expr | @anonymous_method_expr; + +@call = @method_invocation_expr | @constructor_init_expr | @operator_invocation_expr + | @delegate_invocation_expr | @object_creation_expr | @call_access_expr + | @local_function_invocation_expr | @function_pointer_invocation_expr; + +@call_access_expr = @property_access_expr | @event_access_expr | @indexer_access_expr; + +@late_bindable_expr = @dynamic_element_access_expr | @dynamic_member_access_expr + | @object_creation_expr | @method_invocation_expr | @operator_invocation_expr; + +@throw_element = @throw_expr | @throw_stmt; + +@implicitly_typeable_object_creation_expr = @object_creation_expr | @explicit_delegate_creation_expr; + +implicitly_typed_array_creation( + unique int id: @array_creation_expr ref); + +explicitly_sized_array_creation( + unique int id: @array_creation_expr ref); + +stackalloc_array_creation( + unique int id: @array_creation_expr ref); + +implicitly_typed_object_creation( + unique int id: @implicitly_typeable_object_creation_expr ref); + +mutator_invocation_mode( + unique int id: @operator_invocation_expr ref, + int mode: int ref /* prefix = 1, postfix = 2*/); + +expr_compiler_generated( + unique int id: @expr ref); + +expr_value( + unique int id: @expr ref, + string value: string ref); + +expr_call( + unique int caller_id: @expr ref, + int target_id: @callable ref); + +expr_access( + unique int accesser_id: @access_expr ref, + int target_id: @accessible ref); + +@accessible = @method | @assignable | @local_function | @namespace; + +expr_location( + unique int id: @expr ref, + int loc: @location ref); + +dynamic_member_name( + unique int id: @late_bindable_expr ref, + string name: string ref); + +@qualifiable_expr = @member_access_expr + | @method_invocation_expr + | @element_access_expr; + +conditional_access( + unique int id: @qualifiable_expr ref); + +expr_argument( + unique int id: @expr ref, + int mode: int ref); + /* mode is the same as params: value = 0, ref = 1, out = 2 */ + +expr_argument_name( + unique int id: @expr ref, + string name: string ref); + +/** CONTROL/DATA FLOW **/ + +@control_flow_element = @stmt | @expr; + +/* XML Files */ + +xmlEncoding ( + unique int id: @file ref, + string encoding: string ref); + +xmlDTDs( + unique int id: @xmldtd, + string root: string ref, + string publicId: string ref, + string systemId: string ref, + int fileid: @file ref); + +xmlElements( + unique int id: @xmlelement, + string name: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int fileid: @file ref); + +xmlAttrs( + unique int id: @xmlattribute, + int elementid: @xmlelement ref, + string name: string ref, + string value: string ref, + int idx: int ref, + int fileid: @file ref); + +xmlNs( + int id: @xmlnamespace, + string prefixName: string ref, + string URI: string ref, + int fileid: @file ref); + +xmlHasNs( + int elementId: @xmlnamespaceable ref, + int nsId: @xmlnamespace ref, + int fileid: @file ref); + +xmlComments( + unique int id: @xmlcomment, + string text: string ref, + int parentid: @xmlparent ref, + int fileid: @file ref); + +xmlChars( + unique int id: @xmlcharacters, + string text: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int isCDATA: int ref, + int fileid: @file ref); + +@xmlparent = @file | @xmlelement; +@xmlnamespaceable = @xmlelement | @xmlattribute; + +xmllocations( + int xmlElement: @xmllocatable ref, + int location: @location_default ref); + +@xmllocatable = @xmlcharacters | @xmlelement | @xmlcomment | @xmlattribute | @xmldtd | @file | @xmlnamespace; + +/* Comments */ + +commentline( + unique int id: @commentline, + int kind: int ref, + string text: string ref, + string rawtext: string ref); + +case @commentline.kind of + 0 = @singlelinecomment +| 1 = @xmldoccomment +| 2 = @multilinecomment; + +commentline_location( + unique int id: @commentline ref, + int loc: @location ref); + +commentblock( + unique int id : @commentblock); + +commentblock_location( + unique int id: @commentblock ref, + int loc: @location ref); + +commentblock_binding( + int id: @commentblock ref, + int entity: @element ref, + int bindtype: int ref); /* 0: Parent, 1: Best, 2: Before, 3: After */ + +commentblock_child( + int id: @commentblock ref, + int commentline: @commentline ref, + int index: int ref); + +/* ASP.NET */ + +case @asp_element.kind of + 0=@asp_close_tag +| 1=@asp_code +| 2=@asp_comment +| 3=@asp_data_binding +| 4=@asp_directive +| 5=@asp_open_tag +| 6=@asp_quoted_string +| 7=@asp_text +| 8=@asp_xml_directive; + +@asp_attribute = @asp_code | @asp_data_binding | @asp_quoted_string; + +asp_elements( + unique int id: @asp_element, + int kind: int ref, + int loc: @location ref); + +asp_comment_server(unique int comment: @asp_comment ref); +asp_code_inline(unique int code: @asp_code ref); +asp_directive_attribute( + int directive: @asp_directive ref, + int index: int ref, + string name: string ref, + int value: @asp_quoted_string ref); +asp_directive_name( + unique int directive: @asp_directive ref, + string name: string ref); +asp_element_body( + unique int element: @asp_element ref, + string body: string ref); +asp_tag_attribute( + int tag: @asp_open_tag ref, + int index: int ref, + string name: string ref, + int attribute: @asp_attribute ref); +asp_tag_name( + unique int tag: @asp_open_tag ref, + string name: string ref); +asp_tag_isempty(int tag: @asp_open_tag ref); + +/* Common Intermediate Language - CIL */ + +case @cil_instruction.opcode of + 0 = @cil_nop +| 1 = @cil_break +| 2 = @cil_ldarg_0 +| 3 = @cil_ldarg_1 +| 4 = @cil_ldarg_2 +| 5 = @cil_ldarg_3 +| 6 = @cil_ldloc_0 +| 7 = @cil_ldloc_1 +| 8 = @cil_ldloc_2 +| 9 = @cil_ldloc_3 +| 10 = @cil_stloc_0 +| 11 = @cil_stloc_1 +| 12 = @cil_stloc_2 +| 13 = @cil_stloc_3 +| 14 = @cil_ldarg_s +| 15 = @cil_ldarga_s +| 16 = @cil_starg_s +| 17 = @cil_ldloc_s +| 18 = @cil_ldloca_s +| 19 = @cil_stloc_s +| 20 = @cil_ldnull +| 21 = @cil_ldc_i4_m1 +| 22 = @cil_ldc_i4_0 +| 23 = @cil_ldc_i4_1 +| 24 = @cil_ldc_i4_2 +| 25 = @cil_ldc_i4_3 +| 26 = @cil_ldc_i4_4 +| 27 = @cil_ldc_i4_5 +| 28 = @cil_ldc_i4_6 +| 29 = @cil_ldc_i4_7 +| 30 = @cil_ldc_i4_8 +| 31 = @cil_ldc_i4_s +| 32 = @cil_ldc_i4 +| 33 = @cil_ldc_i8 +| 34 = @cil_ldc_r4 +| 35 = @cil_ldc_r8 +| 37 = @cil_dup +| 38 = @cil_pop +| 39 = @cil_jmp +| 40 = @cil_call +| 41 = @cil_calli +| 42 = @cil_ret +| 43 = @cil_br_s +| 44 = @cil_brfalse_s +| 45 = @cil_brtrue_s +| 46 = @cil_beq_s +| 47 = @cil_bge_s +| 48 = @cil_bgt_s +| 49 = @cil_ble_s +| 50 = @cil_blt_s +| 51 = @cil_bne_un_s +| 52 = @cil_bge_un_s +| 53 = @cil_bgt_un_s +| 54 = @cil_ble_un_s +| 55 = @cil_blt_un_s +| 56 = @cil_br +| 57 = @cil_brfalse +| 58 = @cil_brtrue +| 59 = @cil_beq +| 60 = @cil_bge +| 61 = @cil_bgt +| 62 = @cil_ble +| 63 = @cil_blt +| 64 = @cil_bne_un +| 65 = @cil_bge_un +| 66 = @cil_bgt_un +| 67 = @cil_ble_un +| 68 = @cil_blt_un +| 69 = @cil_switch +| 70 = @cil_ldind_i1 +| 71 = @cil_ldind_u1 +| 72 = @cil_ldind_i2 +| 73 = @cil_ldind_u2 +| 74 = @cil_ldind_i4 +| 75 = @cil_ldind_u4 +| 76 = @cil_ldind_i8 +| 77 = @cil_ldind_i +| 78 = @cil_ldind_r4 +| 79 = @cil_ldind_r8 +| 80 = @cil_ldind_ref +| 81 = @cil_stind_ref +| 82 = @cil_stind_i1 +| 83 = @cil_stind_i2 +| 84 = @cil_stind_i4 +| 85 = @cil_stind_i8 +| 86 = @cil_stind_r4 +| 87 = @cil_stind_r8 +| 88 = @cil_add +| 89 = @cil_sub +| 90 = @cil_mul +| 91 = @cil_div +| 92 = @cil_div_un +| 93 = @cil_rem +| 94 = @cil_rem_un +| 95 = @cil_and +| 96 = @cil_or +| 97 = @cil_xor +| 98 = @cil_shl +| 99 = @cil_shr +| 100 = @cil_shr_un +| 101 = @cil_neg +| 102 = @cil_not +| 103 = @cil_conv_i1 +| 104 = @cil_conv_i2 +| 105 = @cil_conv_i4 +| 106 = @cil_conv_i8 +| 107 = @cil_conv_r4 +| 108 = @cil_conv_r8 +| 109 = @cil_conv_u4 +| 110 = @cil_conv_u8 +| 111 = @cil_callvirt +| 112 = @cil_cpobj +| 113 = @cil_ldobj +| 114 = @cil_ldstr +| 115 = @cil_newobj +| 116 = @cil_castclass +| 117 = @cil_isinst +| 118 = @cil_conv_r_un +| 121 = @cil_unbox +| 122 = @cil_throw +| 123 = @cil_ldfld +| 124 = @cil_ldflda +| 125 = @cil_stfld +| 126 = @cil_ldsfld +| 127 = @cil_ldsflda +| 128 = @cil_stsfld +| 129 = @cil_stobj +| 130 = @cil_conv_ovf_i1_un +| 131 = @cil_conv_ovf_i2_un +| 132 = @cil_conv_ovf_i4_un +| 133 = @cil_conv_ovf_i8_un +| 134 = @cil_conv_ovf_u1_un +| 135 = @cil_conv_ovf_u2_un +| 136 = @cil_conv_ovf_u4_un +| 137 = @cil_conv_ovf_u8_un +| 138 = @cil_conv_ovf_i_un +| 139 = @cil_conv_ovf_u_un +| 140 = @cil_box +| 141 = @cil_newarr +| 142 = @cil_ldlen +| 143 = @cil_ldelema +| 144 = @cil_ldelem_i1 +| 145 = @cil_ldelem_u1 +| 146 = @cil_ldelem_i2 +| 147 = @cil_ldelem_u2 +| 148 = @cil_ldelem_i4 +| 149 = @cil_ldelem_u4 +| 150 = @cil_ldelem_i8 +| 151 = @cil_ldelem_i +| 152 = @cil_ldelem_r4 +| 153 = @cil_ldelem_r8 +| 154 = @cil_ldelem_ref +| 155 = @cil_stelem_i +| 156 = @cil_stelem_i1 +| 157 = @cil_stelem_i2 +| 158 = @cil_stelem_i4 +| 159 = @cil_stelem_i8 +| 160 = @cil_stelem_r4 +| 161 = @cil_stelem_r8 +| 162 = @cil_stelem_ref +| 163 = @cil_ldelem +| 164 = @cil_stelem +| 165 = @cil_unbox_any +| 179 = @cil_conv_ovf_i1 +| 180 = @cil_conv_ovf_u1 +| 181 = @cil_conv_ovf_i2 +| 182 = @cil_conv_ovf_u2 +| 183 = @cil_conv_ovf_i4 +| 184 = @cil_conv_ovf_u4 +| 185 = @cil_conv_ovf_i8 +| 186 = @cil_conv_ovf_u8 +| 194 = @cil_refanyval +| 195 = @cil_ckinfinite +| 198 = @cil_mkrefany +| 208 = @cil_ldtoken +| 209 = @cil_conv_u2 +| 210 = @cil_conv_u1 +| 211 = @cil_conv_i +| 212 = @cil_conv_ovf_i +| 213 = @cil_conv_ovf_u +| 214 = @cil_add_ovf +| 215 = @cil_add_ovf_un +| 216 = @cil_mul_ovf +| 217 = @cil_mul_ovf_un +| 218 = @cil_sub_ovf +| 219 = @cil_sub_ovf_un +| 220 = @cil_endfinally +| 221 = @cil_leave +| 222 = @cil_leave_s +| 223 = @cil_stind_i +| 224 = @cil_conv_u +| 65024 = @cil_arglist +| 65025 = @cil_ceq +| 65026 = @cil_cgt +| 65027 = @cil_cgt_un +| 65028 = @cil_clt +| 65029 = @cil_clt_un +| 65030 = @cil_ldftn +| 65031 = @cil_ldvirtftn +| 65033 = @cil_ldarg +| 65034 = @cil_ldarga +| 65035 = @cil_starg +| 65036 = @cil_ldloc +| 65037 = @cil_ldloca +| 65038 = @cil_stloc +| 65039 = @cil_localloc +| 65041 = @cil_endfilter +| 65042 = @cil_unaligned +| 65043 = @cil_volatile +| 65044 = @cil_tail +| 65045 = @cil_initobj +| 65046 = @cil_constrained +| 65047 = @cil_cpblk +| 65048 = @cil_initblk +| 65050 = @cil_rethrow +| 65052 = @cil_sizeof +| 65053 = @cil_refanytype +| 65054 = @cil_readonly +; + +// CIL ignored instructions + +@cil_ignore = @cil_nop | @cil_break | @cil_volatile | @cil_unaligned; + +// CIL local/parameter/field access + +@cil_ldarg_any = @cil_ldarg_0 | @cil_ldarg_1 | @cil_ldarg_2 | @cil_ldarg_3 | @cil_ldarg_s | @cil_ldarga_s | @cil_ldarg | @cil_ldarga; +@cil_starg_any = @cil_starg | @cil_starg_s; + +@cil_ldloc_any = @cil_ldloc_0 | @cil_ldloc_1 | @cil_ldloc_2 | @cil_ldloc_3 | @cil_ldloc_s | @cil_ldloca_s | @cil_ldloc | @cil_ldloca; +@cil_stloc_any = @cil_stloc_0 | @cil_stloc_1 | @cil_stloc_2 | @cil_stloc_3 | @cil_stloc_s | @cil_stloc; + +@cil_ldfld_any = @cil_ldfld | @cil_ldsfld | @cil_ldsflda | @cil_ldflda; +@cil_stfld_any = @cil_stfld | @cil_stsfld; + +@cil_local_access = @cil_stloc_any | @cil_ldloc_any; +@cil_arg_access = @cil_starg_any | @cil_ldarg_any; +@cil_read_access = @cil_ldloc_any | @cil_ldarg_any | @cil_ldfld_any; +@cil_write_access = @cil_stloc_any | @cil_starg_any | @cil_stfld_any; + +@cil_stack_access = @cil_local_access | @cil_arg_access; +@cil_field_access = @cil_ldfld_any | @cil_stfld_any; + +@cil_access = @cil_read_access | @cil_write_access; + +// CIL constant/literal instructions + +@cil_ldc_i = @cil_ldc_i4_any | @cil_ldc_i8; + +@cil_ldc_i4_any = @cil_ldc_i4_m1 | @cil_ldc_i4_0 | @cil_ldc_i4_1 | @cil_ldc_i4_2 | @cil_ldc_i4_3 | + @cil_ldc_i4_4 | @cil_ldc_i4_5 | @cil_ldc_i4_6 | @cil_ldc_i4_7 | @cil_ldc_i4_8 | @cil_ldc_i4_s | @cil_ldc_i4; + +@cil_ldc_r = @cil_ldc_r4 | @cil_ldc_r8; + +@cil_literal = @cil_ldnull | @cil_ldc_i | @cil_ldc_r | @cil_ldstr; + +// Control flow + +@cil_conditional_jump = @cil_binary_jump | @cil_unary_jump; +@cil_binary_jump = @cil_beq_s | @cil_bge_s | @cil_bgt_s | @cil_ble_s | @cil_blt_s | + @cil_bne_un_s | @cil_bge_un_s | @cil_bgt_un_s | @cil_ble_un_s | @cil_blt_un_s | + @cil_beq | @cil_bge | @cil_bgt | @cil_ble | @cil_blt | + @cil_bne_un | @cil_bge_un | @cil_bgt_un | @cil_ble_un | @cil_blt_un; +@cil_unary_jump = @cil_brfalse_s | @cil_brtrue_s | @cil_brfalse | @cil_brtrue | @cil_switch; +@cil_unconditional_jump = @cil_br | @cil_br_s | @cil_leave_any; +@cil_leave_any = @cil_leave | @cil_leave_s; +@cil_jump = @cil_unconditional_jump | @cil_conditional_jump; + +// CIL call instructions + +@cil_call_any = @cil_jmp | @cil_call | @cil_calli | @cil_tail | @cil_callvirt | @cil_newobj; + +// CIL expression instructions + +@cil_expr = @cil_literal | @cil_binary_expr | @cil_unary_expr | @cil_call_any | @cil_read_access | + @cil_newarr | @cil_ldtoken | @cil_sizeof | + @cil_ldftn | @cil_ldvirtftn | @cil_localloc | @cil_mkrefany | @cil_refanytype | @cil_arglist | @cil_dup; + +@cil_unary_expr = + @cil_conversion_operation | @cil_unary_arithmetic_operation | @cil_unary_bitwise_operation| + @cil_ldlen | @cil_isinst | @cil_box | @cil_ldobj | @cil_castclass | @cil_unbox_any | + @cil_ldind | @cil_unbox; + +@cil_conversion_operation = + @cil_conv_i1 | @cil_conv_i2 | @cil_conv_i4 | @cil_conv_i8 | + @cil_conv_u1 | @cil_conv_u2 | @cil_conv_u4 | @cil_conv_u8 | + @cil_conv_ovf_i | @cil_conv_ovf_i_un | @cil_conv_ovf_i1 | @cil_conv_ovf_i1_un | + @cil_conv_ovf_i2 | @cil_conv_ovf_i2_un | @cil_conv_ovf_i4 | @cil_conv_ovf_i4_un | + @cil_conv_ovf_i8 | @cil_conv_ovf_i8_un | @cil_conv_ovf_u | @cil_conv_ovf_u_un | + @cil_conv_ovf_u1 | @cil_conv_ovf_u1_un | @cil_conv_ovf_u2 | @cil_conv_ovf_u2_un | + @cil_conv_ovf_u4 | @cil_conv_ovf_u4_un | @cil_conv_ovf_u8 | @cil_conv_ovf_u8_un | + @cil_conv_r4 | @cil_conv_r8 | @cil_conv_ovf_u2 | @cil_conv_ovf_u2_un | + @cil_conv_i | @cil_conv_u | @cil_conv_r_un; + +@cil_ldind = @cil_ldind_i | @cil_ldind_i1 | @cil_ldind_i2 | @cil_ldind_i4 | @cil_ldind_i8 | + @cil_ldind_r4 | @cil_ldind_r8 | @cil_ldind_ref | @cil_ldind_u1 | @cil_ldind_u2 | @cil_ldind_u4; + +@cil_stind = @cil_stind_i | @cil_stind_i1 | @cil_stind_i2 | @cil_stind_i4 | @cil_stind_i8 | + @cil_stind_r4 | @cil_stind_r8 | @cil_stind_ref; + +@cil_bitwise_operation = @cil_binary_bitwise_operation | @cil_unary_bitwise_operation; + +@cil_binary_bitwise_operation = @cil_and | @cil_or | @cil_xor | @cil_shr | @cil_shr | @cil_shr_un | @cil_shl; + +@cil_binary_arithmetic_operation = @cil_add | @cil_sub | @cil_mul | @cil_div | @cil_div_un | + @cil_rem | @cil_rem_un | @cil_add_ovf | @cil_add_ovf_un | @cil_mul_ovf | @cil_mul_ovf_un | + @cil_sub_ovf | @cil_sub_ovf_un; + +@cil_unary_bitwise_operation = @cil_not; + +@cil_binary_expr = @cil_binary_arithmetic_operation | @cil_binary_bitwise_operation | @cil_read_array | @cil_comparison_operation; + +@cil_unary_arithmetic_operation = @cil_neg; + +@cil_comparison_operation = @cil_cgt_un | @cil_ceq | @cil_cgt | @cil_clt | @cil_clt_un; + +// Elements that retrieve an address of something +@cil_read_ref = @cil_ldloca_s | @cil_ldarga_s | @cil_ldflda | @cil_ldsflda | @cil_ldelema; + +// CIL array instructions + +@cil_read_array = + @cil_ldelem | @cil_ldelema | @cil_ldelem_i1 | @cil_ldelem_ref | @cil_ldelem_i | + @cil_ldelem_i1 | @cil_ldelem_i2 | @cil_ldelem_i4 | @cil_ldelem_i8 | @cil_ldelem_r4 | + @cil_ldelem_r8 | @cil_ldelem_u1 | @cil_ldelem_u2 | @cil_ldelem_u4; + +@cil_write_array = @cil_stelem | @cil_stelem_ref | + @cil_stelem_i | @cil_stelem_i1 | @cil_stelem_i2 | @cil_stelem_i4 | @cil_stelem_i8 | + @cil_stelem_r4 | @cil_stelem_r8; + +@cil_throw_any = @cil_throw | @cil_rethrow; + +#keyset[impl, index] +cil_instruction( + unique int id: @cil_instruction, + int opcode: int ref, + int index: int ref, + int impl: @cil_method_implementation ref); + +cil_jump( + unique int instruction: @cil_jump ref, + int target: @cil_instruction ref); + +cil_access( + unique int instruction: @cil_instruction ref, + int target: @cil_accessible ref); + +cil_value( + unique int instruction: @cil_literal ref, + string value: string ref); + +#keyset[instruction, index] +cil_switch( + int instruction: @cil_switch ref, + int index: int ref, + int target: @cil_instruction ref); + +cil_instruction_location( + unique int id: @cil_instruction ref, + int loc: @location ref); + +cil_type_location( + int id: @cil_type ref, + int loc: @location ref); + +cil_method_location( + int id: @cil_method ref, + int loc: @location ref); + +@cil_namespace = @namespace; + +@cil_type_container = @cil_type | @cil_namespace | @cil_method; + +case @cil_type.kind of + 0 = @cil_valueorreftype +| 1 = @cil_typeparameter +| 2 = @cil_array_type +| 3 = @cil_pointer_type +| 4 = @cil_function_pointer_type +; + +cil_type( + unique int id: @cil_type, + string name: string ref, + int kind: int ref, + int parent: @cil_type_container ref, + int sourceDecl: @cil_type ref); + +cil_pointer_type( + unique int id: @cil_pointer_type ref, + int pointee: @cil_type ref); + +cil_array_type( + unique int id: @cil_array_type ref, + int element_type: @cil_type ref, + int rank: int ref); + +cil_function_pointer_return_type( + unique int id: @cil_function_pointer_type ref, + int return_type: @cil_type ref); + +cil_method( + unique int id: @cil_method, + string name: string ref, + int parent: @cil_type ref, + int return_type: @cil_type ref); + +cil_method_source_declaration( + unique int method: @cil_method ref, + int source: @cil_method ref); + +cil_method_implementation( + unique int id: @cil_method_implementation, + int method: @cil_method ref, + int location: @assembly ref); + +cil_implements( + int id: @cil_method ref, + int decl: @cil_method ref); + +#keyset[parent, name] +cil_field( + unique int id: @cil_field, + int parent: @cil_type ref, + string name: string ref, + int field_type: @cil_type ref); + +@cil_element = @cil_instruction | @cil_declaration | @cil_handler | @cil_attribute | @cil_namespace; +@cil_named_element = @cil_declaration | @cil_namespace; +@cil_declaration = @cil_variable | @cil_method | @cil_type | @cil_member; +@cil_accessible = @cil_declaration; +@cil_variable = @cil_field | @cil_stack_variable; +@cil_stack_variable = @cil_local_variable | @cil_parameter; +@cil_member = @cil_method | @cil_type | @cil_field | @cil_property | @cil_event; +@cil_custom_modifier_receiver = @cil_method | @cil_property | @cil_parameter | @cil_field | @cil_function_pointer_type; +@cil_parameterizable = @cil_method | @cil_function_pointer_type; +@cil_has_type_annotation = @cil_stack_variable | @cil_property | @cil_method | @cil_function_pointer_type; + +#keyset[parameterizable, index] +cil_parameter( + unique int id: @cil_parameter, + int parameterizable: @cil_parameterizable ref, + int index: int ref, + int param_type: @cil_type ref); + +cil_parameter_in(unique int id: @cil_parameter ref); +cil_parameter_out(unique int id: @cil_parameter ref); + +cil_setter(unique int prop: @cil_property ref, + int method: @cil_method ref); + +#keyset[id, modifier] +cil_custom_modifiers( + int id: @cil_custom_modifier_receiver ref, + int modifier: @cil_type ref, + int kind: int ref); // modreq: 1, modopt: 0 + +cil_type_annotation( + int id: @cil_has_type_annotation ref, + int annotation: int ref); + +cil_getter(unique int prop: @cil_property ref, + int method: @cil_method ref); + +cil_adder(unique int event: @cil_event ref, + int method: @cil_method ref); + +cil_remover(unique int event: @cil_event ref, int method: @cil_method ref); + +cil_raiser(unique int event: @cil_event ref, int method: @cil_method ref); + +cil_property( + unique int id: @cil_property, + int parent: @cil_type ref, + string name: string ref, + int property_type: @cil_type ref); + +#keyset[parent, name] +cil_event(unique int id: @cil_event, + int parent: @cil_type ref, + string name: string ref, + int event_type: @cil_type ref); + +#keyset[impl, index] +cil_local_variable( + unique int id: @cil_local_variable, + int impl: @cil_method_implementation ref, + int index: int ref, + int var_type: @cil_type ref); + +cil_function_pointer_calling_conventions( + int id: @cil_function_pointer_type ref, + int kind: int ref); + +// CIL handlers (exception handlers etc). + +case @cil_handler.kind of + 0 = @cil_catch_handler +| 1 = @cil_filter_handler +| 2 = @cil_finally_handler +| 4 = @cil_fault_handler +; + +#keyset[impl, index] +cil_handler( + unique int id: @cil_handler, + int impl: @cil_method_implementation ref, + int index: int ref, + int kind: int ref, + int try_start: @cil_instruction ref, + int try_end: @cil_instruction ref, + int handler_start: @cil_instruction ref); + +cil_handler_filter( + unique int id: @cil_handler ref, + int filter_start: @cil_instruction ref); + +cil_handler_type( + unique int id: @cil_handler ref, + int catch_type: @cil_type ref); + +@cil_controlflow_node = @cil_entry_point | @cil_instruction; + +@cil_entry_point = @cil_method_implementation | @cil_handler; + +@cil_dataflow_node = @cil_instruction | @cil_variable | @cil_method; + +cil_method_stack_size( + unique int method: @cil_method_implementation ref, + int size: int ref); + +// CIL modifiers + +cil_public(int id: @cil_member ref); +cil_private(int id: @cil_member ref); +cil_protected(int id: @cil_member ref); +cil_internal(int id: @cil_member ref); +cil_static(int id: @cil_member ref); +cil_sealed(int id: @cil_member ref); +cil_virtual(int id: @cil_method ref); +cil_abstract(int id: @cil_member ref); +cil_class(int id: @cil_type ref); +cil_interface(int id: @cil_type ref); +cil_security(int id: @cil_member ref); +cil_requiresecobject(int id: @cil_method ref); +cil_specialname(int id: @cil_method ref); +cil_newslot(int id: @cil_method ref); + +cil_base_class(unique int id: @cil_type ref, int base: @cil_type ref); +cil_base_interface(int id: @cil_type ref, int base: @cil_type ref); +cil_enum_underlying_type(unique int id: @cil_type ref, int underlying: @cil_type ref); + +#keyset[unbound, index] +cil_type_parameter( + int unbound: @cil_member ref, + int index: int ref, + int param: @cil_typeparameter ref); + +#keyset[bound, index] +cil_type_argument( + int bound: @cil_member ref, + int index: int ref, + int t: @cil_type ref); + +// CIL type parameter constraints + +cil_typeparam_covariant(int tp: @cil_typeparameter ref); +cil_typeparam_contravariant(int tp: @cil_typeparameter ref); +cil_typeparam_class(int tp: @cil_typeparameter ref); +cil_typeparam_struct(int tp: @cil_typeparameter ref); +cil_typeparam_new(int tp: @cil_typeparameter ref); +cil_typeparam_constraint(int tp: @cil_typeparameter ref, int supertype: @cil_type ref); + +// CIL attributes + +cil_attribute( + unique int attributeid: @cil_attribute, + int element: @cil_declaration ref, + int constructor: @cil_method ref); + +#keyset[attribute_id, param] +cil_attribute_named_argument( + int attribute_id: @cil_attribute ref, + string param: string ref, + string value: string ref); + +#keyset[attribute_id, index] +cil_attribute_positional_argument( + int attribute_id: @cil_attribute ref, + int index: int ref, + string value: string ref); + + +// Common .Net data model covering both C# and CIL + +// Common elements +@dotnet_element = @element | @cil_element; +@dotnet_named_element = @named_element | @cil_named_element; +@dotnet_callable = @callable | @cil_method; +@dotnet_variable = @variable | @cil_variable; +@dotnet_field = @field | @cil_field; +@dotnet_parameter = @parameter | @cil_parameter; +@dotnet_declaration = @declaration | @cil_declaration; +@dotnet_member = @member | @cil_member; +@dotnet_event = @event | @cil_event; +@dotnet_property = @property | @cil_property | @indexer; +@dotnet_parameterizable = @parameterizable | @cil_parameterizable; + +// Common types +@dotnet_type = @type | @cil_type; +@dotnet_call = @call | @cil_call_any; +@dotnet_throw = @throw_element | @cil_throw_any; +@dotnet_valueorreftype = @cil_valueorreftype | @value_or_ref_type | @cil_array_type | @void_type; +@dotnet_typeparameter = @type_parameter | @cil_typeparameter; +@dotnet_array_type = @array_type | @cil_array_type; +@dotnet_pointer_type = @pointer_type | @cil_pointer_type; +@dotnet_type_parameter = @type_parameter | @cil_typeparameter; +@dotnet_generic = @dotnet_valueorreftype | @dotnet_callable; + +// Attributes +@dotnet_attribute = @attribute | @cil_attribute; + +// Expressions +@dotnet_expr = @expr | @cil_expr; + +// Literals +@dotnet_literal = @literal_expr | @cil_literal; +@dotnet_string_literal = @string_literal_expr | @cil_ldstr; +@dotnet_int_literal = @integer_literal_expr | @cil_ldc_i; +@dotnet_float_literal = @float_literal_expr | @cil_ldc_r; +@dotnet_null_literal = @null_literal_expr | @cil_ldnull; + +@metadata_entity = @cil_method | @cil_type | @cil_field | @cil_property | @field | @property | + @callable | @value_or_ref_type | @void_type; + +#keyset[entity, location] +metadata_handle(int entity : @metadata_entity ref, int location: @assembly ref, int handle: int ref) diff --git a/csharp/upgrades/68db341c2ed1693c2ae6e20ad533c84138cb275a/upgrade.properties b/csharp/upgrades/68db341c2ed1693c2ae6e20ad533c84138cb275a/upgrade.properties new file mode 100644 index 00000000000..0b0c3a88460 --- /dev/null +++ b/csharp/upgrades/68db341c2ed1693c2ae6e20ad533c84138cb275a/upgrade.properties @@ -0,0 +1,2 @@ +description: Add 'foreach_stmt_info' and 'foreach_stmt_desugar' relations. +compatibility: backwards \ No newline at end of file diff --git a/csharp/upgrades/98e37f65f0ae39cfe1bff33908d6620ade5df0f7/old.dbscheme b/csharp/upgrades/98e37f65f0ae39cfe1bff33908d6620ade5df0f7/old.dbscheme new file mode 100644 index 00000000000..98e37f65f0a --- /dev/null +++ b/csharp/upgrades/98e37f65f0ae39cfe1bff33908d6620ade5df0f7/old.dbscheme @@ -0,0 +1,1922 @@ + +/** + * An invocation of the compiler. Note that more than one file may be + * compiled per invocation. For example, this command compiles three + * source files: + * + * csc f1.cs f2.cs f3.cs + * + * The `id` simply identifies the invocation, while `cwd` is the working + * directory from which the compiler was invoked. + */ +compilations( + unique int id : @compilation, + string cwd : string ref +); + +/** + * The arguments that were passed to the extractor for a compiler + * invocation. If `id` is for the compiler invocation + * + * csc f1.cs f2.cs f3.cs + * + * then typically there will be rows for + * + * num | arg + * --- | --- + * 0 | --compiler + * 1 | *path to compiler* + * 2 | --cil + * 3 | f1.cs + * 4 | f2.cs + * 5 | f3.cs + */ +#keyset[id, num] +compilation_args( + int id : @compilation ref, + int num : int ref, + string arg : string ref +); + +/** + * The source files that are compiled by a compiler invocation. + * If `id` is for the compiler invocation + * + * csc f1.cs f2.cs f3.cs + * + * then there will be rows for + * + * num | arg + * --- | --- + * 0 | f1.cs + * 1 | f2.cs + * 2 | f3.cs + */ +#keyset[id, num] +compilation_compiling_files( + int id : @compilation ref, + int num : int ref, + int file : @file ref +); + +/** + * The references used by a compiler invocation. + * If `id` is for the compiler invocation + * + * csc f1.cs f2.cs f3.cs /r:ref1.dll /r:ref2.dll /r:ref3.dll + * + * then there will be rows for + * + * num | arg + * --- | --- + * 0 | ref1.dll + * 1 | ref2.dll + * 2 | ref3.dll + */ +#keyset[id, num] +compilation_referencing_files( + int id : @compilation ref, + int num : int ref, + int file : @file ref +); + +/** + * The time taken by the extractor for a compiler invocation. + * + * For each file `num`, there will be rows for + * + * kind | seconds + * ---- | --- + * 1 | CPU seconds used by the extractor frontend + * 2 | Elapsed seconds during the extractor frontend + * 3 | CPU seconds used by the extractor backend + * 4 | Elapsed seconds during the extractor backend + */ +#keyset[id, num, kind] +compilation_time( + int id : @compilation ref, + int num : int ref, + /* kind: + 1 = frontend_cpu_seconds + 2 = frontend_elapsed_seconds + 3 = extractor_cpu_seconds + 4 = extractor_elapsed_seconds + */ + int kind : int ref, + float seconds : float ref +); + +/** + * An error or warning generated by the extractor. + * The diagnostic message `diagnostic` was generated during compiler + * invocation `compilation`, and is the `file_number_diagnostic_number`th + * message generated while extracting the `file_number`th file of that + * invocation. + */ +#keyset[compilation, file_number, file_number_diagnostic_number] +diagnostic_for( + unique int diagnostic : @diagnostic ref, + int compilation : @compilation ref, + int file_number : int ref, + int file_number_diagnostic_number : int ref +); + +diagnostics( + unique int id: @diagnostic, + int severity: int ref, + string error_tag: string ref, + string error_message: string ref, + string full_error_message: string ref, + int location: @location_default ref +); + +extractor_messages( + unique int id: @extractor_message, + int severity: int ref, + string origin : string ref, + string text : string ref, + string entity : string ref, + int location: @location_default ref, + string stack_trace : string ref +); + +/** + * If extraction was successful, then `cpu_seconds` and + * `elapsed_seconds` are the CPU time and elapsed time (respectively) + * that extraction took for compiler invocation `id`. + */ +compilation_finished( + unique int id : @compilation ref, + float cpu_seconds : float ref, + float elapsed_seconds : float ref +); + +compilation_assembly( + unique int id : @compilation ref, + int assembly: @assembly ref +) + +/* + * External artifacts + */ + +externalDefects( + unique int id: @externalDefect, + string queryPath: string ref, + int location: @location ref, + string message: string ref, + float severity: float ref); + +externalMetrics( + unique int id: @externalMetric, + string queryPath: string ref, + int location: @location ref, + float value: float ref); + +externalData( + int id: @externalDataElement, + string path: string ref, + int column: int ref, + string value: string ref); + +snapshotDate( + unique date snapshotDate: date ref); + +sourceLocationPrefix( + string prefix: string ref); + +/* + * Duplicate code + */ + +duplicateCode( + unique int id: @duplication, + string relativePath: string ref, + int equivClass: int ref); + +similarCode( + unique int id: @similarity, + string relativePath: string ref, + int equivClass: int ref); + +@duplication_or_similarity = @duplication | @similarity + +tokens( + int id: @duplication_or_similarity ref, + int offset: int ref, + int beginLine: int ref, + int beginColumn: int ref, + int endLine: int ref, + int endColumn: int ref); + +/* + * C# dbscheme + */ + +/** ELEMENTS **/ + +@element = @declaration | @stmt | @expr | @modifier | @attribute | @namespace_declaration + | @using_directive | @type_parameter_constraints | @external_element + | @xmllocatable | @asp_element | @namespace; + +@declaration = @callable | @generic | @assignable | @namespace; + +@named_element = @namespace | @declaration; + +@declaration_with_accessors = @property | @indexer | @event; + +@assignable = @variable | @assignable_with_accessors | @event; + +@assignable_with_accessors = @property | @indexer; + +@external_element = @externalMetric | @externalDefect | @externalDataElement; + +@attributable = @assembly | @field | @parameter | @operator | @method | @constructor + | @destructor | @callable_accessor | @value_or_ref_type | @declaration_with_accessors + | @local_function; + +/** LOCATIONS, ASEMMBLIES, MODULES, FILES and FOLDERS **/ + +@location = @location_default | @assembly; + +locations_default( + unique int id: @location_default, + int file: @file ref, + int beginLine: int ref, + int beginColumn: int ref, + int endLine: int ref, + int endColumn: int ref); + +@sourceline = @file | @callable | @xmllocatable; + +numlines( + int element_id: @sourceline ref, + int num_lines: int ref, + int num_code: int ref, + int num_comment: int ref); + +assemblies( + unique int id: @assembly, + int file: @file ref, + string fullname: string ref, + string name: string ref, + string version: string ref); + +/* + fromSource(0) = unknown, + fromSource(1) = from source, + fromSource(2) = from library +*/ +files( + unique int id: @file, + string name: string ref, + string simple: string ref, + string ext: string ref, + int fromSource: int ref); + +folders( + unique int id: @folder, + string name: string ref, + string simple: string ref); + +@container = @folder | @file ; + +containerparent( + int parent: @container ref, + unique int child: @container ref); + +file_extraction_mode( + unique int file: @file ref, + int mode: int ref + /* 0 = normal, 1 = standalone extractor */ + ); + +/** NAMESPACES **/ + +@type_container = @namespace | @type; + +namespaces( + unique int id: @namespace, + string name: string ref); + +namespace_declarations( + unique int id: @namespace_declaration, + int namespace_id: @namespace ref); + +namespace_declaration_location( + unique int id: @namespace_declaration ref, + int loc: @location ref); + +parent_namespace( + unique int child_id: @type_container ref, + int namespace_id: @namespace ref); + +@declaration_or_directive = @namespace_declaration | @type | @using_directive; + +parent_namespace_declaration( + int child_id: @declaration_or_directive ref, // cannot be unique because of partial classes + int namespace_id: @namespace_declaration ref); + +@using_directive = @using_namespace_directive | @using_static_directive; + +using_namespace_directives( + unique int id: @using_namespace_directive, + int namespace_id: @namespace ref); + +using_static_directives( + unique int id: @using_static_directive, + int type_id: @type_or_ref ref); + +using_directive_location( + unique int id: @using_directive ref, + int loc: @location ref); + +/** TYPES **/ + +types( + unique int id: @type, + int kind: int ref, + string name: string ref); + +case @type.kind of + 1 = @bool_type +| 2 = @char_type +| 3 = @decimal_type +| 4 = @sbyte_type +| 5 = @short_type +| 6 = @int_type +| 7 = @long_type +| 8 = @byte_type +| 9 = @ushort_type +| 10 = @uint_type +| 11 = @ulong_type +| 12 = @float_type +| 13 = @double_type +| 14 = @enum_type +| 15 = @struct_type +| 17 = @class_type +| 19 = @interface_type +| 20 = @delegate_type +| 21 = @null_type +| 22 = @type_parameter +| 23 = @pointer_type +| 24 = @nullable_type +| 25 = @array_type +| 26 = @void_type +| 27 = @int_ptr_type +| 28 = @uint_ptr_type +| 29 = @dynamic_type +| 30 = @arglist_type +| 31 = @unknown_type +| 32 = @tuple_type + ; + +@simple_type = @bool_type | @char_type | @integral_type | @floating_point_type | @decimal_type; +@integral_type = @signed_integral_type | @unsigned_integral_type; +@signed_integral_type = @sbyte_type | @short_type | @int_type | @long_type; +@unsigned_integral_type = @byte_type | @ushort_type | @uint_type | @ulong_type; +@floating_point_type = @float_type | @double_type; +@value_type = @simple_type | @enum_type | @struct_type | @nullable_type | @int_ptr_type + | @uint_ptr_type | @tuple_type; +@ref_type = @class_type | @interface_type | @array_type | @delegate_type | @null_type + | @dynamic_type; +@value_or_ref_type = @value_type | @ref_type; + +typerefs( + unique int id: @typeref, + string name: string ref); + +typeref_type( + int id: @typeref ref, + unique int typeId: @type ref); + +@type_or_ref = @type | @typeref; + +array_element_type( + unique int array: @array_type ref, + int dimension: int ref, + int rank: int ref, + int element: @type_or_ref ref); + +nullable_underlying_type( + unique int nullable: @nullable_type ref, + int underlying: @type_or_ref ref); + +pointer_referent_type( + unique int pointer: @pointer_type ref, + int referent: @type_or_ref ref); + +enum_underlying_type( + unique int enum_id: @enum_type ref, + int underlying_type_id: @type_or_ref ref); + +delegate_return_type( + unique int delegate_id: @delegate_type ref, + int return_type_id: @type_or_ref ref); + +extend( + unique int sub: @type ref, + int super: @type_or_ref ref); + +anonymous_types( + unique int id: @type ref); + +@interface_or_ref = @interface_type | @typeref; + +implement( + int sub: @type ref, + int super: @type_or_ref ref); + +type_location( + int id: @type ref, + int loc: @location ref); + +tuple_underlying_type( + unique int tuple: @tuple_type ref, + int struct: @type_or_ref ref); + +#keyset[tuple, index] +tuple_element( + int tuple: @tuple_type ref, + int index: int ref, + unique int field: @field ref); + +attributes( + unique int id: @attribute, + int type_id: @type_or_ref ref, + int target: @attributable ref); + +attribute_location( + int id: @attribute ref, + int loc: @location ref); + +@type_mention_parent = @element | @type_mention; + +type_mention( + unique int id: @type_mention, + int type_id: @type_or_ref ref, + int parent: @type_mention_parent ref); + +type_mention_location( + unique int id: @type_mention ref, + int loc: @location ref); + +@has_type_annotation = @assignable | @type_parameter | @callable | @expr | @delegate_type | @generic; + +/** + * A direct annotation on an entity, for example `string? x;`. + * + * Annotations: + * 2 = reftype is not annotated "!" + * 3 = reftype is annotated "?" + * 4 = readonly ref type / in parameter + * 5 = ref type parameter, return or local variable + * 6 = out parameter + * + * Note that the annotation depends on the element it annotates. + * @assignable: The annotation is on the type of the assignable, for example the variable type. + * @type_parameter: The annotation is on the reftype constraint + * @callable: The annotation is on the return type + * @array_type: The annotation is on the element type + */ +type_annotation(int id: @has_type_annotation ref, int annotation: int ref); + +nullability(unique int nullability: @nullability, int kind: int ref); + +case @nullability.kind of + 0 = @oblivious +| 1 = @not_annotated +| 2 = @annotated +; + +#keyset[parent, index] +nullability_parent(int nullability: @nullability ref, int index: int ref, int parent: @nullability ref) + +type_nullability(int id: @has_type_annotation ref, int nullability: @nullability ref); + +/** + * The nullable flow state of an expression, as determined by Roslyn. + * 0 = none (default, not populated) + * 1 = not null + * 2 = maybe null + */ +expr_flowstate(unique int id: @expr ref, int state: int ref); + +/** GENERICS **/ + +@generic = @type | @method | @local_function; + +type_parameters( + unique int id: @type_parameter ref, + int index: int ref, + int generic_id: @generic ref, + int variance: int ref /* none = 0, out = 1, in = 2 */); + +#keyset[constructed_id, index] +type_arguments( + int id: @type_or_ref ref, + int index: int ref, + int constructed_id: @generic_or_ref ref); + +@generic_or_ref = @generic | @typeref; + +constructed_generic( + unique int constructed: @generic ref, + int generic: @generic_or_ref ref); + +type_parameter_constraints( + unique int id: @type_parameter_constraints, + int param_id: @type_parameter ref); + +type_parameter_constraints_location( + int id: @type_parameter_constraints ref, + int loc: @location ref); + +general_type_parameter_constraints( + int id: @type_parameter_constraints ref, + int kind: int ref /* class = 1, struct = 2, new = 3 */); + +specific_type_parameter_constraints( + int id: @type_parameter_constraints ref, + int base_id: @type_or_ref ref); + +specific_type_parameter_nullability( + int id: @type_parameter_constraints ref, + int base_id: @type_or_ref ref, + int nullability: @nullability ref); + +/** MODIFIERS */ + +@modifiable = @modifiable_direct | @event_accessor; + +@modifiable_direct = @member | @accessor | @local_function | @anonymous_function_expr; + +modifiers( + unique int id: @modifier, + string name: string ref); + +has_modifiers( + int id: @modifiable_direct ref, + int mod_id: @modifier ref); + +compiler_generated(unique int id: @modifiable_direct ref); + +/** MEMBERS **/ + +@member = @method | @constructor | @destructor | @field | @property | @event | @operator | @indexer | @type; + +@named_exprorstmt = @goto_stmt | @labeled_stmt | @expr; + +@virtualizable = @method | @property | @indexer | @event; + +exprorstmt_name( + unique int parent_id: @named_exprorstmt ref, + string name: string ref); + +nested_types( + unique int id: @type ref, + int declaring_type_id: @type ref, + int unbound_id: @type ref); + +properties( + unique int id: @property, + string name: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @property ref); + +property_location( + int id: @property ref, + int loc: @location ref); + +indexers( + unique int id: @indexer, + string name: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @indexer ref); + +indexer_location( + int id: @indexer ref, + int loc: @location ref); + +accessors( + unique int id: @accessor, + int kind: int ref, + string name: string ref, + int declaring_member_id: @member ref, + int unbound_id: @accessor ref); + +case @accessor.kind of + 1 = @getter +| 2 = @setter + ; + +init_only_accessors( + unique int id: @accessor ref); + +accessor_location( + int id: @accessor ref, + int loc: @location ref); + +events( + unique int id: @event, + string name: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @event ref); + +event_location( + int id: @event ref, + int loc: @location ref); + +event_accessors( + unique int id: @event_accessor, + int kind: int ref, + string name: string ref, + int declaring_event_id: @event ref, + int unbound_id: @event_accessor ref); + +case @event_accessor.kind of + 1 = @add_event_accessor +| 2 = @remove_event_accessor + ; + +event_accessor_location( + int id: @event_accessor ref, + int loc: @location ref); + +operators( + unique int id: @operator, + string name: string ref, + string symbol: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @operator ref); + +operator_location( + int id: @operator ref, + int loc: @location ref); + +constant_value( + int id: @variable ref, + string value: string ref); + +/** CALLABLES **/ + +@callable = @method | @constructor | @destructor | @operator | @callable_accessor | @anonymous_function_expr | @local_function; + +@callable_accessor = @accessor | @event_accessor; + +methods( + unique int id: @method, + string name: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @method ref); + +method_location( + int id: @method ref, + int loc: @location ref); + +constructors( + unique int id: @constructor, + string name: string ref, + int declaring_type_id: @type ref, + int unbound_id: @constructor ref); + +constructor_location( + int id: @constructor ref, + int loc: @location ref); + +destructors( + unique int id: @destructor, + string name: string ref, + int declaring_type_id: @type ref, + int unbound_id: @destructor ref); + +destructor_location( + int id: @destructor ref, + int loc: @location ref); + +overrides( + int id: @callable ref, + int base_id: @callable ref); + +explicitly_implements( + int id: @member ref, + int interface_id: @interface_or_ref ref); + +local_functions( + unique int id: @local_function, + string name: string ref, + int return_type: @type ref, + int unbound_id: @local_function ref); + +local_function_stmts( + unique int fn: @local_function_stmt ref, + int stmt: @local_function ref); + +/** VARIABLES **/ + +@variable = @local_scope_variable | @field; + +@local_scope_variable = @local_variable | @parameter; + +fields( + unique int id: @field, + int kind: int ref, + string name: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @field ref); + +case @field.kind of + 1 = @addressable_field +| 2 = @constant + ; + +field_location( + int id: @field ref, + int loc: @location ref); + +localvars( + unique int id: @local_variable, + int kind: int ref, + string name: string ref, + int implicitly_typed: int ref /* 0 = no, 1 = yes */, + int type_id: @type_or_ref ref, + int parent_id: @local_var_decl_expr ref); + +case @local_variable.kind of + 1 = @addressable_local_variable +| 2 = @local_constant +| 3 = @local_variable_ref + ; + +localvar_location( + unique int id: @local_variable ref, + int loc: @location ref); + +@parameterizable = @callable | @delegate_type | @indexer; + +#keyset[name, parent_id] +#keyset[index, parent_id] +params( + unique int id: @parameter, + string name: string ref, + int type_id: @type_or_ref ref, + int index: int ref, + int mode: int ref, /* value = 0, ref = 1, out = 2, array = 3, this = 4 */ + int parent_id: @parameterizable ref, + int unbound_id: @parameter ref); + +param_location( + int id: @parameter ref, + int loc: @location ref); + +/** STATEMENTS **/ + +@exprorstmt_parent = @control_flow_element | @top_level_exprorstmt_parent; + +statements( + unique int id: @stmt, + int kind: int ref); + +#keyset[index, parent] +stmt_parent( + unique int stmt: @stmt ref, + int index: int ref, + int parent: @control_flow_element ref); + +@top_level_stmt_parent = @callable; + +// [index, parent] is not a keyset because the same parent may be compiled multiple times +stmt_parent_top_level( + unique int stmt: @stmt ref, + int index: int ref, + int parent: @top_level_stmt_parent ref); + +case @stmt.kind of + 1 = @block_stmt +| 2 = @expr_stmt +| 3 = @if_stmt +| 4 = @switch_stmt +| 5 = @while_stmt +| 6 = @do_stmt +| 7 = @for_stmt +| 8 = @foreach_stmt +| 9 = @break_stmt +| 10 = @continue_stmt +| 11 = @goto_stmt +| 12 = @goto_case_stmt +| 13 = @goto_default_stmt +| 14 = @throw_stmt +| 15 = @return_stmt +| 16 = @yield_stmt +| 17 = @try_stmt +| 18 = @checked_stmt +| 19 = @unchecked_stmt +| 20 = @lock_stmt +| 21 = @using_block_stmt +| 22 = @var_decl_stmt +| 23 = @const_decl_stmt +| 24 = @empty_stmt +| 25 = @unsafe_stmt +| 26 = @fixed_stmt +| 27 = @label_stmt +| 28 = @catch +| 29 = @case_stmt +| 30 = @local_function_stmt +| 31 = @using_decl_stmt + ; + +@using_stmt = @using_block_stmt | @using_decl_stmt; + +@labeled_stmt = @label_stmt | @case; + +@decl_stmt = @var_decl_stmt | @const_decl_stmt | @using_decl_stmt; + +@cond_stmt = @if_stmt | @switch_stmt; + +@loop_stmt = @while_stmt | @do_stmt | @for_stmt | @foreach_stmt; + +@jump_stmt = @break_stmt | @goto_any_stmt | @continue_stmt | @throw_stmt | @return_stmt + | @yield_stmt; + +@goto_any_stmt = @goto_default_stmt | @goto_case_stmt | @goto_stmt; + + +stmt_location( + unique int id: @stmt ref, + int loc: @location ref); + +catch_type( + unique int catch_id: @catch ref, + int type_id: @type_or_ref ref, + int kind: int ref /* explicit = 1, implicit = 2 */); + +/** EXPRESSIONS **/ + +expressions( + unique int id: @expr, + int kind: int ref, + int type_id: @type_or_ref ref); + +#keyset[index, parent] +expr_parent( + unique int expr: @expr ref, + int index: int ref, + int parent: @control_flow_element ref); + +@top_level_expr_parent = @attribute | @field | @property | @indexer | @parameter; + +@top_level_exprorstmt_parent = @top_level_expr_parent | @top_level_stmt_parent; + +// [index, parent] is not a keyset because the same parent may be compiled multiple times +expr_parent_top_level( + unique int expr: @expr ref, + int index: int ref, + int parent: @top_level_exprorstmt_parent ref); + +case @expr.kind of +/* literal */ + 1 = @bool_literal_expr +| 2 = @char_literal_expr +| 3 = @decimal_literal_expr +| 4 = @int_literal_expr +| 5 = @long_literal_expr +| 6 = @uint_literal_expr +| 7 = @ulong_literal_expr +| 8 = @float_literal_expr +| 9 = @double_literal_expr +| 10 = @string_literal_expr +| 11 = @null_literal_expr +/* primary & unary */ +| 12 = @this_access_expr +| 13 = @base_access_expr +| 14 = @local_variable_access_expr +| 15 = @parameter_access_expr +| 16 = @field_access_expr +| 17 = @property_access_expr +| 18 = @method_access_expr +| 19 = @event_access_expr +| 20 = @indexer_access_expr +| 21 = @array_access_expr +| 22 = @type_access_expr +| 23 = @typeof_expr +| 24 = @method_invocation_expr +| 25 = @delegate_invocation_expr +| 26 = @operator_invocation_expr +| 27 = @cast_expr +| 28 = @object_creation_expr +| 29 = @explicit_delegate_creation_expr +| 30 = @implicit_delegate_creation_expr +| 31 = @array_creation_expr +| 32 = @default_expr +| 33 = @plus_expr +| 34 = @minus_expr +| 35 = @bit_not_expr +| 36 = @log_not_expr +| 37 = @post_incr_expr +| 38 = @post_decr_expr +| 39 = @pre_incr_expr +| 40 = @pre_decr_expr +/* multiplicative */ +| 41 = @mul_expr +| 42 = @div_expr +| 43 = @rem_expr +/* additive */ +| 44 = @add_expr +| 45 = @sub_expr +/* shift */ +| 46 = @lshift_expr +| 47 = @rshift_expr +/* relational */ +| 48 = @lt_expr +| 49 = @gt_expr +| 50 = @le_expr +| 51 = @ge_expr +/* equality */ +| 52 = @eq_expr +| 53 = @ne_expr +/* logical */ +| 54 = @bit_and_expr +| 55 = @bit_xor_expr +| 56 = @bit_or_expr +| 57 = @log_and_expr +| 58 = @log_or_expr +/* type testing */ +| 59 = @is_expr +| 60 = @as_expr +/* null coalescing */ +| 61 = @null_coalescing_expr +/* conditional */ +| 62 = @conditional_expr +/* assignment */ +| 63 = @simple_assign_expr +| 64 = @assign_add_expr +| 65 = @assign_sub_expr +| 66 = @assign_mul_expr +| 67 = @assign_div_expr +| 68 = @assign_rem_expr +| 69 = @assign_and_expr +| 70 = @assign_xor_expr +| 71 = @assign_or_expr +| 72 = @assign_lshift_expr +| 73 = @assign_rshift_expr +/* more */ +| 74 = @object_init_expr +| 75 = @collection_init_expr +| 76 = @array_init_expr +| 77 = @checked_expr +| 78 = @unchecked_expr +| 79 = @constructor_init_expr +| 80 = @add_event_expr +| 81 = @remove_event_expr +| 82 = @par_expr +| 83 = @local_var_decl_expr +| 84 = @lambda_expr +| 85 = @anonymous_method_expr +| 86 = @namespace_expr +/* dynamic */ +| 92 = @dynamic_element_access_expr +| 93 = @dynamic_member_access_expr +/* unsafe */ +| 100 = @pointer_indirection_expr +| 101 = @address_of_expr +| 102 = @sizeof_expr +/* async */ +| 103 = @await_expr +/* C# 6.0 */ +| 104 = @nameof_expr +| 105 = @interpolated_string_expr +| 106 = @unknown_expr +/* C# 7.0 */ +| 107 = @throw_expr +| 108 = @tuple_expr +| 109 = @local_function_invocation_expr +| 110 = @ref_expr +| 111 = @discard_expr +/* C# 8.0 */ +| 112 = @range_expr +| 113 = @index_expr +| 114 = @switch_expr +| 115 = @recursive_pattern_expr +| 116 = @property_pattern_expr +| 117 = @positional_pattern_expr +| 118 = @switch_case_expr +| 119 = @assign_coalesce_expr +| 120 = @suppress_nullable_warning_expr +| 121 = @namespace_access_expr +/* C# 9.0 */ +| 122 = @lt_pattern_expr +| 123 = @gt_pattern_expr +| 124 = @le_pattern_expr +| 125 = @ge_pattern_expr +| 126 = @not_pattern_expr +; + +@switch = @switch_stmt | @switch_expr; +@case = @case_stmt | @switch_case_expr; +@pattern_match = @case | @is_expr; +@unary_pattern_expr = @not_pattern_expr; +@relational_pattern_expr = @gt_pattern_expr | @lt_pattern_expr | @ge_pattern_expr | @le_pattern_expr; + +@integer_literal_expr = @int_literal_expr | @long_literal_expr | @uint_literal_expr | @ulong_literal_expr; +@real_literal_expr = @float_literal_expr | @double_literal_expr | @decimal_literal_expr; +@literal_expr = @bool_literal_expr | @char_literal_expr | @integer_literal_expr | @real_literal_expr + | @string_literal_expr | @null_literal_expr; + +@assign_expr = @simple_assign_expr | @assign_op_expr | @local_var_decl_expr; +@assign_op_expr = @assign_arith_expr | @assign_bitwise_expr | @assign_event_expr | @assign_coalesce_expr; +@assign_event_expr = @add_event_expr | @remove_event_expr; + +@assign_arith_expr = @assign_add_expr | @assign_sub_expr | @assign_mul_expr | @assign_div_expr + | @assign_rem_expr +@assign_bitwise_expr = @assign_and_expr | @assign_or_expr | @assign_xor_expr + | @assign_lshift_expr | @assign_rshift_expr; + +@member_access_expr = @field_access_expr | @property_access_expr | @indexer_access_expr | @event_access_expr + | @method_access_expr | @type_access_expr | @dynamic_member_access_expr; +@access_expr = @member_access_expr | @this_access_expr | @base_access_expr | @assignable_access_expr | @namespace_access_expr; +@element_access_expr = @indexer_access_expr | @array_access_expr | @dynamic_element_access_expr; + +@local_variable_access = @local_variable_access_expr | @local_var_decl_expr; +@local_scope_variable_access_expr = @parameter_access_expr | @local_variable_access; +@variable_access_expr = @local_scope_variable_access_expr | @field_access_expr; + +@assignable_access_expr = @variable_access_expr | @property_access_expr | @element_access_expr + | @event_access_expr | @dynamic_member_access_expr; + +@objectorcollection_init_expr = @object_init_expr | @collection_init_expr; + +@delegate_creation_expr = @explicit_delegate_creation_expr | @implicit_delegate_creation_expr; + +@bin_arith_op_expr = @mul_expr | @div_expr | @rem_expr | @add_expr | @sub_expr; +@incr_op_expr = @pre_incr_expr | @post_incr_expr; +@decr_op_expr = @pre_decr_expr | @post_decr_expr; +@mut_op_expr = @incr_op_expr | @decr_op_expr; +@un_arith_op_expr = @plus_expr | @minus_expr | @mut_op_expr; +@arith_op_expr = @bin_arith_op_expr | @un_arith_op_expr; + +@ternary_log_op_expr = @conditional_expr; +@bin_log_op_expr = @log_and_expr | @log_or_expr | @null_coalescing_expr; +@un_log_op_expr = @log_not_expr; +@log_expr = @un_log_op_expr | @bin_log_op_expr | @ternary_log_op_expr; + +@bin_bit_op_expr = @bit_and_expr | @bit_or_expr | @bit_xor_expr | @lshift_expr + | @rshift_expr; +@un_bit_op_expr = @bit_not_expr; +@bit_expr = @un_bit_op_expr | @bin_bit_op_expr; + +@equality_op_expr = @eq_expr | @ne_expr; +@rel_op_expr = @gt_expr | @lt_expr| @ge_expr | @le_expr; +@comp_expr = @equality_op_expr | @rel_op_expr; + +@op_expr = @assign_expr | @un_op | @bin_op | @ternary_op; + +@ternary_op = @ternary_log_op_expr; +@bin_op = @bin_arith_op_expr | @bin_log_op_expr | @bin_bit_op_expr | @comp_expr; +@un_op = @un_arith_op_expr | @un_log_op_expr | @un_bit_op_expr | @sizeof_expr + | @pointer_indirection_expr | @address_of_expr; + +@anonymous_function_expr = @lambda_expr | @anonymous_method_expr; + +@call = @method_invocation_expr | @constructor_init_expr | @operator_invocation_expr + | @delegate_invocation_expr | @object_creation_expr | @call_access_expr + | @local_function_invocation_expr; + +@call_access_expr = @property_access_expr | @event_access_expr | @indexer_access_expr; + +@late_bindable_expr = @dynamic_element_access_expr | @dynamic_member_access_expr + | @object_creation_expr | @method_invocation_expr | @operator_invocation_expr; + +@throw_element = @throw_expr | @throw_stmt; + +@implicitly_typeable_object_creation_expr = @object_creation_expr | @explicit_delegate_creation_expr; + +implicitly_typed_array_creation( + unique int id: @array_creation_expr ref); + +explicitly_sized_array_creation( + unique int id: @array_creation_expr ref); + +stackalloc_array_creation( + unique int id: @array_creation_expr ref); + +implicitly_typed_object_creation( + unique int id: @implicitly_typeable_object_creation_expr ref); + +mutator_invocation_mode( + unique int id: @operator_invocation_expr ref, + int mode: int ref /* prefix = 1, postfix = 2*/); + +expr_compiler_generated( + unique int id: @expr ref); + +expr_value( + unique int id: @expr ref, + string value: string ref); + +expr_call( + unique int caller_id: @expr ref, + int target_id: @callable ref); + +expr_access( + unique int accesser_id: @access_expr ref, + int target_id: @accessible ref); + +@accessible = @method | @assignable | @local_function | @namespace; + +expr_location( + unique int id: @expr ref, + int loc: @location ref); + +dynamic_member_name( + unique int id: @late_bindable_expr ref, + string name: string ref); + +@qualifiable_expr = @member_access_expr + | @method_invocation_expr + | @element_access_expr; + +conditional_access( + unique int id: @qualifiable_expr ref); + +expr_argument( + unique int id: @expr ref, + int mode: int ref); + /* mode is the same as params: value = 0, ref = 1, out = 2 */ + +expr_argument_name( + unique int id: @expr ref, + string name: string ref); + +/** CONTROL/DATA FLOW **/ + +@control_flow_element = @stmt | @expr; + +/* XML Files */ + +xmlEncoding ( + unique int id: @file ref, + string encoding: string ref); + +xmlDTDs( + unique int id: @xmldtd, + string root: string ref, + string publicId: string ref, + string systemId: string ref, + int fileid: @file ref); + +xmlElements( + unique int id: @xmlelement, + string name: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int fileid: @file ref); + +xmlAttrs( + unique int id: @xmlattribute, + int elementid: @xmlelement ref, + string name: string ref, + string value: string ref, + int idx: int ref, + int fileid: @file ref); + +xmlNs( + int id: @xmlnamespace, + string prefixName: string ref, + string URI: string ref, + int fileid: @file ref); + +xmlHasNs( + int elementId: @xmlnamespaceable ref, + int nsId: @xmlnamespace ref, + int fileid: @file ref); + +xmlComments( + unique int id: @xmlcomment, + string text: string ref, + int parentid: @xmlparent ref, + int fileid: @file ref); + +xmlChars( + unique int id: @xmlcharacters, + string text: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int isCDATA: int ref, + int fileid: @file ref); + +@xmlparent = @file | @xmlelement; +@xmlnamespaceable = @xmlelement | @xmlattribute; + +xmllocations( + int xmlElement: @xmllocatable ref, + int location: @location_default ref); + +@xmllocatable = @xmlcharacters | @xmlelement | @xmlcomment | @xmlattribute | @xmldtd | @file | @xmlnamespace; + +/* Comments */ + +commentline( + unique int id: @commentline, + int kind: int ref, + string text: string ref, + string rawtext: string ref); + +case @commentline.kind of + 0 = @singlelinecomment +| 1 = @xmldoccomment +| 2 = @multilinecomment; + +commentline_location( + unique int id: @commentline ref, + int loc: @location ref); + +commentblock( + unique int id : @commentblock); + +commentblock_location( + unique int id: @commentblock ref, + int loc: @location ref); + +commentblock_binding( + int id: @commentblock ref, + int entity: @element ref, + int bindtype: int ref); /* 0: Parent, 1: Best, 2: Before, 3: After */ + +commentblock_child( + int id: @commentblock ref, + int commentline: @commentline ref, + int index: int ref); + +/* ASP.NET */ + +case @asp_element.kind of + 0=@asp_close_tag +| 1=@asp_code +| 2=@asp_comment +| 3=@asp_data_binding +| 4=@asp_directive +| 5=@asp_open_tag +| 6=@asp_quoted_string +| 7=@asp_text +| 8=@asp_xml_directive; + +@asp_attribute = @asp_code | @asp_data_binding | @asp_quoted_string; + +asp_elements( + unique int id: @asp_element, + int kind: int ref, + int loc: @location ref); + +asp_comment_server(unique int comment: @asp_comment ref); +asp_code_inline(unique int code: @asp_code ref); +asp_directive_attribute( + int directive: @asp_directive ref, + int index: int ref, + string name: string ref, + int value: @asp_quoted_string ref); +asp_directive_name( + unique int directive: @asp_directive ref, + string name: string ref); +asp_element_body( + unique int element: @asp_element ref, + string body: string ref); +asp_tag_attribute( + int tag: @asp_open_tag ref, + int index: int ref, + string name: string ref, + int attribute: @asp_attribute ref); +asp_tag_name( + unique int tag: @asp_open_tag ref, + string name: string ref); +asp_tag_isempty(int tag: @asp_open_tag ref); + +/* Common Intermediate Language - CIL */ + +case @cil_instruction.opcode of + 0 = @cil_nop +| 1 = @cil_break +| 2 = @cil_ldarg_0 +| 3 = @cil_ldarg_1 +| 4 = @cil_ldarg_2 +| 5 = @cil_ldarg_3 +| 6 = @cil_ldloc_0 +| 7 = @cil_ldloc_1 +| 8 = @cil_ldloc_2 +| 9 = @cil_ldloc_3 +| 10 = @cil_stloc_0 +| 11 = @cil_stloc_1 +| 12 = @cil_stloc_2 +| 13 = @cil_stloc_3 +| 14 = @cil_ldarg_s +| 15 = @cil_ldarga_s +| 16 = @cil_starg_s +| 17 = @cil_ldloc_s +| 18 = @cil_ldloca_s +| 19 = @cil_stloc_s +| 20 = @cil_ldnull +| 21 = @cil_ldc_i4_m1 +| 22 = @cil_ldc_i4_0 +| 23 = @cil_ldc_i4_1 +| 24 = @cil_ldc_i4_2 +| 25 = @cil_ldc_i4_3 +| 26 = @cil_ldc_i4_4 +| 27 = @cil_ldc_i4_5 +| 28 = @cil_ldc_i4_6 +| 29 = @cil_ldc_i4_7 +| 30 = @cil_ldc_i4_8 +| 31 = @cil_ldc_i4_s +| 32 = @cil_ldc_i4 +| 33 = @cil_ldc_i8 +| 34 = @cil_ldc_r4 +| 35 = @cil_ldc_r8 +| 37 = @cil_dup +| 38 = @cil_pop +| 39 = @cil_jmp +| 40 = @cil_call +| 41 = @cil_calli +| 42 = @cil_ret +| 43 = @cil_br_s +| 44 = @cil_brfalse_s +| 45 = @cil_brtrue_s +| 46 = @cil_beq_s +| 47 = @cil_bge_s +| 48 = @cil_bgt_s +| 49 = @cil_ble_s +| 50 = @cil_blt_s +| 51 = @cil_bne_un_s +| 52 = @cil_bge_un_s +| 53 = @cil_bgt_un_s +| 54 = @cil_ble_un_s +| 55 = @cil_blt_un_s +| 56 = @cil_br +| 57 = @cil_brfalse +| 58 = @cil_brtrue +| 59 = @cil_beq +| 60 = @cil_bge +| 61 = @cil_bgt +| 62 = @cil_ble +| 63 = @cil_blt +| 64 = @cil_bne_un +| 65 = @cil_bge_un +| 66 = @cil_bgt_un +| 67 = @cil_ble_un +| 68 = @cil_blt_un +| 69 = @cil_switch +| 70 = @cil_ldind_i1 +| 71 = @cil_ldind_u1 +| 72 = @cil_ldind_i2 +| 73 = @cil_ldind_u2 +| 74 = @cil_ldind_i4 +| 75 = @cil_ldind_u4 +| 76 = @cil_ldind_i8 +| 77 = @cil_ldind_i +| 78 = @cil_ldind_r4 +| 79 = @cil_ldind_r8 +| 80 = @cil_ldind_ref +| 81 = @cil_stind_ref +| 82 = @cil_stind_i1 +| 83 = @cil_stind_i2 +| 84 = @cil_stind_i4 +| 85 = @cil_stind_i8 +| 86 = @cil_stind_r4 +| 87 = @cil_stind_r8 +| 88 = @cil_add +| 89 = @cil_sub +| 90 = @cil_mul +| 91 = @cil_div +| 92 = @cil_div_un +| 93 = @cil_rem +| 94 = @cil_rem_un +| 95 = @cil_and +| 96 = @cil_or +| 97 = @cil_xor +| 98 = @cil_shl +| 99 = @cil_shr +| 100 = @cil_shr_un +| 101 = @cil_neg +| 102 = @cil_not +| 103 = @cil_conv_i1 +| 104 = @cil_conv_i2 +| 105 = @cil_conv_i4 +| 106 = @cil_conv_i8 +| 107 = @cil_conv_r4 +| 108 = @cil_conv_r8 +| 109 = @cil_conv_u4 +| 110 = @cil_conv_u8 +| 111 = @cil_callvirt +| 112 = @cil_cpobj +| 113 = @cil_ldobj +| 114 = @cil_ldstr +| 115 = @cil_newobj +| 116 = @cil_castclass +| 117 = @cil_isinst +| 118 = @cil_conv_r_un +| 121 = @cil_unbox +| 122 = @cil_throw +| 123 = @cil_ldfld +| 124 = @cil_ldflda +| 125 = @cil_stfld +| 126 = @cil_ldsfld +| 127 = @cil_ldsflda +| 128 = @cil_stsfld +| 129 = @cil_stobj +| 130 = @cil_conv_ovf_i1_un +| 131 = @cil_conv_ovf_i2_un +| 132 = @cil_conv_ovf_i4_un +| 133 = @cil_conv_ovf_i8_un +| 134 = @cil_conv_ovf_u1_un +| 135 = @cil_conv_ovf_u2_un +| 136 = @cil_conv_ovf_u4_un +| 137 = @cil_conv_ovf_u8_un +| 138 = @cil_conv_ovf_i_un +| 139 = @cil_conv_ovf_u_un +| 140 = @cil_box +| 141 = @cil_newarr +| 142 = @cil_ldlen +| 143 = @cil_ldelema +| 144 = @cil_ldelem_i1 +| 145 = @cil_ldelem_u1 +| 146 = @cil_ldelem_i2 +| 147 = @cil_ldelem_u2 +| 148 = @cil_ldelem_i4 +| 149 = @cil_ldelem_u4 +| 150 = @cil_ldelem_i8 +| 151 = @cil_ldelem_i +| 152 = @cil_ldelem_r4 +| 153 = @cil_ldelem_r8 +| 154 = @cil_ldelem_ref +| 155 = @cil_stelem_i +| 156 = @cil_stelem_i1 +| 157 = @cil_stelem_i2 +| 158 = @cil_stelem_i4 +| 159 = @cil_stelem_i8 +| 160 = @cil_stelem_r4 +| 161 = @cil_stelem_r8 +| 162 = @cil_stelem_ref +| 163 = @cil_ldelem +| 164 = @cil_stelem +| 165 = @cil_unbox_any +| 179 = @cil_conv_ovf_i1 +| 180 = @cil_conv_ovf_u1 +| 181 = @cil_conv_ovf_i2 +| 182 = @cil_conv_ovf_u2 +| 183 = @cil_conv_ovf_i4 +| 184 = @cil_conv_ovf_u4 +| 185 = @cil_conv_ovf_i8 +| 186 = @cil_conv_ovf_u8 +| 194 = @cil_refanyval +| 195 = @cil_ckinfinite +| 198 = @cil_mkrefany +| 208 = @cil_ldtoken +| 209 = @cil_conv_u2 +| 210 = @cil_conv_u1 +| 211 = @cil_conv_i +| 212 = @cil_conv_ovf_i +| 213 = @cil_conv_ovf_u +| 214 = @cil_add_ovf +| 215 = @cil_add_ovf_un +| 216 = @cil_mul_ovf +| 217 = @cil_mul_ovf_un +| 218 = @cil_sub_ovf +| 219 = @cil_sub_ovf_un +| 220 = @cil_endfinally +| 221 = @cil_leave +| 222 = @cil_leave_s +| 223 = @cil_stind_i +| 224 = @cil_conv_u +| 65024 = @cil_arglist +| 65025 = @cil_ceq +| 65026 = @cil_cgt +| 65027 = @cil_cgt_un +| 65028 = @cil_clt +| 65029 = @cil_clt_un +| 65030 = @cil_ldftn +| 65031 = @cil_ldvirtftn +| 65033 = @cil_ldarg +| 65034 = @cil_ldarga +| 65035 = @cil_starg +| 65036 = @cil_ldloc +| 65037 = @cil_ldloca +| 65038 = @cil_stloc +| 65039 = @cil_localloc +| 65041 = @cil_endfilter +| 65042 = @cil_unaligned +| 65043 = @cil_volatile +| 65044 = @cil_tail +| 65045 = @cil_initobj +| 65046 = @cil_constrained +| 65047 = @cil_cpblk +| 65048 = @cil_initblk +| 65050 = @cil_rethrow +| 65052 = @cil_sizeof +| 65053 = @cil_refanytype +| 65054 = @cil_readonly +; + +// CIL ignored instructions + +@cil_ignore = @cil_nop | @cil_break | @cil_volatile | @cil_unaligned; + +// CIL local/parameter/field access + +@cil_ldarg_any = @cil_ldarg_0 | @cil_ldarg_1 | @cil_ldarg_2 | @cil_ldarg_3 | @cil_ldarg_s | @cil_ldarga_s | @cil_ldarg | @cil_ldarga; +@cil_starg_any = @cil_starg | @cil_starg_s; + +@cil_ldloc_any = @cil_ldloc_0 | @cil_ldloc_1 | @cil_ldloc_2 | @cil_ldloc_3 | @cil_ldloc_s | @cil_ldloca_s | @cil_ldloc | @cil_ldloca; +@cil_stloc_any = @cil_stloc_0 | @cil_stloc_1 | @cil_stloc_2 | @cil_stloc_3 | @cil_stloc_s | @cil_stloc; + +@cil_ldfld_any = @cil_ldfld | @cil_ldsfld | @cil_ldsflda | @cil_ldflda; +@cil_stfld_any = @cil_stfld | @cil_stsfld; + +@cil_local_access = @cil_stloc_any | @cil_ldloc_any; +@cil_arg_access = @cil_starg_any | @cil_ldarg_any; +@cil_read_access = @cil_ldloc_any | @cil_ldarg_any | @cil_ldfld_any; +@cil_write_access = @cil_stloc_any | @cil_starg_any | @cil_stfld_any; + +@cil_stack_access = @cil_local_access | @cil_arg_access; +@cil_field_access = @cil_ldfld_any | @cil_stfld_any; + +@cil_access = @cil_read_access | @cil_write_access; + +// CIL constant/literal instructions + +@cil_ldc_i = @cil_ldc_i4_any | @cil_ldc_i8; + +@cil_ldc_i4_any = @cil_ldc_i4_m1 | @cil_ldc_i4_0 | @cil_ldc_i4_1 | @cil_ldc_i4_2 | @cil_ldc_i4_3 | + @cil_ldc_i4_4 | @cil_ldc_i4_5 | @cil_ldc_i4_6 | @cil_ldc_i4_7 | @cil_ldc_i4_8 | @cil_ldc_i4_s | @cil_ldc_i4; + +@cil_ldc_r = @cil_ldc_r4 | @cil_ldc_r8; + +@cil_literal = @cil_ldnull | @cil_ldc_i | @cil_ldc_r | @cil_ldstr; + +// Control flow + +@cil_conditional_jump = @cil_binary_jump | @cil_unary_jump; +@cil_binary_jump = @cil_beq_s | @cil_bge_s | @cil_bgt_s | @cil_ble_s | @cil_blt_s | + @cil_bne_un_s | @cil_bge_un_s | @cil_bgt_un_s | @cil_ble_un_s | @cil_blt_un_s | + @cil_beq | @cil_bge | @cil_bgt | @cil_ble | @cil_blt | + @cil_bne_un | @cil_bge_un | @cil_bgt_un | @cil_ble_un | @cil_blt_un; +@cil_unary_jump = @cil_brfalse_s | @cil_brtrue_s | @cil_brfalse | @cil_brtrue | @cil_switch; +@cil_unconditional_jump = @cil_br | @cil_br_s | @cil_leave_any; +@cil_leave_any = @cil_leave | @cil_leave_s; +@cil_jump = @cil_unconditional_jump | @cil_conditional_jump; + +// CIL call instructions + +@cil_call_any = @cil_jmp | @cil_call | @cil_calli | @cil_tail | @cil_callvirt | @cil_newobj; + +// CIL expression instructions + +@cil_expr = @cil_literal | @cil_binary_expr | @cil_unary_expr | @cil_call_any | @cil_read_access | + @cil_newarr | @cil_ldtoken | @cil_sizeof | + @cil_ldftn | @cil_ldvirtftn | @cil_localloc | @cil_mkrefany | @cil_refanytype | @cil_arglist | @cil_dup; + +@cil_unary_expr = + @cil_conversion_operation | @cil_unary_arithmetic_operation | @cil_unary_bitwise_operation| + @cil_ldlen | @cil_isinst | @cil_box | @cil_ldobj | @cil_castclass | @cil_unbox_any | + @cil_ldind | @cil_unbox; + +@cil_conversion_operation = + @cil_conv_i1 | @cil_conv_i2 | @cil_conv_i4 | @cil_conv_i8 | + @cil_conv_u1 | @cil_conv_u2 | @cil_conv_u4 | @cil_conv_u8 | + @cil_conv_ovf_i | @cil_conv_ovf_i_un | @cil_conv_ovf_i1 | @cil_conv_ovf_i1_un | + @cil_conv_ovf_i2 | @cil_conv_ovf_i2_un | @cil_conv_ovf_i4 | @cil_conv_ovf_i4_un | + @cil_conv_ovf_i8 | @cil_conv_ovf_i8_un | @cil_conv_ovf_u | @cil_conv_ovf_u_un | + @cil_conv_ovf_u1 | @cil_conv_ovf_u1_un | @cil_conv_ovf_u2 | @cil_conv_ovf_u2_un | + @cil_conv_ovf_u4 | @cil_conv_ovf_u4_un | @cil_conv_ovf_u8 | @cil_conv_ovf_u8_un | + @cil_conv_r4 | @cil_conv_r8 | @cil_conv_ovf_u2 | @cil_conv_ovf_u2_un | + @cil_conv_i | @cil_conv_u | @cil_conv_r_un; + +@cil_ldind = @cil_ldind_i | @cil_ldind_i1 | @cil_ldind_i2 | @cil_ldind_i4 | @cil_ldind_i8 | + @cil_ldind_r4 | @cil_ldind_r8 | @cil_ldind_ref | @cil_ldind_u1 | @cil_ldind_u2 | @cil_ldind_u4; + +@cil_stind = @cil_stind_i | @cil_stind_i1 | @cil_stind_i2 | @cil_stind_i4 | @cil_stind_i8 | + @cil_stind_r4 | @cil_stind_r8 | @cil_stind_ref; + +@cil_bitwise_operation = @cil_binary_bitwise_operation | @cil_unary_bitwise_operation; + +@cil_binary_bitwise_operation = @cil_and | @cil_or | @cil_xor | @cil_shr | @cil_shr | @cil_shr_un | @cil_shl; + +@cil_binary_arithmetic_operation = @cil_add | @cil_sub | @cil_mul | @cil_div | @cil_div_un | + @cil_rem | @cil_rem_un | @cil_add_ovf | @cil_add_ovf_un | @cil_mul_ovf | @cil_mul_ovf_un | + @cil_sub_ovf | @cil_sub_ovf_un; + +@cil_unary_bitwise_operation = @cil_not; + +@cil_binary_expr = @cil_binary_arithmetic_operation | @cil_binary_bitwise_operation | @cil_read_array | @cil_comparison_operation; + +@cil_unary_arithmetic_operation = @cil_neg; + +@cil_comparison_operation = @cil_cgt_un | @cil_ceq | @cil_cgt | @cil_clt | @cil_clt_un; + +// Elements that retrieve an address of something +@cil_read_ref = @cil_ldloca_s | @cil_ldarga_s | @cil_ldflda | @cil_ldsflda | @cil_ldelema; + +// CIL array instructions + +@cil_read_array = + @cil_ldelem | @cil_ldelema | @cil_ldelem_i1 | @cil_ldelem_ref | @cil_ldelem_i | + @cil_ldelem_i1 | @cil_ldelem_i2 | @cil_ldelem_i4 | @cil_ldelem_i8 | @cil_ldelem_r4 | + @cil_ldelem_r8 | @cil_ldelem_u1 | @cil_ldelem_u2 | @cil_ldelem_u4; + +@cil_write_array = @cil_stelem | @cil_stelem_ref | + @cil_stelem_i | @cil_stelem_i1 | @cil_stelem_i2 | @cil_stelem_i4 | @cil_stelem_i8 | + @cil_stelem_r4 | @cil_stelem_r8; + +@cil_throw_any = @cil_throw | @cil_rethrow; + +#keyset[impl, index] +cil_instruction( + unique int id: @cil_instruction, + int opcode: int ref, + int index: int ref, + int impl: @cil_method_implementation ref); + +cil_jump( + unique int instruction: @cil_jump ref, + int target: @cil_instruction ref); + +cil_access( + unique int instruction: @cil_instruction ref, + int target: @cil_accessible ref); + +cil_value( + unique int instruction: @cil_literal ref, + string value: string ref); + +#keyset[instruction, index] +cil_switch( + int instruction: @cil_switch ref, + int index: int ref, + int target: @cil_instruction ref); + +cil_instruction_location( + unique int id: @cil_instruction ref, + int loc: @location ref); + +cil_type_location( + int id: @cil_type ref, + int loc: @location ref); + +cil_method_location( + int id: @cil_method ref, + int loc: @location ref); + +@cil_namespace = @namespace; + +@cil_type_container = @cil_type | @cil_namespace | @cil_method; + +case @cil_type.kind of + 0 = @cil_valueorreftype +| 1 = @cil_typeparameter +| 2 = @cil_array_type +| 3 = @cil_pointer_type +; + +cil_type( + unique int id: @cil_type, + string name: string ref, + int kind: int ref, + int parent: @cil_type_container ref, + int sourceDecl: @cil_type ref); + +cil_pointer_type( + unique int id: @cil_pointer_type ref, + int pointee: @cil_type ref); + +cil_array_type( + unique int id: @cil_array_type ref, + int element_type: @cil_type ref, + int rank: int ref); + +cil_method( + unique int id: @cil_method, + string name: string ref, + int parent: @cil_type ref, + int return_type: @cil_type ref); + +cil_method_source_declaration( + unique int method: @cil_method ref, + int source: @cil_method ref); + +cil_method_implementation( + unique int id: @cil_method_implementation, + int method: @cil_method ref, + int location: @assembly ref); + +cil_implements( + int id: @cil_method ref, + int decl: @cil_method ref); + +#keyset[parent, name] +cil_field( + unique int id: @cil_field, + int parent: @cil_type ref, + string name: string ref, + int field_type: @cil_type ref); + +@cil_element = @cil_instruction | @cil_declaration | @cil_handler | @cil_attribute | @cil_namespace; +@cil_named_element = @cil_declaration | @cil_namespace; +@cil_declaration = @cil_variable | @cil_method | @cil_type | @cil_member; +@cil_accessible = @cil_declaration; +@cil_variable = @cil_field | @cil_stack_variable; +@cil_stack_variable = @cil_local_variable | @cil_parameter; +@cil_member = @cil_method | @cil_type | @cil_field | @cil_property | @cil_event; +@cil_custom_modifier_receiver = @cil_method | @cil_property | @cil_parameter | @cil_field; // todo: add function pointer type + +#keyset[method, index] +cil_parameter( + unique int id: @cil_parameter, + int method: @cil_method ref, + int index: int ref, + int param_type: @cil_type ref); + +cil_parameter_in(unique int id: @cil_parameter ref); +cil_parameter_out(unique int id: @cil_parameter ref); + +cil_setter(unique int prop: @cil_property ref, + int method: @cil_method ref); + +#keyset[id, modifier] +cil_custom_modifiers( + int id: @cil_custom_modifier_receiver ref, + int modifier: @cil_type ref, + int kind: int ref); // modreq: 1, modopt: 0 + +cil_getter(unique int prop: @cil_property ref, + int method: @cil_method ref); + +cil_adder(unique int event: @cil_event ref, + int method: @cil_method ref); + +cil_remover(unique int event: @cil_event ref, int method: @cil_method ref); + +cil_raiser(unique int event: @cil_event ref, int method: @cil_method ref); + +cil_property( + unique int id: @cil_property, + int parent: @cil_type ref, + string name: string ref, + int property_type: @cil_type ref); + +#keyset[parent, name] +cil_event(unique int id: @cil_event, + int parent: @cil_type ref, + string name: string ref, + int event_type: @cil_type ref); + +#keyset[impl, index] +cil_local_variable( + unique int id: @cil_local_variable, + int impl: @cil_method_implementation ref, + int index: int ref, + int var_type: @cil_type ref); + +// CIL handlers (exception handlers etc). + +case @cil_handler.kind of + 0 = @cil_catch_handler +| 1 = @cil_filter_handler +| 2 = @cil_finally_handler +| 4 = @cil_fault_handler +; + +#keyset[impl, index] +cil_handler( + unique int id: @cil_handler, + int impl: @cil_method_implementation ref, + int index: int ref, + int kind: int ref, + int try_start: @cil_instruction ref, + int try_end: @cil_instruction ref, + int handler_start: @cil_instruction ref); + +cil_handler_filter( + unique int id: @cil_handler ref, + int filter_start: @cil_instruction ref); + +cil_handler_type( + unique int id: @cil_handler ref, + int catch_type: @cil_type ref); + +@cil_controlflow_node = @cil_entry_point | @cil_instruction; + +@cil_entry_point = @cil_method_implementation | @cil_handler; + +@cil_dataflow_node = @cil_instruction | @cil_variable | @cil_method; + +cil_method_stack_size( + unique int method: @cil_method_implementation ref, + int size: int ref); + +// CIL modifiers + +cil_public(int id: @cil_member ref); +cil_private(int id: @cil_member ref); +cil_protected(int id: @cil_member ref); +cil_internal(int id: @cil_member ref); +cil_static(int id: @cil_member ref); +cil_sealed(int id: @cil_member ref); +cil_virtual(int id: @cil_method ref); +cil_abstract(int id: @cil_member ref); +cil_class(int id: @cil_type ref); +cil_interface(int id: @cil_type ref); +cil_security(int id: @cil_member ref); +cil_requiresecobject(int id: @cil_method ref); +cil_specialname(int id: @cil_method ref); +cil_newslot(int id: @cil_method ref); + +cil_base_class(unique int id: @cil_type ref, int base: @cil_type ref); +cil_base_interface(int id: @cil_type ref, int base: @cil_type ref); +cil_enum_underlying_type(unique int id: @cil_type ref, int underlying: @cil_type ref); + +#keyset[unbound, index] +cil_type_parameter( + int unbound: @cil_member ref, + int index: int ref, + int param: @cil_typeparameter ref); + +#keyset[bound, index] +cil_type_argument( + int bound: @cil_member ref, + int index: int ref, + int t: @cil_type ref); + +// CIL type parameter constraints + +cil_typeparam_covariant(int tp: @cil_typeparameter ref); +cil_typeparam_contravariant(int tp: @cil_typeparameter ref); +cil_typeparam_class(int tp: @cil_typeparameter ref); +cil_typeparam_struct(int tp: @cil_typeparameter ref); +cil_typeparam_new(int tp: @cil_typeparameter ref); +cil_typeparam_constraint(int tp: @cil_typeparameter ref, int supertype: @cil_type ref); + +// CIL attributes + +cil_attribute( + unique int attributeid: @cil_attribute, + int element: @cil_declaration ref, + int constructor: @cil_method ref); + +#keyset[attribute_id, param] +cil_attribute_named_argument( + int attribute_id: @cil_attribute ref, + string param: string ref, + string value: string ref); + +#keyset[attribute_id, index] +cil_attribute_positional_argument( + int attribute_id: @cil_attribute ref, + int index: int ref, + string value: string ref); + + +// Common .Net data model covering both C# and CIL + +// Common elements +@dotnet_element = @element | @cil_element; +@dotnet_named_element = @named_element | @cil_named_element; +@dotnet_callable = @callable | @cil_method; +@dotnet_variable = @variable | @cil_variable; +@dotnet_field = @field | @cil_field; +@dotnet_parameter = @parameter | @cil_parameter; +@dotnet_declaration = @declaration | @cil_declaration; +@dotnet_member = @member | @cil_member; +@dotnet_event = @event | @cil_event; +@dotnet_property = @property | @cil_property | @indexer; + +// Common types +@dotnet_type = @type | @cil_type; +@dotnet_call = @call | @cil_call_any; +@dotnet_throw = @throw_element | @cil_throw_any; +@dotnet_valueorreftype = @cil_valueorreftype | @value_or_ref_type | @cil_array_type | @void_type; +@dotnet_typeparameter = @type_parameter | @cil_typeparameter; +@dotnet_array_type = @array_type | @cil_array_type; +@dotnet_pointer_type = @pointer_type | @cil_pointer_type; +@dotnet_type_parameter = @type_parameter | @cil_typeparameter; +@dotnet_generic = @dotnet_valueorreftype | @dotnet_callable; + +// Attributes +@dotnet_attribute = @attribute | @cil_attribute; + +// Expressions +@dotnet_expr = @expr | @cil_expr; + +// Literals +@dotnet_literal = @literal_expr | @cil_literal; +@dotnet_string_literal = @string_literal_expr | @cil_ldstr; +@dotnet_int_literal = @integer_literal_expr | @cil_ldc_i; +@dotnet_float_literal = @float_literal_expr | @cil_ldc_r; +@dotnet_null_literal = @null_literal_expr | @cil_ldnull; + +@metadata_entity = @cil_method | @cil_type | @cil_field | @cil_property | @field | @property | + @callable | @value_or_ref_type | @void_type; + +#keyset[entity, location] +metadata_handle(int entity : @metadata_entity ref, int location: @assembly ref, int handle: int ref) diff --git a/csharp/upgrades/98e37f65f0ae39cfe1bff33908d6620ade5df0f7/semmlecode.csharp.dbscheme b/csharp/upgrades/98e37f65f0ae39cfe1bff33908d6620ade5df0f7/semmlecode.csharp.dbscheme new file mode 100644 index 00000000000..dd813977f70 --- /dev/null +++ b/csharp/upgrades/98e37f65f0ae39cfe1bff33908d6620ade5df0f7/semmlecode.csharp.dbscheme @@ -0,0 +1,1940 @@ + +/** + * An invocation of the compiler. Note that more than one file may be + * compiled per invocation. For example, this command compiles three + * source files: + * + * csc f1.cs f2.cs f3.cs + * + * The `id` simply identifies the invocation, while `cwd` is the working + * directory from which the compiler was invoked. + */ +compilations( + unique int id : @compilation, + string cwd : string ref +); + +/** + * The arguments that were passed to the extractor for a compiler + * invocation. If `id` is for the compiler invocation + * + * csc f1.cs f2.cs f3.cs + * + * then typically there will be rows for + * + * num | arg + * --- | --- + * 0 | --compiler + * 1 | *path to compiler* + * 2 | --cil + * 3 | f1.cs + * 4 | f2.cs + * 5 | f3.cs + */ +#keyset[id, num] +compilation_args( + int id : @compilation ref, + int num : int ref, + string arg : string ref +); + +/** + * The source files that are compiled by a compiler invocation. + * If `id` is for the compiler invocation + * + * csc f1.cs f2.cs f3.cs + * + * then there will be rows for + * + * num | arg + * --- | --- + * 0 | f1.cs + * 1 | f2.cs + * 2 | f3.cs + */ +#keyset[id, num] +compilation_compiling_files( + int id : @compilation ref, + int num : int ref, + int file : @file ref +); + +/** + * The references used by a compiler invocation. + * If `id` is for the compiler invocation + * + * csc f1.cs f2.cs f3.cs /r:ref1.dll /r:ref2.dll /r:ref3.dll + * + * then there will be rows for + * + * num | arg + * --- | --- + * 0 | ref1.dll + * 1 | ref2.dll + * 2 | ref3.dll + */ +#keyset[id, num] +compilation_referencing_files( + int id : @compilation ref, + int num : int ref, + int file : @file ref +); + +/** + * The time taken by the extractor for a compiler invocation. + * + * For each file `num`, there will be rows for + * + * kind | seconds + * ---- | --- + * 1 | CPU seconds used by the extractor frontend + * 2 | Elapsed seconds during the extractor frontend + * 3 | CPU seconds used by the extractor backend + * 4 | Elapsed seconds during the extractor backend + */ +#keyset[id, num, kind] +compilation_time( + int id : @compilation ref, + int num : int ref, + /* kind: + 1 = frontend_cpu_seconds + 2 = frontend_elapsed_seconds + 3 = extractor_cpu_seconds + 4 = extractor_elapsed_seconds + */ + int kind : int ref, + float seconds : float ref +); + +/** + * An error or warning generated by the extractor. + * The diagnostic message `diagnostic` was generated during compiler + * invocation `compilation`, and is the `file_number_diagnostic_number`th + * message generated while extracting the `file_number`th file of that + * invocation. + */ +#keyset[compilation, file_number, file_number_diagnostic_number] +diagnostic_for( + unique int diagnostic : @diagnostic ref, + int compilation : @compilation ref, + int file_number : int ref, + int file_number_diagnostic_number : int ref +); + +diagnostics( + unique int id: @diagnostic, + int severity: int ref, + string error_tag: string ref, + string error_message: string ref, + string full_error_message: string ref, + int location: @location_default ref +); + +extractor_messages( + unique int id: @extractor_message, + int severity: int ref, + string origin : string ref, + string text : string ref, + string entity : string ref, + int location: @location_default ref, + string stack_trace : string ref +); + +/** + * If extraction was successful, then `cpu_seconds` and + * `elapsed_seconds` are the CPU time and elapsed time (respectively) + * that extraction took for compiler invocation `id`. + */ +compilation_finished( + unique int id : @compilation ref, + float cpu_seconds : float ref, + float elapsed_seconds : float ref +); + +compilation_assembly( + unique int id : @compilation ref, + int assembly: @assembly ref +) + +/* + * External artifacts + */ + +externalDefects( + unique int id: @externalDefect, + string queryPath: string ref, + int location: @location ref, + string message: string ref, + float severity: float ref); + +externalMetrics( + unique int id: @externalMetric, + string queryPath: string ref, + int location: @location ref, + float value: float ref); + +externalData( + int id: @externalDataElement, + string path: string ref, + int column: int ref, + string value: string ref); + +snapshotDate( + unique date snapshotDate: date ref); + +sourceLocationPrefix( + string prefix: string ref); + +/* + * Duplicate code + */ + +duplicateCode( + unique int id: @duplication, + string relativePath: string ref, + int equivClass: int ref); + +similarCode( + unique int id: @similarity, + string relativePath: string ref, + int equivClass: int ref); + +@duplication_or_similarity = @duplication | @similarity + +tokens( + int id: @duplication_or_similarity ref, + int offset: int ref, + int beginLine: int ref, + int beginColumn: int ref, + int endLine: int ref, + int endColumn: int ref); + +/* + * C# dbscheme + */ + +/** ELEMENTS **/ + +@element = @declaration | @stmt | @expr | @modifier | @attribute | @namespace_declaration + | @using_directive | @type_parameter_constraints | @external_element + | @xmllocatable | @asp_element | @namespace; + +@declaration = @callable | @generic | @assignable | @namespace; + +@named_element = @namespace | @declaration; + +@declaration_with_accessors = @property | @indexer | @event; + +@assignable = @variable | @assignable_with_accessors | @event; + +@assignable_with_accessors = @property | @indexer; + +@external_element = @externalMetric | @externalDefect | @externalDataElement; + +@attributable = @assembly | @field | @parameter | @operator | @method | @constructor + | @destructor | @callable_accessor | @value_or_ref_type | @declaration_with_accessors + | @local_function; + +/** LOCATIONS, ASEMMBLIES, MODULES, FILES and FOLDERS **/ + +@location = @location_default | @assembly; + +locations_default( + unique int id: @location_default, + int file: @file ref, + int beginLine: int ref, + int beginColumn: int ref, + int endLine: int ref, + int endColumn: int ref); + +@sourceline = @file | @callable | @xmllocatable; + +numlines( + int element_id: @sourceline ref, + int num_lines: int ref, + int num_code: int ref, + int num_comment: int ref); + +assemblies( + unique int id: @assembly, + int file: @file ref, + string fullname: string ref, + string name: string ref, + string version: string ref); + +/* + fromSource(0) = unknown, + fromSource(1) = from source, + fromSource(2) = from library +*/ +files( + unique int id: @file, + string name: string ref, + string simple: string ref, + string ext: string ref, + int fromSource: int ref); + +folders( + unique int id: @folder, + string name: string ref, + string simple: string ref); + +@container = @folder | @file ; + +containerparent( + int parent: @container ref, + unique int child: @container ref); + +file_extraction_mode( + unique int file: @file ref, + int mode: int ref + /* 0 = normal, 1 = standalone extractor */ + ); + +/** NAMESPACES **/ + +@type_container = @namespace | @type; + +namespaces( + unique int id: @namespace, + string name: string ref); + +namespace_declarations( + unique int id: @namespace_declaration, + int namespace_id: @namespace ref); + +namespace_declaration_location( + unique int id: @namespace_declaration ref, + int loc: @location ref); + +parent_namespace( + unique int child_id: @type_container ref, + int namespace_id: @namespace ref); + +@declaration_or_directive = @namespace_declaration | @type | @using_directive; + +parent_namespace_declaration( + int child_id: @declaration_or_directive ref, // cannot be unique because of partial classes + int namespace_id: @namespace_declaration ref); + +@using_directive = @using_namespace_directive | @using_static_directive; + +using_namespace_directives( + unique int id: @using_namespace_directive, + int namespace_id: @namespace ref); + +using_static_directives( + unique int id: @using_static_directive, + int type_id: @type_or_ref ref); + +using_directive_location( + unique int id: @using_directive ref, + int loc: @location ref); + +/** TYPES **/ + +types( + unique int id: @type, + int kind: int ref, + string name: string ref); + +case @type.kind of + 1 = @bool_type +| 2 = @char_type +| 3 = @decimal_type +| 4 = @sbyte_type +| 5 = @short_type +| 6 = @int_type +| 7 = @long_type +| 8 = @byte_type +| 9 = @ushort_type +| 10 = @uint_type +| 11 = @ulong_type +| 12 = @float_type +| 13 = @double_type +| 14 = @enum_type +| 15 = @struct_type +| 17 = @class_type +| 19 = @interface_type +| 20 = @delegate_type +| 21 = @null_type +| 22 = @type_parameter +| 23 = @pointer_type +| 24 = @nullable_type +| 25 = @array_type +| 26 = @void_type +| 27 = @int_ptr_type +| 28 = @uint_ptr_type +| 29 = @dynamic_type +| 30 = @arglist_type +| 31 = @unknown_type +| 32 = @tuple_type +| 33 = @function_pointer_type + ; + +@simple_type = @bool_type | @char_type | @integral_type | @floating_point_type | @decimal_type; +@integral_type = @signed_integral_type | @unsigned_integral_type; +@signed_integral_type = @sbyte_type | @short_type | @int_type | @long_type; +@unsigned_integral_type = @byte_type | @ushort_type | @uint_type | @ulong_type; +@floating_point_type = @float_type | @double_type; +@value_type = @simple_type | @enum_type | @struct_type | @nullable_type | @int_ptr_type + | @uint_ptr_type | @tuple_type; +@ref_type = @class_type | @interface_type | @array_type | @delegate_type | @null_type + | @dynamic_type; +@value_or_ref_type = @value_type | @ref_type; + +typerefs( + unique int id: @typeref, + string name: string ref); + +typeref_type( + int id: @typeref ref, + unique int typeId: @type ref); + +@type_or_ref = @type | @typeref; + +array_element_type( + unique int array: @array_type ref, + int dimension: int ref, + int rank: int ref, + int element: @type_or_ref ref); + +nullable_underlying_type( + unique int nullable: @nullable_type ref, + int underlying: @type_or_ref ref); + +pointer_referent_type( + unique int pointer: @pointer_type ref, + int referent: @type_or_ref ref); + +enum_underlying_type( + unique int enum_id: @enum_type ref, + int underlying_type_id: @type_or_ref ref); + +delegate_return_type( + unique int delegate_id: @delegate_type ref, + int return_type_id: @type_or_ref ref); + +function_pointer_return_type( + unique int function_pointer_id: @function_pointer_type ref, + int return_type_id: @type_or_ref ref); + +extend( + unique int sub: @type ref, + int super: @type_or_ref ref); + +anonymous_types( + unique int id: @type ref); + +@interface_or_ref = @interface_type | @typeref; + +implement( + int sub: @type ref, + int super: @type_or_ref ref); + +type_location( + int id: @type ref, + int loc: @location ref); + +tuple_underlying_type( + unique int tuple: @tuple_type ref, + int struct: @type_or_ref ref); + +#keyset[tuple, index] +tuple_element( + int tuple: @tuple_type ref, + int index: int ref, + unique int field: @field ref); + +attributes( + unique int id: @attribute, + int type_id: @type_or_ref ref, + int target: @attributable ref); + +attribute_location( + int id: @attribute ref, + int loc: @location ref); + +@type_mention_parent = @element | @type_mention; + +type_mention( + unique int id: @type_mention, + int type_id: @type_or_ref ref, + int parent: @type_mention_parent ref); + +type_mention_location( + unique int id: @type_mention ref, + int loc: @location ref); + +@has_type_annotation = @assignable | @type_parameter | @callable | @expr | @delegate_type | @generic | @function_pointer_type; + +/** + * A direct annotation on an entity, for example `string? x;`. + * + * Annotations: + * 2 = reftype is not annotated "!" + * 3 = reftype is annotated "?" + * 4 = readonly ref type / in parameter + * 5 = ref type parameter, return or local variable + * 6 = out parameter + * + * Note that the annotation depends on the element it annotates. + * @assignable: The annotation is on the type of the assignable, for example the variable type. + * @type_parameter: The annotation is on the reftype constraint + * @callable: The annotation is on the return type + * @array_type: The annotation is on the element type + */ +type_annotation(int id: @has_type_annotation ref, int annotation: int ref); + +nullability(unique int nullability: @nullability, int kind: int ref); + +case @nullability.kind of + 0 = @oblivious +| 1 = @not_annotated +| 2 = @annotated +; + +#keyset[parent, index] +nullability_parent(int nullability: @nullability ref, int index: int ref, int parent: @nullability ref) + +type_nullability(int id: @has_type_annotation ref, int nullability: @nullability ref); + +/** + * The nullable flow state of an expression, as determined by Roslyn. + * 0 = none (default, not populated) + * 1 = not null + * 2 = maybe null + */ +expr_flowstate(unique int id: @expr ref, int state: int ref); + +/** GENERICS **/ + +@generic = @type | @method | @local_function; + +type_parameters( + unique int id: @type_parameter ref, + int index: int ref, + int generic_id: @generic ref, + int variance: int ref /* none = 0, out = 1, in = 2 */); + +#keyset[constructed_id, index] +type_arguments( + int id: @type_or_ref ref, + int index: int ref, + int constructed_id: @generic_or_ref ref); + +@generic_or_ref = @generic | @typeref; + +constructed_generic( + unique int constructed: @generic ref, + int generic: @generic_or_ref ref); + +type_parameter_constraints( + unique int id: @type_parameter_constraints, + int param_id: @type_parameter ref); + +type_parameter_constraints_location( + int id: @type_parameter_constraints ref, + int loc: @location ref); + +general_type_parameter_constraints( + int id: @type_parameter_constraints ref, + int kind: int ref /* class = 1, struct = 2, new = 3 */); + +specific_type_parameter_constraints( + int id: @type_parameter_constraints ref, + int base_id: @type_or_ref ref); + +specific_type_parameter_nullability( + int id: @type_parameter_constraints ref, + int base_id: @type_or_ref ref, + int nullability: @nullability ref); + +/** FUNCTION POINTERS */ + +function_pointer_calling_conventions( + int id: @function_pointer_type ref, + int kind: int ref); + +#keyset[id, index] +has_unmanaged_calling_conventions( + int id: @function_pointer_type ref, + int index: int ref, + int conv_id: @type_or_ref ref); + +/** MODIFIERS */ + +@modifiable = @modifiable_direct | @event_accessor; + +@modifiable_direct = @member | @accessor | @local_function | @anonymous_function_expr; + +modifiers( + unique int id: @modifier, + string name: string ref); + +has_modifiers( + int id: @modifiable_direct ref, + int mod_id: @modifier ref); + +compiler_generated(unique int id: @modifiable_direct ref); + +/** MEMBERS **/ + +@member = @method | @constructor | @destructor | @field | @property | @event | @operator | @indexer | @type; + +@named_exprorstmt = @goto_stmt | @labeled_stmt | @expr; + +@virtualizable = @method | @property | @indexer | @event; + +exprorstmt_name( + unique int parent_id: @named_exprorstmt ref, + string name: string ref); + +nested_types( + unique int id: @type ref, + int declaring_type_id: @type ref, + int unbound_id: @type ref); + +properties( + unique int id: @property, + string name: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @property ref); + +property_location( + int id: @property ref, + int loc: @location ref); + +indexers( + unique int id: @indexer, + string name: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @indexer ref); + +indexer_location( + int id: @indexer ref, + int loc: @location ref); + +accessors( + unique int id: @accessor, + int kind: int ref, + string name: string ref, + int declaring_member_id: @member ref, + int unbound_id: @accessor ref); + +case @accessor.kind of + 1 = @getter +| 2 = @setter + ; + +init_only_accessors( + unique int id: @accessor ref); + +accessor_location( + int id: @accessor ref, + int loc: @location ref); + +events( + unique int id: @event, + string name: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @event ref); + +event_location( + int id: @event ref, + int loc: @location ref); + +event_accessors( + unique int id: @event_accessor, + int kind: int ref, + string name: string ref, + int declaring_event_id: @event ref, + int unbound_id: @event_accessor ref); + +case @event_accessor.kind of + 1 = @add_event_accessor +| 2 = @remove_event_accessor + ; + +event_accessor_location( + int id: @event_accessor ref, + int loc: @location ref); + +operators( + unique int id: @operator, + string name: string ref, + string symbol: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @operator ref); + +operator_location( + int id: @operator ref, + int loc: @location ref); + +constant_value( + int id: @variable ref, + string value: string ref); + +/** CALLABLES **/ + +@callable = @method | @constructor | @destructor | @operator | @callable_accessor | @anonymous_function_expr | @local_function; + +@callable_accessor = @accessor | @event_accessor; + +methods( + unique int id: @method, + string name: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @method ref); + +method_location( + int id: @method ref, + int loc: @location ref); + +constructors( + unique int id: @constructor, + string name: string ref, + int declaring_type_id: @type ref, + int unbound_id: @constructor ref); + +constructor_location( + int id: @constructor ref, + int loc: @location ref); + +destructors( + unique int id: @destructor, + string name: string ref, + int declaring_type_id: @type ref, + int unbound_id: @destructor ref); + +destructor_location( + int id: @destructor ref, + int loc: @location ref); + +overrides( + int id: @callable ref, + int base_id: @callable ref); + +explicitly_implements( + int id: @member ref, + int interface_id: @interface_or_ref ref); + +local_functions( + unique int id: @local_function, + string name: string ref, + int return_type: @type ref, + int unbound_id: @local_function ref); + +local_function_stmts( + unique int fn: @local_function_stmt ref, + int stmt: @local_function ref); + +/** VARIABLES **/ + +@variable = @local_scope_variable | @field; + +@local_scope_variable = @local_variable | @parameter; + +fields( + unique int id: @field, + int kind: int ref, + string name: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @field ref); + +case @field.kind of + 1 = @addressable_field +| 2 = @constant + ; + +field_location( + int id: @field ref, + int loc: @location ref); + +localvars( + unique int id: @local_variable, + int kind: int ref, + string name: string ref, + int implicitly_typed: int ref /* 0 = no, 1 = yes */, + int type_id: @type_or_ref ref, + int parent_id: @local_var_decl_expr ref); + +case @local_variable.kind of + 1 = @addressable_local_variable +| 2 = @local_constant +| 3 = @local_variable_ref + ; + +localvar_location( + unique int id: @local_variable ref, + int loc: @location ref); + +@parameterizable = @callable | @delegate_type | @indexer | @function_pointer_type; + +#keyset[name, parent_id] +#keyset[index, parent_id] +params( + unique int id: @parameter, + string name: string ref, + int type_id: @type_or_ref ref, + int index: int ref, + int mode: int ref, /* value = 0, ref = 1, out = 2, array = 3, this = 4 */ + int parent_id: @parameterizable ref, + int unbound_id: @parameter ref); + +param_location( + int id: @parameter ref, + int loc: @location ref); + +/** STATEMENTS **/ + +@exprorstmt_parent = @control_flow_element | @top_level_exprorstmt_parent; + +statements( + unique int id: @stmt, + int kind: int ref); + +#keyset[index, parent] +stmt_parent( + unique int stmt: @stmt ref, + int index: int ref, + int parent: @control_flow_element ref); + +@top_level_stmt_parent = @callable; + +// [index, parent] is not a keyset because the same parent may be compiled multiple times +stmt_parent_top_level( + unique int stmt: @stmt ref, + int index: int ref, + int parent: @top_level_stmt_parent ref); + +case @stmt.kind of + 1 = @block_stmt +| 2 = @expr_stmt +| 3 = @if_stmt +| 4 = @switch_stmt +| 5 = @while_stmt +| 6 = @do_stmt +| 7 = @for_stmt +| 8 = @foreach_stmt +| 9 = @break_stmt +| 10 = @continue_stmt +| 11 = @goto_stmt +| 12 = @goto_case_stmt +| 13 = @goto_default_stmt +| 14 = @throw_stmt +| 15 = @return_stmt +| 16 = @yield_stmt +| 17 = @try_stmt +| 18 = @checked_stmt +| 19 = @unchecked_stmt +| 20 = @lock_stmt +| 21 = @using_block_stmt +| 22 = @var_decl_stmt +| 23 = @const_decl_stmt +| 24 = @empty_stmt +| 25 = @unsafe_stmt +| 26 = @fixed_stmt +| 27 = @label_stmt +| 28 = @catch +| 29 = @case_stmt +| 30 = @local_function_stmt +| 31 = @using_decl_stmt + ; + +@using_stmt = @using_block_stmt | @using_decl_stmt; + +@labeled_stmt = @label_stmt | @case; + +@decl_stmt = @var_decl_stmt | @const_decl_stmt | @using_decl_stmt; + +@cond_stmt = @if_stmt | @switch_stmt; + +@loop_stmt = @while_stmt | @do_stmt | @for_stmt | @foreach_stmt; + +@jump_stmt = @break_stmt | @goto_any_stmt | @continue_stmt | @throw_stmt | @return_stmt + | @yield_stmt; + +@goto_any_stmt = @goto_default_stmt | @goto_case_stmt | @goto_stmt; + + +stmt_location( + unique int id: @stmt ref, + int loc: @location ref); + +catch_type( + unique int catch_id: @catch ref, + int type_id: @type_or_ref ref, + int kind: int ref /* explicit = 1, implicit = 2 */); + +/** EXPRESSIONS **/ + +expressions( + unique int id: @expr, + int kind: int ref, + int type_id: @type_or_ref ref); + +#keyset[index, parent] +expr_parent( + unique int expr: @expr ref, + int index: int ref, + int parent: @control_flow_element ref); + +@top_level_expr_parent = @attribute | @field | @property | @indexer | @parameter; + +@top_level_exprorstmt_parent = @top_level_expr_parent | @top_level_stmt_parent; + +// [index, parent] is not a keyset because the same parent may be compiled multiple times +expr_parent_top_level( + unique int expr: @expr ref, + int index: int ref, + int parent: @top_level_exprorstmt_parent ref); + +case @expr.kind of +/* literal */ + 1 = @bool_literal_expr +| 2 = @char_literal_expr +| 3 = @decimal_literal_expr +| 4 = @int_literal_expr +| 5 = @long_literal_expr +| 6 = @uint_literal_expr +| 7 = @ulong_literal_expr +| 8 = @float_literal_expr +| 9 = @double_literal_expr +| 10 = @string_literal_expr +| 11 = @null_literal_expr +/* primary & unary */ +| 12 = @this_access_expr +| 13 = @base_access_expr +| 14 = @local_variable_access_expr +| 15 = @parameter_access_expr +| 16 = @field_access_expr +| 17 = @property_access_expr +| 18 = @method_access_expr +| 19 = @event_access_expr +| 20 = @indexer_access_expr +| 21 = @array_access_expr +| 22 = @type_access_expr +| 23 = @typeof_expr +| 24 = @method_invocation_expr +| 25 = @delegate_invocation_expr +| 26 = @operator_invocation_expr +| 27 = @cast_expr +| 28 = @object_creation_expr +| 29 = @explicit_delegate_creation_expr +| 30 = @implicit_delegate_creation_expr +| 31 = @array_creation_expr +| 32 = @default_expr +| 33 = @plus_expr +| 34 = @minus_expr +| 35 = @bit_not_expr +| 36 = @log_not_expr +| 37 = @post_incr_expr +| 38 = @post_decr_expr +| 39 = @pre_incr_expr +| 40 = @pre_decr_expr +/* multiplicative */ +| 41 = @mul_expr +| 42 = @div_expr +| 43 = @rem_expr +/* additive */ +| 44 = @add_expr +| 45 = @sub_expr +/* shift */ +| 46 = @lshift_expr +| 47 = @rshift_expr +/* relational */ +| 48 = @lt_expr +| 49 = @gt_expr +| 50 = @le_expr +| 51 = @ge_expr +/* equality */ +| 52 = @eq_expr +| 53 = @ne_expr +/* logical */ +| 54 = @bit_and_expr +| 55 = @bit_xor_expr +| 56 = @bit_or_expr +| 57 = @log_and_expr +| 58 = @log_or_expr +/* type testing */ +| 59 = @is_expr +| 60 = @as_expr +/* null coalescing */ +| 61 = @null_coalescing_expr +/* conditional */ +| 62 = @conditional_expr +/* assignment */ +| 63 = @simple_assign_expr +| 64 = @assign_add_expr +| 65 = @assign_sub_expr +| 66 = @assign_mul_expr +| 67 = @assign_div_expr +| 68 = @assign_rem_expr +| 69 = @assign_and_expr +| 70 = @assign_xor_expr +| 71 = @assign_or_expr +| 72 = @assign_lshift_expr +| 73 = @assign_rshift_expr +/* more */ +| 74 = @object_init_expr +| 75 = @collection_init_expr +| 76 = @array_init_expr +| 77 = @checked_expr +| 78 = @unchecked_expr +| 79 = @constructor_init_expr +| 80 = @add_event_expr +| 81 = @remove_event_expr +| 82 = @par_expr +| 83 = @local_var_decl_expr +| 84 = @lambda_expr +| 85 = @anonymous_method_expr +| 86 = @namespace_expr +/* dynamic */ +| 92 = @dynamic_element_access_expr +| 93 = @dynamic_member_access_expr +/* unsafe */ +| 100 = @pointer_indirection_expr +| 101 = @address_of_expr +| 102 = @sizeof_expr +/* async */ +| 103 = @await_expr +/* C# 6.0 */ +| 104 = @nameof_expr +| 105 = @interpolated_string_expr +| 106 = @unknown_expr +/* C# 7.0 */ +| 107 = @throw_expr +| 108 = @tuple_expr +| 109 = @local_function_invocation_expr +| 110 = @ref_expr +| 111 = @discard_expr +/* C# 8.0 */ +| 112 = @range_expr +| 113 = @index_expr +| 114 = @switch_expr +| 115 = @recursive_pattern_expr +| 116 = @property_pattern_expr +| 117 = @positional_pattern_expr +| 118 = @switch_case_expr +| 119 = @assign_coalesce_expr +| 120 = @suppress_nullable_warning_expr +| 121 = @namespace_access_expr +/* C# 9.0 */ +| 122 = @lt_pattern_expr +| 123 = @gt_pattern_expr +| 124 = @le_pattern_expr +| 125 = @ge_pattern_expr +| 126 = @not_pattern_expr +| 129 = @function_pointer_invocation_expr +; + +@switch = @switch_stmt | @switch_expr; +@case = @case_stmt | @switch_case_expr; +@pattern_match = @case | @is_expr; +@unary_pattern_expr = @not_pattern_expr; +@relational_pattern_expr = @gt_pattern_expr | @lt_pattern_expr | @ge_pattern_expr | @le_pattern_expr; + +@integer_literal_expr = @int_literal_expr | @long_literal_expr | @uint_literal_expr | @ulong_literal_expr; +@real_literal_expr = @float_literal_expr | @double_literal_expr | @decimal_literal_expr; +@literal_expr = @bool_literal_expr | @char_literal_expr | @integer_literal_expr | @real_literal_expr + | @string_literal_expr | @null_literal_expr; + +@assign_expr = @simple_assign_expr | @assign_op_expr | @local_var_decl_expr; +@assign_op_expr = @assign_arith_expr | @assign_bitwise_expr | @assign_event_expr | @assign_coalesce_expr; +@assign_event_expr = @add_event_expr | @remove_event_expr; + +@assign_arith_expr = @assign_add_expr | @assign_sub_expr | @assign_mul_expr | @assign_div_expr + | @assign_rem_expr +@assign_bitwise_expr = @assign_and_expr | @assign_or_expr | @assign_xor_expr + | @assign_lshift_expr | @assign_rshift_expr; + +@member_access_expr = @field_access_expr | @property_access_expr | @indexer_access_expr | @event_access_expr + | @method_access_expr | @type_access_expr | @dynamic_member_access_expr; +@access_expr = @member_access_expr | @this_access_expr | @base_access_expr | @assignable_access_expr | @namespace_access_expr; +@element_access_expr = @indexer_access_expr | @array_access_expr | @dynamic_element_access_expr; + +@local_variable_access = @local_variable_access_expr | @local_var_decl_expr; +@local_scope_variable_access_expr = @parameter_access_expr | @local_variable_access; +@variable_access_expr = @local_scope_variable_access_expr | @field_access_expr; + +@assignable_access_expr = @variable_access_expr | @property_access_expr | @element_access_expr + | @event_access_expr | @dynamic_member_access_expr; + +@objectorcollection_init_expr = @object_init_expr | @collection_init_expr; + +@delegate_creation_expr = @explicit_delegate_creation_expr | @implicit_delegate_creation_expr; + +@bin_arith_op_expr = @mul_expr | @div_expr | @rem_expr | @add_expr | @sub_expr; +@incr_op_expr = @pre_incr_expr | @post_incr_expr; +@decr_op_expr = @pre_decr_expr | @post_decr_expr; +@mut_op_expr = @incr_op_expr | @decr_op_expr; +@un_arith_op_expr = @plus_expr | @minus_expr | @mut_op_expr; +@arith_op_expr = @bin_arith_op_expr | @un_arith_op_expr; + +@ternary_log_op_expr = @conditional_expr; +@bin_log_op_expr = @log_and_expr | @log_or_expr | @null_coalescing_expr; +@un_log_op_expr = @log_not_expr; +@log_expr = @un_log_op_expr | @bin_log_op_expr | @ternary_log_op_expr; + +@bin_bit_op_expr = @bit_and_expr | @bit_or_expr | @bit_xor_expr | @lshift_expr + | @rshift_expr; +@un_bit_op_expr = @bit_not_expr; +@bit_expr = @un_bit_op_expr | @bin_bit_op_expr; + +@equality_op_expr = @eq_expr | @ne_expr; +@rel_op_expr = @gt_expr | @lt_expr| @ge_expr | @le_expr; +@comp_expr = @equality_op_expr | @rel_op_expr; + +@op_expr = @assign_expr | @un_op | @bin_op | @ternary_op; + +@ternary_op = @ternary_log_op_expr; +@bin_op = @bin_arith_op_expr | @bin_log_op_expr | @bin_bit_op_expr | @comp_expr; +@un_op = @un_arith_op_expr | @un_log_op_expr | @un_bit_op_expr | @sizeof_expr + | @pointer_indirection_expr | @address_of_expr; + +@anonymous_function_expr = @lambda_expr | @anonymous_method_expr; + +@call = @method_invocation_expr | @constructor_init_expr | @operator_invocation_expr + | @delegate_invocation_expr | @object_creation_expr | @call_access_expr + | @local_function_invocation_expr | @function_pointer_invocation_expr; + +@call_access_expr = @property_access_expr | @event_access_expr | @indexer_access_expr; + +@late_bindable_expr = @dynamic_element_access_expr | @dynamic_member_access_expr + | @object_creation_expr | @method_invocation_expr | @operator_invocation_expr; + +@throw_element = @throw_expr | @throw_stmt; + +@implicitly_typeable_object_creation_expr = @object_creation_expr | @explicit_delegate_creation_expr; + +implicitly_typed_array_creation( + unique int id: @array_creation_expr ref); + +explicitly_sized_array_creation( + unique int id: @array_creation_expr ref); + +stackalloc_array_creation( + unique int id: @array_creation_expr ref); + +implicitly_typed_object_creation( + unique int id: @implicitly_typeable_object_creation_expr ref); + +mutator_invocation_mode( + unique int id: @operator_invocation_expr ref, + int mode: int ref /* prefix = 1, postfix = 2*/); + +expr_compiler_generated( + unique int id: @expr ref); + +expr_value( + unique int id: @expr ref, + string value: string ref); + +expr_call( + unique int caller_id: @expr ref, + int target_id: @callable ref); + +expr_access( + unique int accesser_id: @access_expr ref, + int target_id: @accessible ref); + +@accessible = @method | @assignable | @local_function | @namespace; + +expr_location( + unique int id: @expr ref, + int loc: @location ref); + +dynamic_member_name( + unique int id: @late_bindable_expr ref, + string name: string ref); + +@qualifiable_expr = @member_access_expr + | @method_invocation_expr + | @element_access_expr; + +conditional_access( + unique int id: @qualifiable_expr ref); + +expr_argument( + unique int id: @expr ref, + int mode: int ref); + /* mode is the same as params: value = 0, ref = 1, out = 2 */ + +expr_argument_name( + unique int id: @expr ref, + string name: string ref); + +/** CONTROL/DATA FLOW **/ + +@control_flow_element = @stmt | @expr; + +/* XML Files */ + +xmlEncoding ( + unique int id: @file ref, + string encoding: string ref); + +xmlDTDs( + unique int id: @xmldtd, + string root: string ref, + string publicId: string ref, + string systemId: string ref, + int fileid: @file ref); + +xmlElements( + unique int id: @xmlelement, + string name: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int fileid: @file ref); + +xmlAttrs( + unique int id: @xmlattribute, + int elementid: @xmlelement ref, + string name: string ref, + string value: string ref, + int idx: int ref, + int fileid: @file ref); + +xmlNs( + int id: @xmlnamespace, + string prefixName: string ref, + string URI: string ref, + int fileid: @file ref); + +xmlHasNs( + int elementId: @xmlnamespaceable ref, + int nsId: @xmlnamespace ref, + int fileid: @file ref); + +xmlComments( + unique int id: @xmlcomment, + string text: string ref, + int parentid: @xmlparent ref, + int fileid: @file ref); + +xmlChars( + unique int id: @xmlcharacters, + string text: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int isCDATA: int ref, + int fileid: @file ref); + +@xmlparent = @file | @xmlelement; +@xmlnamespaceable = @xmlelement | @xmlattribute; + +xmllocations( + int xmlElement: @xmllocatable ref, + int location: @location_default ref); + +@xmllocatable = @xmlcharacters | @xmlelement | @xmlcomment | @xmlattribute | @xmldtd | @file | @xmlnamespace; + +/* Comments */ + +commentline( + unique int id: @commentline, + int kind: int ref, + string text: string ref, + string rawtext: string ref); + +case @commentline.kind of + 0 = @singlelinecomment +| 1 = @xmldoccomment +| 2 = @multilinecomment; + +commentline_location( + unique int id: @commentline ref, + int loc: @location ref); + +commentblock( + unique int id : @commentblock); + +commentblock_location( + unique int id: @commentblock ref, + int loc: @location ref); + +commentblock_binding( + int id: @commentblock ref, + int entity: @element ref, + int bindtype: int ref); /* 0: Parent, 1: Best, 2: Before, 3: After */ + +commentblock_child( + int id: @commentblock ref, + int commentline: @commentline ref, + int index: int ref); + +/* ASP.NET */ + +case @asp_element.kind of + 0=@asp_close_tag +| 1=@asp_code +| 2=@asp_comment +| 3=@asp_data_binding +| 4=@asp_directive +| 5=@asp_open_tag +| 6=@asp_quoted_string +| 7=@asp_text +| 8=@asp_xml_directive; + +@asp_attribute = @asp_code | @asp_data_binding | @asp_quoted_string; + +asp_elements( + unique int id: @asp_element, + int kind: int ref, + int loc: @location ref); + +asp_comment_server(unique int comment: @asp_comment ref); +asp_code_inline(unique int code: @asp_code ref); +asp_directive_attribute( + int directive: @asp_directive ref, + int index: int ref, + string name: string ref, + int value: @asp_quoted_string ref); +asp_directive_name( + unique int directive: @asp_directive ref, + string name: string ref); +asp_element_body( + unique int element: @asp_element ref, + string body: string ref); +asp_tag_attribute( + int tag: @asp_open_tag ref, + int index: int ref, + string name: string ref, + int attribute: @asp_attribute ref); +asp_tag_name( + unique int tag: @asp_open_tag ref, + string name: string ref); +asp_tag_isempty(int tag: @asp_open_tag ref); + +/* Common Intermediate Language - CIL */ + +case @cil_instruction.opcode of + 0 = @cil_nop +| 1 = @cil_break +| 2 = @cil_ldarg_0 +| 3 = @cil_ldarg_1 +| 4 = @cil_ldarg_2 +| 5 = @cil_ldarg_3 +| 6 = @cil_ldloc_0 +| 7 = @cil_ldloc_1 +| 8 = @cil_ldloc_2 +| 9 = @cil_ldloc_3 +| 10 = @cil_stloc_0 +| 11 = @cil_stloc_1 +| 12 = @cil_stloc_2 +| 13 = @cil_stloc_3 +| 14 = @cil_ldarg_s +| 15 = @cil_ldarga_s +| 16 = @cil_starg_s +| 17 = @cil_ldloc_s +| 18 = @cil_ldloca_s +| 19 = @cil_stloc_s +| 20 = @cil_ldnull +| 21 = @cil_ldc_i4_m1 +| 22 = @cil_ldc_i4_0 +| 23 = @cil_ldc_i4_1 +| 24 = @cil_ldc_i4_2 +| 25 = @cil_ldc_i4_3 +| 26 = @cil_ldc_i4_4 +| 27 = @cil_ldc_i4_5 +| 28 = @cil_ldc_i4_6 +| 29 = @cil_ldc_i4_7 +| 30 = @cil_ldc_i4_8 +| 31 = @cil_ldc_i4_s +| 32 = @cil_ldc_i4 +| 33 = @cil_ldc_i8 +| 34 = @cil_ldc_r4 +| 35 = @cil_ldc_r8 +| 37 = @cil_dup +| 38 = @cil_pop +| 39 = @cil_jmp +| 40 = @cil_call +| 41 = @cil_calli +| 42 = @cil_ret +| 43 = @cil_br_s +| 44 = @cil_brfalse_s +| 45 = @cil_brtrue_s +| 46 = @cil_beq_s +| 47 = @cil_bge_s +| 48 = @cil_bgt_s +| 49 = @cil_ble_s +| 50 = @cil_blt_s +| 51 = @cil_bne_un_s +| 52 = @cil_bge_un_s +| 53 = @cil_bgt_un_s +| 54 = @cil_ble_un_s +| 55 = @cil_blt_un_s +| 56 = @cil_br +| 57 = @cil_brfalse +| 58 = @cil_brtrue +| 59 = @cil_beq +| 60 = @cil_bge +| 61 = @cil_bgt +| 62 = @cil_ble +| 63 = @cil_blt +| 64 = @cil_bne_un +| 65 = @cil_bge_un +| 66 = @cil_bgt_un +| 67 = @cil_ble_un +| 68 = @cil_blt_un +| 69 = @cil_switch +| 70 = @cil_ldind_i1 +| 71 = @cil_ldind_u1 +| 72 = @cil_ldind_i2 +| 73 = @cil_ldind_u2 +| 74 = @cil_ldind_i4 +| 75 = @cil_ldind_u4 +| 76 = @cil_ldind_i8 +| 77 = @cil_ldind_i +| 78 = @cil_ldind_r4 +| 79 = @cil_ldind_r8 +| 80 = @cil_ldind_ref +| 81 = @cil_stind_ref +| 82 = @cil_stind_i1 +| 83 = @cil_stind_i2 +| 84 = @cil_stind_i4 +| 85 = @cil_stind_i8 +| 86 = @cil_stind_r4 +| 87 = @cil_stind_r8 +| 88 = @cil_add +| 89 = @cil_sub +| 90 = @cil_mul +| 91 = @cil_div +| 92 = @cil_div_un +| 93 = @cil_rem +| 94 = @cil_rem_un +| 95 = @cil_and +| 96 = @cil_or +| 97 = @cil_xor +| 98 = @cil_shl +| 99 = @cil_shr +| 100 = @cil_shr_un +| 101 = @cil_neg +| 102 = @cil_not +| 103 = @cil_conv_i1 +| 104 = @cil_conv_i2 +| 105 = @cil_conv_i4 +| 106 = @cil_conv_i8 +| 107 = @cil_conv_r4 +| 108 = @cil_conv_r8 +| 109 = @cil_conv_u4 +| 110 = @cil_conv_u8 +| 111 = @cil_callvirt +| 112 = @cil_cpobj +| 113 = @cil_ldobj +| 114 = @cil_ldstr +| 115 = @cil_newobj +| 116 = @cil_castclass +| 117 = @cil_isinst +| 118 = @cil_conv_r_un +| 121 = @cil_unbox +| 122 = @cil_throw +| 123 = @cil_ldfld +| 124 = @cil_ldflda +| 125 = @cil_stfld +| 126 = @cil_ldsfld +| 127 = @cil_ldsflda +| 128 = @cil_stsfld +| 129 = @cil_stobj +| 130 = @cil_conv_ovf_i1_un +| 131 = @cil_conv_ovf_i2_un +| 132 = @cil_conv_ovf_i4_un +| 133 = @cil_conv_ovf_i8_un +| 134 = @cil_conv_ovf_u1_un +| 135 = @cil_conv_ovf_u2_un +| 136 = @cil_conv_ovf_u4_un +| 137 = @cil_conv_ovf_u8_un +| 138 = @cil_conv_ovf_i_un +| 139 = @cil_conv_ovf_u_un +| 140 = @cil_box +| 141 = @cil_newarr +| 142 = @cil_ldlen +| 143 = @cil_ldelema +| 144 = @cil_ldelem_i1 +| 145 = @cil_ldelem_u1 +| 146 = @cil_ldelem_i2 +| 147 = @cil_ldelem_u2 +| 148 = @cil_ldelem_i4 +| 149 = @cil_ldelem_u4 +| 150 = @cil_ldelem_i8 +| 151 = @cil_ldelem_i +| 152 = @cil_ldelem_r4 +| 153 = @cil_ldelem_r8 +| 154 = @cil_ldelem_ref +| 155 = @cil_stelem_i +| 156 = @cil_stelem_i1 +| 157 = @cil_stelem_i2 +| 158 = @cil_stelem_i4 +| 159 = @cil_stelem_i8 +| 160 = @cil_stelem_r4 +| 161 = @cil_stelem_r8 +| 162 = @cil_stelem_ref +| 163 = @cil_ldelem +| 164 = @cil_stelem +| 165 = @cil_unbox_any +| 179 = @cil_conv_ovf_i1 +| 180 = @cil_conv_ovf_u1 +| 181 = @cil_conv_ovf_i2 +| 182 = @cil_conv_ovf_u2 +| 183 = @cil_conv_ovf_i4 +| 184 = @cil_conv_ovf_u4 +| 185 = @cil_conv_ovf_i8 +| 186 = @cil_conv_ovf_u8 +| 194 = @cil_refanyval +| 195 = @cil_ckinfinite +| 198 = @cil_mkrefany +| 208 = @cil_ldtoken +| 209 = @cil_conv_u2 +| 210 = @cil_conv_u1 +| 211 = @cil_conv_i +| 212 = @cil_conv_ovf_i +| 213 = @cil_conv_ovf_u +| 214 = @cil_add_ovf +| 215 = @cil_add_ovf_un +| 216 = @cil_mul_ovf +| 217 = @cil_mul_ovf_un +| 218 = @cil_sub_ovf +| 219 = @cil_sub_ovf_un +| 220 = @cil_endfinally +| 221 = @cil_leave +| 222 = @cil_leave_s +| 223 = @cil_stind_i +| 224 = @cil_conv_u +| 65024 = @cil_arglist +| 65025 = @cil_ceq +| 65026 = @cil_cgt +| 65027 = @cil_cgt_un +| 65028 = @cil_clt +| 65029 = @cil_clt_un +| 65030 = @cil_ldftn +| 65031 = @cil_ldvirtftn +| 65033 = @cil_ldarg +| 65034 = @cil_ldarga +| 65035 = @cil_starg +| 65036 = @cil_ldloc +| 65037 = @cil_ldloca +| 65038 = @cil_stloc +| 65039 = @cil_localloc +| 65041 = @cil_endfilter +| 65042 = @cil_unaligned +| 65043 = @cil_volatile +| 65044 = @cil_tail +| 65045 = @cil_initobj +| 65046 = @cil_constrained +| 65047 = @cil_cpblk +| 65048 = @cil_initblk +| 65050 = @cil_rethrow +| 65052 = @cil_sizeof +| 65053 = @cil_refanytype +| 65054 = @cil_readonly +; + +// CIL ignored instructions + +@cil_ignore = @cil_nop | @cil_break | @cil_volatile | @cil_unaligned; + +// CIL local/parameter/field access + +@cil_ldarg_any = @cil_ldarg_0 | @cil_ldarg_1 | @cil_ldarg_2 | @cil_ldarg_3 | @cil_ldarg_s | @cil_ldarga_s | @cil_ldarg | @cil_ldarga; +@cil_starg_any = @cil_starg | @cil_starg_s; + +@cil_ldloc_any = @cil_ldloc_0 | @cil_ldloc_1 | @cil_ldloc_2 | @cil_ldloc_3 | @cil_ldloc_s | @cil_ldloca_s | @cil_ldloc | @cil_ldloca; +@cil_stloc_any = @cil_stloc_0 | @cil_stloc_1 | @cil_stloc_2 | @cil_stloc_3 | @cil_stloc_s | @cil_stloc; + +@cil_ldfld_any = @cil_ldfld | @cil_ldsfld | @cil_ldsflda | @cil_ldflda; +@cil_stfld_any = @cil_stfld | @cil_stsfld; + +@cil_local_access = @cil_stloc_any | @cil_ldloc_any; +@cil_arg_access = @cil_starg_any | @cil_ldarg_any; +@cil_read_access = @cil_ldloc_any | @cil_ldarg_any | @cil_ldfld_any; +@cil_write_access = @cil_stloc_any | @cil_starg_any | @cil_stfld_any; + +@cil_stack_access = @cil_local_access | @cil_arg_access; +@cil_field_access = @cil_ldfld_any | @cil_stfld_any; + +@cil_access = @cil_read_access | @cil_write_access; + +// CIL constant/literal instructions + +@cil_ldc_i = @cil_ldc_i4_any | @cil_ldc_i8; + +@cil_ldc_i4_any = @cil_ldc_i4_m1 | @cil_ldc_i4_0 | @cil_ldc_i4_1 | @cil_ldc_i4_2 | @cil_ldc_i4_3 | + @cil_ldc_i4_4 | @cil_ldc_i4_5 | @cil_ldc_i4_6 | @cil_ldc_i4_7 | @cil_ldc_i4_8 | @cil_ldc_i4_s | @cil_ldc_i4; + +@cil_ldc_r = @cil_ldc_r4 | @cil_ldc_r8; + +@cil_literal = @cil_ldnull | @cil_ldc_i | @cil_ldc_r | @cil_ldstr; + +// Control flow + +@cil_conditional_jump = @cil_binary_jump | @cil_unary_jump; +@cil_binary_jump = @cil_beq_s | @cil_bge_s | @cil_bgt_s | @cil_ble_s | @cil_blt_s | + @cil_bne_un_s | @cil_bge_un_s | @cil_bgt_un_s | @cil_ble_un_s | @cil_blt_un_s | + @cil_beq | @cil_bge | @cil_bgt | @cil_ble | @cil_blt | + @cil_bne_un | @cil_bge_un | @cil_bgt_un | @cil_ble_un | @cil_blt_un; +@cil_unary_jump = @cil_brfalse_s | @cil_brtrue_s | @cil_brfalse | @cil_brtrue | @cil_switch; +@cil_unconditional_jump = @cil_br | @cil_br_s | @cil_leave_any; +@cil_leave_any = @cil_leave | @cil_leave_s; +@cil_jump = @cil_unconditional_jump | @cil_conditional_jump; + +// CIL call instructions + +@cil_call_any = @cil_jmp | @cil_call | @cil_calli | @cil_tail | @cil_callvirt | @cil_newobj; + +// CIL expression instructions + +@cil_expr = @cil_literal | @cil_binary_expr | @cil_unary_expr | @cil_call_any | @cil_read_access | + @cil_newarr | @cil_ldtoken | @cil_sizeof | + @cil_ldftn | @cil_ldvirtftn | @cil_localloc | @cil_mkrefany | @cil_refanytype | @cil_arglist | @cil_dup; + +@cil_unary_expr = + @cil_conversion_operation | @cil_unary_arithmetic_operation | @cil_unary_bitwise_operation| + @cil_ldlen | @cil_isinst | @cil_box | @cil_ldobj | @cil_castclass | @cil_unbox_any | + @cil_ldind | @cil_unbox; + +@cil_conversion_operation = + @cil_conv_i1 | @cil_conv_i2 | @cil_conv_i4 | @cil_conv_i8 | + @cil_conv_u1 | @cil_conv_u2 | @cil_conv_u4 | @cil_conv_u8 | + @cil_conv_ovf_i | @cil_conv_ovf_i_un | @cil_conv_ovf_i1 | @cil_conv_ovf_i1_un | + @cil_conv_ovf_i2 | @cil_conv_ovf_i2_un | @cil_conv_ovf_i4 | @cil_conv_ovf_i4_un | + @cil_conv_ovf_i8 | @cil_conv_ovf_i8_un | @cil_conv_ovf_u | @cil_conv_ovf_u_un | + @cil_conv_ovf_u1 | @cil_conv_ovf_u1_un | @cil_conv_ovf_u2 | @cil_conv_ovf_u2_un | + @cil_conv_ovf_u4 | @cil_conv_ovf_u4_un | @cil_conv_ovf_u8 | @cil_conv_ovf_u8_un | + @cil_conv_r4 | @cil_conv_r8 | @cil_conv_ovf_u2 | @cil_conv_ovf_u2_un | + @cil_conv_i | @cil_conv_u | @cil_conv_r_un; + +@cil_ldind = @cil_ldind_i | @cil_ldind_i1 | @cil_ldind_i2 | @cil_ldind_i4 | @cil_ldind_i8 | + @cil_ldind_r4 | @cil_ldind_r8 | @cil_ldind_ref | @cil_ldind_u1 | @cil_ldind_u2 | @cil_ldind_u4; + +@cil_stind = @cil_stind_i | @cil_stind_i1 | @cil_stind_i2 | @cil_stind_i4 | @cil_stind_i8 | + @cil_stind_r4 | @cil_stind_r8 | @cil_stind_ref; + +@cil_bitwise_operation = @cil_binary_bitwise_operation | @cil_unary_bitwise_operation; + +@cil_binary_bitwise_operation = @cil_and | @cil_or | @cil_xor | @cil_shr | @cil_shr | @cil_shr_un | @cil_shl; + +@cil_binary_arithmetic_operation = @cil_add | @cil_sub | @cil_mul | @cil_div | @cil_div_un | + @cil_rem | @cil_rem_un | @cil_add_ovf | @cil_add_ovf_un | @cil_mul_ovf | @cil_mul_ovf_un | + @cil_sub_ovf | @cil_sub_ovf_un; + +@cil_unary_bitwise_operation = @cil_not; + +@cil_binary_expr = @cil_binary_arithmetic_operation | @cil_binary_bitwise_operation | @cil_read_array | @cil_comparison_operation; + +@cil_unary_arithmetic_operation = @cil_neg; + +@cil_comparison_operation = @cil_cgt_un | @cil_ceq | @cil_cgt | @cil_clt | @cil_clt_un; + +// Elements that retrieve an address of something +@cil_read_ref = @cil_ldloca_s | @cil_ldarga_s | @cil_ldflda | @cil_ldsflda | @cil_ldelema; + +// CIL array instructions + +@cil_read_array = + @cil_ldelem | @cil_ldelema | @cil_ldelem_i1 | @cil_ldelem_ref | @cil_ldelem_i | + @cil_ldelem_i1 | @cil_ldelem_i2 | @cil_ldelem_i4 | @cil_ldelem_i8 | @cil_ldelem_r4 | + @cil_ldelem_r8 | @cil_ldelem_u1 | @cil_ldelem_u2 | @cil_ldelem_u4; + +@cil_write_array = @cil_stelem | @cil_stelem_ref | + @cil_stelem_i | @cil_stelem_i1 | @cil_stelem_i2 | @cil_stelem_i4 | @cil_stelem_i8 | + @cil_stelem_r4 | @cil_stelem_r8; + +@cil_throw_any = @cil_throw | @cil_rethrow; + +#keyset[impl, index] +cil_instruction( + unique int id: @cil_instruction, + int opcode: int ref, + int index: int ref, + int impl: @cil_method_implementation ref); + +cil_jump( + unique int instruction: @cil_jump ref, + int target: @cil_instruction ref); + +cil_access( + unique int instruction: @cil_instruction ref, + int target: @cil_accessible ref); + +cil_value( + unique int instruction: @cil_literal ref, + string value: string ref); + +#keyset[instruction, index] +cil_switch( + int instruction: @cil_switch ref, + int index: int ref, + int target: @cil_instruction ref); + +cil_instruction_location( + unique int id: @cil_instruction ref, + int loc: @location ref); + +cil_type_location( + int id: @cil_type ref, + int loc: @location ref); + +cil_method_location( + int id: @cil_method ref, + int loc: @location ref); + +@cil_namespace = @namespace; + +@cil_type_container = @cil_type | @cil_namespace | @cil_method; + +case @cil_type.kind of + 0 = @cil_valueorreftype +| 1 = @cil_typeparameter +| 2 = @cil_array_type +| 3 = @cil_pointer_type +; + +cil_type( + unique int id: @cil_type, + string name: string ref, + int kind: int ref, + int parent: @cil_type_container ref, + int sourceDecl: @cil_type ref); + +cil_pointer_type( + unique int id: @cil_pointer_type ref, + int pointee: @cil_type ref); + +cil_array_type( + unique int id: @cil_array_type ref, + int element_type: @cil_type ref, + int rank: int ref); + +cil_method( + unique int id: @cil_method, + string name: string ref, + int parent: @cil_type ref, + int return_type: @cil_type ref); + +cil_method_source_declaration( + unique int method: @cil_method ref, + int source: @cil_method ref); + +cil_method_implementation( + unique int id: @cil_method_implementation, + int method: @cil_method ref, + int location: @assembly ref); + +cil_implements( + int id: @cil_method ref, + int decl: @cil_method ref); + +#keyset[parent, name] +cil_field( + unique int id: @cil_field, + int parent: @cil_type ref, + string name: string ref, + int field_type: @cil_type ref); + +@cil_element = @cil_instruction | @cil_declaration | @cil_handler | @cil_attribute | @cil_namespace; +@cil_named_element = @cil_declaration | @cil_namespace; +@cil_declaration = @cil_variable | @cil_method | @cil_type | @cil_member; +@cil_accessible = @cil_declaration; +@cil_variable = @cil_field | @cil_stack_variable; +@cil_stack_variable = @cil_local_variable | @cil_parameter; +@cil_member = @cil_method | @cil_type | @cil_field | @cil_property | @cil_event; +@cil_custom_modifier_receiver = @cil_method | @cil_property | @cil_parameter | @cil_field; // todo: add function pointer type + +#keyset[method, index] +cil_parameter( + unique int id: @cil_parameter, + int method: @cil_method ref, + int index: int ref, + int param_type: @cil_type ref); + +cil_parameter_in(unique int id: @cil_parameter ref); +cil_parameter_out(unique int id: @cil_parameter ref); + +cil_setter(unique int prop: @cil_property ref, + int method: @cil_method ref); + +#keyset[id, modifier] +cil_custom_modifiers( + int id: @cil_custom_modifier_receiver ref, + int modifier: @cil_type ref, + int kind: int ref); // modreq: 1, modopt: 0 + +cil_getter(unique int prop: @cil_property ref, + int method: @cil_method ref); + +cil_adder(unique int event: @cil_event ref, + int method: @cil_method ref); + +cil_remover(unique int event: @cil_event ref, int method: @cil_method ref); + +cil_raiser(unique int event: @cil_event ref, int method: @cil_method ref); + +cil_property( + unique int id: @cil_property, + int parent: @cil_type ref, + string name: string ref, + int property_type: @cil_type ref); + +#keyset[parent, name] +cil_event(unique int id: @cil_event, + int parent: @cil_type ref, + string name: string ref, + int event_type: @cil_type ref); + +#keyset[impl, index] +cil_local_variable( + unique int id: @cil_local_variable, + int impl: @cil_method_implementation ref, + int index: int ref, + int var_type: @cil_type ref); + +// CIL handlers (exception handlers etc). + +case @cil_handler.kind of + 0 = @cil_catch_handler +| 1 = @cil_filter_handler +| 2 = @cil_finally_handler +| 4 = @cil_fault_handler +; + +#keyset[impl, index] +cil_handler( + unique int id: @cil_handler, + int impl: @cil_method_implementation ref, + int index: int ref, + int kind: int ref, + int try_start: @cil_instruction ref, + int try_end: @cil_instruction ref, + int handler_start: @cil_instruction ref); + +cil_handler_filter( + unique int id: @cil_handler ref, + int filter_start: @cil_instruction ref); + +cil_handler_type( + unique int id: @cil_handler ref, + int catch_type: @cil_type ref); + +@cil_controlflow_node = @cil_entry_point | @cil_instruction; + +@cil_entry_point = @cil_method_implementation | @cil_handler; + +@cil_dataflow_node = @cil_instruction | @cil_variable | @cil_method; + +cil_method_stack_size( + unique int method: @cil_method_implementation ref, + int size: int ref); + +// CIL modifiers + +cil_public(int id: @cil_member ref); +cil_private(int id: @cil_member ref); +cil_protected(int id: @cil_member ref); +cil_internal(int id: @cil_member ref); +cil_static(int id: @cil_member ref); +cil_sealed(int id: @cil_member ref); +cil_virtual(int id: @cil_method ref); +cil_abstract(int id: @cil_member ref); +cil_class(int id: @cil_type ref); +cil_interface(int id: @cil_type ref); +cil_security(int id: @cil_member ref); +cil_requiresecobject(int id: @cil_method ref); +cil_specialname(int id: @cil_method ref); +cil_newslot(int id: @cil_method ref); + +cil_base_class(unique int id: @cil_type ref, int base: @cil_type ref); +cil_base_interface(int id: @cil_type ref, int base: @cil_type ref); +cil_enum_underlying_type(unique int id: @cil_type ref, int underlying: @cil_type ref); + +#keyset[unbound, index] +cil_type_parameter( + int unbound: @cil_member ref, + int index: int ref, + int param: @cil_typeparameter ref); + +#keyset[bound, index] +cil_type_argument( + int bound: @cil_member ref, + int index: int ref, + int t: @cil_type ref); + +// CIL type parameter constraints + +cil_typeparam_covariant(int tp: @cil_typeparameter ref); +cil_typeparam_contravariant(int tp: @cil_typeparameter ref); +cil_typeparam_class(int tp: @cil_typeparameter ref); +cil_typeparam_struct(int tp: @cil_typeparameter ref); +cil_typeparam_new(int tp: @cil_typeparameter ref); +cil_typeparam_constraint(int tp: @cil_typeparameter ref, int supertype: @cil_type ref); + +// CIL attributes + +cil_attribute( + unique int attributeid: @cil_attribute, + int element: @cil_declaration ref, + int constructor: @cil_method ref); + +#keyset[attribute_id, param] +cil_attribute_named_argument( + int attribute_id: @cil_attribute ref, + string param: string ref, + string value: string ref); + +#keyset[attribute_id, index] +cil_attribute_positional_argument( + int attribute_id: @cil_attribute ref, + int index: int ref, + string value: string ref); + + +// Common .Net data model covering both C# and CIL + +// Common elements +@dotnet_element = @element | @cil_element; +@dotnet_named_element = @named_element | @cil_named_element; +@dotnet_callable = @callable | @cil_method; +@dotnet_variable = @variable | @cil_variable; +@dotnet_field = @field | @cil_field; +@dotnet_parameter = @parameter | @cil_parameter; +@dotnet_declaration = @declaration | @cil_declaration; +@dotnet_member = @member | @cil_member; +@dotnet_event = @event | @cil_event; +@dotnet_property = @property | @cil_property | @indexer; + +// Common types +@dotnet_type = @type | @cil_type; +@dotnet_call = @call | @cil_call_any; +@dotnet_throw = @throw_element | @cil_throw_any; +@dotnet_valueorreftype = @cil_valueorreftype | @value_or_ref_type | @cil_array_type | @void_type; +@dotnet_typeparameter = @type_parameter | @cil_typeparameter; +@dotnet_array_type = @array_type | @cil_array_type; +@dotnet_pointer_type = @pointer_type | @cil_pointer_type; +@dotnet_type_parameter = @type_parameter | @cil_typeparameter; +@dotnet_generic = @dotnet_valueorreftype | @dotnet_callable; + +// Attributes +@dotnet_attribute = @attribute | @cil_attribute; + +// Expressions +@dotnet_expr = @expr | @cil_expr; + +// Literals +@dotnet_literal = @literal_expr | @cil_literal; +@dotnet_string_literal = @string_literal_expr | @cil_ldstr; +@dotnet_int_literal = @integer_literal_expr | @cil_ldc_i; +@dotnet_float_literal = @float_literal_expr | @cil_ldc_r; +@dotnet_null_literal = @null_literal_expr | @cil_ldnull; + +@metadata_entity = @cil_method | @cil_type | @cil_field | @cil_property | @field | @property | + @callable | @value_or_ref_type | @void_type; + +#keyset[entity, location] +metadata_handle(int entity : @metadata_entity ref, int location: @assembly ref, int handle: int ref) diff --git a/csharp/upgrades/98e37f65f0ae39cfe1bff33908d6620ade5df0f7/upgrade.properties b/csharp/upgrades/98e37f65f0ae39cfe1bff33908d6620ade5df0f7/upgrade.properties new file mode 100644 index 00000000000..ff9999cd8df --- /dev/null +++ b/csharp/upgrades/98e37f65f0ae39cfe1bff33908d6620ade5df0f7/upgrade.properties @@ -0,0 +1,2 @@ +description: Added '@function_pointer_type', '@function_pointer_invocation_expr' and related relations. +compatibility: backwards diff --git a/csharp/upgrades/b93e202508f21bdf2e0d831e464c3b14187378cc/old.dbscheme b/csharp/upgrades/b93e202508f21bdf2e0d831e464c3b14187378cc/old.dbscheme new file mode 100644 index 00000000000..b93e202508f --- /dev/null +++ b/csharp/upgrades/b93e202508f21bdf2e0d831e464c3b14187378cc/old.dbscheme @@ -0,0 +1,1894 @@ + +/** + * An invocation of the compiler. Note that more than one file may be + * compiled per invocation. For example, this command compiles three + * source files: + * + * csc f1.cs f2.cs f3.cs + * + * The `id` simply identifies the invocation, while `cwd` is the working + * directory from which the compiler was invoked. + */ +compilations( + unique int id : @compilation, + string cwd : string ref +); + +/** + * The arguments that were passed to the extractor for a compiler + * invocation. If `id` is for the compiler invocation + * + * csc f1.cs f2.cs f3.cs + * + * then typically there will be rows for + * + * num | arg + * --- | --- + * 0 | --compiler + * 1 | *path to compiler* + * 2 | --cil + * 3 | f1.cs + * 4 | f2.cs + * 5 | f3.cs + */ +#keyset[id, num] +compilation_args( + int id : @compilation ref, + int num : int ref, + string arg : string ref +); + +/** + * The source files that are compiled by a compiler invocation. + * If `id` is for the compiler invocation + * + * csc f1.cs f2.cs f3.cs + * + * then there will be rows for + * + * num | arg + * --- | --- + * 0 | f1.cs + * 1 | f2.cs + * 2 | f3.cs + */ +#keyset[id, num] +compilation_compiling_files( + int id : @compilation ref, + int num : int ref, + int file : @file ref +); + +/** + * The references used by a compiler invocation. + * If `id` is for the compiler invocation + * + * csc f1.cs f2.cs f3.cs /r:ref1.dll /r:ref2.dll /r:ref3.dll + * + * then there will be rows for + * + * num | arg + * --- | --- + * 0 | ref1.dll + * 1 | ref2.dll + * 2 | ref3.dll + */ +#keyset[id, num] +compilation_referencing_files( + int id : @compilation ref, + int num : int ref, + int file : @file ref +); + +/** + * The time taken by the extractor for a compiler invocation. + * + * For each file `num`, there will be rows for + * + * kind | seconds + * ---- | --- + * 1 | CPU seconds used by the extractor frontend + * 2 | Elapsed seconds during the extractor frontend + * 3 | CPU seconds used by the extractor backend + * 4 | Elapsed seconds during the extractor backend + */ +#keyset[id, num, kind] +compilation_time( + int id : @compilation ref, + int num : int ref, + /* kind: + 1 = frontend_cpu_seconds + 2 = frontend_elapsed_seconds + 3 = extractor_cpu_seconds + 4 = extractor_elapsed_seconds + */ + int kind : int ref, + float seconds : float ref +); + +/** + * An error or warning generated by the extractor. + * The diagnostic message `diagnostic` was generated during compiler + * invocation `compilation`, and is the `file_number_diagnostic_number`th + * message generated while extracting the `file_number`th file of that + * invocation. + */ +#keyset[compilation, file_number, file_number_diagnostic_number] +diagnostic_for( + unique int diagnostic : @diagnostic ref, + int compilation : @compilation ref, + int file_number : int ref, + int file_number_diagnostic_number : int ref +); + +diagnostics( + unique int id: @diagnostic, + int severity: int ref, + string error_tag: string ref, + string error_message: string ref, + string full_error_message: string ref, + int location: @location_default ref +); + +extractor_messages( + unique int id: @extractor_message, + int severity: int ref, + string origin : string ref, + string text : string ref, + string entity : string ref, + int location: @location_default ref, + string stack_trace : string ref +); + +/** + * If extraction was successful, then `cpu_seconds` and + * `elapsed_seconds` are the CPU time and elapsed time (respectively) + * that extraction took for compiler invocation `id`. + */ +compilation_finished( + unique int id : @compilation ref, + float cpu_seconds : float ref, + float elapsed_seconds : float ref +); + +/* + * External artifacts + */ + +externalDefects( + unique int id: @externalDefect, + string queryPath: string ref, + int location: @location ref, + string message: string ref, + float severity: float ref); + +externalMetrics( + unique int id: @externalMetric, + string queryPath: string ref, + int location: @location ref, + float value: float ref); + +externalData( + int id: @externalDataElement, + string path: string ref, + int column: int ref, + string value: string ref); + +snapshotDate( + unique date snapshotDate: date ref); + +sourceLocationPrefix( + string prefix: string ref); + +/* + * Duplicate code + */ + +duplicateCode( + unique int id: @duplication, + string relativePath: string ref, + int equivClass: int ref); + +similarCode( + unique int id: @similarity, + string relativePath: string ref, + int equivClass: int ref); + +@duplication_or_similarity = @duplication | @similarity + +tokens( + int id: @duplication_or_similarity ref, + int offset: int ref, + int beginLine: int ref, + int beginColumn: int ref, + int endLine: int ref, + int endColumn: int ref); + +/* + * C# dbscheme + */ + +/** ELEMENTS **/ + +@element = @declaration | @stmt | @expr | @modifier | @attribute | @namespace_declaration + | @using_directive | @type_parameter_constraints | @external_element + | @xmllocatable | @asp_element | @namespace; + +@declaration = @callable | @generic | @assignable | @namespace; + +@named_element = @namespace | @declaration; + +@declaration_with_accessors = @property | @indexer | @event; + +@assignable = @variable | @assignable_with_accessors | @event; + +@assignable_with_accessors = @property | @indexer; + +@external_element = @externalMetric | @externalDefect | @externalDataElement; + +@attributable = @assembly | @field | @parameter | @operator | @method | @constructor + | @destructor | @callable_accessor | @value_or_ref_type | @declaration_with_accessors + | @local_function; + +/** LOCATIONS, ASEMMBLIES, MODULES, FILES and FOLDERS **/ + +@location = @location_default | @assembly; + +locations_default( + unique int id: @location_default, + int file: @file ref, + int beginLine: int ref, + int beginColumn: int ref, + int endLine: int ref, + int endColumn: int ref); + +@sourceline = @file | @callable | @xmllocatable; + +numlines( + int element_id: @sourceline ref, + int num_lines: int ref, + int num_code: int ref, + int num_comment: int ref); + +assemblies( + unique int id: @assembly, + int file: @file ref, + string fullname: string ref, + string name: string ref, + string version: string ref); + +/* + fromSource(0) = unknown, + fromSource(1) = from source, + fromSource(2) = from library +*/ +files( + unique int id: @file, + string name: string ref, + string simple: string ref, + string ext: string ref, + int fromSource: int ref); + +folders( + unique int id: @folder, + string name: string ref, + string simple: string ref); + +@container = @folder | @file ; + +containerparent( + int parent: @container ref, + unique int child: @container ref); + +file_extraction_mode( + unique int file: @file ref, + int mode: int ref + /* 0 = normal, 1 = standalone extractor */ + ); + +/** NAMESPACES **/ + +@type_container = @namespace | @type; + +namespaces( + unique int id: @namespace, + string name: string ref); + +namespace_declarations( + unique int id: @namespace_declaration, + int namespace_id: @namespace ref); + +namespace_declaration_location( + unique int id: @namespace_declaration ref, + int loc: @location ref); + +parent_namespace( + unique int child_id: @type_container ref, + int namespace_id: @namespace ref); + +@declaration_or_directive = @namespace_declaration | @type | @using_directive; + +parent_namespace_declaration( + int child_id: @declaration_or_directive ref, // cannot be unique because of partial classes + int namespace_id: @namespace_declaration ref); + +@using_directive = @using_namespace_directive | @using_static_directive; + +using_namespace_directives( + unique int id: @using_namespace_directive, + int namespace_id: @namespace ref); + +using_static_directives( + unique int id: @using_static_directive, + int type_id: @type_or_ref ref); + +using_directive_location( + unique int id: @using_directive ref, + int loc: @location ref); + +/** TYPES **/ + +types( + unique int id: @type, + int kind: int ref, + string name: string ref); + +case @type.kind of + 1 = @bool_type +| 2 = @char_type +| 3 = @decimal_type +| 4 = @sbyte_type +| 5 = @short_type +| 6 = @int_type +| 7 = @long_type +| 8 = @byte_type +| 9 = @ushort_type +| 10 = @uint_type +| 11 = @ulong_type +| 12 = @float_type +| 13 = @double_type +| 14 = @enum_type +| 15 = @struct_type +| 17 = @class_type +| 19 = @interface_type +| 20 = @delegate_type +| 21 = @null_type +| 22 = @type_parameter +| 23 = @pointer_type +| 24 = @nullable_type +| 25 = @array_type +| 26 = @void_type +| 27 = @int_ptr_type +| 28 = @uint_ptr_type +| 29 = @dynamic_type +| 30 = @arglist_type +| 31 = @unknown_type +| 32 = @tuple_type + ; + +@simple_type = @bool_type | @char_type | @integral_type | @floating_point_type | @decimal_type; +@integral_type = @signed_integral_type | @unsigned_integral_type; +@signed_integral_type = @sbyte_type | @short_type | @int_type | @long_type; +@unsigned_integral_type = @byte_type | @ushort_type | @uint_type | @ulong_type; +@floating_point_type = @float_type | @double_type; +@value_type = @simple_type | @enum_type | @struct_type | @nullable_type | @int_ptr_type + | @uint_ptr_type | @tuple_type; +@ref_type = @class_type | @interface_type | @array_type | @delegate_type | @null_type + | @dynamic_type; +@value_or_ref_type = @value_type | @ref_type; + +typerefs( + unique int id: @typeref, + string name: string ref); + +typeref_type( + int id: @typeref ref, + unique int typeId: @type ref); + +@type_or_ref = @type | @typeref; + +array_element_type( + unique int array: @array_type ref, + int dimension: int ref, + int rank: int ref, + int element: @type_or_ref ref); + +nullable_underlying_type( + unique int nullable: @nullable_type ref, + int underlying: @type_or_ref ref); + +pointer_referent_type( + unique int pointer: @pointer_type ref, + int referent: @type_or_ref ref); + +enum_underlying_type( + unique int enum_id: @enum_type ref, + int underlying_type_id: @type_or_ref ref); + +delegate_return_type( + unique int delegate_id: @delegate_type ref, + int return_type_id: @type_or_ref ref); + +extend( + unique int sub: @type ref, + int super: @type_or_ref ref); + +@interface_or_ref = @interface_type | @typeref; + +implement( + int sub: @type ref, + int super: @type_or_ref ref); + +type_location( + int id: @type ref, + int loc: @location ref); + +tuple_underlying_type( + unique int tuple: @tuple_type ref, + int struct: @type_or_ref ref); + +#keyset[tuple, index] +tuple_element( + int tuple: @tuple_type ref, + int index: int ref, + unique int field: @field ref); + +attributes( + unique int id: @attribute, + int type_id: @type_or_ref ref, + int target: @attributable ref); + +attribute_location( + int id: @attribute ref, + int loc: @location ref); + +@type_mention_parent = @element | @type_mention; + +type_mention( + unique int id: @type_mention, + int type_id: @type_or_ref ref, + int parent: @type_mention_parent ref); + +type_mention_location( + unique int id: @type_mention ref, + int loc: @location ref); + +@has_type_annotation = @assignable | @type_parameter | @callable | @expr | @delegate_type | @generic; + +/** + * A direct annotation on an entity, for example `string? x;`. + * + * Annotations: + * 2 = reftype is not annotated "!" + * 3 = reftype is annotated "?" + * 4 = readonly ref type / in parameter + * 5 = ref type parameter, return or local variable + * 6 = out parameter + * + * Note that the annotation depends on the element it annotates. + * @assignable: The annotation is on the type of the assignable, for example the variable type. + * @type_parameter: The annotation is on the reftype constraint + * @callable: The annotation is on the return type + * @array_type: The annotation is on the element type + */ +type_annotation(int id: @has_type_annotation ref, int annotation: int ref); + +nullability(unique int nullability: @nullability, int kind: int ref); + +case @nullability.kind of + 0 = @oblivious +| 1 = @not_annotated +| 2 = @annotated +; + +#keyset[parent, index] +nullability_parent(int nullability: @nullability ref, int index: int ref, int parent: @nullability ref) + +type_nullability(int id: @has_type_annotation ref, int nullability: @nullability ref); + +/** + * The nullable flow state of an expression, as determined by Roslyn. + * 0 = none (default, not populated) + * 1 = not null + * 2 = maybe null + */ +expr_flowstate(unique int id: @expr ref, int state: int ref); + +/** GENERICS **/ + +@generic = @type | @method | @local_function; + +type_parameters( + unique int id: @type_parameter ref, + int index: int ref, + int generic_id: @generic ref, + int variance: int ref /* none = 0, out = 1, in = 2 */); + +#keyset[constructed_id, index] +type_arguments( + int id: @type_or_ref ref, + int index: int ref, + int constructed_id: @generic_or_ref ref); + +@generic_or_ref = @generic | @typeref; + +constructed_generic( + unique int constructed: @generic ref, + int generic: @generic_or_ref ref); + +type_parameter_constraints( + unique int id: @type_parameter_constraints, + int param_id: @type_parameter ref); + +type_parameter_constraints_location( + int id: @type_parameter_constraints ref, + int loc: @location ref); + +general_type_parameter_constraints( + int id: @type_parameter_constraints ref, + int kind: int ref /* class = 1, struct = 2, new = 3 */); + +specific_type_parameter_constraints( + int id: @type_parameter_constraints ref, + int base_id: @type_or_ref ref); + +specific_type_parameter_nullability( + int id: @type_parameter_constraints ref, + int base_id: @type_or_ref ref, + int nullability: @nullability ref); + +/** MODIFIERS */ + +@modifiable = @modifiable_direct | @event_accessor; + +@modifiable_direct = @member | @accessor | @local_function | @anonymous_function_expr; + +modifiers( + unique int id: @modifier, + string name: string ref); + +has_modifiers( + int id: @modifiable_direct ref, + int mod_id: @modifier ref); + +compiler_generated(unique int id: @modifiable_direct ref); + +/** MEMBERS **/ + +@member = @method | @constructor | @destructor | @field | @property | @event | @operator | @indexer | @type; + +@named_exprorstmt = @goto_stmt | @labeled_stmt | @expr; + +@virtualizable = @method | @property | @indexer | @event; + +exprorstmt_name( + unique int parent_id: @named_exprorstmt ref, + string name: string ref); + +nested_types( + unique int id: @type ref, + int declaring_type_id: @type ref, + int unbound_id: @type ref); + +properties( + unique int id: @property, + string name: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @property ref); + +property_location( + int id: @property ref, + int loc: @location ref); + +indexers( + unique int id: @indexer, + string name: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @indexer ref); + +indexer_location( + int id: @indexer ref, + int loc: @location ref); + +accessors( + unique int id: @accessor, + int kind: int ref, + string name: string ref, + int declaring_member_id: @member ref, + int unbound_id: @accessor ref); + +case @accessor.kind of + 1 = @getter +| 2 = @setter + ; + +init_only_accessors( + unique int id: @accessor ref); + +accessor_location( + int id: @accessor ref, + int loc: @location ref); + +events( + unique int id: @event, + string name: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @event ref); + +event_location( + int id: @event ref, + int loc: @location ref); + +event_accessors( + unique int id: @event_accessor, + int kind: int ref, + string name: string ref, + int declaring_event_id: @event ref, + int unbound_id: @event_accessor ref); + +case @event_accessor.kind of + 1 = @add_event_accessor +| 2 = @remove_event_accessor + ; + +event_accessor_location( + int id: @event_accessor ref, + int loc: @location ref); + +operators( + unique int id: @operator, + string name: string ref, + string symbol: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @operator ref); + +operator_location( + int id: @operator ref, + int loc: @location ref); + +constant_value( + int id: @variable ref, + string value: string ref); + +/** CALLABLES **/ + +@callable = @method | @constructor | @destructor | @operator | @callable_accessor | @anonymous_function_expr | @local_function; + +@callable_accessor = @accessor | @event_accessor; + +methods( + unique int id: @method, + string name: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @method ref); + +method_location( + int id: @method ref, + int loc: @location ref); + +constructors( + unique int id: @constructor, + string name: string ref, + int declaring_type_id: @type ref, + int unbound_id: @constructor ref); + +constructor_location( + int id: @constructor ref, + int loc: @location ref); + +destructors( + unique int id: @destructor, + string name: string ref, + int declaring_type_id: @type ref, + int unbound_id: @destructor ref); + +destructor_location( + int id: @destructor ref, + int loc: @location ref); + +overrides( + int id: @callable ref, + int base_id: @callable ref); + +explicitly_implements( + int id: @member ref, + int interface_id: @interface_or_ref ref); + +local_functions( + unique int id: @local_function, + string name: string ref, + int return_type: @type ref, + int unbound_id: @local_function ref); + +local_function_stmts( + unique int fn: @local_function_stmt ref, + int stmt: @local_function ref); + +/** VARIABLES **/ + +@variable = @local_scope_variable | @field; + +@local_scope_variable = @local_variable | @parameter; + +fields( + unique int id: @field, + int kind: int ref, + string name: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @field ref); + +case @field.kind of + 1 = @addressable_field +| 2 = @constant + ; + +field_location( + int id: @field ref, + int loc: @location ref); + +localvars( + unique int id: @local_variable, + int kind: int ref, + string name: string ref, + int implicitly_typed: int ref /* 0 = no, 1 = yes */, + int type_id: @type_or_ref ref, + int parent_id: @local_var_decl_expr ref); + +case @local_variable.kind of + 1 = @addressable_local_variable +| 2 = @local_constant +| 3 = @local_variable_ref + ; + +localvar_location( + unique int id: @local_variable ref, + int loc: @location ref); + +@parameterizable = @callable | @delegate_type | @indexer; + +#keyset[name, parent_id] +#keyset[index, parent_id] +params( + unique int id: @parameter, + string name: string ref, + int type_id: @type_or_ref ref, + int index: int ref, + int mode: int ref, /* value = 0, ref = 1, out = 2, array = 3, this = 4 */ + int parent_id: @parameterizable ref, + int unbound_id: @parameter ref); + +param_location( + int id: @parameter ref, + int loc: @location ref); + +/** STATEMENTS **/ + +@exprorstmt_parent = @control_flow_element | @top_level_exprorstmt_parent; + +statements( + unique int id: @stmt, + int kind: int ref); + +#keyset[index, parent] +stmt_parent( + unique int stmt: @stmt ref, + int index: int ref, + int parent: @control_flow_element ref); + +@top_level_stmt_parent = @callable; + +// [index, parent] is not a keyset because the same parent may be compiled multiple times +stmt_parent_top_level( + unique int stmt: @stmt ref, + int index: int ref, + int parent: @top_level_stmt_parent ref); + +case @stmt.kind of + 1 = @block_stmt +| 2 = @expr_stmt +| 3 = @if_stmt +| 4 = @switch_stmt +| 5 = @while_stmt +| 6 = @do_stmt +| 7 = @for_stmt +| 8 = @foreach_stmt +| 9 = @break_stmt +| 10 = @continue_stmt +| 11 = @goto_stmt +| 12 = @goto_case_stmt +| 13 = @goto_default_stmt +| 14 = @throw_stmt +| 15 = @return_stmt +| 16 = @yield_stmt +| 17 = @try_stmt +| 18 = @checked_stmt +| 19 = @unchecked_stmt +| 20 = @lock_stmt +| 21 = @using_block_stmt +| 22 = @var_decl_stmt +| 23 = @const_decl_stmt +| 24 = @empty_stmt +| 25 = @unsafe_stmt +| 26 = @fixed_stmt +| 27 = @label_stmt +| 28 = @catch +| 29 = @case_stmt +| 30 = @local_function_stmt +| 31 = @using_decl_stmt + ; + +@using_stmt = @using_block_stmt | @using_decl_stmt; + +@labeled_stmt = @label_stmt | @case; + +@decl_stmt = @var_decl_stmt | @const_decl_stmt | @using_decl_stmt; + +@cond_stmt = @if_stmt | @switch_stmt; + +@loop_stmt = @while_stmt | @do_stmt | @for_stmt | @foreach_stmt; + +@jump_stmt = @break_stmt | @goto_any_stmt | @continue_stmt | @throw_stmt | @return_stmt + | @yield_stmt; + +@goto_any_stmt = @goto_default_stmt | @goto_case_stmt | @goto_stmt; + + +stmt_location( + unique int id: @stmt ref, + int loc: @location ref); + +catch_type( + unique int catch_id: @catch ref, + int type_id: @type_or_ref ref, + int kind: int ref /* explicit = 1, implicit = 2 */); + +/** EXPRESSIONS **/ + +expressions( + unique int id: @expr, + int kind: int ref, + int type_id: @type_or_ref ref); + +#keyset[index, parent] +expr_parent( + unique int expr: @expr ref, + int index: int ref, + int parent: @control_flow_element ref); + +@top_level_expr_parent = @attribute | @field | @property | @indexer | @parameter; + +@top_level_exprorstmt_parent = @top_level_expr_parent | @top_level_stmt_parent; + +// [index, parent] is not a keyset because the same parent may be compiled multiple times +expr_parent_top_level( + unique int expr: @expr ref, + int index: int ref, + int parent: @top_level_exprorstmt_parent ref); + +case @expr.kind of +/* literal */ + 1 = @bool_literal_expr +| 2 = @char_literal_expr +| 3 = @decimal_literal_expr +| 4 = @int_literal_expr +| 5 = @long_literal_expr +| 6 = @uint_literal_expr +| 7 = @ulong_literal_expr +| 8 = @float_literal_expr +| 9 = @double_literal_expr +| 10 = @string_literal_expr +| 11 = @null_literal_expr +/* primary & unary */ +| 12 = @this_access_expr +| 13 = @base_access_expr +| 14 = @local_variable_access_expr +| 15 = @parameter_access_expr +| 16 = @field_access_expr +| 17 = @property_access_expr +| 18 = @method_access_expr +| 19 = @event_access_expr +| 20 = @indexer_access_expr +| 21 = @array_access_expr +| 22 = @type_access_expr +| 23 = @typeof_expr +| 24 = @method_invocation_expr +| 25 = @delegate_invocation_expr +| 26 = @operator_invocation_expr +| 27 = @cast_expr +| 28 = @object_creation_expr +| 29 = @explicit_delegate_creation_expr +| 30 = @implicit_delegate_creation_expr +| 31 = @array_creation_expr +| 32 = @default_expr +| 33 = @plus_expr +| 34 = @minus_expr +| 35 = @bit_not_expr +| 36 = @log_not_expr +| 37 = @post_incr_expr +| 38 = @post_decr_expr +| 39 = @pre_incr_expr +| 40 = @pre_decr_expr +/* multiplicative */ +| 41 = @mul_expr +| 42 = @div_expr +| 43 = @rem_expr +/* additive */ +| 44 = @add_expr +| 45 = @sub_expr +/* shift */ +| 46 = @lshift_expr +| 47 = @rshift_expr +/* relational */ +| 48 = @lt_expr +| 49 = @gt_expr +| 50 = @le_expr +| 51 = @ge_expr +/* equality */ +| 52 = @eq_expr +| 53 = @ne_expr +/* logical */ +| 54 = @bit_and_expr +| 55 = @bit_xor_expr +| 56 = @bit_or_expr +| 57 = @log_and_expr +| 58 = @log_or_expr +/* type testing */ +| 59 = @is_expr +| 60 = @as_expr +/* null coalescing */ +| 61 = @null_coalescing_expr +/* conditional */ +| 62 = @conditional_expr +/* assignment */ +| 63 = @simple_assign_expr +| 64 = @assign_add_expr +| 65 = @assign_sub_expr +| 66 = @assign_mul_expr +| 67 = @assign_div_expr +| 68 = @assign_rem_expr +| 69 = @assign_and_expr +| 70 = @assign_xor_expr +| 71 = @assign_or_expr +| 72 = @assign_lshift_expr +| 73 = @assign_rshift_expr +/* more */ +| 74 = @object_init_expr +| 75 = @collection_init_expr +| 76 = @array_init_expr +| 77 = @checked_expr +| 78 = @unchecked_expr +| 79 = @constructor_init_expr +| 80 = @add_event_expr +| 81 = @remove_event_expr +| 82 = @par_expr +| 83 = @local_var_decl_expr +| 84 = @lambda_expr +| 85 = @anonymous_method_expr +| 86 = @namespace_expr +/* dynamic */ +| 92 = @dynamic_element_access_expr +| 93 = @dynamic_member_access_expr +/* unsafe */ +| 100 = @pointer_indirection_expr +| 101 = @address_of_expr +| 102 = @sizeof_expr +/* async */ +| 103 = @await_expr +/* C# 6.0 */ +| 104 = @nameof_expr +| 105 = @interpolated_string_expr +| 106 = @unknown_expr +/* C# 7.0 */ +| 107 = @throw_expr +| 108 = @tuple_expr +| 109 = @local_function_invocation_expr +| 110 = @ref_expr +| 111 = @discard_expr +/* C# 8.0 */ +| 112 = @range_expr +| 113 = @index_expr +| 114 = @switch_expr +| 115 = @recursive_pattern_expr +| 116 = @property_pattern_expr +| 117 = @positional_pattern_expr +| 118 = @switch_case_expr +| 119 = @assign_coalesce_expr +| 120 = @suppress_nullable_warning_expr +| 121 = @namespace_access_expr +; + +@switch = @switch_stmt | @switch_expr; +@case = @case_stmt | @switch_case_expr; +@pattern_match = @case | @is_expr; + +@integer_literal_expr = @int_literal_expr | @long_literal_expr | @uint_literal_expr | @ulong_literal_expr; +@real_literal_expr = @float_literal_expr | @double_literal_expr | @decimal_literal_expr; +@literal_expr = @bool_literal_expr | @char_literal_expr | @integer_literal_expr | @real_literal_expr + | @string_literal_expr | @null_literal_expr; + +@assign_expr = @simple_assign_expr | @assign_op_expr | @local_var_decl_expr; +@assign_op_expr = @assign_arith_expr | @assign_bitwise_expr | @assign_event_expr | @assign_coalesce_expr; +@assign_event_expr = @add_event_expr | @remove_event_expr; + +@assign_arith_expr = @assign_add_expr | @assign_sub_expr | @assign_mul_expr | @assign_div_expr + | @assign_rem_expr +@assign_bitwise_expr = @assign_and_expr | @assign_or_expr | @assign_xor_expr + | @assign_lshift_expr | @assign_rshift_expr; + +@member_access_expr = @field_access_expr | @property_access_expr | @indexer_access_expr | @event_access_expr + | @method_access_expr | @type_access_expr | @dynamic_member_access_expr; +@access_expr = @member_access_expr | @this_access_expr | @base_access_expr | @assignable_access_expr | @namespace_access_expr; +@element_access_expr = @indexer_access_expr | @array_access_expr | @dynamic_element_access_expr; + +@local_variable_access = @local_variable_access_expr | @local_var_decl_expr; +@local_scope_variable_access_expr = @parameter_access_expr | @local_variable_access; +@variable_access_expr = @local_scope_variable_access_expr | @field_access_expr; + +@assignable_access_expr = @variable_access_expr | @property_access_expr | @element_access_expr + | @event_access_expr | @dynamic_member_access_expr; + +@objectorcollection_init_expr = @object_init_expr | @collection_init_expr; + +@delegate_creation_expr = @explicit_delegate_creation_expr | @implicit_delegate_creation_expr; + +@bin_arith_op_expr = @mul_expr | @div_expr | @rem_expr | @add_expr | @sub_expr; +@incr_op_expr = @pre_incr_expr | @post_incr_expr; +@decr_op_expr = @pre_decr_expr | @post_decr_expr; +@mut_op_expr = @incr_op_expr | @decr_op_expr; +@un_arith_op_expr = @plus_expr | @minus_expr | @mut_op_expr; +@arith_op_expr = @bin_arith_op_expr | @un_arith_op_expr; + +@ternary_log_op_expr = @conditional_expr; +@bin_log_op_expr = @log_and_expr | @log_or_expr | @null_coalescing_expr; +@un_log_op_expr = @log_not_expr; +@log_expr = @un_log_op_expr | @bin_log_op_expr | @ternary_log_op_expr; + +@bin_bit_op_expr = @bit_and_expr | @bit_or_expr | @bit_xor_expr | @lshift_expr + | @rshift_expr; +@un_bit_op_expr = @bit_not_expr; +@bit_expr = @un_bit_op_expr | @bin_bit_op_expr; + +@equality_op_expr = @eq_expr | @ne_expr; +@rel_op_expr = @gt_expr | @lt_expr| @ge_expr | @le_expr; +@comp_expr = @equality_op_expr | @rel_op_expr; + +@op_expr = @assign_expr | @un_op | @bin_op | @ternary_op; + +@ternary_op = @ternary_log_op_expr; +@bin_op = @bin_arith_op_expr | @bin_log_op_expr | @bin_bit_op_expr | @comp_expr; +@un_op = @un_arith_op_expr | @un_log_op_expr | @un_bit_op_expr | @sizeof_expr + | @pointer_indirection_expr | @address_of_expr; + +@anonymous_function_expr = @lambda_expr | @anonymous_method_expr; + +@call = @method_invocation_expr | @constructor_init_expr | @operator_invocation_expr + | @delegate_invocation_expr | @object_creation_expr | @call_access_expr + | @local_function_invocation_expr; + +@call_access_expr = @property_access_expr | @event_access_expr | @indexer_access_expr; + +@late_bindable_expr = @dynamic_element_access_expr | @dynamic_member_access_expr + | @object_creation_expr | @method_invocation_expr | @operator_invocation_expr; + +@throw_element = @throw_expr | @throw_stmt; + +implicitly_typed_array_creation( + unique int id: @array_creation_expr ref); + +explicitly_sized_array_creation( + unique int id: @array_creation_expr ref); + +stackalloc_array_creation( + unique int id: @array_creation_expr ref); + +mutator_invocation_mode( + unique int id: @operator_invocation_expr ref, + int mode: int ref /* prefix = 1, postfix = 2*/); + +expr_compiler_generated( + unique int id: @expr ref); + +expr_value( + unique int id: @expr ref, + string value: string ref); + +expr_call( + unique int caller_id: @expr ref, + int target_id: @callable ref); + +expr_access( + unique int accesser_id: @access_expr ref, + int target_id: @accessible ref); + +@accessible = @method | @assignable | @local_function | @namespace; + +expr_location( + unique int id: @expr ref, + int loc: @location ref); + +dynamic_member_name( + unique int id: @late_bindable_expr ref, + string name: string ref); + +@qualifiable_expr = @member_access_expr + | @method_invocation_expr + | @element_access_expr; + +conditional_access( + unique int id: @qualifiable_expr ref); + +expr_argument( + unique int id: @expr ref, + int mode: int ref); + /* mode is the same as params: value = 0, ref = 1, out = 2 */ + +expr_argument_name( + unique int id: @expr ref, + string name: string ref); + +/** CONTROL/DATA FLOW **/ + +@control_flow_element = @stmt | @expr; + +/* XML Files */ + +xmlEncoding ( + unique int id: @file ref, + string encoding: string ref); + +xmlDTDs( + unique int id: @xmldtd, + string root: string ref, + string publicId: string ref, + string systemId: string ref, + int fileid: @file ref); + +xmlElements( + unique int id: @xmlelement, + string name: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int fileid: @file ref); + +xmlAttrs( + unique int id: @xmlattribute, + int elementid: @xmlelement ref, + string name: string ref, + string value: string ref, + int idx: int ref, + int fileid: @file ref); + +xmlNs( + int id: @xmlnamespace, + string prefixName: string ref, + string URI: string ref, + int fileid: @file ref); + +xmlHasNs( + int elementId: @xmlnamespaceable ref, + int nsId: @xmlnamespace ref, + int fileid: @file ref); + +xmlComments( + unique int id: @xmlcomment, + string text: string ref, + int parentid: @xmlparent ref, + int fileid: @file ref); + +xmlChars( + unique int id: @xmlcharacters, + string text: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int isCDATA: int ref, + int fileid: @file ref); + +@xmlparent = @file | @xmlelement; +@xmlnamespaceable = @xmlelement | @xmlattribute; + +xmllocations( + int xmlElement: @xmllocatable ref, + int location: @location_default ref); + +@xmllocatable = @xmlcharacters | @xmlelement | @xmlcomment | @xmlattribute | @xmldtd | @file | @xmlnamespace; + +/* Comments */ + +commentline( + unique int id: @commentline, + int kind: int ref, + string text: string ref, + string rawtext: string ref); + +case @commentline.kind of + 0 = @singlelinecomment +| 1 = @xmldoccomment +| 2 = @multilinecomment; + +commentline_location( + unique int id: @commentline ref, + int loc: @location ref); + +commentblock( + unique int id : @commentblock); + +commentblock_location( + unique int id: @commentblock ref, + int loc: @location ref); + +commentblock_binding( + int id: @commentblock ref, + int entity: @element ref, + int bindtype: int ref); /* 0: Parent, 1: Best, 2: Before, 3: After */ + +commentblock_child( + int id: @commentblock ref, + int commentline: @commentline ref, + int index: int ref); + +/* ASP.NET */ + +case @asp_element.kind of + 0=@asp_close_tag +| 1=@asp_code +| 2=@asp_comment +| 3=@asp_data_binding +| 4=@asp_directive +| 5=@asp_open_tag +| 6=@asp_quoted_string +| 7=@asp_text +| 8=@asp_xml_directive; + +@asp_attribute = @asp_code | @asp_data_binding | @asp_quoted_string; + +asp_elements( + unique int id: @asp_element, + int kind: int ref, + int loc: @location ref); + +asp_comment_server(unique int comment: @asp_comment ref); +asp_code_inline(unique int code: @asp_code ref); +asp_directive_attribute( + int directive: @asp_directive ref, + int index: int ref, + string name: string ref, + int value: @asp_quoted_string ref); +asp_directive_name( + unique int directive: @asp_directive ref, + string name: string ref); +asp_element_body( + unique int element: @asp_element ref, + string body: string ref); +asp_tag_attribute( + int tag: @asp_open_tag ref, + int index: int ref, + string name: string ref, + int attribute: @asp_attribute ref); +asp_tag_name( + unique int tag: @asp_open_tag ref, + string name: string ref); +asp_tag_isempty(int tag: @asp_open_tag ref); + +/* Common Intermediate Language - CIL */ + +case @cil_instruction.opcode of + 0 = @cil_nop +| 1 = @cil_break +| 2 = @cil_ldarg_0 +| 3 = @cil_ldarg_1 +| 4 = @cil_ldarg_2 +| 5 = @cil_ldarg_3 +| 6 = @cil_ldloc_0 +| 7 = @cil_ldloc_1 +| 8 = @cil_ldloc_2 +| 9 = @cil_ldloc_3 +| 10 = @cil_stloc_0 +| 11 = @cil_stloc_1 +| 12 = @cil_stloc_2 +| 13 = @cil_stloc_3 +| 14 = @cil_ldarg_s +| 15 = @cil_ldarga_s +| 16 = @cil_starg_s +| 17 = @cil_ldloc_s +| 18 = @cil_ldloca_s +| 19 = @cil_stloc_s +| 20 = @cil_ldnull +| 21 = @cil_ldc_i4_m1 +| 22 = @cil_ldc_i4_0 +| 23 = @cil_ldc_i4_1 +| 24 = @cil_ldc_i4_2 +| 25 = @cil_ldc_i4_3 +| 26 = @cil_ldc_i4_4 +| 27 = @cil_ldc_i4_5 +| 28 = @cil_ldc_i4_6 +| 29 = @cil_ldc_i4_7 +| 30 = @cil_ldc_i4_8 +| 31 = @cil_ldc_i4_s +| 32 = @cil_ldc_i4 +| 33 = @cil_ldc_i8 +| 34 = @cil_ldc_r4 +| 35 = @cil_ldc_r8 +| 37 = @cil_dup +| 38 = @cil_pop +| 39 = @cil_jmp +| 40 = @cil_call +| 41 = @cil_calli +| 42 = @cil_ret +| 43 = @cil_br_s +| 44 = @cil_brfalse_s +| 45 = @cil_brtrue_s +| 46 = @cil_beq_s +| 47 = @cil_bge_s +| 48 = @cil_bgt_s +| 49 = @cil_ble_s +| 50 = @cil_blt_s +| 51 = @cil_bne_un_s +| 52 = @cil_bge_un_s +| 53 = @cil_bgt_un_s +| 54 = @cil_ble_un_s +| 55 = @cil_blt_un_s +| 56 = @cil_br +| 57 = @cil_brfalse +| 58 = @cil_brtrue +| 59 = @cil_beq +| 60 = @cil_bge +| 61 = @cil_bgt +| 62 = @cil_ble +| 63 = @cil_blt +| 64 = @cil_bne_un +| 65 = @cil_bge_un +| 66 = @cil_bgt_un +| 67 = @cil_ble_un +| 68 = @cil_blt_un +| 69 = @cil_switch +| 70 = @cil_ldind_i1 +| 71 = @cil_ldind_u1 +| 72 = @cil_ldind_i2 +| 73 = @cil_ldind_u2 +| 74 = @cil_ldind_i4 +| 75 = @cil_ldind_u4 +| 76 = @cil_ldind_i8 +| 77 = @cil_ldind_i +| 78 = @cil_ldind_r4 +| 79 = @cil_ldind_r8 +| 80 = @cil_ldind_ref +| 81 = @cil_stind_ref +| 82 = @cil_stind_i1 +| 83 = @cil_stind_i2 +| 84 = @cil_stind_i4 +| 85 = @cil_stind_i8 +| 86 = @cil_stind_r4 +| 87 = @cil_stind_r8 +| 88 = @cil_add +| 89 = @cil_sub +| 90 = @cil_mul +| 91 = @cil_div +| 92 = @cil_div_un +| 93 = @cil_rem +| 94 = @cil_rem_un +| 95 = @cil_and +| 96 = @cil_or +| 97 = @cil_xor +| 98 = @cil_shl +| 99 = @cil_shr +| 100 = @cil_shr_un +| 101 = @cil_neg +| 102 = @cil_not +| 103 = @cil_conv_i1 +| 104 = @cil_conv_i2 +| 105 = @cil_conv_i4 +| 106 = @cil_conv_i8 +| 107 = @cil_conv_r4 +| 108 = @cil_conv_r8 +| 109 = @cil_conv_u4 +| 110 = @cil_conv_u8 +| 111 = @cil_callvirt +| 112 = @cil_cpobj +| 113 = @cil_ldobj +| 114 = @cil_ldstr +| 115 = @cil_newobj +| 116 = @cil_castclass +| 117 = @cil_isinst +| 118 = @cil_conv_r_un +| 121 = @cil_unbox +| 122 = @cil_throw +| 123 = @cil_ldfld +| 124 = @cil_ldflda +| 125 = @cil_stfld +| 126 = @cil_ldsfld +| 127 = @cil_ldsflda +| 128 = @cil_stsfld +| 129 = @cil_stobj +| 130 = @cil_conv_ovf_i1_un +| 131 = @cil_conv_ovf_i2_un +| 132 = @cil_conv_ovf_i4_un +| 133 = @cil_conv_ovf_i8_un +| 134 = @cil_conv_ovf_u1_un +| 135 = @cil_conv_ovf_u2_un +| 136 = @cil_conv_ovf_u4_un +| 137 = @cil_conv_ovf_u8_un +| 138 = @cil_conv_ovf_i_un +| 139 = @cil_conv_ovf_u_un +| 140 = @cil_box +| 141 = @cil_newarr +| 142 = @cil_ldlen +| 143 = @cil_ldelema +| 144 = @cil_ldelem_i1 +| 145 = @cil_ldelem_u1 +| 146 = @cil_ldelem_i2 +| 147 = @cil_ldelem_u2 +| 148 = @cil_ldelem_i4 +| 149 = @cil_ldelem_u4 +| 150 = @cil_ldelem_i8 +| 151 = @cil_ldelem_i +| 152 = @cil_ldelem_r4 +| 153 = @cil_ldelem_r8 +| 154 = @cil_ldelem_ref +| 155 = @cil_stelem_i +| 156 = @cil_stelem_i1 +| 157 = @cil_stelem_i2 +| 158 = @cil_stelem_i4 +| 159 = @cil_stelem_i8 +| 160 = @cil_stelem_r4 +| 161 = @cil_stelem_r8 +| 162 = @cil_stelem_ref +| 163 = @cil_ldelem +| 164 = @cil_stelem +| 165 = @cil_unbox_any +| 179 = @cil_conv_ovf_i1 +| 180 = @cil_conv_ovf_u1 +| 181 = @cil_conv_ovf_i2 +| 182 = @cil_conv_ovf_u2 +| 183 = @cil_conv_ovf_i4 +| 184 = @cil_conv_ovf_u4 +| 185 = @cil_conv_ovf_i8 +| 186 = @cil_conv_ovf_u8 +| 194 = @cil_refanyval +| 195 = @cil_ckinfinite +| 198 = @cil_mkrefany +| 208 = @cil_ldtoken +| 209 = @cil_conv_u2 +| 210 = @cil_conv_u1 +| 211 = @cil_conv_i +| 212 = @cil_conv_ovf_i +| 213 = @cil_conv_ovf_u +| 214 = @cil_add_ovf +| 215 = @cil_add_ovf_un +| 216 = @cil_mul_ovf +| 217 = @cil_mul_ovf_un +| 218 = @cil_sub_ovf +| 219 = @cil_sub_ovf_un +| 220 = @cil_endfinally +| 221 = @cil_leave +| 222 = @cil_leave_s +| 223 = @cil_stind_i +| 224 = @cil_conv_u +| 65024 = @cil_arglist +| 65025 = @cil_ceq +| 65026 = @cil_cgt +| 65027 = @cil_cgt_un +| 65028 = @cil_clt +| 65029 = @cil_clt_un +| 65030 = @cil_ldftn +| 65031 = @cil_ldvirtftn +| 65033 = @cil_ldarg +| 65034 = @cil_ldarga +| 65035 = @cil_starg +| 65036 = @cil_ldloc +| 65037 = @cil_ldloca +| 65038 = @cil_stloc +| 65039 = @cil_localloc +| 65041 = @cil_endfilter +| 65042 = @cil_unaligned +| 65043 = @cil_volatile +| 65044 = @cil_tail +| 65045 = @cil_initobj +| 65046 = @cil_constrained +| 65047 = @cil_cpblk +| 65048 = @cil_initblk +| 65050 = @cil_rethrow +| 65052 = @cil_sizeof +| 65053 = @cil_refanytype +| 65054 = @cil_readonly +; + +// CIL ignored instructions + +@cil_ignore = @cil_nop | @cil_break | @cil_volatile | @cil_unaligned; + +// CIL local/parameter/field access + +@cil_ldarg_any = @cil_ldarg_0 | @cil_ldarg_1 | @cil_ldarg_2 | @cil_ldarg_3 | @cil_ldarg_s | @cil_ldarga_s | @cil_ldarg | @cil_ldarga; +@cil_starg_any = @cil_starg | @cil_starg_s; + +@cil_ldloc_any = @cil_ldloc_0 | @cil_ldloc_1 | @cil_ldloc_2 | @cil_ldloc_3 | @cil_ldloc_s | @cil_ldloca_s | @cil_ldloc | @cil_ldloca; +@cil_stloc_any = @cil_stloc_0 | @cil_stloc_1 | @cil_stloc_2 | @cil_stloc_3 | @cil_stloc_s | @cil_stloc; + +@cil_ldfld_any = @cil_ldfld | @cil_ldsfld | @cil_ldsflda | @cil_ldflda; +@cil_stfld_any = @cil_stfld | @cil_stsfld; + +@cil_local_access = @cil_stloc_any | @cil_ldloc_any; +@cil_arg_access = @cil_starg_any | @cil_ldarg_any; +@cil_read_access = @cil_ldloc_any | @cil_ldarg_any | @cil_ldfld_any; +@cil_write_access = @cil_stloc_any | @cil_starg_any | @cil_stfld_any; + +@cil_stack_access = @cil_local_access | @cil_arg_access; +@cil_field_access = @cil_ldfld_any | @cil_stfld_any; + +@cil_access = @cil_read_access | @cil_write_access; + +// CIL constant/literal instructions + +@cil_ldc_i = @cil_ldc_i4_any | @cil_ldc_i8; + +@cil_ldc_i4_any = @cil_ldc_i4_m1 | @cil_ldc_i4_0 | @cil_ldc_i4_1 | @cil_ldc_i4_2 | @cil_ldc_i4_3 | + @cil_ldc_i4_4 | @cil_ldc_i4_5 | @cil_ldc_i4_6 | @cil_ldc_i4_7 | @cil_ldc_i4_8 | @cil_ldc_i4_s | @cil_ldc_i4; + +@cil_ldc_r = @cil_ldc_r4 | @cil_ldc_r8; + +@cil_literal = @cil_ldnull | @cil_ldc_i | @cil_ldc_r | @cil_ldstr; + +// Control flow + +@cil_conditional_jump = @cil_binary_jump | @cil_unary_jump; +@cil_binary_jump = @cil_beq_s | @cil_bge_s | @cil_bgt_s | @cil_ble_s | @cil_blt_s | + @cil_bne_un_s | @cil_bge_un_s | @cil_bgt_un_s | @cil_ble_un_s | @cil_blt_un_s | + @cil_beq | @cil_bge | @cil_bgt | @cil_ble | @cil_blt | + @cil_bne_un | @cil_bge_un | @cil_bgt_un | @cil_ble_un | @cil_blt_un; +@cil_unary_jump = @cil_brfalse_s | @cil_brtrue_s | @cil_brfalse | @cil_brtrue | @cil_switch; +@cil_unconditional_jump = @cil_br | @cil_br_s | @cil_leave_any; +@cil_leave_any = @cil_leave | @cil_leave_s; +@cil_jump = @cil_unconditional_jump | @cil_conditional_jump; + +// CIL call instructions + +@cil_call_any = @cil_jmp | @cil_call | @cil_calli | @cil_tail | @cil_callvirt | @cil_newobj; + +// CIL expression instructions + +@cil_expr = @cil_literal | @cil_binary_expr | @cil_unary_expr | @cil_call_any | @cil_read_access | + @cil_newarr | @cil_ldtoken | @cil_sizeof | + @cil_ldftn | @cil_ldvirtftn | @cil_localloc | @cil_mkrefany | @cil_refanytype | @cil_arglist | @cil_dup; + +@cil_unary_expr = + @cil_conversion_operation | @cil_unary_arithmetic_operation | @cil_unary_bitwise_operation| + @cil_ldlen | @cil_isinst | @cil_box | @cil_ldobj | @cil_castclass | @cil_unbox_any | + @cil_ldind | @cil_unbox; + +@cil_conversion_operation = + @cil_conv_i1 | @cil_conv_i2 | @cil_conv_i4 | @cil_conv_i8 | + @cil_conv_u1 | @cil_conv_u2 | @cil_conv_u4 | @cil_conv_u8 | + @cil_conv_ovf_i | @cil_conv_ovf_i_un | @cil_conv_ovf_i1 | @cil_conv_ovf_i1_un | + @cil_conv_ovf_i2 | @cil_conv_ovf_i2_un | @cil_conv_ovf_i4 | @cil_conv_ovf_i4_un | + @cil_conv_ovf_i8 | @cil_conv_ovf_i8_un | @cil_conv_ovf_u | @cil_conv_ovf_u_un | + @cil_conv_ovf_u1 | @cil_conv_ovf_u1_un | @cil_conv_ovf_u2 | @cil_conv_ovf_u2_un | + @cil_conv_ovf_u4 | @cil_conv_ovf_u4_un | @cil_conv_ovf_u8 | @cil_conv_ovf_u8_un | + @cil_conv_r4 | @cil_conv_r8 | @cil_conv_ovf_u2 | @cil_conv_ovf_u2_un | + @cil_conv_i | @cil_conv_u | @cil_conv_r_un; + +@cil_ldind = @cil_ldind_i | @cil_ldind_i1 | @cil_ldind_i2 | @cil_ldind_i4 | @cil_ldind_i8 | + @cil_ldind_r4 | @cil_ldind_r8 | @cil_ldind_ref | @cil_ldind_u1 | @cil_ldind_u2 | @cil_ldind_u4; + +@cil_stind = @cil_stind_i | @cil_stind_i1 | @cil_stind_i2 | @cil_stind_i4 | @cil_stind_i8 | + @cil_stind_r4 | @cil_stind_r8 | @cil_stind_ref; + +@cil_bitwise_operation = @cil_binary_bitwise_operation | @cil_unary_bitwise_operation; + +@cil_binary_bitwise_operation = @cil_and | @cil_or | @cil_xor | @cil_shr | @cil_shr | @cil_shr_un | @cil_shl; + +@cil_binary_arithmetic_operation = @cil_add | @cil_sub | @cil_mul | @cil_div | @cil_div_un | + @cil_rem | @cil_rem_un | @cil_add_ovf | @cil_add_ovf_un | @cil_mul_ovf | @cil_mul_ovf_un | + @cil_sub_ovf | @cil_sub_ovf_un; + +@cil_unary_bitwise_operation = @cil_not; + +@cil_binary_expr = @cil_binary_arithmetic_operation | @cil_binary_bitwise_operation | @cil_read_array | @cil_comparison_operation; + +@cil_unary_arithmetic_operation = @cil_neg; + +@cil_comparison_operation = @cil_cgt_un | @cil_ceq | @cil_cgt | @cil_clt | @cil_clt_un; + +// Elements that retrieve an address of something +@cil_read_ref = @cil_ldloca_s | @cil_ldarga_s | @cil_ldflda | @cil_ldsflda | @cil_ldelema; + +// CIL array instructions + +@cil_read_array = + @cil_ldelem | @cil_ldelema | @cil_ldelem_i1 | @cil_ldelem_ref | @cil_ldelem_i | + @cil_ldelem_i1 | @cil_ldelem_i2 | @cil_ldelem_i4 | @cil_ldelem_i8 | @cil_ldelem_r4 | + @cil_ldelem_r8 | @cil_ldelem_u1 | @cil_ldelem_u2 | @cil_ldelem_u4; + +@cil_write_array = @cil_stelem | @cil_stelem_ref | + @cil_stelem_i | @cil_stelem_i1 | @cil_stelem_i2 | @cil_stelem_i4 | @cil_stelem_i8 | + @cil_stelem_r4 | @cil_stelem_r8; + +@cil_throw_any = @cil_throw | @cil_rethrow; + +#keyset[impl, index] +cil_instruction( + unique int id: @cil_instruction, + int opcode: int ref, + int index: int ref, + int impl: @cil_method_implementation ref); + +cil_jump( + unique int instruction: @cil_jump ref, + int target: @cil_instruction ref); + +cil_access( + unique int instruction: @cil_instruction ref, + int target: @cil_accessible ref); + +cil_value( + unique int instruction: @cil_literal ref, + string value: string ref); + +#keyset[instruction, index] +cil_switch( + int instruction: @cil_switch ref, + int index: int ref, + int target: @cil_instruction ref); + +cil_instruction_location( + unique int id: @cil_instruction ref, + int loc: @location ref); + +cil_type_location( + int id: @cil_type ref, + int loc: @location ref); + +cil_method_location( + int id: @cil_method ref, + int loc: @location ref); + +@cil_namespace = @namespace; + +@cil_type_container = @cil_type | @cil_namespace | @cil_method; + +case @cil_type.kind of + 0 = @cil_valueorreftype +| 1 = @cil_typeparameter +| 2 = @cil_array_type +| 3 = @cil_pointer_type +; + +cil_type( + unique int id: @cil_type, + string name: string ref, + int kind: int ref, + int parent: @cil_type_container ref, + int sourceDecl: @cil_type ref); + +cil_pointer_type( + unique int id: @cil_pointer_type ref, + int pointee: @cil_type ref); + +cil_array_type( + unique int id: @cil_array_type ref, + int element_type: @cil_type ref, + int rank: int ref); + +cil_method( + unique int id: @cil_method, + string name: string ref, + int parent: @cil_type ref, + int return_type: @cil_type ref); + +cil_method_source_declaration( + unique int method: @cil_method ref, + int source: @cil_method ref); + +cil_method_implementation( + unique int id: @cil_method_implementation, + int method: @cil_method ref, + int location: @assembly ref); + +cil_implements( + int id: @cil_method ref, + int decl: @cil_method ref); + +#keyset[parent, name] +cil_field( + unique int id: @cil_field, + int parent: @cil_type ref, + string name: string ref, + int field_type: @cil_type ref); + +@cil_element = @cil_instruction | @cil_declaration | @cil_handler | @cil_attribute | @cil_namespace; +@cil_named_element = @cil_declaration | @cil_namespace; +@cil_declaration = @cil_variable | @cil_method | @cil_type | @cil_member; +@cil_accessible = @cil_declaration; +@cil_variable = @cil_field | @cil_stack_variable; +@cil_stack_variable = @cil_local_variable | @cil_parameter; +@cil_member = @cil_method | @cil_type | @cil_field | @cil_property | @cil_event; + +#keyset[method, index] +cil_parameter( + unique int id: @cil_parameter, + int method: @cil_method ref, + int index: int ref, + int param_type: @cil_type ref); + +cil_parameter_in(unique int id: @cil_parameter ref); +cil_parameter_out(unique int id: @cil_parameter ref); + +cil_setter(unique int prop: @cil_property ref, + int method: @cil_method ref); + +cil_getter(unique int prop: @cil_property ref, + int method: @cil_method ref); + +cil_adder(unique int event: @cil_event ref, + int method: @cil_method ref); + +cil_remover(unique int event: @cil_event ref, int method: @cil_method ref); + +cil_raiser(unique int event: @cil_event ref, int method: @cil_method ref); + +cil_property( + unique int id: @cil_property, + int parent: @cil_type ref, + string name: string ref, + int property_type: @cil_type ref); + +#keyset[parent, name] +cil_event(unique int id: @cil_event, + int parent: @cil_type ref, + string name: string ref, + int event_type: @cil_type ref); + +#keyset[impl, index] +cil_local_variable( + unique int id: @cil_local_variable, + int impl: @cil_method_implementation ref, + int index: int ref, + int var_type: @cil_type ref); + +// CIL handlers (exception handlers etc). + +case @cil_handler.kind of + 0 = @cil_catch_handler +| 1 = @cil_filter_handler +| 2 = @cil_finally_handler +| 4 = @cil_fault_handler +; + +#keyset[impl, index] +cil_handler( + unique int id: @cil_handler, + int impl: @cil_method_implementation ref, + int index: int ref, + int kind: int ref, + int try_start: @cil_instruction ref, + int try_end: @cil_instruction ref, + int handler_start: @cil_instruction ref); + +cil_handler_filter( + unique int id: @cil_handler ref, + int filter_start: @cil_instruction ref); + +cil_handler_type( + unique int id: @cil_handler ref, + int catch_type: @cil_type ref); + +@cil_controlflow_node = @cil_entry_point | @cil_instruction; + +@cil_entry_point = @cil_method_implementation | @cil_handler; + +@cil_dataflow_node = @cil_instruction | @cil_variable | @cil_method; + +cil_method_stack_size( + unique int method: @cil_method_implementation ref, + int size: int ref); + +// CIL modifiers + +cil_public(int id: @cil_member ref); +cil_private(int id: @cil_member ref); +cil_protected(int id: @cil_member ref); +cil_internal(int id: @cil_member ref); +cil_static(int id: @cil_member ref); +cil_sealed(int id: @cil_member ref); +cil_virtual(int id: @cil_method ref); +cil_abstract(int id: @cil_member ref); +cil_class(int id: @cil_type ref); +cil_interface(int id: @cil_type ref); +cil_security(int id: @cil_member ref); +cil_requiresecobject(int id: @cil_method ref); +cil_specialname(int id: @cil_method ref); +cil_newslot(int id: @cil_method ref); + +cil_base_class(unique int id: @cil_type ref, int base: @cil_type ref); +cil_base_interface(int id: @cil_type ref, int base: @cil_type ref); +cil_enum_underlying_type(unique int id: @cil_type ref, int underlying: @cil_type ref); + +#keyset[unbound, index] +cil_type_parameter( + int unbound: @cil_member ref, + int index: int ref, + int param: @cil_typeparameter ref); + +#keyset[bound, index] +cil_type_argument( + int bound: @cil_member ref, + int index: int ref, + int t: @cil_type ref); + +// CIL type parameter constraints + +cil_typeparam_covariant(int tp: @cil_typeparameter ref); +cil_typeparam_contravariant(int tp: @cil_typeparameter ref); +cil_typeparam_class(int tp: @cil_typeparameter ref); +cil_typeparam_struct(int tp: @cil_typeparameter ref); +cil_typeparam_new(int tp: @cil_typeparameter ref); +cil_typeparam_constraint(int tp: @cil_typeparameter ref, int supertype: @cil_type ref); + +// CIL attributes + +cil_attribute( + unique int attributeid: @cil_attribute, + int element: @cil_declaration ref, + int constructor: @cil_method ref); + +#keyset[attribute_id, param] +cil_attribute_named_argument( + int attribute_id: @cil_attribute ref, + string param: string ref, + string value: string ref); + +#keyset[attribute_id, index] +cil_attribute_positional_argument( + int attribute_id: @cil_attribute ref, + int index: int ref, + string value: string ref); + + +// Common .Net data model covering both C# and CIL + +// Common elements +@dotnet_element = @element | @cil_element; +@dotnet_named_element = @named_element | @cil_named_element; +@dotnet_callable = @callable | @cil_method; +@dotnet_variable = @variable | @cil_variable; +@dotnet_field = @field | @cil_field; +@dotnet_parameter = @parameter | @cil_parameter; +@dotnet_declaration = @declaration | @cil_declaration; +@dotnet_member = @member | @cil_member; +@dotnet_event = @event | @cil_event; +@dotnet_property = @property | @cil_property | @indexer; + +// Common types +@dotnet_type = @type | @cil_type; +@dotnet_call = @call | @cil_call_any; +@dotnet_throw = @throw_element | @cil_throw_any; +@dotnet_valueorreftype = @cil_valueorreftype | @value_or_ref_type | @cil_array_type | @void_type; +@dotnet_typeparameter = @type_parameter | @cil_typeparameter; +@dotnet_array_type = @array_type | @cil_array_type; +@dotnet_pointer_type = @pointer_type | @cil_pointer_type; +@dotnet_type_parameter = @type_parameter | @cil_typeparameter; +@dotnet_generic = @dotnet_valueorreftype | @dotnet_callable; + +// Attributes +@dotnet_attribute = @attribute | @cil_attribute; + +// Expressions +@dotnet_expr = @expr | @cil_expr; + +// Literals +@dotnet_literal = @literal_expr | @cil_literal; +@dotnet_string_literal = @string_literal_expr | @cil_ldstr; +@dotnet_int_literal = @integer_literal_expr | @cil_ldc_i; +@dotnet_float_literal = @float_literal_expr | @cil_ldc_r; +@dotnet_null_literal = @null_literal_expr | @cil_ldnull; + +@metadata_entity = @cil_method | @cil_type | @cil_field | @cil_property | @field | @property | + @callable | @value_or_ref_type | @void_type; + +#keyset[entity, location] +metadata_handle(int entity : @metadata_entity ref, int location: @assembly ref, int handle: int ref) diff --git a/csharp/upgrades/b93e202508f21bdf2e0d831e464c3b14187378cc/semmlecode.csharp.dbscheme b/csharp/upgrades/b93e202508f21bdf2e0d831e464c3b14187378cc/semmlecode.csharp.dbscheme new file mode 100644 index 00000000000..f5903552e30 --- /dev/null +++ b/csharp/upgrades/b93e202508f21bdf2e0d831e464c3b14187378cc/semmlecode.csharp.dbscheme @@ -0,0 +1,1899 @@ + +/** + * An invocation of the compiler. Note that more than one file may be + * compiled per invocation. For example, this command compiles three + * source files: + * + * csc f1.cs f2.cs f3.cs + * + * The `id` simply identifies the invocation, while `cwd` is the working + * directory from which the compiler was invoked. + */ +compilations( + unique int id : @compilation, + string cwd : string ref +); + +/** + * The arguments that were passed to the extractor for a compiler + * invocation. If `id` is for the compiler invocation + * + * csc f1.cs f2.cs f3.cs + * + * then typically there will be rows for + * + * num | arg + * --- | --- + * 0 | --compiler + * 1 | *path to compiler* + * 2 | --cil + * 3 | f1.cs + * 4 | f2.cs + * 5 | f3.cs + */ +#keyset[id, num] +compilation_args( + int id : @compilation ref, + int num : int ref, + string arg : string ref +); + +/** + * The source files that are compiled by a compiler invocation. + * If `id` is for the compiler invocation + * + * csc f1.cs f2.cs f3.cs + * + * then there will be rows for + * + * num | arg + * --- | --- + * 0 | f1.cs + * 1 | f2.cs + * 2 | f3.cs + */ +#keyset[id, num] +compilation_compiling_files( + int id : @compilation ref, + int num : int ref, + int file : @file ref +); + +/** + * The references used by a compiler invocation. + * If `id` is for the compiler invocation + * + * csc f1.cs f2.cs f3.cs /r:ref1.dll /r:ref2.dll /r:ref3.dll + * + * then there will be rows for + * + * num | arg + * --- | --- + * 0 | ref1.dll + * 1 | ref2.dll + * 2 | ref3.dll + */ +#keyset[id, num] +compilation_referencing_files( + int id : @compilation ref, + int num : int ref, + int file : @file ref +); + +/** + * The time taken by the extractor for a compiler invocation. + * + * For each file `num`, there will be rows for + * + * kind | seconds + * ---- | --- + * 1 | CPU seconds used by the extractor frontend + * 2 | Elapsed seconds during the extractor frontend + * 3 | CPU seconds used by the extractor backend + * 4 | Elapsed seconds during the extractor backend + */ +#keyset[id, num, kind] +compilation_time( + int id : @compilation ref, + int num : int ref, + /* kind: + 1 = frontend_cpu_seconds + 2 = frontend_elapsed_seconds + 3 = extractor_cpu_seconds + 4 = extractor_elapsed_seconds + */ + int kind : int ref, + float seconds : float ref +); + +/** + * An error or warning generated by the extractor. + * The diagnostic message `diagnostic` was generated during compiler + * invocation `compilation`, and is the `file_number_diagnostic_number`th + * message generated while extracting the `file_number`th file of that + * invocation. + */ +#keyset[compilation, file_number, file_number_diagnostic_number] +diagnostic_for( + unique int diagnostic : @diagnostic ref, + int compilation : @compilation ref, + int file_number : int ref, + int file_number_diagnostic_number : int ref +); + +diagnostics( + unique int id: @diagnostic, + int severity: int ref, + string error_tag: string ref, + string error_message: string ref, + string full_error_message: string ref, + int location: @location_default ref +); + +extractor_messages( + unique int id: @extractor_message, + int severity: int ref, + string origin : string ref, + string text : string ref, + string entity : string ref, + int location: @location_default ref, + string stack_trace : string ref +); + +/** + * If extraction was successful, then `cpu_seconds` and + * `elapsed_seconds` are the CPU time and elapsed time (respectively) + * that extraction took for compiler invocation `id`. + */ +compilation_finished( + unique int id : @compilation ref, + float cpu_seconds : float ref, + float elapsed_seconds : float ref +); + +/* + * External artifacts + */ + +externalDefects( + unique int id: @externalDefect, + string queryPath: string ref, + int location: @location ref, + string message: string ref, + float severity: float ref); + +externalMetrics( + unique int id: @externalMetric, + string queryPath: string ref, + int location: @location ref, + float value: float ref); + +externalData( + int id: @externalDataElement, + string path: string ref, + int column: int ref, + string value: string ref); + +snapshotDate( + unique date snapshotDate: date ref); + +sourceLocationPrefix( + string prefix: string ref); + +/* + * Duplicate code + */ + +duplicateCode( + unique int id: @duplication, + string relativePath: string ref, + int equivClass: int ref); + +similarCode( + unique int id: @similarity, + string relativePath: string ref, + int equivClass: int ref); + +@duplication_or_similarity = @duplication | @similarity + +tokens( + int id: @duplication_or_similarity ref, + int offset: int ref, + int beginLine: int ref, + int beginColumn: int ref, + int endLine: int ref, + int endColumn: int ref); + +/* + * C# dbscheme + */ + +/** ELEMENTS **/ + +@element = @declaration | @stmt | @expr | @modifier | @attribute | @namespace_declaration + | @using_directive | @type_parameter_constraints | @external_element + | @xmllocatable | @asp_element | @namespace; + +@declaration = @callable | @generic | @assignable | @namespace; + +@named_element = @namespace | @declaration; + +@declaration_with_accessors = @property | @indexer | @event; + +@assignable = @variable | @assignable_with_accessors | @event; + +@assignable_with_accessors = @property | @indexer; + +@external_element = @externalMetric | @externalDefect | @externalDataElement; + +@attributable = @assembly | @field | @parameter | @operator | @method | @constructor + | @destructor | @callable_accessor | @value_or_ref_type | @declaration_with_accessors + | @local_function; + +/** LOCATIONS, ASEMMBLIES, MODULES, FILES and FOLDERS **/ + +@location = @location_default | @assembly; + +locations_default( + unique int id: @location_default, + int file: @file ref, + int beginLine: int ref, + int beginColumn: int ref, + int endLine: int ref, + int endColumn: int ref); + +@sourceline = @file | @callable | @xmllocatable; + +numlines( + int element_id: @sourceline ref, + int num_lines: int ref, + int num_code: int ref, + int num_comment: int ref); + +assemblies( + unique int id: @assembly, + int file: @file ref, + string fullname: string ref, + string name: string ref, + string version: string ref); + +/* + fromSource(0) = unknown, + fromSource(1) = from source, + fromSource(2) = from library +*/ +files( + unique int id: @file, + string name: string ref, + string simple: string ref, + string ext: string ref, + int fromSource: int ref); + +folders( + unique int id: @folder, + string name: string ref, + string simple: string ref); + +@container = @folder | @file ; + +containerparent( + int parent: @container ref, + unique int child: @container ref); + +file_extraction_mode( + unique int file: @file ref, + int mode: int ref + /* 0 = normal, 1 = standalone extractor */ + ); + +/** NAMESPACES **/ + +@type_container = @namespace | @type; + +namespaces( + unique int id: @namespace, + string name: string ref); + +namespace_declarations( + unique int id: @namespace_declaration, + int namespace_id: @namespace ref); + +namespace_declaration_location( + unique int id: @namespace_declaration ref, + int loc: @location ref); + +parent_namespace( + unique int child_id: @type_container ref, + int namespace_id: @namespace ref); + +@declaration_or_directive = @namespace_declaration | @type | @using_directive; + +parent_namespace_declaration( + int child_id: @declaration_or_directive ref, // cannot be unique because of partial classes + int namespace_id: @namespace_declaration ref); + +@using_directive = @using_namespace_directive | @using_static_directive; + +using_namespace_directives( + unique int id: @using_namespace_directive, + int namespace_id: @namespace ref); + +using_static_directives( + unique int id: @using_static_directive, + int type_id: @type_or_ref ref); + +using_directive_location( + unique int id: @using_directive ref, + int loc: @location ref); + +/** TYPES **/ + +types( + unique int id: @type, + int kind: int ref, + string name: string ref); + +case @type.kind of + 1 = @bool_type +| 2 = @char_type +| 3 = @decimal_type +| 4 = @sbyte_type +| 5 = @short_type +| 6 = @int_type +| 7 = @long_type +| 8 = @byte_type +| 9 = @ushort_type +| 10 = @uint_type +| 11 = @ulong_type +| 12 = @float_type +| 13 = @double_type +| 14 = @enum_type +| 15 = @struct_type +| 17 = @class_type +| 19 = @interface_type +| 20 = @delegate_type +| 21 = @null_type +| 22 = @type_parameter +| 23 = @pointer_type +| 24 = @nullable_type +| 25 = @array_type +| 26 = @void_type +| 27 = @int_ptr_type +| 28 = @uint_ptr_type +| 29 = @dynamic_type +| 30 = @arglist_type +| 31 = @unknown_type +| 32 = @tuple_type + ; + +@simple_type = @bool_type | @char_type | @integral_type | @floating_point_type | @decimal_type; +@integral_type = @signed_integral_type | @unsigned_integral_type; +@signed_integral_type = @sbyte_type | @short_type | @int_type | @long_type; +@unsigned_integral_type = @byte_type | @ushort_type | @uint_type | @ulong_type; +@floating_point_type = @float_type | @double_type; +@value_type = @simple_type | @enum_type | @struct_type | @nullable_type | @int_ptr_type + | @uint_ptr_type | @tuple_type; +@ref_type = @class_type | @interface_type | @array_type | @delegate_type | @null_type + | @dynamic_type; +@value_or_ref_type = @value_type | @ref_type; + +typerefs( + unique int id: @typeref, + string name: string ref); + +typeref_type( + int id: @typeref ref, + unique int typeId: @type ref); + +@type_or_ref = @type | @typeref; + +array_element_type( + unique int array: @array_type ref, + int dimension: int ref, + int rank: int ref, + int element: @type_or_ref ref); + +nullable_underlying_type( + unique int nullable: @nullable_type ref, + int underlying: @type_or_ref ref); + +pointer_referent_type( + unique int pointer: @pointer_type ref, + int referent: @type_or_ref ref); + +enum_underlying_type( + unique int enum_id: @enum_type ref, + int underlying_type_id: @type_or_ref ref); + +delegate_return_type( + unique int delegate_id: @delegate_type ref, + int return_type_id: @type_or_ref ref); + +extend( + unique int sub: @type ref, + int super: @type_or_ref ref); + +@interface_or_ref = @interface_type | @typeref; + +implement( + int sub: @type ref, + int super: @type_or_ref ref); + +type_location( + int id: @type ref, + int loc: @location ref); + +tuple_underlying_type( + unique int tuple: @tuple_type ref, + int struct: @type_or_ref ref); + +#keyset[tuple, index] +tuple_element( + int tuple: @tuple_type ref, + int index: int ref, + unique int field: @field ref); + +attributes( + unique int id: @attribute, + int type_id: @type_or_ref ref, + int target: @attributable ref); + +attribute_location( + int id: @attribute ref, + int loc: @location ref); + +@type_mention_parent = @element | @type_mention; + +type_mention( + unique int id: @type_mention, + int type_id: @type_or_ref ref, + int parent: @type_mention_parent ref); + +type_mention_location( + unique int id: @type_mention ref, + int loc: @location ref); + +@has_type_annotation = @assignable | @type_parameter | @callable | @expr | @delegate_type | @generic; + +/** + * A direct annotation on an entity, for example `string? x;`. + * + * Annotations: + * 2 = reftype is not annotated "!" + * 3 = reftype is annotated "?" + * 4 = readonly ref type / in parameter + * 5 = ref type parameter, return or local variable + * 6 = out parameter + * + * Note that the annotation depends on the element it annotates. + * @assignable: The annotation is on the type of the assignable, for example the variable type. + * @type_parameter: The annotation is on the reftype constraint + * @callable: The annotation is on the return type + * @array_type: The annotation is on the element type + */ +type_annotation(int id: @has_type_annotation ref, int annotation: int ref); + +nullability(unique int nullability: @nullability, int kind: int ref); + +case @nullability.kind of + 0 = @oblivious +| 1 = @not_annotated +| 2 = @annotated +; + +#keyset[parent, index] +nullability_parent(int nullability: @nullability ref, int index: int ref, int parent: @nullability ref) + +type_nullability(int id: @has_type_annotation ref, int nullability: @nullability ref); + +/** + * The nullable flow state of an expression, as determined by Roslyn. + * 0 = none (default, not populated) + * 1 = not null + * 2 = maybe null + */ +expr_flowstate(unique int id: @expr ref, int state: int ref); + +/** GENERICS **/ + +@generic = @type | @method | @local_function; + +type_parameters( + unique int id: @type_parameter ref, + int index: int ref, + int generic_id: @generic ref, + int variance: int ref /* none = 0, out = 1, in = 2 */); + +#keyset[constructed_id, index] +type_arguments( + int id: @type_or_ref ref, + int index: int ref, + int constructed_id: @generic_or_ref ref); + +@generic_or_ref = @generic | @typeref; + +constructed_generic( + unique int constructed: @generic ref, + int generic: @generic_or_ref ref); + +type_parameter_constraints( + unique int id: @type_parameter_constraints, + int param_id: @type_parameter ref); + +type_parameter_constraints_location( + int id: @type_parameter_constraints ref, + int loc: @location ref); + +general_type_parameter_constraints( + int id: @type_parameter_constraints ref, + int kind: int ref /* class = 1, struct = 2, new = 3 */); + +specific_type_parameter_constraints( + int id: @type_parameter_constraints ref, + int base_id: @type_or_ref ref); + +specific_type_parameter_nullability( + int id: @type_parameter_constraints ref, + int base_id: @type_or_ref ref, + int nullability: @nullability ref); + +/** MODIFIERS */ + +@modifiable = @modifiable_direct | @event_accessor; + +@modifiable_direct = @member | @accessor | @local_function | @anonymous_function_expr; + +modifiers( + unique int id: @modifier, + string name: string ref); + +has_modifiers( + int id: @modifiable_direct ref, + int mod_id: @modifier ref); + +compiler_generated(unique int id: @modifiable_direct ref); + +/** MEMBERS **/ + +@member = @method | @constructor | @destructor | @field | @property | @event | @operator | @indexer | @type; + +@named_exprorstmt = @goto_stmt | @labeled_stmt | @expr; + +@virtualizable = @method | @property | @indexer | @event; + +exprorstmt_name( + unique int parent_id: @named_exprorstmt ref, + string name: string ref); + +nested_types( + unique int id: @type ref, + int declaring_type_id: @type ref, + int unbound_id: @type ref); + +properties( + unique int id: @property, + string name: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @property ref); + +property_location( + int id: @property ref, + int loc: @location ref); + +indexers( + unique int id: @indexer, + string name: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @indexer ref); + +indexer_location( + int id: @indexer ref, + int loc: @location ref); + +accessors( + unique int id: @accessor, + int kind: int ref, + string name: string ref, + int declaring_member_id: @member ref, + int unbound_id: @accessor ref); + +case @accessor.kind of + 1 = @getter +| 2 = @setter + ; + +init_only_accessors( + unique int id: @accessor ref); + +accessor_location( + int id: @accessor ref, + int loc: @location ref); + +events( + unique int id: @event, + string name: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @event ref); + +event_location( + int id: @event ref, + int loc: @location ref); + +event_accessors( + unique int id: @event_accessor, + int kind: int ref, + string name: string ref, + int declaring_event_id: @event ref, + int unbound_id: @event_accessor ref); + +case @event_accessor.kind of + 1 = @add_event_accessor +| 2 = @remove_event_accessor + ; + +event_accessor_location( + int id: @event_accessor ref, + int loc: @location ref); + +operators( + unique int id: @operator, + string name: string ref, + string symbol: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @operator ref); + +operator_location( + int id: @operator ref, + int loc: @location ref); + +constant_value( + int id: @variable ref, + string value: string ref); + +/** CALLABLES **/ + +@callable = @method | @constructor | @destructor | @operator | @callable_accessor | @anonymous_function_expr | @local_function; + +@callable_accessor = @accessor | @event_accessor; + +methods( + unique int id: @method, + string name: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @method ref); + +method_location( + int id: @method ref, + int loc: @location ref); + +constructors( + unique int id: @constructor, + string name: string ref, + int declaring_type_id: @type ref, + int unbound_id: @constructor ref); + +constructor_location( + int id: @constructor ref, + int loc: @location ref); + +destructors( + unique int id: @destructor, + string name: string ref, + int declaring_type_id: @type ref, + int unbound_id: @destructor ref); + +destructor_location( + int id: @destructor ref, + int loc: @location ref); + +overrides( + int id: @callable ref, + int base_id: @callable ref); + +explicitly_implements( + int id: @member ref, + int interface_id: @interface_or_ref ref); + +local_functions( + unique int id: @local_function, + string name: string ref, + int return_type: @type ref, + int unbound_id: @local_function ref); + +local_function_stmts( + unique int fn: @local_function_stmt ref, + int stmt: @local_function ref); + +/** VARIABLES **/ + +@variable = @local_scope_variable | @field; + +@local_scope_variable = @local_variable | @parameter; + +fields( + unique int id: @field, + int kind: int ref, + string name: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @field ref); + +case @field.kind of + 1 = @addressable_field +| 2 = @constant + ; + +field_location( + int id: @field ref, + int loc: @location ref); + +localvars( + unique int id: @local_variable, + int kind: int ref, + string name: string ref, + int implicitly_typed: int ref /* 0 = no, 1 = yes */, + int type_id: @type_or_ref ref, + int parent_id: @local_var_decl_expr ref); + +case @local_variable.kind of + 1 = @addressable_local_variable +| 2 = @local_constant +| 3 = @local_variable_ref + ; + +localvar_location( + unique int id: @local_variable ref, + int loc: @location ref); + +@parameterizable = @callable | @delegate_type | @indexer; + +#keyset[name, parent_id] +#keyset[index, parent_id] +params( + unique int id: @parameter, + string name: string ref, + int type_id: @type_or_ref ref, + int index: int ref, + int mode: int ref, /* value = 0, ref = 1, out = 2, array = 3, this = 4 */ + int parent_id: @parameterizable ref, + int unbound_id: @parameter ref); + +param_location( + int id: @parameter ref, + int loc: @location ref); + +/** STATEMENTS **/ + +@exprorstmt_parent = @control_flow_element | @top_level_exprorstmt_parent; + +statements( + unique int id: @stmt, + int kind: int ref); + +#keyset[index, parent] +stmt_parent( + unique int stmt: @stmt ref, + int index: int ref, + int parent: @control_flow_element ref); + +@top_level_stmt_parent = @callable; + +// [index, parent] is not a keyset because the same parent may be compiled multiple times +stmt_parent_top_level( + unique int stmt: @stmt ref, + int index: int ref, + int parent: @top_level_stmt_parent ref); + +case @stmt.kind of + 1 = @block_stmt +| 2 = @expr_stmt +| 3 = @if_stmt +| 4 = @switch_stmt +| 5 = @while_stmt +| 6 = @do_stmt +| 7 = @for_stmt +| 8 = @foreach_stmt +| 9 = @break_stmt +| 10 = @continue_stmt +| 11 = @goto_stmt +| 12 = @goto_case_stmt +| 13 = @goto_default_stmt +| 14 = @throw_stmt +| 15 = @return_stmt +| 16 = @yield_stmt +| 17 = @try_stmt +| 18 = @checked_stmt +| 19 = @unchecked_stmt +| 20 = @lock_stmt +| 21 = @using_block_stmt +| 22 = @var_decl_stmt +| 23 = @const_decl_stmt +| 24 = @empty_stmt +| 25 = @unsafe_stmt +| 26 = @fixed_stmt +| 27 = @label_stmt +| 28 = @catch +| 29 = @case_stmt +| 30 = @local_function_stmt +| 31 = @using_decl_stmt + ; + +@using_stmt = @using_block_stmt | @using_decl_stmt; + +@labeled_stmt = @label_stmt | @case; + +@decl_stmt = @var_decl_stmt | @const_decl_stmt | @using_decl_stmt; + +@cond_stmt = @if_stmt | @switch_stmt; + +@loop_stmt = @while_stmt | @do_stmt | @for_stmt | @foreach_stmt; + +@jump_stmt = @break_stmt | @goto_any_stmt | @continue_stmt | @throw_stmt | @return_stmt + | @yield_stmt; + +@goto_any_stmt = @goto_default_stmt | @goto_case_stmt | @goto_stmt; + + +stmt_location( + unique int id: @stmt ref, + int loc: @location ref); + +catch_type( + unique int catch_id: @catch ref, + int type_id: @type_or_ref ref, + int kind: int ref /* explicit = 1, implicit = 2 */); + +/** EXPRESSIONS **/ + +expressions( + unique int id: @expr, + int kind: int ref, + int type_id: @type_or_ref ref); + +#keyset[index, parent] +expr_parent( + unique int expr: @expr ref, + int index: int ref, + int parent: @control_flow_element ref); + +@top_level_expr_parent = @attribute | @field | @property | @indexer | @parameter; + +@top_level_exprorstmt_parent = @top_level_expr_parent | @top_level_stmt_parent; + +// [index, parent] is not a keyset because the same parent may be compiled multiple times +expr_parent_top_level( + unique int expr: @expr ref, + int index: int ref, + int parent: @top_level_exprorstmt_parent ref); + +case @expr.kind of +/* literal */ + 1 = @bool_literal_expr +| 2 = @char_literal_expr +| 3 = @decimal_literal_expr +| 4 = @int_literal_expr +| 5 = @long_literal_expr +| 6 = @uint_literal_expr +| 7 = @ulong_literal_expr +| 8 = @float_literal_expr +| 9 = @double_literal_expr +| 10 = @string_literal_expr +| 11 = @null_literal_expr +/* primary & unary */ +| 12 = @this_access_expr +| 13 = @base_access_expr +| 14 = @local_variable_access_expr +| 15 = @parameter_access_expr +| 16 = @field_access_expr +| 17 = @property_access_expr +| 18 = @method_access_expr +| 19 = @event_access_expr +| 20 = @indexer_access_expr +| 21 = @array_access_expr +| 22 = @type_access_expr +| 23 = @typeof_expr +| 24 = @method_invocation_expr +| 25 = @delegate_invocation_expr +| 26 = @operator_invocation_expr +| 27 = @cast_expr +| 28 = @object_creation_expr +| 29 = @explicit_delegate_creation_expr +| 30 = @implicit_delegate_creation_expr +| 31 = @array_creation_expr +| 32 = @default_expr +| 33 = @plus_expr +| 34 = @minus_expr +| 35 = @bit_not_expr +| 36 = @log_not_expr +| 37 = @post_incr_expr +| 38 = @post_decr_expr +| 39 = @pre_incr_expr +| 40 = @pre_decr_expr +/* multiplicative */ +| 41 = @mul_expr +| 42 = @div_expr +| 43 = @rem_expr +/* additive */ +| 44 = @add_expr +| 45 = @sub_expr +/* shift */ +| 46 = @lshift_expr +| 47 = @rshift_expr +/* relational */ +| 48 = @lt_expr +| 49 = @gt_expr +| 50 = @le_expr +| 51 = @ge_expr +/* equality */ +| 52 = @eq_expr +| 53 = @ne_expr +/* logical */ +| 54 = @bit_and_expr +| 55 = @bit_xor_expr +| 56 = @bit_or_expr +| 57 = @log_and_expr +| 58 = @log_or_expr +/* type testing */ +| 59 = @is_expr +| 60 = @as_expr +/* null coalescing */ +| 61 = @null_coalescing_expr +/* conditional */ +| 62 = @conditional_expr +/* assignment */ +| 63 = @simple_assign_expr +| 64 = @assign_add_expr +| 65 = @assign_sub_expr +| 66 = @assign_mul_expr +| 67 = @assign_div_expr +| 68 = @assign_rem_expr +| 69 = @assign_and_expr +| 70 = @assign_xor_expr +| 71 = @assign_or_expr +| 72 = @assign_lshift_expr +| 73 = @assign_rshift_expr +/* more */ +| 74 = @object_init_expr +| 75 = @collection_init_expr +| 76 = @array_init_expr +| 77 = @checked_expr +| 78 = @unchecked_expr +| 79 = @constructor_init_expr +| 80 = @add_event_expr +| 81 = @remove_event_expr +| 82 = @par_expr +| 83 = @local_var_decl_expr +| 84 = @lambda_expr +| 85 = @anonymous_method_expr +| 86 = @namespace_expr +/* dynamic */ +| 92 = @dynamic_element_access_expr +| 93 = @dynamic_member_access_expr +/* unsafe */ +| 100 = @pointer_indirection_expr +| 101 = @address_of_expr +| 102 = @sizeof_expr +/* async */ +| 103 = @await_expr +/* C# 6.0 */ +| 104 = @nameof_expr +| 105 = @interpolated_string_expr +| 106 = @unknown_expr +/* C# 7.0 */ +| 107 = @throw_expr +| 108 = @tuple_expr +| 109 = @local_function_invocation_expr +| 110 = @ref_expr +| 111 = @discard_expr +/* C# 8.0 */ +| 112 = @range_expr +| 113 = @index_expr +| 114 = @switch_expr +| 115 = @recursive_pattern_expr +| 116 = @property_pattern_expr +| 117 = @positional_pattern_expr +| 118 = @switch_case_expr +| 119 = @assign_coalesce_expr +| 120 = @suppress_nullable_warning_expr +| 121 = @namespace_access_expr +; + +@switch = @switch_stmt | @switch_expr; +@case = @case_stmt | @switch_case_expr; +@pattern_match = @case | @is_expr; + +@integer_literal_expr = @int_literal_expr | @long_literal_expr | @uint_literal_expr | @ulong_literal_expr; +@real_literal_expr = @float_literal_expr | @double_literal_expr | @decimal_literal_expr; +@literal_expr = @bool_literal_expr | @char_literal_expr | @integer_literal_expr | @real_literal_expr + | @string_literal_expr | @null_literal_expr; + +@assign_expr = @simple_assign_expr | @assign_op_expr | @local_var_decl_expr; +@assign_op_expr = @assign_arith_expr | @assign_bitwise_expr | @assign_event_expr | @assign_coalesce_expr; +@assign_event_expr = @add_event_expr | @remove_event_expr; + +@assign_arith_expr = @assign_add_expr | @assign_sub_expr | @assign_mul_expr | @assign_div_expr + | @assign_rem_expr +@assign_bitwise_expr = @assign_and_expr | @assign_or_expr | @assign_xor_expr + | @assign_lshift_expr | @assign_rshift_expr; + +@member_access_expr = @field_access_expr | @property_access_expr | @indexer_access_expr | @event_access_expr + | @method_access_expr | @type_access_expr | @dynamic_member_access_expr; +@access_expr = @member_access_expr | @this_access_expr | @base_access_expr | @assignable_access_expr | @namespace_access_expr; +@element_access_expr = @indexer_access_expr | @array_access_expr | @dynamic_element_access_expr; + +@local_variable_access = @local_variable_access_expr | @local_var_decl_expr; +@local_scope_variable_access_expr = @parameter_access_expr | @local_variable_access; +@variable_access_expr = @local_scope_variable_access_expr | @field_access_expr; + +@assignable_access_expr = @variable_access_expr | @property_access_expr | @element_access_expr + | @event_access_expr | @dynamic_member_access_expr; + +@objectorcollection_init_expr = @object_init_expr | @collection_init_expr; + +@delegate_creation_expr = @explicit_delegate_creation_expr | @implicit_delegate_creation_expr; + +@bin_arith_op_expr = @mul_expr | @div_expr | @rem_expr | @add_expr | @sub_expr; +@incr_op_expr = @pre_incr_expr | @post_incr_expr; +@decr_op_expr = @pre_decr_expr | @post_decr_expr; +@mut_op_expr = @incr_op_expr | @decr_op_expr; +@un_arith_op_expr = @plus_expr | @minus_expr | @mut_op_expr; +@arith_op_expr = @bin_arith_op_expr | @un_arith_op_expr; + +@ternary_log_op_expr = @conditional_expr; +@bin_log_op_expr = @log_and_expr | @log_or_expr | @null_coalescing_expr; +@un_log_op_expr = @log_not_expr; +@log_expr = @un_log_op_expr | @bin_log_op_expr | @ternary_log_op_expr; + +@bin_bit_op_expr = @bit_and_expr | @bit_or_expr | @bit_xor_expr | @lshift_expr + | @rshift_expr; +@un_bit_op_expr = @bit_not_expr; +@bit_expr = @un_bit_op_expr | @bin_bit_op_expr; + +@equality_op_expr = @eq_expr | @ne_expr; +@rel_op_expr = @gt_expr | @lt_expr| @ge_expr | @le_expr; +@comp_expr = @equality_op_expr | @rel_op_expr; + +@op_expr = @assign_expr | @un_op | @bin_op | @ternary_op; + +@ternary_op = @ternary_log_op_expr; +@bin_op = @bin_arith_op_expr | @bin_log_op_expr | @bin_bit_op_expr | @comp_expr; +@un_op = @un_arith_op_expr | @un_log_op_expr | @un_bit_op_expr | @sizeof_expr + | @pointer_indirection_expr | @address_of_expr; + +@anonymous_function_expr = @lambda_expr | @anonymous_method_expr; + +@call = @method_invocation_expr | @constructor_init_expr | @operator_invocation_expr + | @delegate_invocation_expr | @object_creation_expr | @call_access_expr + | @local_function_invocation_expr; + +@call_access_expr = @property_access_expr | @event_access_expr | @indexer_access_expr; + +@late_bindable_expr = @dynamic_element_access_expr | @dynamic_member_access_expr + | @object_creation_expr | @method_invocation_expr | @operator_invocation_expr; + +@throw_element = @throw_expr | @throw_stmt; + +@implicitly_typeable_object_creation_expr = @object_creation_expr | @explicit_delegate_creation_expr; + +implicitly_typed_array_creation( + unique int id: @array_creation_expr ref); + +explicitly_sized_array_creation( + unique int id: @array_creation_expr ref); + +stackalloc_array_creation( + unique int id: @array_creation_expr ref); + +implicitly_typed_object_creation( + unique int id: @implicitly_typeable_object_creation_expr ref); + +mutator_invocation_mode( + unique int id: @operator_invocation_expr ref, + int mode: int ref /* prefix = 1, postfix = 2*/); + +expr_compiler_generated( + unique int id: @expr ref); + +expr_value( + unique int id: @expr ref, + string value: string ref); + +expr_call( + unique int caller_id: @expr ref, + int target_id: @callable ref); + +expr_access( + unique int accesser_id: @access_expr ref, + int target_id: @accessible ref); + +@accessible = @method | @assignable | @local_function | @namespace; + +expr_location( + unique int id: @expr ref, + int loc: @location ref); + +dynamic_member_name( + unique int id: @late_bindable_expr ref, + string name: string ref); + +@qualifiable_expr = @member_access_expr + | @method_invocation_expr + | @element_access_expr; + +conditional_access( + unique int id: @qualifiable_expr ref); + +expr_argument( + unique int id: @expr ref, + int mode: int ref); + /* mode is the same as params: value = 0, ref = 1, out = 2 */ + +expr_argument_name( + unique int id: @expr ref, + string name: string ref); + +/** CONTROL/DATA FLOW **/ + +@control_flow_element = @stmt | @expr; + +/* XML Files */ + +xmlEncoding ( + unique int id: @file ref, + string encoding: string ref); + +xmlDTDs( + unique int id: @xmldtd, + string root: string ref, + string publicId: string ref, + string systemId: string ref, + int fileid: @file ref); + +xmlElements( + unique int id: @xmlelement, + string name: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int fileid: @file ref); + +xmlAttrs( + unique int id: @xmlattribute, + int elementid: @xmlelement ref, + string name: string ref, + string value: string ref, + int idx: int ref, + int fileid: @file ref); + +xmlNs( + int id: @xmlnamespace, + string prefixName: string ref, + string URI: string ref, + int fileid: @file ref); + +xmlHasNs( + int elementId: @xmlnamespaceable ref, + int nsId: @xmlnamespace ref, + int fileid: @file ref); + +xmlComments( + unique int id: @xmlcomment, + string text: string ref, + int parentid: @xmlparent ref, + int fileid: @file ref); + +xmlChars( + unique int id: @xmlcharacters, + string text: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int isCDATA: int ref, + int fileid: @file ref); + +@xmlparent = @file | @xmlelement; +@xmlnamespaceable = @xmlelement | @xmlattribute; + +xmllocations( + int xmlElement: @xmllocatable ref, + int location: @location_default ref); + +@xmllocatable = @xmlcharacters | @xmlelement | @xmlcomment | @xmlattribute | @xmldtd | @file | @xmlnamespace; + +/* Comments */ + +commentline( + unique int id: @commentline, + int kind: int ref, + string text: string ref, + string rawtext: string ref); + +case @commentline.kind of + 0 = @singlelinecomment +| 1 = @xmldoccomment +| 2 = @multilinecomment; + +commentline_location( + unique int id: @commentline ref, + int loc: @location ref); + +commentblock( + unique int id : @commentblock); + +commentblock_location( + unique int id: @commentblock ref, + int loc: @location ref); + +commentblock_binding( + int id: @commentblock ref, + int entity: @element ref, + int bindtype: int ref); /* 0: Parent, 1: Best, 2: Before, 3: After */ + +commentblock_child( + int id: @commentblock ref, + int commentline: @commentline ref, + int index: int ref); + +/* ASP.NET */ + +case @asp_element.kind of + 0=@asp_close_tag +| 1=@asp_code +| 2=@asp_comment +| 3=@asp_data_binding +| 4=@asp_directive +| 5=@asp_open_tag +| 6=@asp_quoted_string +| 7=@asp_text +| 8=@asp_xml_directive; + +@asp_attribute = @asp_code | @asp_data_binding | @asp_quoted_string; + +asp_elements( + unique int id: @asp_element, + int kind: int ref, + int loc: @location ref); + +asp_comment_server(unique int comment: @asp_comment ref); +asp_code_inline(unique int code: @asp_code ref); +asp_directive_attribute( + int directive: @asp_directive ref, + int index: int ref, + string name: string ref, + int value: @asp_quoted_string ref); +asp_directive_name( + unique int directive: @asp_directive ref, + string name: string ref); +asp_element_body( + unique int element: @asp_element ref, + string body: string ref); +asp_tag_attribute( + int tag: @asp_open_tag ref, + int index: int ref, + string name: string ref, + int attribute: @asp_attribute ref); +asp_tag_name( + unique int tag: @asp_open_tag ref, + string name: string ref); +asp_tag_isempty(int tag: @asp_open_tag ref); + +/* Common Intermediate Language - CIL */ + +case @cil_instruction.opcode of + 0 = @cil_nop +| 1 = @cil_break +| 2 = @cil_ldarg_0 +| 3 = @cil_ldarg_1 +| 4 = @cil_ldarg_2 +| 5 = @cil_ldarg_3 +| 6 = @cil_ldloc_0 +| 7 = @cil_ldloc_1 +| 8 = @cil_ldloc_2 +| 9 = @cil_ldloc_3 +| 10 = @cil_stloc_0 +| 11 = @cil_stloc_1 +| 12 = @cil_stloc_2 +| 13 = @cil_stloc_3 +| 14 = @cil_ldarg_s +| 15 = @cil_ldarga_s +| 16 = @cil_starg_s +| 17 = @cil_ldloc_s +| 18 = @cil_ldloca_s +| 19 = @cil_stloc_s +| 20 = @cil_ldnull +| 21 = @cil_ldc_i4_m1 +| 22 = @cil_ldc_i4_0 +| 23 = @cil_ldc_i4_1 +| 24 = @cil_ldc_i4_2 +| 25 = @cil_ldc_i4_3 +| 26 = @cil_ldc_i4_4 +| 27 = @cil_ldc_i4_5 +| 28 = @cil_ldc_i4_6 +| 29 = @cil_ldc_i4_7 +| 30 = @cil_ldc_i4_8 +| 31 = @cil_ldc_i4_s +| 32 = @cil_ldc_i4 +| 33 = @cil_ldc_i8 +| 34 = @cil_ldc_r4 +| 35 = @cil_ldc_r8 +| 37 = @cil_dup +| 38 = @cil_pop +| 39 = @cil_jmp +| 40 = @cil_call +| 41 = @cil_calli +| 42 = @cil_ret +| 43 = @cil_br_s +| 44 = @cil_brfalse_s +| 45 = @cil_brtrue_s +| 46 = @cil_beq_s +| 47 = @cil_bge_s +| 48 = @cil_bgt_s +| 49 = @cil_ble_s +| 50 = @cil_blt_s +| 51 = @cil_bne_un_s +| 52 = @cil_bge_un_s +| 53 = @cil_bgt_un_s +| 54 = @cil_ble_un_s +| 55 = @cil_blt_un_s +| 56 = @cil_br +| 57 = @cil_brfalse +| 58 = @cil_brtrue +| 59 = @cil_beq +| 60 = @cil_bge +| 61 = @cil_bgt +| 62 = @cil_ble +| 63 = @cil_blt +| 64 = @cil_bne_un +| 65 = @cil_bge_un +| 66 = @cil_bgt_un +| 67 = @cil_ble_un +| 68 = @cil_blt_un +| 69 = @cil_switch +| 70 = @cil_ldind_i1 +| 71 = @cil_ldind_u1 +| 72 = @cil_ldind_i2 +| 73 = @cil_ldind_u2 +| 74 = @cil_ldind_i4 +| 75 = @cil_ldind_u4 +| 76 = @cil_ldind_i8 +| 77 = @cil_ldind_i +| 78 = @cil_ldind_r4 +| 79 = @cil_ldind_r8 +| 80 = @cil_ldind_ref +| 81 = @cil_stind_ref +| 82 = @cil_stind_i1 +| 83 = @cil_stind_i2 +| 84 = @cil_stind_i4 +| 85 = @cil_stind_i8 +| 86 = @cil_stind_r4 +| 87 = @cil_stind_r8 +| 88 = @cil_add +| 89 = @cil_sub +| 90 = @cil_mul +| 91 = @cil_div +| 92 = @cil_div_un +| 93 = @cil_rem +| 94 = @cil_rem_un +| 95 = @cil_and +| 96 = @cil_or +| 97 = @cil_xor +| 98 = @cil_shl +| 99 = @cil_shr +| 100 = @cil_shr_un +| 101 = @cil_neg +| 102 = @cil_not +| 103 = @cil_conv_i1 +| 104 = @cil_conv_i2 +| 105 = @cil_conv_i4 +| 106 = @cil_conv_i8 +| 107 = @cil_conv_r4 +| 108 = @cil_conv_r8 +| 109 = @cil_conv_u4 +| 110 = @cil_conv_u8 +| 111 = @cil_callvirt +| 112 = @cil_cpobj +| 113 = @cil_ldobj +| 114 = @cil_ldstr +| 115 = @cil_newobj +| 116 = @cil_castclass +| 117 = @cil_isinst +| 118 = @cil_conv_r_un +| 121 = @cil_unbox +| 122 = @cil_throw +| 123 = @cil_ldfld +| 124 = @cil_ldflda +| 125 = @cil_stfld +| 126 = @cil_ldsfld +| 127 = @cil_ldsflda +| 128 = @cil_stsfld +| 129 = @cil_stobj +| 130 = @cil_conv_ovf_i1_un +| 131 = @cil_conv_ovf_i2_un +| 132 = @cil_conv_ovf_i4_un +| 133 = @cil_conv_ovf_i8_un +| 134 = @cil_conv_ovf_u1_un +| 135 = @cil_conv_ovf_u2_un +| 136 = @cil_conv_ovf_u4_un +| 137 = @cil_conv_ovf_u8_un +| 138 = @cil_conv_ovf_i_un +| 139 = @cil_conv_ovf_u_un +| 140 = @cil_box +| 141 = @cil_newarr +| 142 = @cil_ldlen +| 143 = @cil_ldelema +| 144 = @cil_ldelem_i1 +| 145 = @cil_ldelem_u1 +| 146 = @cil_ldelem_i2 +| 147 = @cil_ldelem_u2 +| 148 = @cil_ldelem_i4 +| 149 = @cil_ldelem_u4 +| 150 = @cil_ldelem_i8 +| 151 = @cil_ldelem_i +| 152 = @cil_ldelem_r4 +| 153 = @cil_ldelem_r8 +| 154 = @cil_ldelem_ref +| 155 = @cil_stelem_i +| 156 = @cil_stelem_i1 +| 157 = @cil_stelem_i2 +| 158 = @cil_stelem_i4 +| 159 = @cil_stelem_i8 +| 160 = @cil_stelem_r4 +| 161 = @cil_stelem_r8 +| 162 = @cil_stelem_ref +| 163 = @cil_ldelem +| 164 = @cil_stelem +| 165 = @cil_unbox_any +| 179 = @cil_conv_ovf_i1 +| 180 = @cil_conv_ovf_u1 +| 181 = @cil_conv_ovf_i2 +| 182 = @cil_conv_ovf_u2 +| 183 = @cil_conv_ovf_i4 +| 184 = @cil_conv_ovf_u4 +| 185 = @cil_conv_ovf_i8 +| 186 = @cil_conv_ovf_u8 +| 194 = @cil_refanyval +| 195 = @cil_ckinfinite +| 198 = @cil_mkrefany +| 208 = @cil_ldtoken +| 209 = @cil_conv_u2 +| 210 = @cil_conv_u1 +| 211 = @cil_conv_i +| 212 = @cil_conv_ovf_i +| 213 = @cil_conv_ovf_u +| 214 = @cil_add_ovf +| 215 = @cil_add_ovf_un +| 216 = @cil_mul_ovf +| 217 = @cil_mul_ovf_un +| 218 = @cil_sub_ovf +| 219 = @cil_sub_ovf_un +| 220 = @cil_endfinally +| 221 = @cil_leave +| 222 = @cil_leave_s +| 223 = @cil_stind_i +| 224 = @cil_conv_u +| 65024 = @cil_arglist +| 65025 = @cil_ceq +| 65026 = @cil_cgt +| 65027 = @cil_cgt_un +| 65028 = @cil_clt +| 65029 = @cil_clt_un +| 65030 = @cil_ldftn +| 65031 = @cil_ldvirtftn +| 65033 = @cil_ldarg +| 65034 = @cil_ldarga +| 65035 = @cil_starg +| 65036 = @cil_ldloc +| 65037 = @cil_ldloca +| 65038 = @cil_stloc +| 65039 = @cil_localloc +| 65041 = @cil_endfilter +| 65042 = @cil_unaligned +| 65043 = @cil_volatile +| 65044 = @cil_tail +| 65045 = @cil_initobj +| 65046 = @cil_constrained +| 65047 = @cil_cpblk +| 65048 = @cil_initblk +| 65050 = @cil_rethrow +| 65052 = @cil_sizeof +| 65053 = @cil_refanytype +| 65054 = @cil_readonly +; + +// CIL ignored instructions + +@cil_ignore = @cil_nop | @cil_break | @cil_volatile | @cil_unaligned; + +// CIL local/parameter/field access + +@cil_ldarg_any = @cil_ldarg_0 | @cil_ldarg_1 | @cil_ldarg_2 | @cil_ldarg_3 | @cil_ldarg_s | @cil_ldarga_s | @cil_ldarg | @cil_ldarga; +@cil_starg_any = @cil_starg | @cil_starg_s; + +@cil_ldloc_any = @cil_ldloc_0 | @cil_ldloc_1 | @cil_ldloc_2 | @cil_ldloc_3 | @cil_ldloc_s | @cil_ldloca_s | @cil_ldloc | @cil_ldloca; +@cil_stloc_any = @cil_stloc_0 | @cil_stloc_1 | @cil_stloc_2 | @cil_stloc_3 | @cil_stloc_s | @cil_stloc; + +@cil_ldfld_any = @cil_ldfld | @cil_ldsfld | @cil_ldsflda | @cil_ldflda; +@cil_stfld_any = @cil_stfld | @cil_stsfld; + +@cil_local_access = @cil_stloc_any | @cil_ldloc_any; +@cil_arg_access = @cil_starg_any | @cil_ldarg_any; +@cil_read_access = @cil_ldloc_any | @cil_ldarg_any | @cil_ldfld_any; +@cil_write_access = @cil_stloc_any | @cil_starg_any | @cil_stfld_any; + +@cil_stack_access = @cil_local_access | @cil_arg_access; +@cil_field_access = @cil_ldfld_any | @cil_stfld_any; + +@cil_access = @cil_read_access | @cil_write_access; + +// CIL constant/literal instructions + +@cil_ldc_i = @cil_ldc_i4_any | @cil_ldc_i8; + +@cil_ldc_i4_any = @cil_ldc_i4_m1 | @cil_ldc_i4_0 | @cil_ldc_i4_1 | @cil_ldc_i4_2 | @cil_ldc_i4_3 | + @cil_ldc_i4_4 | @cil_ldc_i4_5 | @cil_ldc_i4_6 | @cil_ldc_i4_7 | @cil_ldc_i4_8 | @cil_ldc_i4_s | @cil_ldc_i4; + +@cil_ldc_r = @cil_ldc_r4 | @cil_ldc_r8; + +@cil_literal = @cil_ldnull | @cil_ldc_i | @cil_ldc_r | @cil_ldstr; + +// Control flow + +@cil_conditional_jump = @cil_binary_jump | @cil_unary_jump; +@cil_binary_jump = @cil_beq_s | @cil_bge_s | @cil_bgt_s | @cil_ble_s | @cil_blt_s | + @cil_bne_un_s | @cil_bge_un_s | @cil_bgt_un_s | @cil_ble_un_s | @cil_blt_un_s | + @cil_beq | @cil_bge | @cil_bgt | @cil_ble | @cil_blt | + @cil_bne_un | @cil_bge_un | @cil_bgt_un | @cil_ble_un | @cil_blt_un; +@cil_unary_jump = @cil_brfalse_s | @cil_brtrue_s | @cil_brfalse | @cil_brtrue | @cil_switch; +@cil_unconditional_jump = @cil_br | @cil_br_s | @cil_leave_any; +@cil_leave_any = @cil_leave | @cil_leave_s; +@cil_jump = @cil_unconditional_jump | @cil_conditional_jump; + +// CIL call instructions + +@cil_call_any = @cil_jmp | @cil_call | @cil_calli | @cil_tail | @cil_callvirt | @cil_newobj; + +// CIL expression instructions + +@cil_expr = @cil_literal | @cil_binary_expr | @cil_unary_expr | @cil_call_any | @cil_read_access | + @cil_newarr | @cil_ldtoken | @cil_sizeof | + @cil_ldftn | @cil_ldvirtftn | @cil_localloc | @cil_mkrefany | @cil_refanytype | @cil_arglist | @cil_dup; + +@cil_unary_expr = + @cil_conversion_operation | @cil_unary_arithmetic_operation | @cil_unary_bitwise_operation| + @cil_ldlen | @cil_isinst | @cil_box | @cil_ldobj | @cil_castclass | @cil_unbox_any | + @cil_ldind | @cil_unbox; + +@cil_conversion_operation = + @cil_conv_i1 | @cil_conv_i2 | @cil_conv_i4 | @cil_conv_i8 | + @cil_conv_u1 | @cil_conv_u2 | @cil_conv_u4 | @cil_conv_u8 | + @cil_conv_ovf_i | @cil_conv_ovf_i_un | @cil_conv_ovf_i1 | @cil_conv_ovf_i1_un | + @cil_conv_ovf_i2 | @cil_conv_ovf_i2_un | @cil_conv_ovf_i4 | @cil_conv_ovf_i4_un | + @cil_conv_ovf_i8 | @cil_conv_ovf_i8_un | @cil_conv_ovf_u | @cil_conv_ovf_u_un | + @cil_conv_ovf_u1 | @cil_conv_ovf_u1_un | @cil_conv_ovf_u2 | @cil_conv_ovf_u2_un | + @cil_conv_ovf_u4 | @cil_conv_ovf_u4_un | @cil_conv_ovf_u8 | @cil_conv_ovf_u8_un | + @cil_conv_r4 | @cil_conv_r8 | @cil_conv_ovf_u2 | @cil_conv_ovf_u2_un | + @cil_conv_i | @cil_conv_u | @cil_conv_r_un; + +@cil_ldind = @cil_ldind_i | @cil_ldind_i1 | @cil_ldind_i2 | @cil_ldind_i4 | @cil_ldind_i8 | + @cil_ldind_r4 | @cil_ldind_r8 | @cil_ldind_ref | @cil_ldind_u1 | @cil_ldind_u2 | @cil_ldind_u4; + +@cil_stind = @cil_stind_i | @cil_stind_i1 | @cil_stind_i2 | @cil_stind_i4 | @cil_stind_i8 | + @cil_stind_r4 | @cil_stind_r8 | @cil_stind_ref; + +@cil_bitwise_operation = @cil_binary_bitwise_operation | @cil_unary_bitwise_operation; + +@cil_binary_bitwise_operation = @cil_and | @cil_or | @cil_xor | @cil_shr | @cil_shr | @cil_shr_un | @cil_shl; + +@cil_binary_arithmetic_operation = @cil_add | @cil_sub | @cil_mul | @cil_div | @cil_div_un | + @cil_rem | @cil_rem_un | @cil_add_ovf | @cil_add_ovf_un | @cil_mul_ovf | @cil_mul_ovf_un | + @cil_sub_ovf | @cil_sub_ovf_un; + +@cil_unary_bitwise_operation = @cil_not; + +@cil_binary_expr = @cil_binary_arithmetic_operation | @cil_binary_bitwise_operation | @cil_read_array | @cil_comparison_operation; + +@cil_unary_arithmetic_operation = @cil_neg; + +@cil_comparison_operation = @cil_cgt_un | @cil_ceq | @cil_cgt | @cil_clt | @cil_clt_un; + +// Elements that retrieve an address of something +@cil_read_ref = @cil_ldloca_s | @cil_ldarga_s | @cil_ldflda | @cil_ldsflda | @cil_ldelema; + +// CIL array instructions + +@cil_read_array = + @cil_ldelem | @cil_ldelema | @cil_ldelem_i1 | @cil_ldelem_ref | @cil_ldelem_i | + @cil_ldelem_i1 | @cil_ldelem_i2 | @cil_ldelem_i4 | @cil_ldelem_i8 | @cil_ldelem_r4 | + @cil_ldelem_r8 | @cil_ldelem_u1 | @cil_ldelem_u2 | @cil_ldelem_u4; + +@cil_write_array = @cil_stelem | @cil_stelem_ref | + @cil_stelem_i | @cil_stelem_i1 | @cil_stelem_i2 | @cil_stelem_i4 | @cil_stelem_i8 | + @cil_stelem_r4 | @cil_stelem_r8; + +@cil_throw_any = @cil_throw | @cil_rethrow; + +#keyset[impl, index] +cil_instruction( + unique int id: @cil_instruction, + int opcode: int ref, + int index: int ref, + int impl: @cil_method_implementation ref); + +cil_jump( + unique int instruction: @cil_jump ref, + int target: @cil_instruction ref); + +cil_access( + unique int instruction: @cil_instruction ref, + int target: @cil_accessible ref); + +cil_value( + unique int instruction: @cil_literal ref, + string value: string ref); + +#keyset[instruction, index] +cil_switch( + int instruction: @cil_switch ref, + int index: int ref, + int target: @cil_instruction ref); + +cil_instruction_location( + unique int id: @cil_instruction ref, + int loc: @location ref); + +cil_type_location( + int id: @cil_type ref, + int loc: @location ref); + +cil_method_location( + int id: @cil_method ref, + int loc: @location ref); + +@cil_namespace = @namespace; + +@cil_type_container = @cil_type | @cil_namespace | @cil_method; + +case @cil_type.kind of + 0 = @cil_valueorreftype +| 1 = @cil_typeparameter +| 2 = @cil_array_type +| 3 = @cil_pointer_type +; + +cil_type( + unique int id: @cil_type, + string name: string ref, + int kind: int ref, + int parent: @cil_type_container ref, + int sourceDecl: @cil_type ref); + +cil_pointer_type( + unique int id: @cil_pointer_type ref, + int pointee: @cil_type ref); + +cil_array_type( + unique int id: @cil_array_type ref, + int element_type: @cil_type ref, + int rank: int ref); + +cil_method( + unique int id: @cil_method, + string name: string ref, + int parent: @cil_type ref, + int return_type: @cil_type ref); + +cil_method_source_declaration( + unique int method: @cil_method ref, + int source: @cil_method ref); + +cil_method_implementation( + unique int id: @cil_method_implementation, + int method: @cil_method ref, + int location: @assembly ref); + +cil_implements( + int id: @cil_method ref, + int decl: @cil_method ref); + +#keyset[parent, name] +cil_field( + unique int id: @cil_field, + int parent: @cil_type ref, + string name: string ref, + int field_type: @cil_type ref); + +@cil_element = @cil_instruction | @cil_declaration | @cil_handler | @cil_attribute | @cil_namespace; +@cil_named_element = @cil_declaration | @cil_namespace; +@cil_declaration = @cil_variable | @cil_method | @cil_type | @cil_member; +@cil_accessible = @cil_declaration; +@cil_variable = @cil_field | @cil_stack_variable; +@cil_stack_variable = @cil_local_variable | @cil_parameter; +@cil_member = @cil_method | @cil_type | @cil_field | @cil_property | @cil_event; + +#keyset[method, index] +cil_parameter( + unique int id: @cil_parameter, + int method: @cil_method ref, + int index: int ref, + int param_type: @cil_type ref); + +cil_parameter_in(unique int id: @cil_parameter ref); +cil_parameter_out(unique int id: @cil_parameter ref); + +cil_setter(unique int prop: @cil_property ref, + int method: @cil_method ref); + +cil_getter(unique int prop: @cil_property ref, + int method: @cil_method ref); + +cil_adder(unique int event: @cil_event ref, + int method: @cil_method ref); + +cil_remover(unique int event: @cil_event ref, int method: @cil_method ref); + +cil_raiser(unique int event: @cil_event ref, int method: @cil_method ref); + +cil_property( + unique int id: @cil_property, + int parent: @cil_type ref, + string name: string ref, + int property_type: @cil_type ref); + +#keyset[parent, name] +cil_event(unique int id: @cil_event, + int parent: @cil_type ref, + string name: string ref, + int event_type: @cil_type ref); + +#keyset[impl, index] +cil_local_variable( + unique int id: @cil_local_variable, + int impl: @cil_method_implementation ref, + int index: int ref, + int var_type: @cil_type ref); + +// CIL handlers (exception handlers etc). + +case @cil_handler.kind of + 0 = @cil_catch_handler +| 1 = @cil_filter_handler +| 2 = @cil_finally_handler +| 4 = @cil_fault_handler +; + +#keyset[impl, index] +cil_handler( + unique int id: @cil_handler, + int impl: @cil_method_implementation ref, + int index: int ref, + int kind: int ref, + int try_start: @cil_instruction ref, + int try_end: @cil_instruction ref, + int handler_start: @cil_instruction ref); + +cil_handler_filter( + unique int id: @cil_handler ref, + int filter_start: @cil_instruction ref); + +cil_handler_type( + unique int id: @cil_handler ref, + int catch_type: @cil_type ref); + +@cil_controlflow_node = @cil_entry_point | @cil_instruction; + +@cil_entry_point = @cil_method_implementation | @cil_handler; + +@cil_dataflow_node = @cil_instruction | @cil_variable | @cil_method; + +cil_method_stack_size( + unique int method: @cil_method_implementation ref, + int size: int ref); + +// CIL modifiers + +cil_public(int id: @cil_member ref); +cil_private(int id: @cil_member ref); +cil_protected(int id: @cil_member ref); +cil_internal(int id: @cil_member ref); +cil_static(int id: @cil_member ref); +cil_sealed(int id: @cil_member ref); +cil_virtual(int id: @cil_method ref); +cil_abstract(int id: @cil_member ref); +cil_class(int id: @cil_type ref); +cil_interface(int id: @cil_type ref); +cil_security(int id: @cil_member ref); +cil_requiresecobject(int id: @cil_method ref); +cil_specialname(int id: @cil_method ref); +cil_newslot(int id: @cil_method ref); + +cil_base_class(unique int id: @cil_type ref, int base: @cil_type ref); +cil_base_interface(int id: @cil_type ref, int base: @cil_type ref); +cil_enum_underlying_type(unique int id: @cil_type ref, int underlying: @cil_type ref); + +#keyset[unbound, index] +cil_type_parameter( + int unbound: @cil_member ref, + int index: int ref, + int param: @cil_typeparameter ref); + +#keyset[bound, index] +cil_type_argument( + int bound: @cil_member ref, + int index: int ref, + int t: @cil_type ref); + +// CIL type parameter constraints + +cil_typeparam_covariant(int tp: @cil_typeparameter ref); +cil_typeparam_contravariant(int tp: @cil_typeparameter ref); +cil_typeparam_class(int tp: @cil_typeparameter ref); +cil_typeparam_struct(int tp: @cil_typeparameter ref); +cil_typeparam_new(int tp: @cil_typeparameter ref); +cil_typeparam_constraint(int tp: @cil_typeparameter ref, int supertype: @cil_type ref); + +// CIL attributes + +cil_attribute( + unique int attributeid: @cil_attribute, + int element: @cil_declaration ref, + int constructor: @cil_method ref); + +#keyset[attribute_id, param] +cil_attribute_named_argument( + int attribute_id: @cil_attribute ref, + string param: string ref, + string value: string ref); + +#keyset[attribute_id, index] +cil_attribute_positional_argument( + int attribute_id: @cil_attribute ref, + int index: int ref, + string value: string ref); + + +// Common .Net data model covering both C# and CIL + +// Common elements +@dotnet_element = @element | @cil_element; +@dotnet_named_element = @named_element | @cil_named_element; +@dotnet_callable = @callable | @cil_method; +@dotnet_variable = @variable | @cil_variable; +@dotnet_field = @field | @cil_field; +@dotnet_parameter = @parameter | @cil_parameter; +@dotnet_declaration = @declaration | @cil_declaration; +@dotnet_member = @member | @cil_member; +@dotnet_event = @event | @cil_event; +@dotnet_property = @property | @cil_property | @indexer; + +// Common types +@dotnet_type = @type | @cil_type; +@dotnet_call = @call | @cil_call_any; +@dotnet_throw = @throw_element | @cil_throw_any; +@dotnet_valueorreftype = @cil_valueorreftype | @value_or_ref_type | @cil_array_type | @void_type; +@dotnet_typeparameter = @type_parameter | @cil_typeparameter; +@dotnet_array_type = @array_type | @cil_array_type; +@dotnet_pointer_type = @pointer_type | @cil_pointer_type; +@dotnet_type_parameter = @type_parameter | @cil_typeparameter; +@dotnet_generic = @dotnet_valueorreftype | @dotnet_callable; + +// Attributes +@dotnet_attribute = @attribute | @cil_attribute; + +// Expressions +@dotnet_expr = @expr | @cil_expr; + +// Literals +@dotnet_literal = @literal_expr | @cil_literal; +@dotnet_string_literal = @string_literal_expr | @cil_ldstr; +@dotnet_int_literal = @integer_literal_expr | @cil_ldc_i; +@dotnet_float_literal = @float_literal_expr | @cil_ldc_r; +@dotnet_null_literal = @null_literal_expr | @cil_ldnull; + +@metadata_entity = @cil_method | @cil_type | @cil_field | @cil_property | @field | @property | + @callable | @value_or_ref_type | @void_type; + +#keyset[entity, location] +metadata_handle(int entity : @metadata_entity ref, int location: @assembly ref, int handle: int ref) diff --git a/csharp/upgrades/b93e202508f21bdf2e0d831e464c3b14187378cc/upgrade.properties b/csharp/upgrades/b93e202508f21bdf2e0d831e464c3b14187378cc/upgrade.properties new file mode 100644 index 00000000000..3cd65f1ce23 --- /dev/null +++ b/csharp/upgrades/b93e202508f21bdf2e0d831e464c3b14187378cc/upgrade.properties @@ -0,0 +1,2 @@ +description: Added 'implicitly_typed_object_creation' and 'implicitly_typeable_object_creation_expr'. +compatibility: backwards diff --git a/csharp/upgrades/cfaa4e90da23a5ca3f0e914fbd5ca689ba0282d9/old.dbscheme b/csharp/upgrades/cfaa4e90da23a5ca3f0e914fbd5ca689ba0282d9/old.dbscheme new file mode 100644 index 00000000000..cfaa4e90da2 --- /dev/null +++ b/csharp/upgrades/cfaa4e90da23a5ca3f0e914fbd5ca689ba0282d9/old.dbscheme @@ -0,0 +1,1891 @@ + +/** + * An invocation of the compiler. Note that more than one file may be + * compiled per invocation. For example, this command compiles three + * source files: + * + * csc f1.cs f2.cs f3.cs + * + * The `id` simply identifies the invocation, while `cwd` is the working + * directory from which the compiler was invoked. + */ +compilations( + unique int id : @compilation, + string cwd : string ref +); + +/** + * The arguments that were passed to the extractor for a compiler + * invocation. If `id` is for the compiler invocation + * + * csc f1.cs f2.cs f3.cs + * + * then typically there will be rows for + * + * num | arg + * --- | --- + * 0 | --compiler + * 1 | *path to compiler* + * 2 | --cil + * 3 | f1.cs + * 4 | f2.cs + * 5 | f3.cs + */ +#keyset[id, num] +compilation_args( + int id : @compilation ref, + int num : int ref, + string arg : string ref +); + +/** + * The source files that are compiled by a compiler invocation. + * If `id` is for the compiler invocation + * + * csc f1.cs f2.cs f3.cs + * + * then there will be rows for + * + * num | arg + * --- | --- + * 0 | f1.cs + * 1 | f2.cs + * 2 | f3.cs + */ +#keyset[id, num] +compilation_compiling_files( + int id : @compilation ref, + int num : int ref, + int file : @file ref +); + +/** + * The references used by a compiler invocation. + * If `id` is for the compiler invocation + * + * csc f1.cs f2.cs f3.cs /r:ref1.dll /r:ref2.dll /r:ref3.dll + * + * then there will be rows for + * + * num | arg + * --- | --- + * 0 | ref1.dll + * 1 | ref2.dll + * 2 | ref3.dll + */ +#keyset[id, num] +compilation_referencing_files( + int id : @compilation ref, + int num : int ref, + int file : @file ref +); + +/** + * The time taken by the extractor for a compiler invocation. + * + * For each file `num`, there will be rows for + * + * kind | seconds + * ---- | --- + * 1 | CPU seconds used by the extractor frontend + * 2 | Elapsed seconds during the extractor frontend + * 3 | CPU seconds used by the extractor backend + * 4 | Elapsed seconds during the extractor backend + */ +#keyset[id, num, kind] +compilation_time( + int id : @compilation ref, + int num : int ref, + /* kind: + 1 = frontend_cpu_seconds + 2 = frontend_elapsed_seconds + 3 = extractor_cpu_seconds + 4 = extractor_elapsed_seconds + */ + int kind : int ref, + float seconds : float ref +); + +/** + * An error or warning generated by the extractor. + * The diagnostic message `diagnostic` was generated during compiler + * invocation `compilation`, and is the `file_number_diagnostic_number`th + * message generated while extracting the `file_number`th file of that + * invocation. + */ +#keyset[compilation, file_number, file_number_diagnostic_number] +diagnostic_for( + unique int diagnostic : @diagnostic ref, + int compilation : @compilation ref, + int file_number : int ref, + int file_number_diagnostic_number : int ref +); + +diagnostics( + unique int id: @diagnostic, + int severity: int ref, + string error_tag: string ref, + string error_message: string ref, + string full_error_message: string ref, + int location: @location_default ref +); + +extractor_messages( + unique int id: @extractor_message, + int severity: int ref, + string origin : string ref, + string text : string ref, + string entity : string ref, + int location: @location_default ref, + string stack_trace : string ref +); + +/** + * If extraction was successful, then `cpu_seconds` and + * `elapsed_seconds` are the CPU time and elapsed time (respectively) + * that extraction took for compiler invocation `id`. + */ +compilation_finished( + unique int id : @compilation ref, + float cpu_seconds : float ref, + float elapsed_seconds : float ref +); + +/* + * External artifacts + */ + +externalDefects( + unique int id: @externalDefect, + string queryPath: string ref, + int location: @location ref, + string message: string ref, + float severity: float ref); + +externalMetrics( + unique int id: @externalMetric, + string queryPath: string ref, + int location: @location ref, + float value: float ref); + +externalData( + int id: @externalDataElement, + string path: string ref, + int column: int ref, + string value: string ref); + +snapshotDate( + unique date snapshotDate: date ref); + +sourceLocationPrefix( + string prefix: string ref); + +/* + * Duplicate code + */ + +duplicateCode( + unique int id: @duplication, + string relativePath: string ref, + int equivClass: int ref); + +similarCode( + unique int id: @similarity, + string relativePath: string ref, + int equivClass: int ref); + +@duplication_or_similarity = @duplication | @similarity + +tokens( + int id: @duplication_or_similarity ref, + int offset: int ref, + int beginLine: int ref, + int beginColumn: int ref, + int endLine: int ref, + int endColumn: int ref); + +/* + * C# dbscheme + */ + +/** ELEMENTS **/ + +@element = @declaration | @stmt | @expr | @modifier | @attribute | @namespace_declaration + | @using_directive | @type_parameter_constraints | @external_element + | @xmllocatable | @asp_element | @namespace; + +@declaration = @callable | @generic | @assignable | @namespace; + +@named_element = @namespace | @declaration; + +@declaration_with_accessors = @property | @indexer | @event; + +@assignable = @variable | @assignable_with_accessors | @event; + +@assignable_with_accessors = @property | @indexer; + +@external_element = @externalMetric | @externalDefect | @externalDataElement; + +@attributable = @assembly | @field | @parameter | @operator | @method | @constructor + | @destructor | @callable_accessor | @value_or_ref_type | @declaration_with_accessors + | @local_function; + +/** LOCATIONS, ASEMMBLIES, MODULES, FILES and FOLDERS **/ + +@location = @location_default | @assembly; + +locations_default( + unique int id: @location_default, + int file: @file ref, + int beginLine: int ref, + int beginColumn: int ref, + int endLine: int ref, + int endColumn: int ref); + +@sourceline = @file | @callable | @xmllocatable; + +numlines( + int element_id: @sourceline ref, + int num_lines: int ref, + int num_code: int ref, + int num_comment: int ref); + +assemblies( + unique int id: @assembly, + int file: @file ref, + string fullname: string ref, + string name: string ref, + string version: string ref); + +/* + fromSource(0) = unknown, + fromSource(1) = from source, + fromSource(2) = from library +*/ +files( + unique int id: @file, + string name: string ref, + string simple: string ref, + string ext: string ref, + int fromSource: int ref); + +folders( + unique int id: @folder, + string name: string ref, + string simple: string ref); + +@container = @folder | @file ; + +containerparent( + int parent: @container ref, + unique int child: @container ref); + +file_extraction_mode( + unique int file: @file ref, + int mode: int ref + /* 0 = normal, 1 = standalone extractor */ + ); + +/** NAMESPACES **/ + +@type_container = @namespace | @type; + +namespaces( + unique int id: @namespace, + string name: string ref); + +namespace_declarations( + unique int id: @namespace_declaration, + int namespace_id: @namespace ref); + +namespace_declaration_location( + unique int id: @namespace_declaration ref, + int loc: @location ref); + +parent_namespace( + unique int child_id: @type_container ref, + int namespace_id: @namespace ref); + +@declaration_or_directive = @namespace_declaration | @type | @using_directive; + +parent_namespace_declaration( + int child_id: @declaration_or_directive ref, // cannot be unique because of partial classes + int namespace_id: @namespace_declaration ref); + +@using_directive = @using_namespace_directive | @using_static_directive; + +using_namespace_directives( + unique int id: @using_namespace_directive, + int namespace_id: @namespace ref); + +using_static_directives( + unique int id: @using_static_directive, + int type_id: @type_or_ref ref); + +using_directive_location( + unique int id: @using_directive ref, + int loc: @location ref); + +/** TYPES **/ + +types( + unique int id: @type, + int kind: int ref, + string name: string ref); + +case @type.kind of + 1 = @bool_type +| 2 = @char_type +| 3 = @decimal_type +| 4 = @sbyte_type +| 5 = @short_type +| 6 = @int_type +| 7 = @long_type +| 8 = @byte_type +| 9 = @ushort_type +| 10 = @uint_type +| 11 = @ulong_type +| 12 = @float_type +| 13 = @double_type +| 14 = @enum_type +| 15 = @struct_type +| 17 = @class_type +| 19 = @interface_type +| 20 = @delegate_type +| 21 = @null_type +| 22 = @type_parameter +| 23 = @pointer_type +| 24 = @nullable_type +| 25 = @array_type +| 26 = @void_type +| 27 = @int_ptr_type +| 28 = @uint_ptr_type +| 29 = @dynamic_type +| 30 = @arglist_type +| 31 = @unknown_type +| 32 = @tuple_type + ; + +@simple_type = @bool_type | @char_type | @integral_type | @floating_point_type | @decimal_type; +@integral_type = @signed_integral_type | @unsigned_integral_type; +@signed_integral_type = @sbyte_type | @short_type | @int_type | @long_type; +@unsigned_integral_type = @byte_type | @ushort_type | @uint_type | @ulong_type; +@floating_point_type = @float_type | @double_type; +@value_type = @simple_type | @enum_type | @struct_type | @nullable_type | @int_ptr_type + | @uint_ptr_type | @tuple_type; +@ref_type = @class_type | @interface_type | @array_type | @delegate_type | @null_type + | @dynamic_type; +@value_or_ref_type = @value_type | @ref_type; + +typerefs( + unique int id: @typeref, + string name: string ref); + +typeref_type( + int id: @typeref ref, + unique int typeId: @type ref); + +@type_or_ref = @type | @typeref; + +array_element_type( + unique int array: @array_type ref, + int dimension: int ref, + int rank: int ref, + int element: @type_or_ref ref); + +nullable_underlying_type( + unique int nullable: @nullable_type ref, + int underlying: @type_or_ref ref); + +pointer_referent_type( + unique int pointer: @pointer_type ref, + int referent: @type_or_ref ref); + +enum_underlying_type( + unique int enum_id: @enum_type ref, + int underlying_type_id: @type_or_ref ref); + +delegate_return_type( + unique int delegate_id: @delegate_type ref, + int return_type_id: @type_or_ref ref); + +extend( + unique int sub: @type ref, + int super: @type_or_ref ref); + +@interface_or_ref = @interface_type | @typeref; + +implement( + int sub: @type ref, + int super: @type_or_ref ref); + +type_location( + int id: @type ref, + int loc: @location ref); + +tuple_underlying_type( + unique int tuple: @tuple_type ref, + int struct: @type_or_ref ref); + +#keyset[tuple, index] +tuple_element( + int tuple: @tuple_type ref, + int index: int ref, + unique int field: @field ref); + +attributes( + unique int id: @attribute, + int type_id: @type_or_ref ref, + int target: @attributable ref); + +attribute_location( + int id: @attribute ref, + int loc: @location ref); + +@type_mention_parent = @element | @type_mention; + +type_mention( + unique int id: @type_mention, + int type_id: @type_or_ref ref, + int parent: @type_mention_parent ref); + +type_mention_location( + unique int id: @type_mention ref, + int loc: @location ref); + +@has_type_annotation = @assignable | @type_parameter | @callable | @expr | @delegate_type | @generic; + +/** + * A direct annotation on an entity, for example `string? x;`. + * + * Annotations: + * 2 = reftype is not annotated "!" + * 3 = reftype is annotated "?" + * 4 = readonly ref type / in parameter + * 5 = ref type parameter, return or local variable + * 6 = out parameter + * + * Note that the annotation depends on the element it annotates. + * @assignable: The annotation is on the type of the assignable, for example the variable type. + * @type_parameter: The annotation is on the reftype constraint + * @callable: The annotation is on the return type + * @array_type: The annotation is on the element type + */ +type_annotation(int id: @has_type_annotation ref, int annotation: int ref); + +nullability(unique int nullability: @nullability, int kind: int ref); + +case @nullability.kind of + 0 = @oblivious +| 1 = @not_annotated +| 2 = @annotated +; + +#keyset[parent, index] +nullability_parent(int nullability: @nullability ref, int index: int ref, int parent: @nullability ref) + +type_nullability(int id: @has_type_annotation ref, int nullability: @nullability ref); + +/** + * The nullable flow state of an expression, as determined by Roslyn. + * 0 = none (default, not populated) + * 1 = not null + * 2 = maybe null + */ +expr_flowstate(unique int id: @expr ref, int state: int ref); + +/** GENERICS **/ + +@generic = @type | @method | @local_function; + +type_parameters( + unique int id: @type_parameter ref, + int index: int ref, + int generic_id: @generic ref, + int variance: int ref /* none = 0, out = 1, in = 2 */); + +#keyset[constructed_id, index] +type_arguments( + int id: @type_or_ref ref, + int index: int ref, + int constructed_id: @generic_or_ref ref); + +@generic_or_ref = @generic | @typeref; + +constructed_generic( + unique int constructed: @generic ref, + int generic: @generic_or_ref ref); + +type_parameter_constraints( + unique int id: @type_parameter_constraints, + int param_id: @type_parameter ref); + +type_parameter_constraints_location( + int id: @type_parameter_constraints ref, + int loc: @location ref); + +general_type_parameter_constraints( + int id: @type_parameter_constraints ref, + int kind: int ref /* class = 1, struct = 2, new = 3 */); + +specific_type_parameter_constraints( + int id: @type_parameter_constraints ref, + int base_id: @type_or_ref ref); + +specific_type_parameter_nullability( + int id: @type_parameter_constraints ref, + int base_id: @type_or_ref ref, + int nullability: @nullability ref); + +/** MODIFIERS */ + +@modifiable = @modifiable_direct | @event_accessor; + +@modifiable_direct = @member | @accessor | @local_function | @anonymous_function_expr; + +modifiers( + unique int id: @modifier, + string name: string ref); + +has_modifiers( + int id: @modifiable_direct ref, + int mod_id: @modifier ref); + +compiler_generated(unique int id: @modifiable_direct ref); + +/** MEMBERS **/ + +@member = @method | @constructor | @destructor | @field | @property | @event | @operator | @indexer | @type; + +@named_exprorstmt = @goto_stmt | @labeled_stmt | @expr; + +@virtualizable = @method | @property | @indexer | @event; + +exprorstmt_name( + unique int parent_id: @named_exprorstmt ref, + string name: string ref); + +nested_types( + unique int id: @type ref, + int declaring_type_id: @type ref, + int unbound_id: @type ref); + +properties( + unique int id: @property, + string name: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @property ref); + +property_location( + int id: @property ref, + int loc: @location ref); + +indexers( + unique int id: @indexer, + string name: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @indexer ref); + +indexer_location( + int id: @indexer ref, + int loc: @location ref); + +accessors( + unique int id: @accessor, + int kind: int ref, + string name: string ref, + int declaring_member_id: @member ref, + int unbound_id: @accessor ref); + +case @accessor.kind of + 1 = @getter +| 2 = @setter + ; + +accessor_location( + int id: @accessor ref, + int loc: @location ref); + +events( + unique int id: @event, + string name: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @event ref); + +event_location( + int id: @event ref, + int loc: @location ref); + +event_accessors( + unique int id: @event_accessor, + int kind: int ref, + string name: string ref, + int declaring_event_id: @event ref, + int unbound_id: @event_accessor ref); + +case @event_accessor.kind of + 1 = @add_event_accessor +| 2 = @remove_event_accessor + ; + +event_accessor_location( + int id: @event_accessor ref, + int loc: @location ref); + +operators( + unique int id: @operator, + string name: string ref, + string symbol: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @operator ref); + +operator_location( + int id: @operator ref, + int loc: @location ref); + +constant_value( + int id: @variable ref, + string value: string ref); + +/** CALLABLES **/ + +@callable = @method | @constructor | @destructor | @operator | @callable_accessor | @anonymous_function_expr | @local_function; + +@callable_accessor = @accessor | @event_accessor; + +methods( + unique int id: @method, + string name: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @method ref); + +method_location( + int id: @method ref, + int loc: @location ref); + +constructors( + unique int id: @constructor, + string name: string ref, + int declaring_type_id: @type ref, + int unbound_id: @constructor ref); + +constructor_location( + int id: @constructor ref, + int loc: @location ref); + +destructors( + unique int id: @destructor, + string name: string ref, + int declaring_type_id: @type ref, + int unbound_id: @destructor ref); + +destructor_location( + int id: @destructor ref, + int loc: @location ref); + +overrides( + int id: @callable ref, + int base_id: @callable ref); + +explicitly_implements( + int id: @member ref, + int interface_id: @interface_or_ref ref); + +local_functions( + unique int id: @local_function, + string name: string ref, + int return_type: @type ref, + int unbound_id: @local_function ref); + +local_function_stmts( + unique int fn: @local_function_stmt ref, + int stmt: @local_function ref); + +/** VARIABLES **/ + +@variable = @local_scope_variable | @field; + +@local_scope_variable = @local_variable | @parameter; + +fields( + unique int id: @field, + int kind: int ref, + string name: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @field ref); + +case @field.kind of + 1 = @addressable_field +| 2 = @constant + ; + +field_location( + int id: @field ref, + int loc: @location ref); + +localvars( + unique int id: @local_variable, + int kind: int ref, + string name: string ref, + int implicitly_typed: int ref /* 0 = no, 1 = yes */, + int type_id: @type_or_ref ref, + int parent_id: @local_var_decl_expr ref); + +case @local_variable.kind of + 1 = @addressable_local_variable +| 2 = @local_constant +| 3 = @local_variable_ref + ; + +localvar_location( + unique int id: @local_variable ref, + int loc: @location ref); + +@parameterizable = @callable | @delegate_type | @indexer; + +#keyset[name, parent_id] +#keyset[index, parent_id] +params( + unique int id: @parameter, + string name: string ref, + int type_id: @type_or_ref ref, + int index: int ref, + int mode: int ref, /* value = 0, ref = 1, out = 2, array = 3, this = 4 */ + int parent_id: @parameterizable ref, + int unbound_id: @parameter ref); + +param_location( + int id: @parameter ref, + int loc: @location ref); + +/** STATEMENTS **/ + +@exprorstmt_parent = @control_flow_element | @top_level_exprorstmt_parent; + +statements( + unique int id: @stmt, + int kind: int ref); + +#keyset[index, parent] +stmt_parent( + unique int stmt: @stmt ref, + int index: int ref, + int parent: @control_flow_element ref); + +@top_level_stmt_parent = @callable; + +// [index, parent] is not a keyset because the same parent may be compiled multiple times +stmt_parent_top_level( + unique int stmt: @stmt ref, + int index: int ref, + int parent: @top_level_stmt_parent ref); + +case @stmt.kind of + 1 = @block_stmt +| 2 = @expr_stmt +| 3 = @if_stmt +| 4 = @switch_stmt +| 5 = @while_stmt +| 6 = @do_stmt +| 7 = @for_stmt +| 8 = @foreach_stmt +| 9 = @break_stmt +| 10 = @continue_stmt +| 11 = @goto_stmt +| 12 = @goto_case_stmt +| 13 = @goto_default_stmt +| 14 = @throw_stmt +| 15 = @return_stmt +| 16 = @yield_stmt +| 17 = @try_stmt +| 18 = @checked_stmt +| 19 = @unchecked_stmt +| 20 = @lock_stmt +| 21 = @using_block_stmt +| 22 = @var_decl_stmt +| 23 = @const_decl_stmt +| 24 = @empty_stmt +| 25 = @unsafe_stmt +| 26 = @fixed_stmt +| 27 = @label_stmt +| 28 = @catch +| 29 = @case_stmt +| 30 = @local_function_stmt +| 31 = @using_decl_stmt + ; + +@using_stmt = @using_block_stmt | @using_decl_stmt; + +@labeled_stmt = @label_stmt | @case; + +@decl_stmt = @var_decl_stmt | @const_decl_stmt | @using_decl_stmt; + +@cond_stmt = @if_stmt | @switch_stmt; + +@loop_stmt = @while_stmt | @do_stmt | @for_stmt | @foreach_stmt; + +@jump_stmt = @break_stmt | @goto_any_stmt | @continue_stmt | @throw_stmt | @return_stmt + | @yield_stmt; + +@goto_any_stmt = @goto_default_stmt | @goto_case_stmt | @goto_stmt; + + +stmt_location( + unique int id: @stmt ref, + int loc: @location ref); + +catch_type( + unique int catch_id: @catch ref, + int type_id: @type_or_ref ref, + int kind: int ref /* explicit = 1, implicit = 2 */); + +/** EXPRESSIONS **/ + +expressions( + unique int id: @expr, + int kind: int ref, + int type_id: @type_or_ref ref); + +#keyset[index, parent] +expr_parent( + unique int expr: @expr ref, + int index: int ref, + int parent: @control_flow_element ref); + +@top_level_expr_parent = @attribute | @field | @property | @indexer | @parameter; + +@top_level_exprorstmt_parent = @top_level_expr_parent | @top_level_stmt_parent; + +// [index, parent] is not a keyset because the same parent may be compiled multiple times +expr_parent_top_level( + unique int expr: @expr ref, + int index: int ref, + int parent: @top_level_exprorstmt_parent ref); + +case @expr.kind of +/* literal */ + 1 = @bool_literal_expr +| 2 = @char_literal_expr +| 3 = @decimal_literal_expr +| 4 = @int_literal_expr +| 5 = @long_literal_expr +| 6 = @uint_literal_expr +| 7 = @ulong_literal_expr +| 8 = @float_literal_expr +| 9 = @double_literal_expr +| 10 = @string_literal_expr +| 11 = @null_literal_expr +/* primary & unary */ +| 12 = @this_access_expr +| 13 = @base_access_expr +| 14 = @local_variable_access_expr +| 15 = @parameter_access_expr +| 16 = @field_access_expr +| 17 = @property_access_expr +| 18 = @method_access_expr +| 19 = @event_access_expr +| 20 = @indexer_access_expr +| 21 = @array_access_expr +| 22 = @type_access_expr +| 23 = @typeof_expr +| 24 = @method_invocation_expr +| 25 = @delegate_invocation_expr +| 26 = @operator_invocation_expr +| 27 = @cast_expr +| 28 = @object_creation_expr +| 29 = @explicit_delegate_creation_expr +| 30 = @implicit_delegate_creation_expr +| 31 = @array_creation_expr +| 32 = @default_expr +| 33 = @plus_expr +| 34 = @minus_expr +| 35 = @bit_not_expr +| 36 = @log_not_expr +| 37 = @post_incr_expr +| 38 = @post_decr_expr +| 39 = @pre_incr_expr +| 40 = @pre_decr_expr +/* multiplicative */ +| 41 = @mul_expr +| 42 = @div_expr +| 43 = @rem_expr +/* additive */ +| 44 = @add_expr +| 45 = @sub_expr +/* shift */ +| 46 = @lshift_expr +| 47 = @rshift_expr +/* relational */ +| 48 = @lt_expr +| 49 = @gt_expr +| 50 = @le_expr +| 51 = @ge_expr +/* equality */ +| 52 = @eq_expr +| 53 = @ne_expr +/* logical */ +| 54 = @bit_and_expr +| 55 = @bit_xor_expr +| 56 = @bit_or_expr +| 57 = @log_and_expr +| 58 = @log_or_expr +/* type testing */ +| 59 = @is_expr +| 60 = @as_expr +/* null coalescing */ +| 61 = @null_coalescing_expr +/* conditional */ +| 62 = @conditional_expr +/* assignment */ +| 63 = @simple_assign_expr +| 64 = @assign_add_expr +| 65 = @assign_sub_expr +| 66 = @assign_mul_expr +| 67 = @assign_div_expr +| 68 = @assign_rem_expr +| 69 = @assign_and_expr +| 70 = @assign_xor_expr +| 71 = @assign_or_expr +| 72 = @assign_lshift_expr +| 73 = @assign_rshift_expr +/* more */ +| 74 = @object_init_expr +| 75 = @collection_init_expr +| 76 = @array_init_expr +| 77 = @checked_expr +| 78 = @unchecked_expr +| 79 = @constructor_init_expr +| 80 = @add_event_expr +| 81 = @remove_event_expr +| 82 = @par_expr +| 83 = @local_var_decl_expr +| 84 = @lambda_expr +| 85 = @anonymous_method_expr +| 86 = @namespace_expr +/* dynamic */ +| 92 = @dynamic_element_access_expr +| 93 = @dynamic_member_access_expr +/* unsafe */ +| 100 = @pointer_indirection_expr +| 101 = @address_of_expr +| 102 = @sizeof_expr +/* async */ +| 103 = @await_expr +/* C# 6.0 */ +| 104 = @nameof_expr +| 105 = @interpolated_string_expr +| 106 = @unknown_expr +/* C# 7.0 */ +| 107 = @throw_expr +| 108 = @tuple_expr +| 109 = @local_function_invocation_expr +| 110 = @ref_expr +| 111 = @discard_expr +/* C# 8.0 */ +| 112 = @range_expr +| 113 = @index_expr +| 114 = @switch_expr +| 115 = @recursive_pattern_expr +| 116 = @property_pattern_expr +| 117 = @positional_pattern_expr +| 118 = @switch_case_expr +| 119 = @assign_coalesce_expr +| 120 = @suppress_nullable_warning_expr +| 121 = @namespace_access_expr +; + +@switch = @switch_stmt | @switch_expr; +@case = @case_stmt | @switch_case_expr; +@pattern_match = @case | @is_expr; + +@integer_literal_expr = @int_literal_expr | @long_literal_expr | @uint_literal_expr | @ulong_literal_expr; +@real_literal_expr = @float_literal_expr | @double_literal_expr | @decimal_literal_expr; +@literal_expr = @bool_literal_expr | @char_literal_expr | @integer_literal_expr | @real_literal_expr + | @string_literal_expr | @null_literal_expr; + +@assign_expr = @simple_assign_expr | @assign_op_expr | @local_var_decl_expr; +@assign_op_expr = @assign_arith_expr | @assign_bitwise_expr | @assign_event_expr | @assign_coalesce_expr; +@assign_event_expr = @add_event_expr | @remove_event_expr; + +@assign_arith_expr = @assign_add_expr | @assign_sub_expr | @assign_mul_expr | @assign_div_expr + | @assign_rem_expr +@assign_bitwise_expr = @assign_and_expr | @assign_or_expr | @assign_xor_expr + | @assign_lshift_expr | @assign_rshift_expr; + +@member_access_expr = @field_access_expr | @property_access_expr | @indexer_access_expr | @event_access_expr + | @method_access_expr | @type_access_expr | @dynamic_member_access_expr; +@access_expr = @member_access_expr | @this_access_expr | @base_access_expr | @assignable_access_expr | @namespace_access_expr; +@element_access_expr = @indexer_access_expr | @array_access_expr | @dynamic_element_access_expr; + +@local_variable_access = @local_variable_access_expr | @local_var_decl_expr; +@local_scope_variable_access_expr = @parameter_access_expr | @local_variable_access; +@variable_access_expr = @local_scope_variable_access_expr | @field_access_expr; + +@assignable_access_expr = @variable_access_expr | @property_access_expr | @element_access_expr + | @event_access_expr | @dynamic_member_access_expr; + +@objectorcollection_init_expr = @object_init_expr | @collection_init_expr; + +@delegate_creation_expr = @explicit_delegate_creation_expr | @implicit_delegate_creation_expr; + +@bin_arith_op_expr = @mul_expr | @div_expr | @rem_expr | @add_expr | @sub_expr; +@incr_op_expr = @pre_incr_expr | @post_incr_expr; +@decr_op_expr = @pre_decr_expr | @post_decr_expr; +@mut_op_expr = @incr_op_expr | @decr_op_expr; +@un_arith_op_expr = @plus_expr | @minus_expr | @mut_op_expr; +@arith_op_expr = @bin_arith_op_expr | @un_arith_op_expr; + +@ternary_log_op_expr = @conditional_expr; +@bin_log_op_expr = @log_and_expr | @log_or_expr | @null_coalescing_expr; +@un_log_op_expr = @log_not_expr; +@log_expr = @un_log_op_expr | @bin_log_op_expr | @ternary_log_op_expr; + +@bin_bit_op_expr = @bit_and_expr | @bit_or_expr | @bit_xor_expr | @lshift_expr + | @rshift_expr; +@un_bit_op_expr = @bit_not_expr; +@bit_expr = @un_bit_op_expr | @bin_bit_op_expr; + +@equality_op_expr = @eq_expr | @ne_expr; +@rel_op_expr = @gt_expr | @lt_expr| @ge_expr | @le_expr; +@comp_expr = @equality_op_expr | @rel_op_expr; + +@op_expr = @assign_expr | @un_op | @bin_op | @ternary_op; + +@ternary_op = @ternary_log_op_expr; +@bin_op = @bin_arith_op_expr | @bin_log_op_expr | @bin_bit_op_expr | @comp_expr; +@un_op = @un_arith_op_expr | @un_log_op_expr | @un_bit_op_expr | @sizeof_expr + | @pointer_indirection_expr | @address_of_expr; + +@anonymous_function_expr = @lambda_expr | @anonymous_method_expr; + +@call = @method_invocation_expr | @constructor_init_expr | @operator_invocation_expr + | @delegate_invocation_expr | @object_creation_expr | @call_access_expr + | @local_function_invocation_expr; + +@call_access_expr = @property_access_expr | @event_access_expr | @indexer_access_expr; + +@late_bindable_expr = @dynamic_element_access_expr | @dynamic_member_access_expr + | @object_creation_expr | @method_invocation_expr | @operator_invocation_expr; + +@throw_element = @throw_expr | @throw_stmt; + +implicitly_typed_array_creation( + unique int id: @array_creation_expr ref); + +explicitly_sized_array_creation( + unique int id: @array_creation_expr ref); + +stackalloc_array_creation( + unique int id: @array_creation_expr ref); + +mutator_invocation_mode( + unique int id: @operator_invocation_expr ref, + int mode: int ref /* prefix = 1, postfix = 2*/); + +expr_compiler_generated( + unique int id: @expr ref); + +expr_value( + unique int id: @expr ref, + string value: string ref); + +expr_call( + unique int caller_id: @expr ref, + int target_id: @callable ref); + +expr_access( + unique int accesser_id: @access_expr ref, + int target_id: @accessible ref); + +@accessible = @method | @assignable | @local_function | @namespace; + +expr_location( + unique int id: @expr ref, + int loc: @location ref); + +dynamic_member_name( + unique int id: @late_bindable_expr ref, + string name: string ref); + +@qualifiable_expr = @member_access_expr + | @method_invocation_expr + | @element_access_expr; + +conditional_access( + unique int id: @qualifiable_expr ref); + +expr_argument( + unique int id: @expr ref, + int mode: int ref); + /* mode is the same as params: value = 0, ref = 1, out = 2 */ + +expr_argument_name( + unique int id: @expr ref, + string name: string ref); + +/** CONTROL/DATA FLOW **/ + +@control_flow_element = @stmt | @expr; + +/* XML Files */ + +xmlEncoding ( + unique int id: @file ref, + string encoding: string ref); + +xmlDTDs( + unique int id: @xmldtd, + string root: string ref, + string publicId: string ref, + string systemId: string ref, + int fileid: @file ref); + +xmlElements( + unique int id: @xmlelement, + string name: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int fileid: @file ref); + +xmlAttrs( + unique int id: @xmlattribute, + int elementid: @xmlelement ref, + string name: string ref, + string value: string ref, + int idx: int ref, + int fileid: @file ref); + +xmlNs( + int id: @xmlnamespace, + string prefixName: string ref, + string URI: string ref, + int fileid: @file ref); + +xmlHasNs( + int elementId: @xmlnamespaceable ref, + int nsId: @xmlnamespace ref, + int fileid: @file ref); + +xmlComments( + unique int id: @xmlcomment, + string text: string ref, + int parentid: @xmlparent ref, + int fileid: @file ref); + +xmlChars( + unique int id: @xmlcharacters, + string text: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int isCDATA: int ref, + int fileid: @file ref); + +@xmlparent = @file | @xmlelement; +@xmlnamespaceable = @xmlelement | @xmlattribute; + +xmllocations( + int xmlElement: @xmllocatable ref, + int location: @location_default ref); + +@xmllocatable = @xmlcharacters | @xmlelement | @xmlcomment | @xmlattribute | @xmldtd | @file | @xmlnamespace; + +/* Comments */ + +commentline( + unique int id: @commentline, + int kind: int ref, + string text: string ref, + string rawtext: string ref); + +case @commentline.kind of + 0 = @singlelinecomment +| 1 = @xmldoccomment +| 2 = @multilinecomment; + +commentline_location( + unique int id: @commentline ref, + int loc: @location ref); + +commentblock( + unique int id : @commentblock); + +commentblock_location( + unique int id: @commentblock ref, + int loc: @location ref); + +commentblock_binding( + int id: @commentblock ref, + int entity: @element ref, + int bindtype: int ref); /* 0: Parent, 1: Best, 2: Before, 3: After */ + +commentblock_child( + int id: @commentblock ref, + int commentline: @commentline ref, + int index: int ref); + +/* ASP.NET */ + +case @asp_element.kind of + 0=@asp_close_tag +| 1=@asp_code +| 2=@asp_comment +| 3=@asp_data_binding +| 4=@asp_directive +| 5=@asp_open_tag +| 6=@asp_quoted_string +| 7=@asp_text +| 8=@asp_xml_directive; + +@asp_attribute = @asp_code | @asp_data_binding | @asp_quoted_string; + +asp_elements( + unique int id: @asp_element, + int kind: int ref, + int loc: @location ref); + +asp_comment_server(unique int comment: @asp_comment ref); +asp_code_inline(unique int code: @asp_code ref); +asp_directive_attribute( + int directive: @asp_directive ref, + int index: int ref, + string name: string ref, + int value: @asp_quoted_string ref); +asp_directive_name( + unique int directive: @asp_directive ref, + string name: string ref); +asp_element_body( + unique int element: @asp_element ref, + string body: string ref); +asp_tag_attribute( + int tag: @asp_open_tag ref, + int index: int ref, + string name: string ref, + int attribute: @asp_attribute ref); +asp_tag_name( + unique int tag: @asp_open_tag ref, + string name: string ref); +asp_tag_isempty(int tag: @asp_open_tag ref); + +/* Common Intermediate Language - CIL */ + +case @cil_instruction.opcode of + 0 = @cil_nop +| 1 = @cil_break +| 2 = @cil_ldarg_0 +| 3 = @cil_ldarg_1 +| 4 = @cil_ldarg_2 +| 5 = @cil_ldarg_3 +| 6 = @cil_ldloc_0 +| 7 = @cil_ldloc_1 +| 8 = @cil_ldloc_2 +| 9 = @cil_ldloc_3 +| 10 = @cil_stloc_0 +| 11 = @cil_stloc_1 +| 12 = @cil_stloc_2 +| 13 = @cil_stloc_3 +| 14 = @cil_ldarg_s +| 15 = @cil_ldarga_s +| 16 = @cil_starg_s +| 17 = @cil_ldloc_s +| 18 = @cil_ldloca_s +| 19 = @cil_stloc_s +| 20 = @cil_ldnull +| 21 = @cil_ldc_i4_m1 +| 22 = @cil_ldc_i4_0 +| 23 = @cil_ldc_i4_1 +| 24 = @cil_ldc_i4_2 +| 25 = @cil_ldc_i4_3 +| 26 = @cil_ldc_i4_4 +| 27 = @cil_ldc_i4_5 +| 28 = @cil_ldc_i4_6 +| 29 = @cil_ldc_i4_7 +| 30 = @cil_ldc_i4_8 +| 31 = @cil_ldc_i4_s +| 32 = @cil_ldc_i4 +| 33 = @cil_ldc_i8 +| 34 = @cil_ldc_r4 +| 35 = @cil_ldc_r8 +| 37 = @cil_dup +| 38 = @cil_pop +| 39 = @cil_jmp +| 40 = @cil_call +| 41 = @cil_calli +| 42 = @cil_ret +| 43 = @cil_br_s +| 44 = @cil_brfalse_s +| 45 = @cil_brtrue_s +| 46 = @cil_beq_s +| 47 = @cil_bge_s +| 48 = @cil_bgt_s +| 49 = @cil_ble_s +| 50 = @cil_blt_s +| 51 = @cil_bne_un_s +| 52 = @cil_bge_un_s +| 53 = @cil_bgt_un_s +| 54 = @cil_ble_un_s +| 55 = @cil_blt_un_s +| 56 = @cil_br +| 57 = @cil_brfalse +| 58 = @cil_brtrue +| 59 = @cil_beq +| 60 = @cil_bge +| 61 = @cil_bgt +| 62 = @cil_ble +| 63 = @cil_blt +| 64 = @cil_bne_un +| 65 = @cil_bge_un +| 66 = @cil_bgt_un +| 67 = @cil_ble_un +| 68 = @cil_blt_un +| 69 = @cil_switch +| 70 = @cil_ldind_i1 +| 71 = @cil_ldind_u1 +| 72 = @cil_ldind_i2 +| 73 = @cil_ldind_u2 +| 74 = @cil_ldind_i4 +| 75 = @cil_ldind_u4 +| 76 = @cil_ldind_i8 +| 77 = @cil_ldind_i +| 78 = @cil_ldind_r4 +| 79 = @cil_ldind_r8 +| 80 = @cil_ldind_ref +| 81 = @cil_stind_ref +| 82 = @cil_stind_i1 +| 83 = @cil_stind_i2 +| 84 = @cil_stind_i4 +| 85 = @cil_stind_i8 +| 86 = @cil_stind_r4 +| 87 = @cil_stind_r8 +| 88 = @cil_add +| 89 = @cil_sub +| 90 = @cil_mul +| 91 = @cil_div +| 92 = @cil_div_un +| 93 = @cil_rem +| 94 = @cil_rem_un +| 95 = @cil_and +| 96 = @cil_or +| 97 = @cil_xor +| 98 = @cil_shl +| 99 = @cil_shr +| 100 = @cil_shr_un +| 101 = @cil_neg +| 102 = @cil_not +| 103 = @cil_conv_i1 +| 104 = @cil_conv_i2 +| 105 = @cil_conv_i4 +| 106 = @cil_conv_i8 +| 107 = @cil_conv_r4 +| 108 = @cil_conv_r8 +| 109 = @cil_conv_u4 +| 110 = @cil_conv_u8 +| 111 = @cil_callvirt +| 112 = @cil_cpobj +| 113 = @cil_ldobj +| 114 = @cil_ldstr +| 115 = @cil_newobj +| 116 = @cil_castclass +| 117 = @cil_isinst +| 118 = @cil_conv_r_un +| 121 = @cil_unbox +| 122 = @cil_throw +| 123 = @cil_ldfld +| 124 = @cil_ldflda +| 125 = @cil_stfld +| 126 = @cil_ldsfld +| 127 = @cil_ldsflda +| 128 = @cil_stsfld +| 129 = @cil_stobj +| 130 = @cil_conv_ovf_i1_un +| 131 = @cil_conv_ovf_i2_un +| 132 = @cil_conv_ovf_i4_un +| 133 = @cil_conv_ovf_i8_un +| 134 = @cil_conv_ovf_u1_un +| 135 = @cil_conv_ovf_u2_un +| 136 = @cil_conv_ovf_u4_un +| 137 = @cil_conv_ovf_u8_un +| 138 = @cil_conv_ovf_i_un +| 139 = @cil_conv_ovf_u_un +| 140 = @cil_box +| 141 = @cil_newarr +| 142 = @cil_ldlen +| 143 = @cil_ldelema +| 144 = @cil_ldelem_i1 +| 145 = @cil_ldelem_u1 +| 146 = @cil_ldelem_i2 +| 147 = @cil_ldelem_u2 +| 148 = @cil_ldelem_i4 +| 149 = @cil_ldelem_u4 +| 150 = @cil_ldelem_i8 +| 151 = @cil_ldelem_i +| 152 = @cil_ldelem_r4 +| 153 = @cil_ldelem_r8 +| 154 = @cil_ldelem_ref +| 155 = @cil_stelem_i +| 156 = @cil_stelem_i1 +| 157 = @cil_stelem_i2 +| 158 = @cil_stelem_i4 +| 159 = @cil_stelem_i8 +| 160 = @cil_stelem_r4 +| 161 = @cil_stelem_r8 +| 162 = @cil_stelem_ref +| 163 = @cil_ldelem +| 164 = @cil_stelem +| 165 = @cil_unbox_any +| 179 = @cil_conv_ovf_i1 +| 180 = @cil_conv_ovf_u1 +| 181 = @cil_conv_ovf_i2 +| 182 = @cil_conv_ovf_u2 +| 183 = @cil_conv_ovf_i4 +| 184 = @cil_conv_ovf_u4 +| 185 = @cil_conv_ovf_i8 +| 186 = @cil_conv_ovf_u8 +| 194 = @cil_refanyval +| 195 = @cil_ckinfinite +| 198 = @cil_mkrefany +| 208 = @cil_ldtoken +| 209 = @cil_conv_u2 +| 210 = @cil_conv_u1 +| 211 = @cil_conv_i +| 212 = @cil_conv_ovf_i +| 213 = @cil_conv_ovf_u +| 214 = @cil_add_ovf +| 215 = @cil_add_ovf_un +| 216 = @cil_mul_ovf +| 217 = @cil_mul_ovf_un +| 218 = @cil_sub_ovf +| 219 = @cil_sub_ovf_un +| 220 = @cil_endfinally +| 221 = @cil_leave +| 222 = @cil_leave_s +| 223 = @cil_stind_i +| 224 = @cil_conv_u +| 65024 = @cil_arglist +| 65025 = @cil_ceq +| 65026 = @cil_cgt +| 65027 = @cil_cgt_un +| 65028 = @cil_clt +| 65029 = @cil_clt_un +| 65030 = @cil_ldftn +| 65031 = @cil_ldvirtftn +| 65033 = @cil_ldarg +| 65034 = @cil_ldarga +| 65035 = @cil_starg +| 65036 = @cil_ldloc +| 65037 = @cil_ldloca +| 65038 = @cil_stloc +| 65039 = @cil_localloc +| 65041 = @cil_endfilter +| 65042 = @cil_unaligned +| 65043 = @cil_volatile +| 65044 = @cil_tail +| 65045 = @cil_initobj +| 65046 = @cil_constrained +| 65047 = @cil_cpblk +| 65048 = @cil_initblk +| 65050 = @cil_rethrow +| 65052 = @cil_sizeof +| 65053 = @cil_refanytype +| 65054 = @cil_readonly +; + +// CIL ignored instructions + +@cil_ignore = @cil_nop | @cil_break | @cil_volatile | @cil_unaligned; + +// CIL local/parameter/field access + +@cil_ldarg_any = @cil_ldarg_0 | @cil_ldarg_1 | @cil_ldarg_2 | @cil_ldarg_3 | @cil_ldarg_s | @cil_ldarga_s | @cil_ldarg | @cil_ldarga; +@cil_starg_any = @cil_starg | @cil_starg_s; + +@cil_ldloc_any = @cil_ldloc_0 | @cil_ldloc_1 | @cil_ldloc_2 | @cil_ldloc_3 | @cil_ldloc_s | @cil_ldloca_s | @cil_ldloc | @cil_ldloca; +@cil_stloc_any = @cil_stloc_0 | @cil_stloc_1 | @cil_stloc_2 | @cil_stloc_3 | @cil_stloc_s | @cil_stloc; + +@cil_ldfld_any = @cil_ldfld | @cil_ldsfld | @cil_ldsflda | @cil_ldflda; +@cil_stfld_any = @cil_stfld | @cil_stsfld; + +@cil_local_access = @cil_stloc_any | @cil_ldloc_any; +@cil_arg_access = @cil_starg_any | @cil_ldarg_any; +@cil_read_access = @cil_ldloc_any | @cil_ldarg_any | @cil_ldfld_any; +@cil_write_access = @cil_stloc_any | @cil_starg_any | @cil_stfld_any; + +@cil_stack_access = @cil_local_access | @cil_arg_access; +@cil_field_access = @cil_ldfld_any | @cil_stfld_any; + +@cil_access = @cil_read_access | @cil_write_access; + +// CIL constant/literal instructions + +@cil_ldc_i = @cil_ldc_i4_any | @cil_ldc_i8; + +@cil_ldc_i4_any = @cil_ldc_i4_m1 | @cil_ldc_i4_0 | @cil_ldc_i4_1 | @cil_ldc_i4_2 | @cil_ldc_i4_3 | + @cil_ldc_i4_4 | @cil_ldc_i4_5 | @cil_ldc_i4_6 | @cil_ldc_i4_7 | @cil_ldc_i4_8 | @cil_ldc_i4_s | @cil_ldc_i4; + +@cil_ldc_r = @cil_ldc_r4 | @cil_ldc_r8; + +@cil_literal = @cil_ldnull | @cil_ldc_i | @cil_ldc_r | @cil_ldstr; + +// Control flow + +@cil_conditional_jump = @cil_binary_jump | @cil_unary_jump; +@cil_binary_jump = @cil_beq_s | @cil_bge_s | @cil_bgt_s | @cil_ble_s | @cil_blt_s | + @cil_bne_un_s | @cil_bge_un_s | @cil_bgt_un_s | @cil_ble_un_s | @cil_blt_un_s | + @cil_beq | @cil_bge | @cil_bgt | @cil_ble | @cil_blt | + @cil_bne_un | @cil_bge_un | @cil_bgt_un | @cil_ble_un | @cil_blt_un; +@cil_unary_jump = @cil_brfalse_s | @cil_brtrue_s | @cil_brfalse | @cil_brtrue | @cil_switch; +@cil_unconditional_jump = @cil_br | @cil_br_s | @cil_leave_any; +@cil_leave_any = @cil_leave | @cil_leave_s; +@cil_jump = @cil_unconditional_jump | @cil_conditional_jump; + +// CIL call instructions + +@cil_call_any = @cil_jmp | @cil_call | @cil_calli | @cil_tail | @cil_callvirt | @cil_newobj; + +// CIL expression instructions + +@cil_expr = @cil_literal | @cil_binary_expr | @cil_unary_expr | @cil_call_any | @cil_read_access | + @cil_newarr | @cil_ldtoken | @cil_sizeof | + @cil_ldftn | @cil_ldvirtftn | @cil_localloc | @cil_mkrefany | @cil_refanytype | @cil_arglist | @cil_dup; + +@cil_unary_expr = + @cil_conversion_operation | @cil_unary_arithmetic_operation | @cil_unary_bitwise_operation| + @cil_ldlen | @cil_isinst | @cil_box | @cil_ldobj | @cil_castclass | @cil_unbox_any | + @cil_ldind | @cil_unbox; + +@cil_conversion_operation = + @cil_conv_i1 | @cil_conv_i2 | @cil_conv_i4 | @cil_conv_i8 | + @cil_conv_u1 | @cil_conv_u2 | @cil_conv_u4 | @cil_conv_u8 | + @cil_conv_ovf_i | @cil_conv_ovf_i_un | @cil_conv_ovf_i1 | @cil_conv_ovf_i1_un | + @cil_conv_ovf_i2 | @cil_conv_ovf_i2_un | @cil_conv_ovf_i4 | @cil_conv_ovf_i4_un | + @cil_conv_ovf_i8 | @cil_conv_ovf_i8_un | @cil_conv_ovf_u | @cil_conv_ovf_u_un | + @cil_conv_ovf_u1 | @cil_conv_ovf_u1_un | @cil_conv_ovf_u2 | @cil_conv_ovf_u2_un | + @cil_conv_ovf_u4 | @cil_conv_ovf_u4_un | @cil_conv_ovf_u8 | @cil_conv_ovf_u8_un | + @cil_conv_r4 | @cil_conv_r8 | @cil_conv_ovf_u2 | @cil_conv_ovf_u2_un | + @cil_conv_i | @cil_conv_u | @cil_conv_r_un; + +@cil_ldind = @cil_ldind_i | @cil_ldind_i1 | @cil_ldind_i2 | @cil_ldind_i4 | @cil_ldind_i8 | + @cil_ldind_r4 | @cil_ldind_r8 | @cil_ldind_ref | @cil_ldind_u1 | @cil_ldind_u2 | @cil_ldind_u4; + +@cil_stind = @cil_stind_i | @cil_stind_i1 | @cil_stind_i2 | @cil_stind_i4 | @cil_stind_i8 | + @cil_stind_r4 | @cil_stind_r8 | @cil_stind_ref; + +@cil_bitwise_operation = @cil_binary_bitwise_operation | @cil_unary_bitwise_operation; + +@cil_binary_bitwise_operation = @cil_and | @cil_or | @cil_xor | @cil_shr | @cil_shr | @cil_shr_un | @cil_shl; + +@cil_binary_arithmetic_operation = @cil_add | @cil_sub | @cil_mul | @cil_div | @cil_div_un | + @cil_rem | @cil_rem_un | @cil_add_ovf | @cil_add_ovf_un | @cil_mul_ovf | @cil_mul_ovf_un | + @cil_sub_ovf | @cil_sub_ovf_un; + +@cil_unary_bitwise_operation = @cil_not; + +@cil_binary_expr = @cil_binary_arithmetic_operation | @cil_binary_bitwise_operation | @cil_read_array | @cil_comparison_operation; + +@cil_unary_arithmetic_operation = @cil_neg; + +@cil_comparison_operation = @cil_cgt_un | @cil_ceq | @cil_cgt | @cil_clt | @cil_clt_un; + +// Elements that retrieve an address of something +@cil_read_ref = @cil_ldloca_s | @cil_ldarga_s | @cil_ldflda | @cil_ldsflda | @cil_ldelema; + +// CIL array instructions + +@cil_read_array = + @cil_ldelem | @cil_ldelema | @cil_ldelem_i1 | @cil_ldelem_ref | @cil_ldelem_i | + @cil_ldelem_i1 | @cil_ldelem_i2 | @cil_ldelem_i4 | @cil_ldelem_i8 | @cil_ldelem_r4 | + @cil_ldelem_r8 | @cil_ldelem_u1 | @cil_ldelem_u2 | @cil_ldelem_u4; + +@cil_write_array = @cil_stelem | @cil_stelem_ref | + @cil_stelem_i | @cil_stelem_i1 | @cil_stelem_i2 | @cil_stelem_i4 | @cil_stelem_i8 | + @cil_stelem_r4 | @cil_stelem_r8; + +@cil_throw_any = @cil_throw | @cil_rethrow; + +#keyset[impl, index] +cil_instruction( + unique int id: @cil_instruction, + int opcode: int ref, + int index: int ref, + int impl: @cil_method_implementation ref); + +cil_jump( + unique int instruction: @cil_jump ref, + int target: @cil_instruction ref); + +cil_access( + unique int instruction: @cil_instruction ref, + int target: @cil_accessible ref); + +cil_value( + unique int instruction: @cil_literal ref, + string value: string ref); + +#keyset[instruction, index] +cil_switch( + int instruction: @cil_switch ref, + int index: int ref, + int target: @cil_instruction ref); + +cil_instruction_location( + unique int id: @cil_instruction ref, + int loc: @location ref); + +cil_type_location( + int id: @cil_type ref, + int loc: @location ref); + +cil_method_location( + int id: @cil_method ref, + int loc: @location ref); + +@cil_namespace = @namespace; + +@cil_type_container = @cil_type | @cil_namespace | @cil_method; + +case @cil_type.kind of + 0 = @cil_valueorreftype +| 1 = @cil_typeparameter +| 2 = @cil_array_type +| 3 = @cil_pointer_type +; + +cil_type( + unique int id: @cil_type, + string name: string ref, + int kind: int ref, + int parent: @cil_type_container ref, + int sourceDecl: @cil_type ref); + +cil_pointer_type( + unique int id: @cil_pointer_type ref, + int pointee: @cil_type ref); + +cil_array_type( + unique int id: @cil_array_type ref, + int element_type: @cil_type ref, + int rank: int ref); + +cil_method( + unique int id: @cil_method, + string name: string ref, + int parent: @cil_type ref, + int return_type: @cil_type ref); + +cil_method_source_declaration( + unique int method: @cil_method ref, + int source: @cil_method ref); + +cil_method_implementation( + unique int id: @cil_method_implementation, + int method: @cil_method ref, + int location: @assembly ref); + +cil_implements( + int id: @cil_method ref, + int decl: @cil_method ref); + +#keyset[parent, name] +cil_field( + unique int id: @cil_field, + int parent: @cil_type ref, + string name: string ref, + int field_type: @cil_type ref); + +@cil_element = @cil_instruction | @cil_declaration | @cil_handler | @cil_attribute | @cil_namespace; +@cil_named_element = @cil_declaration | @cil_namespace; +@cil_declaration = @cil_variable | @cil_method | @cil_type | @cil_member; +@cil_accessible = @cil_declaration; +@cil_variable = @cil_field | @cil_stack_variable; +@cil_stack_variable = @cil_local_variable | @cil_parameter; +@cil_member = @cil_method | @cil_type | @cil_field | @cil_property | @cil_event; + +#keyset[method, index] +cil_parameter( + unique int id: @cil_parameter, + int method: @cil_method ref, + int index: int ref, + int param_type: @cil_type ref); + +cil_parameter_in(unique int id: @cil_parameter ref); +cil_parameter_out(unique int id: @cil_parameter ref); + +cil_setter(unique int prop: @cil_property ref, + int method: @cil_method ref); + +cil_getter(unique int prop: @cil_property ref, + int method: @cil_method ref); + +cil_adder(unique int event: @cil_event ref, + int method: @cil_method ref); + +cil_remover(unique int event: @cil_event ref, int method: @cil_method ref); + +cil_raiser(unique int event: @cil_event ref, int method: @cil_method ref); + +cil_property( + unique int id: @cil_property, + int parent: @cil_type ref, + string name: string ref, + int property_type: @cil_type ref); + +#keyset[parent, name] +cil_event(unique int id: @cil_event, + int parent: @cil_type ref, + string name: string ref, + int event_type: @cil_type ref); + +#keyset[impl, index] +cil_local_variable( + unique int id: @cil_local_variable, + int impl: @cil_method_implementation ref, + int index: int ref, + int var_type: @cil_type ref); + +// CIL handlers (exception handlers etc). + +case @cil_handler.kind of + 0 = @cil_catch_handler +| 1 = @cil_filter_handler +| 2 = @cil_finally_handler +| 4 = @cil_fault_handler +; + +#keyset[impl, index] +cil_handler( + unique int id: @cil_handler, + int impl: @cil_method_implementation ref, + int index: int ref, + int kind: int ref, + int try_start: @cil_instruction ref, + int try_end: @cil_instruction ref, + int handler_start: @cil_instruction ref); + +cil_handler_filter( + unique int id: @cil_handler ref, + int filter_start: @cil_instruction ref); + +cil_handler_type( + unique int id: @cil_handler ref, + int catch_type: @cil_type ref); + +@cil_controlflow_node = @cil_entry_point | @cil_instruction; + +@cil_entry_point = @cil_method_implementation | @cil_handler; + +@cil_dataflow_node = @cil_instruction | @cil_variable | @cil_method; + +cil_method_stack_size( + unique int method: @cil_method_implementation ref, + int size: int ref); + +// CIL modifiers + +cil_public(int id: @cil_member ref); +cil_private(int id: @cil_member ref); +cil_protected(int id: @cil_member ref); +cil_internal(int id: @cil_member ref); +cil_static(int id: @cil_member ref); +cil_sealed(int id: @cil_member ref); +cil_virtual(int id: @cil_method ref); +cil_abstract(int id: @cil_member ref); +cil_class(int id: @cil_type ref); +cil_interface(int id: @cil_type ref); +cil_security(int id: @cil_member ref); +cil_requiresecobject(int id: @cil_method ref); +cil_specialname(int id: @cil_method ref); +cil_newslot(int id: @cil_method ref); + +cil_base_class(unique int id: @cil_type ref, int base: @cil_type ref); +cil_base_interface(int id: @cil_type ref, int base: @cil_type ref); +cil_enum_underlying_type(unique int id: @cil_type ref, int underlying: @cil_type ref); + +#keyset[unbound, index] +cil_type_parameter( + int unbound: @cil_member ref, + int index: int ref, + int param: @cil_typeparameter ref); + +#keyset[bound, index] +cil_type_argument( + int bound: @cil_member ref, + int index: int ref, + int t: @cil_type ref); + +// CIL type parameter constraints + +cil_typeparam_covariant(int tp: @cil_typeparameter ref); +cil_typeparam_contravariant(int tp: @cil_typeparameter ref); +cil_typeparam_class(int tp: @cil_typeparameter ref); +cil_typeparam_struct(int tp: @cil_typeparameter ref); +cil_typeparam_new(int tp: @cil_typeparameter ref); +cil_typeparam_constraint(int tp: @cil_typeparameter ref, int supertype: @cil_type ref); + +// CIL attributes + +cil_attribute( + unique int attributeid: @cil_attribute, + int element: @cil_declaration ref, + int constructor: @cil_method ref); + +#keyset[attribute_id, param] +cil_attribute_named_argument( + int attribute_id: @cil_attribute ref, + string param: string ref, + string value: string ref); + +#keyset[attribute_id, index] +cil_attribute_positional_argument( + int attribute_id: @cil_attribute ref, + int index: int ref, + string value: string ref); + + +// Common .Net data model covering both C# and CIL + +// Common elements +@dotnet_element = @element | @cil_element; +@dotnet_named_element = @named_element | @cil_named_element; +@dotnet_callable = @callable | @cil_method; +@dotnet_variable = @variable | @cil_variable; +@dotnet_field = @field | @cil_field; +@dotnet_parameter = @parameter | @cil_parameter; +@dotnet_declaration = @declaration | @cil_declaration; +@dotnet_member = @member | @cil_member; +@dotnet_event = @event | @cil_event; +@dotnet_property = @property | @cil_property | @indexer; + +// Common types +@dotnet_type = @type | @cil_type; +@dotnet_call = @call | @cil_call_any; +@dotnet_throw = @throw_element | @cil_throw_any; +@dotnet_valueorreftype = @cil_valueorreftype | @value_or_ref_type | @cil_array_type | @void_type; +@dotnet_typeparameter = @type_parameter | @cil_typeparameter; +@dotnet_array_type = @array_type | @cil_array_type; +@dotnet_pointer_type = @pointer_type | @cil_pointer_type; +@dotnet_type_parameter = @type_parameter | @cil_typeparameter; +@dotnet_generic = @dotnet_valueorreftype | @dotnet_callable; + +// Attributes +@dotnet_attribute = @attribute | @cil_attribute; + +// Expressions +@dotnet_expr = @expr | @cil_expr; + +// Literals +@dotnet_literal = @literal_expr | @cil_literal; +@dotnet_string_literal = @string_literal_expr | @cil_ldstr; +@dotnet_int_literal = @integer_literal_expr | @cil_ldc_i; +@dotnet_float_literal = @float_literal_expr | @cil_ldc_r; +@dotnet_null_literal = @null_literal_expr | @cil_ldnull; + +@metadata_entity = @cil_method | @cil_type | @cil_field | @cil_property | @field | @property | + @callable | @value_or_ref_type | @void_type; + +#keyset[entity, location] +metadata_handle(int entity : @metadata_entity ref, int location: @assembly ref, int handle: int ref) diff --git a/csharp/upgrades/cfaa4e90da23a5ca3f0e914fbd5ca689ba0282d9/semmlecode.csharp.dbscheme b/csharp/upgrades/cfaa4e90da23a5ca3f0e914fbd5ca689ba0282d9/semmlecode.csharp.dbscheme new file mode 100644 index 00000000000..b93e202508f --- /dev/null +++ b/csharp/upgrades/cfaa4e90da23a5ca3f0e914fbd5ca689ba0282d9/semmlecode.csharp.dbscheme @@ -0,0 +1,1894 @@ + +/** + * An invocation of the compiler. Note that more than one file may be + * compiled per invocation. For example, this command compiles three + * source files: + * + * csc f1.cs f2.cs f3.cs + * + * The `id` simply identifies the invocation, while `cwd` is the working + * directory from which the compiler was invoked. + */ +compilations( + unique int id : @compilation, + string cwd : string ref +); + +/** + * The arguments that were passed to the extractor for a compiler + * invocation. If `id` is for the compiler invocation + * + * csc f1.cs f2.cs f3.cs + * + * then typically there will be rows for + * + * num | arg + * --- | --- + * 0 | --compiler + * 1 | *path to compiler* + * 2 | --cil + * 3 | f1.cs + * 4 | f2.cs + * 5 | f3.cs + */ +#keyset[id, num] +compilation_args( + int id : @compilation ref, + int num : int ref, + string arg : string ref +); + +/** + * The source files that are compiled by a compiler invocation. + * If `id` is for the compiler invocation + * + * csc f1.cs f2.cs f3.cs + * + * then there will be rows for + * + * num | arg + * --- | --- + * 0 | f1.cs + * 1 | f2.cs + * 2 | f3.cs + */ +#keyset[id, num] +compilation_compiling_files( + int id : @compilation ref, + int num : int ref, + int file : @file ref +); + +/** + * The references used by a compiler invocation. + * If `id` is for the compiler invocation + * + * csc f1.cs f2.cs f3.cs /r:ref1.dll /r:ref2.dll /r:ref3.dll + * + * then there will be rows for + * + * num | arg + * --- | --- + * 0 | ref1.dll + * 1 | ref2.dll + * 2 | ref3.dll + */ +#keyset[id, num] +compilation_referencing_files( + int id : @compilation ref, + int num : int ref, + int file : @file ref +); + +/** + * The time taken by the extractor for a compiler invocation. + * + * For each file `num`, there will be rows for + * + * kind | seconds + * ---- | --- + * 1 | CPU seconds used by the extractor frontend + * 2 | Elapsed seconds during the extractor frontend + * 3 | CPU seconds used by the extractor backend + * 4 | Elapsed seconds during the extractor backend + */ +#keyset[id, num, kind] +compilation_time( + int id : @compilation ref, + int num : int ref, + /* kind: + 1 = frontend_cpu_seconds + 2 = frontend_elapsed_seconds + 3 = extractor_cpu_seconds + 4 = extractor_elapsed_seconds + */ + int kind : int ref, + float seconds : float ref +); + +/** + * An error or warning generated by the extractor. + * The diagnostic message `diagnostic` was generated during compiler + * invocation `compilation`, and is the `file_number_diagnostic_number`th + * message generated while extracting the `file_number`th file of that + * invocation. + */ +#keyset[compilation, file_number, file_number_diagnostic_number] +diagnostic_for( + unique int diagnostic : @diagnostic ref, + int compilation : @compilation ref, + int file_number : int ref, + int file_number_diagnostic_number : int ref +); + +diagnostics( + unique int id: @diagnostic, + int severity: int ref, + string error_tag: string ref, + string error_message: string ref, + string full_error_message: string ref, + int location: @location_default ref +); + +extractor_messages( + unique int id: @extractor_message, + int severity: int ref, + string origin : string ref, + string text : string ref, + string entity : string ref, + int location: @location_default ref, + string stack_trace : string ref +); + +/** + * If extraction was successful, then `cpu_seconds` and + * `elapsed_seconds` are the CPU time and elapsed time (respectively) + * that extraction took for compiler invocation `id`. + */ +compilation_finished( + unique int id : @compilation ref, + float cpu_seconds : float ref, + float elapsed_seconds : float ref +); + +/* + * External artifacts + */ + +externalDefects( + unique int id: @externalDefect, + string queryPath: string ref, + int location: @location ref, + string message: string ref, + float severity: float ref); + +externalMetrics( + unique int id: @externalMetric, + string queryPath: string ref, + int location: @location ref, + float value: float ref); + +externalData( + int id: @externalDataElement, + string path: string ref, + int column: int ref, + string value: string ref); + +snapshotDate( + unique date snapshotDate: date ref); + +sourceLocationPrefix( + string prefix: string ref); + +/* + * Duplicate code + */ + +duplicateCode( + unique int id: @duplication, + string relativePath: string ref, + int equivClass: int ref); + +similarCode( + unique int id: @similarity, + string relativePath: string ref, + int equivClass: int ref); + +@duplication_or_similarity = @duplication | @similarity + +tokens( + int id: @duplication_or_similarity ref, + int offset: int ref, + int beginLine: int ref, + int beginColumn: int ref, + int endLine: int ref, + int endColumn: int ref); + +/* + * C# dbscheme + */ + +/** ELEMENTS **/ + +@element = @declaration | @stmt | @expr | @modifier | @attribute | @namespace_declaration + | @using_directive | @type_parameter_constraints | @external_element + | @xmllocatable | @asp_element | @namespace; + +@declaration = @callable | @generic | @assignable | @namespace; + +@named_element = @namespace | @declaration; + +@declaration_with_accessors = @property | @indexer | @event; + +@assignable = @variable | @assignable_with_accessors | @event; + +@assignable_with_accessors = @property | @indexer; + +@external_element = @externalMetric | @externalDefect | @externalDataElement; + +@attributable = @assembly | @field | @parameter | @operator | @method | @constructor + | @destructor | @callable_accessor | @value_or_ref_type | @declaration_with_accessors + | @local_function; + +/** LOCATIONS, ASEMMBLIES, MODULES, FILES and FOLDERS **/ + +@location = @location_default | @assembly; + +locations_default( + unique int id: @location_default, + int file: @file ref, + int beginLine: int ref, + int beginColumn: int ref, + int endLine: int ref, + int endColumn: int ref); + +@sourceline = @file | @callable | @xmllocatable; + +numlines( + int element_id: @sourceline ref, + int num_lines: int ref, + int num_code: int ref, + int num_comment: int ref); + +assemblies( + unique int id: @assembly, + int file: @file ref, + string fullname: string ref, + string name: string ref, + string version: string ref); + +/* + fromSource(0) = unknown, + fromSource(1) = from source, + fromSource(2) = from library +*/ +files( + unique int id: @file, + string name: string ref, + string simple: string ref, + string ext: string ref, + int fromSource: int ref); + +folders( + unique int id: @folder, + string name: string ref, + string simple: string ref); + +@container = @folder | @file ; + +containerparent( + int parent: @container ref, + unique int child: @container ref); + +file_extraction_mode( + unique int file: @file ref, + int mode: int ref + /* 0 = normal, 1 = standalone extractor */ + ); + +/** NAMESPACES **/ + +@type_container = @namespace | @type; + +namespaces( + unique int id: @namespace, + string name: string ref); + +namespace_declarations( + unique int id: @namespace_declaration, + int namespace_id: @namespace ref); + +namespace_declaration_location( + unique int id: @namespace_declaration ref, + int loc: @location ref); + +parent_namespace( + unique int child_id: @type_container ref, + int namespace_id: @namespace ref); + +@declaration_or_directive = @namespace_declaration | @type | @using_directive; + +parent_namespace_declaration( + int child_id: @declaration_or_directive ref, // cannot be unique because of partial classes + int namespace_id: @namespace_declaration ref); + +@using_directive = @using_namespace_directive | @using_static_directive; + +using_namespace_directives( + unique int id: @using_namespace_directive, + int namespace_id: @namespace ref); + +using_static_directives( + unique int id: @using_static_directive, + int type_id: @type_or_ref ref); + +using_directive_location( + unique int id: @using_directive ref, + int loc: @location ref); + +/** TYPES **/ + +types( + unique int id: @type, + int kind: int ref, + string name: string ref); + +case @type.kind of + 1 = @bool_type +| 2 = @char_type +| 3 = @decimal_type +| 4 = @sbyte_type +| 5 = @short_type +| 6 = @int_type +| 7 = @long_type +| 8 = @byte_type +| 9 = @ushort_type +| 10 = @uint_type +| 11 = @ulong_type +| 12 = @float_type +| 13 = @double_type +| 14 = @enum_type +| 15 = @struct_type +| 17 = @class_type +| 19 = @interface_type +| 20 = @delegate_type +| 21 = @null_type +| 22 = @type_parameter +| 23 = @pointer_type +| 24 = @nullable_type +| 25 = @array_type +| 26 = @void_type +| 27 = @int_ptr_type +| 28 = @uint_ptr_type +| 29 = @dynamic_type +| 30 = @arglist_type +| 31 = @unknown_type +| 32 = @tuple_type + ; + +@simple_type = @bool_type | @char_type | @integral_type | @floating_point_type | @decimal_type; +@integral_type = @signed_integral_type | @unsigned_integral_type; +@signed_integral_type = @sbyte_type | @short_type | @int_type | @long_type; +@unsigned_integral_type = @byte_type | @ushort_type | @uint_type | @ulong_type; +@floating_point_type = @float_type | @double_type; +@value_type = @simple_type | @enum_type | @struct_type | @nullable_type | @int_ptr_type + | @uint_ptr_type | @tuple_type; +@ref_type = @class_type | @interface_type | @array_type | @delegate_type | @null_type + | @dynamic_type; +@value_or_ref_type = @value_type | @ref_type; + +typerefs( + unique int id: @typeref, + string name: string ref); + +typeref_type( + int id: @typeref ref, + unique int typeId: @type ref); + +@type_or_ref = @type | @typeref; + +array_element_type( + unique int array: @array_type ref, + int dimension: int ref, + int rank: int ref, + int element: @type_or_ref ref); + +nullable_underlying_type( + unique int nullable: @nullable_type ref, + int underlying: @type_or_ref ref); + +pointer_referent_type( + unique int pointer: @pointer_type ref, + int referent: @type_or_ref ref); + +enum_underlying_type( + unique int enum_id: @enum_type ref, + int underlying_type_id: @type_or_ref ref); + +delegate_return_type( + unique int delegate_id: @delegate_type ref, + int return_type_id: @type_or_ref ref); + +extend( + unique int sub: @type ref, + int super: @type_or_ref ref); + +@interface_or_ref = @interface_type | @typeref; + +implement( + int sub: @type ref, + int super: @type_or_ref ref); + +type_location( + int id: @type ref, + int loc: @location ref); + +tuple_underlying_type( + unique int tuple: @tuple_type ref, + int struct: @type_or_ref ref); + +#keyset[tuple, index] +tuple_element( + int tuple: @tuple_type ref, + int index: int ref, + unique int field: @field ref); + +attributes( + unique int id: @attribute, + int type_id: @type_or_ref ref, + int target: @attributable ref); + +attribute_location( + int id: @attribute ref, + int loc: @location ref); + +@type_mention_parent = @element | @type_mention; + +type_mention( + unique int id: @type_mention, + int type_id: @type_or_ref ref, + int parent: @type_mention_parent ref); + +type_mention_location( + unique int id: @type_mention ref, + int loc: @location ref); + +@has_type_annotation = @assignable | @type_parameter | @callable | @expr | @delegate_type | @generic; + +/** + * A direct annotation on an entity, for example `string? x;`. + * + * Annotations: + * 2 = reftype is not annotated "!" + * 3 = reftype is annotated "?" + * 4 = readonly ref type / in parameter + * 5 = ref type parameter, return or local variable + * 6 = out parameter + * + * Note that the annotation depends on the element it annotates. + * @assignable: The annotation is on the type of the assignable, for example the variable type. + * @type_parameter: The annotation is on the reftype constraint + * @callable: The annotation is on the return type + * @array_type: The annotation is on the element type + */ +type_annotation(int id: @has_type_annotation ref, int annotation: int ref); + +nullability(unique int nullability: @nullability, int kind: int ref); + +case @nullability.kind of + 0 = @oblivious +| 1 = @not_annotated +| 2 = @annotated +; + +#keyset[parent, index] +nullability_parent(int nullability: @nullability ref, int index: int ref, int parent: @nullability ref) + +type_nullability(int id: @has_type_annotation ref, int nullability: @nullability ref); + +/** + * The nullable flow state of an expression, as determined by Roslyn. + * 0 = none (default, not populated) + * 1 = not null + * 2 = maybe null + */ +expr_flowstate(unique int id: @expr ref, int state: int ref); + +/** GENERICS **/ + +@generic = @type | @method | @local_function; + +type_parameters( + unique int id: @type_parameter ref, + int index: int ref, + int generic_id: @generic ref, + int variance: int ref /* none = 0, out = 1, in = 2 */); + +#keyset[constructed_id, index] +type_arguments( + int id: @type_or_ref ref, + int index: int ref, + int constructed_id: @generic_or_ref ref); + +@generic_or_ref = @generic | @typeref; + +constructed_generic( + unique int constructed: @generic ref, + int generic: @generic_or_ref ref); + +type_parameter_constraints( + unique int id: @type_parameter_constraints, + int param_id: @type_parameter ref); + +type_parameter_constraints_location( + int id: @type_parameter_constraints ref, + int loc: @location ref); + +general_type_parameter_constraints( + int id: @type_parameter_constraints ref, + int kind: int ref /* class = 1, struct = 2, new = 3 */); + +specific_type_parameter_constraints( + int id: @type_parameter_constraints ref, + int base_id: @type_or_ref ref); + +specific_type_parameter_nullability( + int id: @type_parameter_constraints ref, + int base_id: @type_or_ref ref, + int nullability: @nullability ref); + +/** MODIFIERS */ + +@modifiable = @modifiable_direct | @event_accessor; + +@modifiable_direct = @member | @accessor | @local_function | @anonymous_function_expr; + +modifiers( + unique int id: @modifier, + string name: string ref); + +has_modifiers( + int id: @modifiable_direct ref, + int mod_id: @modifier ref); + +compiler_generated(unique int id: @modifiable_direct ref); + +/** MEMBERS **/ + +@member = @method | @constructor | @destructor | @field | @property | @event | @operator | @indexer | @type; + +@named_exprorstmt = @goto_stmt | @labeled_stmt | @expr; + +@virtualizable = @method | @property | @indexer | @event; + +exprorstmt_name( + unique int parent_id: @named_exprorstmt ref, + string name: string ref); + +nested_types( + unique int id: @type ref, + int declaring_type_id: @type ref, + int unbound_id: @type ref); + +properties( + unique int id: @property, + string name: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @property ref); + +property_location( + int id: @property ref, + int loc: @location ref); + +indexers( + unique int id: @indexer, + string name: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @indexer ref); + +indexer_location( + int id: @indexer ref, + int loc: @location ref); + +accessors( + unique int id: @accessor, + int kind: int ref, + string name: string ref, + int declaring_member_id: @member ref, + int unbound_id: @accessor ref); + +case @accessor.kind of + 1 = @getter +| 2 = @setter + ; + +init_only_accessors( + unique int id: @accessor ref); + +accessor_location( + int id: @accessor ref, + int loc: @location ref); + +events( + unique int id: @event, + string name: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @event ref); + +event_location( + int id: @event ref, + int loc: @location ref); + +event_accessors( + unique int id: @event_accessor, + int kind: int ref, + string name: string ref, + int declaring_event_id: @event ref, + int unbound_id: @event_accessor ref); + +case @event_accessor.kind of + 1 = @add_event_accessor +| 2 = @remove_event_accessor + ; + +event_accessor_location( + int id: @event_accessor ref, + int loc: @location ref); + +operators( + unique int id: @operator, + string name: string ref, + string symbol: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @operator ref); + +operator_location( + int id: @operator ref, + int loc: @location ref); + +constant_value( + int id: @variable ref, + string value: string ref); + +/** CALLABLES **/ + +@callable = @method | @constructor | @destructor | @operator | @callable_accessor | @anonymous_function_expr | @local_function; + +@callable_accessor = @accessor | @event_accessor; + +methods( + unique int id: @method, + string name: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @method ref); + +method_location( + int id: @method ref, + int loc: @location ref); + +constructors( + unique int id: @constructor, + string name: string ref, + int declaring_type_id: @type ref, + int unbound_id: @constructor ref); + +constructor_location( + int id: @constructor ref, + int loc: @location ref); + +destructors( + unique int id: @destructor, + string name: string ref, + int declaring_type_id: @type ref, + int unbound_id: @destructor ref); + +destructor_location( + int id: @destructor ref, + int loc: @location ref); + +overrides( + int id: @callable ref, + int base_id: @callable ref); + +explicitly_implements( + int id: @member ref, + int interface_id: @interface_or_ref ref); + +local_functions( + unique int id: @local_function, + string name: string ref, + int return_type: @type ref, + int unbound_id: @local_function ref); + +local_function_stmts( + unique int fn: @local_function_stmt ref, + int stmt: @local_function ref); + +/** VARIABLES **/ + +@variable = @local_scope_variable | @field; + +@local_scope_variable = @local_variable | @parameter; + +fields( + unique int id: @field, + int kind: int ref, + string name: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @field ref); + +case @field.kind of + 1 = @addressable_field +| 2 = @constant + ; + +field_location( + int id: @field ref, + int loc: @location ref); + +localvars( + unique int id: @local_variable, + int kind: int ref, + string name: string ref, + int implicitly_typed: int ref /* 0 = no, 1 = yes */, + int type_id: @type_or_ref ref, + int parent_id: @local_var_decl_expr ref); + +case @local_variable.kind of + 1 = @addressable_local_variable +| 2 = @local_constant +| 3 = @local_variable_ref + ; + +localvar_location( + unique int id: @local_variable ref, + int loc: @location ref); + +@parameterizable = @callable | @delegate_type | @indexer; + +#keyset[name, parent_id] +#keyset[index, parent_id] +params( + unique int id: @parameter, + string name: string ref, + int type_id: @type_or_ref ref, + int index: int ref, + int mode: int ref, /* value = 0, ref = 1, out = 2, array = 3, this = 4 */ + int parent_id: @parameterizable ref, + int unbound_id: @parameter ref); + +param_location( + int id: @parameter ref, + int loc: @location ref); + +/** STATEMENTS **/ + +@exprorstmt_parent = @control_flow_element | @top_level_exprorstmt_parent; + +statements( + unique int id: @stmt, + int kind: int ref); + +#keyset[index, parent] +stmt_parent( + unique int stmt: @stmt ref, + int index: int ref, + int parent: @control_flow_element ref); + +@top_level_stmt_parent = @callable; + +// [index, parent] is not a keyset because the same parent may be compiled multiple times +stmt_parent_top_level( + unique int stmt: @stmt ref, + int index: int ref, + int parent: @top_level_stmt_parent ref); + +case @stmt.kind of + 1 = @block_stmt +| 2 = @expr_stmt +| 3 = @if_stmt +| 4 = @switch_stmt +| 5 = @while_stmt +| 6 = @do_stmt +| 7 = @for_stmt +| 8 = @foreach_stmt +| 9 = @break_stmt +| 10 = @continue_stmt +| 11 = @goto_stmt +| 12 = @goto_case_stmt +| 13 = @goto_default_stmt +| 14 = @throw_stmt +| 15 = @return_stmt +| 16 = @yield_stmt +| 17 = @try_stmt +| 18 = @checked_stmt +| 19 = @unchecked_stmt +| 20 = @lock_stmt +| 21 = @using_block_stmt +| 22 = @var_decl_stmt +| 23 = @const_decl_stmt +| 24 = @empty_stmt +| 25 = @unsafe_stmt +| 26 = @fixed_stmt +| 27 = @label_stmt +| 28 = @catch +| 29 = @case_stmt +| 30 = @local_function_stmt +| 31 = @using_decl_stmt + ; + +@using_stmt = @using_block_stmt | @using_decl_stmt; + +@labeled_stmt = @label_stmt | @case; + +@decl_stmt = @var_decl_stmt | @const_decl_stmt | @using_decl_stmt; + +@cond_stmt = @if_stmt | @switch_stmt; + +@loop_stmt = @while_stmt | @do_stmt | @for_stmt | @foreach_stmt; + +@jump_stmt = @break_stmt | @goto_any_stmt | @continue_stmt | @throw_stmt | @return_stmt + | @yield_stmt; + +@goto_any_stmt = @goto_default_stmt | @goto_case_stmt | @goto_stmt; + + +stmt_location( + unique int id: @stmt ref, + int loc: @location ref); + +catch_type( + unique int catch_id: @catch ref, + int type_id: @type_or_ref ref, + int kind: int ref /* explicit = 1, implicit = 2 */); + +/** EXPRESSIONS **/ + +expressions( + unique int id: @expr, + int kind: int ref, + int type_id: @type_or_ref ref); + +#keyset[index, parent] +expr_parent( + unique int expr: @expr ref, + int index: int ref, + int parent: @control_flow_element ref); + +@top_level_expr_parent = @attribute | @field | @property | @indexer | @parameter; + +@top_level_exprorstmt_parent = @top_level_expr_parent | @top_level_stmt_parent; + +// [index, parent] is not a keyset because the same parent may be compiled multiple times +expr_parent_top_level( + unique int expr: @expr ref, + int index: int ref, + int parent: @top_level_exprorstmt_parent ref); + +case @expr.kind of +/* literal */ + 1 = @bool_literal_expr +| 2 = @char_literal_expr +| 3 = @decimal_literal_expr +| 4 = @int_literal_expr +| 5 = @long_literal_expr +| 6 = @uint_literal_expr +| 7 = @ulong_literal_expr +| 8 = @float_literal_expr +| 9 = @double_literal_expr +| 10 = @string_literal_expr +| 11 = @null_literal_expr +/* primary & unary */ +| 12 = @this_access_expr +| 13 = @base_access_expr +| 14 = @local_variable_access_expr +| 15 = @parameter_access_expr +| 16 = @field_access_expr +| 17 = @property_access_expr +| 18 = @method_access_expr +| 19 = @event_access_expr +| 20 = @indexer_access_expr +| 21 = @array_access_expr +| 22 = @type_access_expr +| 23 = @typeof_expr +| 24 = @method_invocation_expr +| 25 = @delegate_invocation_expr +| 26 = @operator_invocation_expr +| 27 = @cast_expr +| 28 = @object_creation_expr +| 29 = @explicit_delegate_creation_expr +| 30 = @implicit_delegate_creation_expr +| 31 = @array_creation_expr +| 32 = @default_expr +| 33 = @plus_expr +| 34 = @minus_expr +| 35 = @bit_not_expr +| 36 = @log_not_expr +| 37 = @post_incr_expr +| 38 = @post_decr_expr +| 39 = @pre_incr_expr +| 40 = @pre_decr_expr +/* multiplicative */ +| 41 = @mul_expr +| 42 = @div_expr +| 43 = @rem_expr +/* additive */ +| 44 = @add_expr +| 45 = @sub_expr +/* shift */ +| 46 = @lshift_expr +| 47 = @rshift_expr +/* relational */ +| 48 = @lt_expr +| 49 = @gt_expr +| 50 = @le_expr +| 51 = @ge_expr +/* equality */ +| 52 = @eq_expr +| 53 = @ne_expr +/* logical */ +| 54 = @bit_and_expr +| 55 = @bit_xor_expr +| 56 = @bit_or_expr +| 57 = @log_and_expr +| 58 = @log_or_expr +/* type testing */ +| 59 = @is_expr +| 60 = @as_expr +/* null coalescing */ +| 61 = @null_coalescing_expr +/* conditional */ +| 62 = @conditional_expr +/* assignment */ +| 63 = @simple_assign_expr +| 64 = @assign_add_expr +| 65 = @assign_sub_expr +| 66 = @assign_mul_expr +| 67 = @assign_div_expr +| 68 = @assign_rem_expr +| 69 = @assign_and_expr +| 70 = @assign_xor_expr +| 71 = @assign_or_expr +| 72 = @assign_lshift_expr +| 73 = @assign_rshift_expr +/* more */ +| 74 = @object_init_expr +| 75 = @collection_init_expr +| 76 = @array_init_expr +| 77 = @checked_expr +| 78 = @unchecked_expr +| 79 = @constructor_init_expr +| 80 = @add_event_expr +| 81 = @remove_event_expr +| 82 = @par_expr +| 83 = @local_var_decl_expr +| 84 = @lambda_expr +| 85 = @anonymous_method_expr +| 86 = @namespace_expr +/* dynamic */ +| 92 = @dynamic_element_access_expr +| 93 = @dynamic_member_access_expr +/* unsafe */ +| 100 = @pointer_indirection_expr +| 101 = @address_of_expr +| 102 = @sizeof_expr +/* async */ +| 103 = @await_expr +/* C# 6.0 */ +| 104 = @nameof_expr +| 105 = @interpolated_string_expr +| 106 = @unknown_expr +/* C# 7.0 */ +| 107 = @throw_expr +| 108 = @tuple_expr +| 109 = @local_function_invocation_expr +| 110 = @ref_expr +| 111 = @discard_expr +/* C# 8.0 */ +| 112 = @range_expr +| 113 = @index_expr +| 114 = @switch_expr +| 115 = @recursive_pattern_expr +| 116 = @property_pattern_expr +| 117 = @positional_pattern_expr +| 118 = @switch_case_expr +| 119 = @assign_coalesce_expr +| 120 = @suppress_nullable_warning_expr +| 121 = @namespace_access_expr +; + +@switch = @switch_stmt | @switch_expr; +@case = @case_stmt | @switch_case_expr; +@pattern_match = @case | @is_expr; + +@integer_literal_expr = @int_literal_expr | @long_literal_expr | @uint_literal_expr | @ulong_literal_expr; +@real_literal_expr = @float_literal_expr | @double_literal_expr | @decimal_literal_expr; +@literal_expr = @bool_literal_expr | @char_literal_expr | @integer_literal_expr | @real_literal_expr + | @string_literal_expr | @null_literal_expr; + +@assign_expr = @simple_assign_expr | @assign_op_expr | @local_var_decl_expr; +@assign_op_expr = @assign_arith_expr | @assign_bitwise_expr | @assign_event_expr | @assign_coalesce_expr; +@assign_event_expr = @add_event_expr | @remove_event_expr; + +@assign_arith_expr = @assign_add_expr | @assign_sub_expr | @assign_mul_expr | @assign_div_expr + | @assign_rem_expr +@assign_bitwise_expr = @assign_and_expr | @assign_or_expr | @assign_xor_expr + | @assign_lshift_expr | @assign_rshift_expr; + +@member_access_expr = @field_access_expr | @property_access_expr | @indexer_access_expr | @event_access_expr + | @method_access_expr | @type_access_expr | @dynamic_member_access_expr; +@access_expr = @member_access_expr | @this_access_expr | @base_access_expr | @assignable_access_expr | @namespace_access_expr; +@element_access_expr = @indexer_access_expr | @array_access_expr | @dynamic_element_access_expr; + +@local_variable_access = @local_variable_access_expr | @local_var_decl_expr; +@local_scope_variable_access_expr = @parameter_access_expr | @local_variable_access; +@variable_access_expr = @local_scope_variable_access_expr | @field_access_expr; + +@assignable_access_expr = @variable_access_expr | @property_access_expr | @element_access_expr + | @event_access_expr | @dynamic_member_access_expr; + +@objectorcollection_init_expr = @object_init_expr | @collection_init_expr; + +@delegate_creation_expr = @explicit_delegate_creation_expr | @implicit_delegate_creation_expr; + +@bin_arith_op_expr = @mul_expr | @div_expr | @rem_expr | @add_expr | @sub_expr; +@incr_op_expr = @pre_incr_expr | @post_incr_expr; +@decr_op_expr = @pre_decr_expr | @post_decr_expr; +@mut_op_expr = @incr_op_expr | @decr_op_expr; +@un_arith_op_expr = @plus_expr | @minus_expr | @mut_op_expr; +@arith_op_expr = @bin_arith_op_expr | @un_arith_op_expr; + +@ternary_log_op_expr = @conditional_expr; +@bin_log_op_expr = @log_and_expr | @log_or_expr | @null_coalescing_expr; +@un_log_op_expr = @log_not_expr; +@log_expr = @un_log_op_expr | @bin_log_op_expr | @ternary_log_op_expr; + +@bin_bit_op_expr = @bit_and_expr | @bit_or_expr | @bit_xor_expr | @lshift_expr + | @rshift_expr; +@un_bit_op_expr = @bit_not_expr; +@bit_expr = @un_bit_op_expr | @bin_bit_op_expr; + +@equality_op_expr = @eq_expr | @ne_expr; +@rel_op_expr = @gt_expr | @lt_expr| @ge_expr | @le_expr; +@comp_expr = @equality_op_expr | @rel_op_expr; + +@op_expr = @assign_expr | @un_op | @bin_op | @ternary_op; + +@ternary_op = @ternary_log_op_expr; +@bin_op = @bin_arith_op_expr | @bin_log_op_expr | @bin_bit_op_expr | @comp_expr; +@un_op = @un_arith_op_expr | @un_log_op_expr | @un_bit_op_expr | @sizeof_expr + | @pointer_indirection_expr | @address_of_expr; + +@anonymous_function_expr = @lambda_expr | @anonymous_method_expr; + +@call = @method_invocation_expr | @constructor_init_expr | @operator_invocation_expr + | @delegate_invocation_expr | @object_creation_expr | @call_access_expr + | @local_function_invocation_expr; + +@call_access_expr = @property_access_expr | @event_access_expr | @indexer_access_expr; + +@late_bindable_expr = @dynamic_element_access_expr | @dynamic_member_access_expr + | @object_creation_expr | @method_invocation_expr | @operator_invocation_expr; + +@throw_element = @throw_expr | @throw_stmt; + +implicitly_typed_array_creation( + unique int id: @array_creation_expr ref); + +explicitly_sized_array_creation( + unique int id: @array_creation_expr ref); + +stackalloc_array_creation( + unique int id: @array_creation_expr ref); + +mutator_invocation_mode( + unique int id: @operator_invocation_expr ref, + int mode: int ref /* prefix = 1, postfix = 2*/); + +expr_compiler_generated( + unique int id: @expr ref); + +expr_value( + unique int id: @expr ref, + string value: string ref); + +expr_call( + unique int caller_id: @expr ref, + int target_id: @callable ref); + +expr_access( + unique int accesser_id: @access_expr ref, + int target_id: @accessible ref); + +@accessible = @method | @assignable | @local_function | @namespace; + +expr_location( + unique int id: @expr ref, + int loc: @location ref); + +dynamic_member_name( + unique int id: @late_bindable_expr ref, + string name: string ref); + +@qualifiable_expr = @member_access_expr + | @method_invocation_expr + | @element_access_expr; + +conditional_access( + unique int id: @qualifiable_expr ref); + +expr_argument( + unique int id: @expr ref, + int mode: int ref); + /* mode is the same as params: value = 0, ref = 1, out = 2 */ + +expr_argument_name( + unique int id: @expr ref, + string name: string ref); + +/** CONTROL/DATA FLOW **/ + +@control_flow_element = @stmt | @expr; + +/* XML Files */ + +xmlEncoding ( + unique int id: @file ref, + string encoding: string ref); + +xmlDTDs( + unique int id: @xmldtd, + string root: string ref, + string publicId: string ref, + string systemId: string ref, + int fileid: @file ref); + +xmlElements( + unique int id: @xmlelement, + string name: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int fileid: @file ref); + +xmlAttrs( + unique int id: @xmlattribute, + int elementid: @xmlelement ref, + string name: string ref, + string value: string ref, + int idx: int ref, + int fileid: @file ref); + +xmlNs( + int id: @xmlnamespace, + string prefixName: string ref, + string URI: string ref, + int fileid: @file ref); + +xmlHasNs( + int elementId: @xmlnamespaceable ref, + int nsId: @xmlnamespace ref, + int fileid: @file ref); + +xmlComments( + unique int id: @xmlcomment, + string text: string ref, + int parentid: @xmlparent ref, + int fileid: @file ref); + +xmlChars( + unique int id: @xmlcharacters, + string text: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int isCDATA: int ref, + int fileid: @file ref); + +@xmlparent = @file | @xmlelement; +@xmlnamespaceable = @xmlelement | @xmlattribute; + +xmllocations( + int xmlElement: @xmllocatable ref, + int location: @location_default ref); + +@xmllocatable = @xmlcharacters | @xmlelement | @xmlcomment | @xmlattribute | @xmldtd | @file | @xmlnamespace; + +/* Comments */ + +commentline( + unique int id: @commentline, + int kind: int ref, + string text: string ref, + string rawtext: string ref); + +case @commentline.kind of + 0 = @singlelinecomment +| 1 = @xmldoccomment +| 2 = @multilinecomment; + +commentline_location( + unique int id: @commentline ref, + int loc: @location ref); + +commentblock( + unique int id : @commentblock); + +commentblock_location( + unique int id: @commentblock ref, + int loc: @location ref); + +commentblock_binding( + int id: @commentblock ref, + int entity: @element ref, + int bindtype: int ref); /* 0: Parent, 1: Best, 2: Before, 3: After */ + +commentblock_child( + int id: @commentblock ref, + int commentline: @commentline ref, + int index: int ref); + +/* ASP.NET */ + +case @asp_element.kind of + 0=@asp_close_tag +| 1=@asp_code +| 2=@asp_comment +| 3=@asp_data_binding +| 4=@asp_directive +| 5=@asp_open_tag +| 6=@asp_quoted_string +| 7=@asp_text +| 8=@asp_xml_directive; + +@asp_attribute = @asp_code | @asp_data_binding | @asp_quoted_string; + +asp_elements( + unique int id: @asp_element, + int kind: int ref, + int loc: @location ref); + +asp_comment_server(unique int comment: @asp_comment ref); +asp_code_inline(unique int code: @asp_code ref); +asp_directive_attribute( + int directive: @asp_directive ref, + int index: int ref, + string name: string ref, + int value: @asp_quoted_string ref); +asp_directive_name( + unique int directive: @asp_directive ref, + string name: string ref); +asp_element_body( + unique int element: @asp_element ref, + string body: string ref); +asp_tag_attribute( + int tag: @asp_open_tag ref, + int index: int ref, + string name: string ref, + int attribute: @asp_attribute ref); +asp_tag_name( + unique int tag: @asp_open_tag ref, + string name: string ref); +asp_tag_isempty(int tag: @asp_open_tag ref); + +/* Common Intermediate Language - CIL */ + +case @cil_instruction.opcode of + 0 = @cil_nop +| 1 = @cil_break +| 2 = @cil_ldarg_0 +| 3 = @cil_ldarg_1 +| 4 = @cil_ldarg_2 +| 5 = @cil_ldarg_3 +| 6 = @cil_ldloc_0 +| 7 = @cil_ldloc_1 +| 8 = @cil_ldloc_2 +| 9 = @cil_ldloc_3 +| 10 = @cil_stloc_0 +| 11 = @cil_stloc_1 +| 12 = @cil_stloc_2 +| 13 = @cil_stloc_3 +| 14 = @cil_ldarg_s +| 15 = @cil_ldarga_s +| 16 = @cil_starg_s +| 17 = @cil_ldloc_s +| 18 = @cil_ldloca_s +| 19 = @cil_stloc_s +| 20 = @cil_ldnull +| 21 = @cil_ldc_i4_m1 +| 22 = @cil_ldc_i4_0 +| 23 = @cil_ldc_i4_1 +| 24 = @cil_ldc_i4_2 +| 25 = @cil_ldc_i4_3 +| 26 = @cil_ldc_i4_4 +| 27 = @cil_ldc_i4_5 +| 28 = @cil_ldc_i4_6 +| 29 = @cil_ldc_i4_7 +| 30 = @cil_ldc_i4_8 +| 31 = @cil_ldc_i4_s +| 32 = @cil_ldc_i4 +| 33 = @cil_ldc_i8 +| 34 = @cil_ldc_r4 +| 35 = @cil_ldc_r8 +| 37 = @cil_dup +| 38 = @cil_pop +| 39 = @cil_jmp +| 40 = @cil_call +| 41 = @cil_calli +| 42 = @cil_ret +| 43 = @cil_br_s +| 44 = @cil_brfalse_s +| 45 = @cil_brtrue_s +| 46 = @cil_beq_s +| 47 = @cil_bge_s +| 48 = @cil_bgt_s +| 49 = @cil_ble_s +| 50 = @cil_blt_s +| 51 = @cil_bne_un_s +| 52 = @cil_bge_un_s +| 53 = @cil_bgt_un_s +| 54 = @cil_ble_un_s +| 55 = @cil_blt_un_s +| 56 = @cil_br +| 57 = @cil_brfalse +| 58 = @cil_brtrue +| 59 = @cil_beq +| 60 = @cil_bge +| 61 = @cil_bgt +| 62 = @cil_ble +| 63 = @cil_blt +| 64 = @cil_bne_un +| 65 = @cil_bge_un +| 66 = @cil_bgt_un +| 67 = @cil_ble_un +| 68 = @cil_blt_un +| 69 = @cil_switch +| 70 = @cil_ldind_i1 +| 71 = @cil_ldind_u1 +| 72 = @cil_ldind_i2 +| 73 = @cil_ldind_u2 +| 74 = @cil_ldind_i4 +| 75 = @cil_ldind_u4 +| 76 = @cil_ldind_i8 +| 77 = @cil_ldind_i +| 78 = @cil_ldind_r4 +| 79 = @cil_ldind_r8 +| 80 = @cil_ldind_ref +| 81 = @cil_stind_ref +| 82 = @cil_stind_i1 +| 83 = @cil_stind_i2 +| 84 = @cil_stind_i4 +| 85 = @cil_stind_i8 +| 86 = @cil_stind_r4 +| 87 = @cil_stind_r8 +| 88 = @cil_add +| 89 = @cil_sub +| 90 = @cil_mul +| 91 = @cil_div +| 92 = @cil_div_un +| 93 = @cil_rem +| 94 = @cil_rem_un +| 95 = @cil_and +| 96 = @cil_or +| 97 = @cil_xor +| 98 = @cil_shl +| 99 = @cil_shr +| 100 = @cil_shr_un +| 101 = @cil_neg +| 102 = @cil_not +| 103 = @cil_conv_i1 +| 104 = @cil_conv_i2 +| 105 = @cil_conv_i4 +| 106 = @cil_conv_i8 +| 107 = @cil_conv_r4 +| 108 = @cil_conv_r8 +| 109 = @cil_conv_u4 +| 110 = @cil_conv_u8 +| 111 = @cil_callvirt +| 112 = @cil_cpobj +| 113 = @cil_ldobj +| 114 = @cil_ldstr +| 115 = @cil_newobj +| 116 = @cil_castclass +| 117 = @cil_isinst +| 118 = @cil_conv_r_un +| 121 = @cil_unbox +| 122 = @cil_throw +| 123 = @cil_ldfld +| 124 = @cil_ldflda +| 125 = @cil_stfld +| 126 = @cil_ldsfld +| 127 = @cil_ldsflda +| 128 = @cil_stsfld +| 129 = @cil_stobj +| 130 = @cil_conv_ovf_i1_un +| 131 = @cil_conv_ovf_i2_un +| 132 = @cil_conv_ovf_i4_un +| 133 = @cil_conv_ovf_i8_un +| 134 = @cil_conv_ovf_u1_un +| 135 = @cil_conv_ovf_u2_un +| 136 = @cil_conv_ovf_u4_un +| 137 = @cil_conv_ovf_u8_un +| 138 = @cil_conv_ovf_i_un +| 139 = @cil_conv_ovf_u_un +| 140 = @cil_box +| 141 = @cil_newarr +| 142 = @cil_ldlen +| 143 = @cil_ldelema +| 144 = @cil_ldelem_i1 +| 145 = @cil_ldelem_u1 +| 146 = @cil_ldelem_i2 +| 147 = @cil_ldelem_u2 +| 148 = @cil_ldelem_i4 +| 149 = @cil_ldelem_u4 +| 150 = @cil_ldelem_i8 +| 151 = @cil_ldelem_i +| 152 = @cil_ldelem_r4 +| 153 = @cil_ldelem_r8 +| 154 = @cil_ldelem_ref +| 155 = @cil_stelem_i +| 156 = @cil_stelem_i1 +| 157 = @cil_stelem_i2 +| 158 = @cil_stelem_i4 +| 159 = @cil_stelem_i8 +| 160 = @cil_stelem_r4 +| 161 = @cil_stelem_r8 +| 162 = @cil_stelem_ref +| 163 = @cil_ldelem +| 164 = @cil_stelem +| 165 = @cil_unbox_any +| 179 = @cil_conv_ovf_i1 +| 180 = @cil_conv_ovf_u1 +| 181 = @cil_conv_ovf_i2 +| 182 = @cil_conv_ovf_u2 +| 183 = @cil_conv_ovf_i4 +| 184 = @cil_conv_ovf_u4 +| 185 = @cil_conv_ovf_i8 +| 186 = @cil_conv_ovf_u8 +| 194 = @cil_refanyval +| 195 = @cil_ckinfinite +| 198 = @cil_mkrefany +| 208 = @cil_ldtoken +| 209 = @cil_conv_u2 +| 210 = @cil_conv_u1 +| 211 = @cil_conv_i +| 212 = @cil_conv_ovf_i +| 213 = @cil_conv_ovf_u +| 214 = @cil_add_ovf +| 215 = @cil_add_ovf_un +| 216 = @cil_mul_ovf +| 217 = @cil_mul_ovf_un +| 218 = @cil_sub_ovf +| 219 = @cil_sub_ovf_un +| 220 = @cil_endfinally +| 221 = @cil_leave +| 222 = @cil_leave_s +| 223 = @cil_stind_i +| 224 = @cil_conv_u +| 65024 = @cil_arglist +| 65025 = @cil_ceq +| 65026 = @cil_cgt +| 65027 = @cil_cgt_un +| 65028 = @cil_clt +| 65029 = @cil_clt_un +| 65030 = @cil_ldftn +| 65031 = @cil_ldvirtftn +| 65033 = @cil_ldarg +| 65034 = @cil_ldarga +| 65035 = @cil_starg +| 65036 = @cil_ldloc +| 65037 = @cil_ldloca +| 65038 = @cil_stloc +| 65039 = @cil_localloc +| 65041 = @cil_endfilter +| 65042 = @cil_unaligned +| 65043 = @cil_volatile +| 65044 = @cil_tail +| 65045 = @cil_initobj +| 65046 = @cil_constrained +| 65047 = @cil_cpblk +| 65048 = @cil_initblk +| 65050 = @cil_rethrow +| 65052 = @cil_sizeof +| 65053 = @cil_refanytype +| 65054 = @cil_readonly +; + +// CIL ignored instructions + +@cil_ignore = @cil_nop | @cil_break | @cil_volatile | @cil_unaligned; + +// CIL local/parameter/field access + +@cil_ldarg_any = @cil_ldarg_0 | @cil_ldarg_1 | @cil_ldarg_2 | @cil_ldarg_3 | @cil_ldarg_s | @cil_ldarga_s | @cil_ldarg | @cil_ldarga; +@cil_starg_any = @cil_starg | @cil_starg_s; + +@cil_ldloc_any = @cil_ldloc_0 | @cil_ldloc_1 | @cil_ldloc_2 | @cil_ldloc_3 | @cil_ldloc_s | @cil_ldloca_s | @cil_ldloc | @cil_ldloca; +@cil_stloc_any = @cil_stloc_0 | @cil_stloc_1 | @cil_stloc_2 | @cil_stloc_3 | @cil_stloc_s | @cil_stloc; + +@cil_ldfld_any = @cil_ldfld | @cil_ldsfld | @cil_ldsflda | @cil_ldflda; +@cil_stfld_any = @cil_stfld | @cil_stsfld; + +@cil_local_access = @cil_stloc_any | @cil_ldloc_any; +@cil_arg_access = @cil_starg_any | @cil_ldarg_any; +@cil_read_access = @cil_ldloc_any | @cil_ldarg_any | @cil_ldfld_any; +@cil_write_access = @cil_stloc_any | @cil_starg_any | @cil_stfld_any; + +@cil_stack_access = @cil_local_access | @cil_arg_access; +@cil_field_access = @cil_ldfld_any | @cil_stfld_any; + +@cil_access = @cil_read_access | @cil_write_access; + +// CIL constant/literal instructions + +@cil_ldc_i = @cil_ldc_i4_any | @cil_ldc_i8; + +@cil_ldc_i4_any = @cil_ldc_i4_m1 | @cil_ldc_i4_0 | @cil_ldc_i4_1 | @cil_ldc_i4_2 | @cil_ldc_i4_3 | + @cil_ldc_i4_4 | @cil_ldc_i4_5 | @cil_ldc_i4_6 | @cil_ldc_i4_7 | @cil_ldc_i4_8 | @cil_ldc_i4_s | @cil_ldc_i4; + +@cil_ldc_r = @cil_ldc_r4 | @cil_ldc_r8; + +@cil_literal = @cil_ldnull | @cil_ldc_i | @cil_ldc_r | @cil_ldstr; + +// Control flow + +@cil_conditional_jump = @cil_binary_jump | @cil_unary_jump; +@cil_binary_jump = @cil_beq_s | @cil_bge_s | @cil_bgt_s | @cil_ble_s | @cil_blt_s | + @cil_bne_un_s | @cil_bge_un_s | @cil_bgt_un_s | @cil_ble_un_s | @cil_blt_un_s | + @cil_beq | @cil_bge | @cil_bgt | @cil_ble | @cil_blt | + @cil_bne_un | @cil_bge_un | @cil_bgt_un | @cil_ble_un | @cil_blt_un; +@cil_unary_jump = @cil_brfalse_s | @cil_brtrue_s | @cil_brfalse | @cil_brtrue | @cil_switch; +@cil_unconditional_jump = @cil_br | @cil_br_s | @cil_leave_any; +@cil_leave_any = @cil_leave | @cil_leave_s; +@cil_jump = @cil_unconditional_jump | @cil_conditional_jump; + +// CIL call instructions + +@cil_call_any = @cil_jmp | @cil_call | @cil_calli | @cil_tail | @cil_callvirt | @cil_newobj; + +// CIL expression instructions + +@cil_expr = @cil_literal | @cil_binary_expr | @cil_unary_expr | @cil_call_any | @cil_read_access | + @cil_newarr | @cil_ldtoken | @cil_sizeof | + @cil_ldftn | @cil_ldvirtftn | @cil_localloc | @cil_mkrefany | @cil_refanytype | @cil_arglist | @cil_dup; + +@cil_unary_expr = + @cil_conversion_operation | @cil_unary_arithmetic_operation | @cil_unary_bitwise_operation| + @cil_ldlen | @cil_isinst | @cil_box | @cil_ldobj | @cil_castclass | @cil_unbox_any | + @cil_ldind | @cil_unbox; + +@cil_conversion_operation = + @cil_conv_i1 | @cil_conv_i2 | @cil_conv_i4 | @cil_conv_i8 | + @cil_conv_u1 | @cil_conv_u2 | @cil_conv_u4 | @cil_conv_u8 | + @cil_conv_ovf_i | @cil_conv_ovf_i_un | @cil_conv_ovf_i1 | @cil_conv_ovf_i1_un | + @cil_conv_ovf_i2 | @cil_conv_ovf_i2_un | @cil_conv_ovf_i4 | @cil_conv_ovf_i4_un | + @cil_conv_ovf_i8 | @cil_conv_ovf_i8_un | @cil_conv_ovf_u | @cil_conv_ovf_u_un | + @cil_conv_ovf_u1 | @cil_conv_ovf_u1_un | @cil_conv_ovf_u2 | @cil_conv_ovf_u2_un | + @cil_conv_ovf_u4 | @cil_conv_ovf_u4_un | @cil_conv_ovf_u8 | @cil_conv_ovf_u8_un | + @cil_conv_r4 | @cil_conv_r8 | @cil_conv_ovf_u2 | @cil_conv_ovf_u2_un | + @cil_conv_i | @cil_conv_u | @cil_conv_r_un; + +@cil_ldind = @cil_ldind_i | @cil_ldind_i1 | @cil_ldind_i2 | @cil_ldind_i4 | @cil_ldind_i8 | + @cil_ldind_r4 | @cil_ldind_r8 | @cil_ldind_ref | @cil_ldind_u1 | @cil_ldind_u2 | @cil_ldind_u4; + +@cil_stind = @cil_stind_i | @cil_stind_i1 | @cil_stind_i2 | @cil_stind_i4 | @cil_stind_i8 | + @cil_stind_r4 | @cil_stind_r8 | @cil_stind_ref; + +@cil_bitwise_operation = @cil_binary_bitwise_operation | @cil_unary_bitwise_operation; + +@cil_binary_bitwise_operation = @cil_and | @cil_or | @cil_xor | @cil_shr | @cil_shr | @cil_shr_un | @cil_shl; + +@cil_binary_arithmetic_operation = @cil_add | @cil_sub | @cil_mul | @cil_div | @cil_div_un | + @cil_rem | @cil_rem_un | @cil_add_ovf | @cil_add_ovf_un | @cil_mul_ovf | @cil_mul_ovf_un | + @cil_sub_ovf | @cil_sub_ovf_un; + +@cil_unary_bitwise_operation = @cil_not; + +@cil_binary_expr = @cil_binary_arithmetic_operation | @cil_binary_bitwise_operation | @cil_read_array | @cil_comparison_operation; + +@cil_unary_arithmetic_operation = @cil_neg; + +@cil_comparison_operation = @cil_cgt_un | @cil_ceq | @cil_cgt | @cil_clt | @cil_clt_un; + +// Elements that retrieve an address of something +@cil_read_ref = @cil_ldloca_s | @cil_ldarga_s | @cil_ldflda | @cil_ldsflda | @cil_ldelema; + +// CIL array instructions + +@cil_read_array = + @cil_ldelem | @cil_ldelema | @cil_ldelem_i1 | @cil_ldelem_ref | @cil_ldelem_i | + @cil_ldelem_i1 | @cil_ldelem_i2 | @cil_ldelem_i4 | @cil_ldelem_i8 | @cil_ldelem_r4 | + @cil_ldelem_r8 | @cil_ldelem_u1 | @cil_ldelem_u2 | @cil_ldelem_u4; + +@cil_write_array = @cil_stelem | @cil_stelem_ref | + @cil_stelem_i | @cil_stelem_i1 | @cil_stelem_i2 | @cil_stelem_i4 | @cil_stelem_i8 | + @cil_stelem_r4 | @cil_stelem_r8; + +@cil_throw_any = @cil_throw | @cil_rethrow; + +#keyset[impl, index] +cil_instruction( + unique int id: @cil_instruction, + int opcode: int ref, + int index: int ref, + int impl: @cil_method_implementation ref); + +cil_jump( + unique int instruction: @cil_jump ref, + int target: @cil_instruction ref); + +cil_access( + unique int instruction: @cil_instruction ref, + int target: @cil_accessible ref); + +cil_value( + unique int instruction: @cil_literal ref, + string value: string ref); + +#keyset[instruction, index] +cil_switch( + int instruction: @cil_switch ref, + int index: int ref, + int target: @cil_instruction ref); + +cil_instruction_location( + unique int id: @cil_instruction ref, + int loc: @location ref); + +cil_type_location( + int id: @cil_type ref, + int loc: @location ref); + +cil_method_location( + int id: @cil_method ref, + int loc: @location ref); + +@cil_namespace = @namespace; + +@cil_type_container = @cil_type | @cil_namespace | @cil_method; + +case @cil_type.kind of + 0 = @cil_valueorreftype +| 1 = @cil_typeparameter +| 2 = @cil_array_type +| 3 = @cil_pointer_type +; + +cil_type( + unique int id: @cil_type, + string name: string ref, + int kind: int ref, + int parent: @cil_type_container ref, + int sourceDecl: @cil_type ref); + +cil_pointer_type( + unique int id: @cil_pointer_type ref, + int pointee: @cil_type ref); + +cil_array_type( + unique int id: @cil_array_type ref, + int element_type: @cil_type ref, + int rank: int ref); + +cil_method( + unique int id: @cil_method, + string name: string ref, + int parent: @cil_type ref, + int return_type: @cil_type ref); + +cil_method_source_declaration( + unique int method: @cil_method ref, + int source: @cil_method ref); + +cil_method_implementation( + unique int id: @cil_method_implementation, + int method: @cil_method ref, + int location: @assembly ref); + +cil_implements( + int id: @cil_method ref, + int decl: @cil_method ref); + +#keyset[parent, name] +cil_field( + unique int id: @cil_field, + int parent: @cil_type ref, + string name: string ref, + int field_type: @cil_type ref); + +@cil_element = @cil_instruction | @cil_declaration | @cil_handler | @cil_attribute | @cil_namespace; +@cil_named_element = @cil_declaration | @cil_namespace; +@cil_declaration = @cil_variable | @cil_method | @cil_type | @cil_member; +@cil_accessible = @cil_declaration; +@cil_variable = @cil_field | @cil_stack_variable; +@cil_stack_variable = @cil_local_variable | @cil_parameter; +@cil_member = @cil_method | @cil_type | @cil_field | @cil_property | @cil_event; + +#keyset[method, index] +cil_parameter( + unique int id: @cil_parameter, + int method: @cil_method ref, + int index: int ref, + int param_type: @cil_type ref); + +cil_parameter_in(unique int id: @cil_parameter ref); +cil_parameter_out(unique int id: @cil_parameter ref); + +cil_setter(unique int prop: @cil_property ref, + int method: @cil_method ref); + +cil_getter(unique int prop: @cil_property ref, + int method: @cil_method ref); + +cil_adder(unique int event: @cil_event ref, + int method: @cil_method ref); + +cil_remover(unique int event: @cil_event ref, int method: @cil_method ref); + +cil_raiser(unique int event: @cil_event ref, int method: @cil_method ref); + +cil_property( + unique int id: @cil_property, + int parent: @cil_type ref, + string name: string ref, + int property_type: @cil_type ref); + +#keyset[parent, name] +cil_event(unique int id: @cil_event, + int parent: @cil_type ref, + string name: string ref, + int event_type: @cil_type ref); + +#keyset[impl, index] +cil_local_variable( + unique int id: @cil_local_variable, + int impl: @cil_method_implementation ref, + int index: int ref, + int var_type: @cil_type ref); + +// CIL handlers (exception handlers etc). + +case @cil_handler.kind of + 0 = @cil_catch_handler +| 1 = @cil_filter_handler +| 2 = @cil_finally_handler +| 4 = @cil_fault_handler +; + +#keyset[impl, index] +cil_handler( + unique int id: @cil_handler, + int impl: @cil_method_implementation ref, + int index: int ref, + int kind: int ref, + int try_start: @cil_instruction ref, + int try_end: @cil_instruction ref, + int handler_start: @cil_instruction ref); + +cil_handler_filter( + unique int id: @cil_handler ref, + int filter_start: @cil_instruction ref); + +cil_handler_type( + unique int id: @cil_handler ref, + int catch_type: @cil_type ref); + +@cil_controlflow_node = @cil_entry_point | @cil_instruction; + +@cil_entry_point = @cil_method_implementation | @cil_handler; + +@cil_dataflow_node = @cil_instruction | @cil_variable | @cil_method; + +cil_method_stack_size( + unique int method: @cil_method_implementation ref, + int size: int ref); + +// CIL modifiers + +cil_public(int id: @cil_member ref); +cil_private(int id: @cil_member ref); +cil_protected(int id: @cil_member ref); +cil_internal(int id: @cil_member ref); +cil_static(int id: @cil_member ref); +cil_sealed(int id: @cil_member ref); +cil_virtual(int id: @cil_method ref); +cil_abstract(int id: @cil_member ref); +cil_class(int id: @cil_type ref); +cil_interface(int id: @cil_type ref); +cil_security(int id: @cil_member ref); +cil_requiresecobject(int id: @cil_method ref); +cil_specialname(int id: @cil_method ref); +cil_newslot(int id: @cil_method ref); + +cil_base_class(unique int id: @cil_type ref, int base: @cil_type ref); +cil_base_interface(int id: @cil_type ref, int base: @cil_type ref); +cil_enum_underlying_type(unique int id: @cil_type ref, int underlying: @cil_type ref); + +#keyset[unbound, index] +cil_type_parameter( + int unbound: @cil_member ref, + int index: int ref, + int param: @cil_typeparameter ref); + +#keyset[bound, index] +cil_type_argument( + int bound: @cil_member ref, + int index: int ref, + int t: @cil_type ref); + +// CIL type parameter constraints + +cil_typeparam_covariant(int tp: @cil_typeparameter ref); +cil_typeparam_contravariant(int tp: @cil_typeparameter ref); +cil_typeparam_class(int tp: @cil_typeparameter ref); +cil_typeparam_struct(int tp: @cil_typeparameter ref); +cil_typeparam_new(int tp: @cil_typeparameter ref); +cil_typeparam_constraint(int tp: @cil_typeparameter ref, int supertype: @cil_type ref); + +// CIL attributes + +cil_attribute( + unique int attributeid: @cil_attribute, + int element: @cil_declaration ref, + int constructor: @cil_method ref); + +#keyset[attribute_id, param] +cil_attribute_named_argument( + int attribute_id: @cil_attribute ref, + string param: string ref, + string value: string ref); + +#keyset[attribute_id, index] +cil_attribute_positional_argument( + int attribute_id: @cil_attribute ref, + int index: int ref, + string value: string ref); + + +// Common .Net data model covering both C# and CIL + +// Common elements +@dotnet_element = @element | @cil_element; +@dotnet_named_element = @named_element | @cil_named_element; +@dotnet_callable = @callable | @cil_method; +@dotnet_variable = @variable | @cil_variable; +@dotnet_field = @field | @cil_field; +@dotnet_parameter = @parameter | @cil_parameter; +@dotnet_declaration = @declaration | @cil_declaration; +@dotnet_member = @member | @cil_member; +@dotnet_event = @event | @cil_event; +@dotnet_property = @property | @cil_property | @indexer; + +// Common types +@dotnet_type = @type | @cil_type; +@dotnet_call = @call | @cil_call_any; +@dotnet_throw = @throw_element | @cil_throw_any; +@dotnet_valueorreftype = @cil_valueorreftype | @value_or_ref_type | @cil_array_type | @void_type; +@dotnet_typeparameter = @type_parameter | @cil_typeparameter; +@dotnet_array_type = @array_type | @cil_array_type; +@dotnet_pointer_type = @pointer_type | @cil_pointer_type; +@dotnet_type_parameter = @type_parameter | @cil_typeparameter; +@dotnet_generic = @dotnet_valueorreftype | @dotnet_callable; + +// Attributes +@dotnet_attribute = @attribute | @cil_attribute; + +// Expressions +@dotnet_expr = @expr | @cil_expr; + +// Literals +@dotnet_literal = @literal_expr | @cil_literal; +@dotnet_string_literal = @string_literal_expr | @cil_ldstr; +@dotnet_int_literal = @integer_literal_expr | @cil_ldc_i; +@dotnet_float_literal = @float_literal_expr | @cil_ldc_r; +@dotnet_null_literal = @null_literal_expr | @cil_ldnull; + +@metadata_entity = @cil_method | @cil_type | @cil_field | @cil_property | @field | @property | + @callable | @value_or_ref_type | @void_type; + +#keyset[entity, location] +metadata_handle(int entity : @metadata_entity ref, int location: @assembly ref, int handle: int ref) diff --git a/csharp/upgrades/cfaa4e90da23a5ca3f0e914fbd5ca689ba0282d9/upgrade.properties b/csharp/upgrades/cfaa4e90da23a5ca3f0e914fbd5ca689ba0282d9/upgrade.properties new file mode 100644 index 00000000000..6de36036f5a --- /dev/null +++ b/csharp/upgrades/cfaa4e90da23a5ca3f0e914fbd5ca689ba0282d9/upgrade.properties @@ -0,0 +1,2 @@ +description: Added 'init_only_accessors' relation. +compatibility: backwards diff --git a/csharp/upgrades/dd813977f70fcbf737b0bbe9dc8297edff713168/old.dbscheme b/csharp/upgrades/dd813977f70fcbf737b0bbe9dc8297edff713168/old.dbscheme new file mode 100644 index 00000000000..dd813977f70 --- /dev/null +++ b/csharp/upgrades/dd813977f70fcbf737b0bbe9dc8297edff713168/old.dbscheme @@ -0,0 +1,1940 @@ + +/** + * An invocation of the compiler. Note that more than one file may be + * compiled per invocation. For example, this command compiles three + * source files: + * + * csc f1.cs f2.cs f3.cs + * + * The `id` simply identifies the invocation, while `cwd` is the working + * directory from which the compiler was invoked. + */ +compilations( + unique int id : @compilation, + string cwd : string ref +); + +/** + * The arguments that were passed to the extractor for a compiler + * invocation. If `id` is for the compiler invocation + * + * csc f1.cs f2.cs f3.cs + * + * then typically there will be rows for + * + * num | arg + * --- | --- + * 0 | --compiler + * 1 | *path to compiler* + * 2 | --cil + * 3 | f1.cs + * 4 | f2.cs + * 5 | f3.cs + */ +#keyset[id, num] +compilation_args( + int id : @compilation ref, + int num : int ref, + string arg : string ref +); + +/** + * The source files that are compiled by a compiler invocation. + * If `id` is for the compiler invocation + * + * csc f1.cs f2.cs f3.cs + * + * then there will be rows for + * + * num | arg + * --- | --- + * 0 | f1.cs + * 1 | f2.cs + * 2 | f3.cs + */ +#keyset[id, num] +compilation_compiling_files( + int id : @compilation ref, + int num : int ref, + int file : @file ref +); + +/** + * The references used by a compiler invocation. + * If `id` is for the compiler invocation + * + * csc f1.cs f2.cs f3.cs /r:ref1.dll /r:ref2.dll /r:ref3.dll + * + * then there will be rows for + * + * num | arg + * --- | --- + * 0 | ref1.dll + * 1 | ref2.dll + * 2 | ref3.dll + */ +#keyset[id, num] +compilation_referencing_files( + int id : @compilation ref, + int num : int ref, + int file : @file ref +); + +/** + * The time taken by the extractor for a compiler invocation. + * + * For each file `num`, there will be rows for + * + * kind | seconds + * ---- | --- + * 1 | CPU seconds used by the extractor frontend + * 2 | Elapsed seconds during the extractor frontend + * 3 | CPU seconds used by the extractor backend + * 4 | Elapsed seconds during the extractor backend + */ +#keyset[id, num, kind] +compilation_time( + int id : @compilation ref, + int num : int ref, + /* kind: + 1 = frontend_cpu_seconds + 2 = frontend_elapsed_seconds + 3 = extractor_cpu_seconds + 4 = extractor_elapsed_seconds + */ + int kind : int ref, + float seconds : float ref +); + +/** + * An error or warning generated by the extractor. + * The diagnostic message `diagnostic` was generated during compiler + * invocation `compilation`, and is the `file_number_diagnostic_number`th + * message generated while extracting the `file_number`th file of that + * invocation. + */ +#keyset[compilation, file_number, file_number_diagnostic_number] +diagnostic_for( + unique int diagnostic : @diagnostic ref, + int compilation : @compilation ref, + int file_number : int ref, + int file_number_diagnostic_number : int ref +); + +diagnostics( + unique int id: @diagnostic, + int severity: int ref, + string error_tag: string ref, + string error_message: string ref, + string full_error_message: string ref, + int location: @location_default ref +); + +extractor_messages( + unique int id: @extractor_message, + int severity: int ref, + string origin : string ref, + string text : string ref, + string entity : string ref, + int location: @location_default ref, + string stack_trace : string ref +); + +/** + * If extraction was successful, then `cpu_seconds` and + * `elapsed_seconds` are the CPU time and elapsed time (respectively) + * that extraction took for compiler invocation `id`. + */ +compilation_finished( + unique int id : @compilation ref, + float cpu_seconds : float ref, + float elapsed_seconds : float ref +); + +compilation_assembly( + unique int id : @compilation ref, + int assembly: @assembly ref +) + +/* + * External artifacts + */ + +externalDefects( + unique int id: @externalDefect, + string queryPath: string ref, + int location: @location ref, + string message: string ref, + float severity: float ref); + +externalMetrics( + unique int id: @externalMetric, + string queryPath: string ref, + int location: @location ref, + float value: float ref); + +externalData( + int id: @externalDataElement, + string path: string ref, + int column: int ref, + string value: string ref); + +snapshotDate( + unique date snapshotDate: date ref); + +sourceLocationPrefix( + string prefix: string ref); + +/* + * Duplicate code + */ + +duplicateCode( + unique int id: @duplication, + string relativePath: string ref, + int equivClass: int ref); + +similarCode( + unique int id: @similarity, + string relativePath: string ref, + int equivClass: int ref); + +@duplication_or_similarity = @duplication | @similarity + +tokens( + int id: @duplication_or_similarity ref, + int offset: int ref, + int beginLine: int ref, + int beginColumn: int ref, + int endLine: int ref, + int endColumn: int ref); + +/* + * C# dbscheme + */ + +/** ELEMENTS **/ + +@element = @declaration | @stmt | @expr | @modifier | @attribute | @namespace_declaration + | @using_directive | @type_parameter_constraints | @external_element + | @xmllocatable | @asp_element | @namespace; + +@declaration = @callable | @generic | @assignable | @namespace; + +@named_element = @namespace | @declaration; + +@declaration_with_accessors = @property | @indexer | @event; + +@assignable = @variable | @assignable_with_accessors | @event; + +@assignable_with_accessors = @property | @indexer; + +@external_element = @externalMetric | @externalDefect | @externalDataElement; + +@attributable = @assembly | @field | @parameter | @operator | @method | @constructor + | @destructor | @callable_accessor | @value_or_ref_type | @declaration_with_accessors + | @local_function; + +/** LOCATIONS, ASEMMBLIES, MODULES, FILES and FOLDERS **/ + +@location = @location_default | @assembly; + +locations_default( + unique int id: @location_default, + int file: @file ref, + int beginLine: int ref, + int beginColumn: int ref, + int endLine: int ref, + int endColumn: int ref); + +@sourceline = @file | @callable | @xmllocatable; + +numlines( + int element_id: @sourceline ref, + int num_lines: int ref, + int num_code: int ref, + int num_comment: int ref); + +assemblies( + unique int id: @assembly, + int file: @file ref, + string fullname: string ref, + string name: string ref, + string version: string ref); + +/* + fromSource(0) = unknown, + fromSource(1) = from source, + fromSource(2) = from library +*/ +files( + unique int id: @file, + string name: string ref, + string simple: string ref, + string ext: string ref, + int fromSource: int ref); + +folders( + unique int id: @folder, + string name: string ref, + string simple: string ref); + +@container = @folder | @file ; + +containerparent( + int parent: @container ref, + unique int child: @container ref); + +file_extraction_mode( + unique int file: @file ref, + int mode: int ref + /* 0 = normal, 1 = standalone extractor */ + ); + +/** NAMESPACES **/ + +@type_container = @namespace | @type; + +namespaces( + unique int id: @namespace, + string name: string ref); + +namespace_declarations( + unique int id: @namespace_declaration, + int namespace_id: @namespace ref); + +namespace_declaration_location( + unique int id: @namespace_declaration ref, + int loc: @location ref); + +parent_namespace( + unique int child_id: @type_container ref, + int namespace_id: @namespace ref); + +@declaration_or_directive = @namespace_declaration | @type | @using_directive; + +parent_namespace_declaration( + int child_id: @declaration_or_directive ref, // cannot be unique because of partial classes + int namespace_id: @namespace_declaration ref); + +@using_directive = @using_namespace_directive | @using_static_directive; + +using_namespace_directives( + unique int id: @using_namespace_directive, + int namespace_id: @namespace ref); + +using_static_directives( + unique int id: @using_static_directive, + int type_id: @type_or_ref ref); + +using_directive_location( + unique int id: @using_directive ref, + int loc: @location ref); + +/** TYPES **/ + +types( + unique int id: @type, + int kind: int ref, + string name: string ref); + +case @type.kind of + 1 = @bool_type +| 2 = @char_type +| 3 = @decimal_type +| 4 = @sbyte_type +| 5 = @short_type +| 6 = @int_type +| 7 = @long_type +| 8 = @byte_type +| 9 = @ushort_type +| 10 = @uint_type +| 11 = @ulong_type +| 12 = @float_type +| 13 = @double_type +| 14 = @enum_type +| 15 = @struct_type +| 17 = @class_type +| 19 = @interface_type +| 20 = @delegate_type +| 21 = @null_type +| 22 = @type_parameter +| 23 = @pointer_type +| 24 = @nullable_type +| 25 = @array_type +| 26 = @void_type +| 27 = @int_ptr_type +| 28 = @uint_ptr_type +| 29 = @dynamic_type +| 30 = @arglist_type +| 31 = @unknown_type +| 32 = @tuple_type +| 33 = @function_pointer_type + ; + +@simple_type = @bool_type | @char_type | @integral_type | @floating_point_type | @decimal_type; +@integral_type = @signed_integral_type | @unsigned_integral_type; +@signed_integral_type = @sbyte_type | @short_type | @int_type | @long_type; +@unsigned_integral_type = @byte_type | @ushort_type | @uint_type | @ulong_type; +@floating_point_type = @float_type | @double_type; +@value_type = @simple_type | @enum_type | @struct_type | @nullable_type | @int_ptr_type + | @uint_ptr_type | @tuple_type; +@ref_type = @class_type | @interface_type | @array_type | @delegate_type | @null_type + | @dynamic_type; +@value_or_ref_type = @value_type | @ref_type; + +typerefs( + unique int id: @typeref, + string name: string ref); + +typeref_type( + int id: @typeref ref, + unique int typeId: @type ref); + +@type_or_ref = @type | @typeref; + +array_element_type( + unique int array: @array_type ref, + int dimension: int ref, + int rank: int ref, + int element: @type_or_ref ref); + +nullable_underlying_type( + unique int nullable: @nullable_type ref, + int underlying: @type_or_ref ref); + +pointer_referent_type( + unique int pointer: @pointer_type ref, + int referent: @type_or_ref ref); + +enum_underlying_type( + unique int enum_id: @enum_type ref, + int underlying_type_id: @type_or_ref ref); + +delegate_return_type( + unique int delegate_id: @delegate_type ref, + int return_type_id: @type_or_ref ref); + +function_pointer_return_type( + unique int function_pointer_id: @function_pointer_type ref, + int return_type_id: @type_or_ref ref); + +extend( + unique int sub: @type ref, + int super: @type_or_ref ref); + +anonymous_types( + unique int id: @type ref); + +@interface_or_ref = @interface_type | @typeref; + +implement( + int sub: @type ref, + int super: @type_or_ref ref); + +type_location( + int id: @type ref, + int loc: @location ref); + +tuple_underlying_type( + unique int tuple: @tuple_type ref, + int struct: @type_or_ref ref); + +#keyset[tuple, index] +tuple_element( + int tuple: @tuple_type ref, + int index: int ref, + unique int field: @field ref); + +attributes( + unique int id: @attribute, + int type_id: @type_or_ref ref, + int target: @attributable ref); + +attribute_location( + int id: @attribute ref, + int loc: @location ref); + +@type_mention_parent = @element | @type_mention; + +type_mention( + unique int id: @type_mention, + int type_id: @type_or_ref ref, + int parent: @type_mention_parent ref); + +type_mention_location( + unique int id: @type_mention ref, + int loc: @location ref); + +@has_type_annotation = @assignable | @type_parameter | @callable | @expr | @delegate_type | @generic | @function_pointer_type; + +/** + * A direct annotation on an entity, for example `string? x;`. + * + * Annotations: + * 2 = reftype is not annotated "!" + * 3 = reftype is annotated "?" + * 4 = readonly ref type / in parameter + * 5 = ref type parameter, return or local variable + * 6 = out parameter + * + * Note that the annotation depends on the element it annotates. + * @assignable: The annotation is on the type of the assignable, for example the variable type. + * @type_parameter: The annotation is on the reftype constraint + * @callable: The annotation is on the return type + * @array_type: The annotation is on the element type + */ +type_annotation(int id: @has_type_annotation ref, int annotation: int ref); + +nullability(unique int nullability: @nullability, int kind: int ref); + +case @nullability.kind of + 0 = @oblivious +| 1 = @not_annotated +| 2 = @annotated +; + +#keyset[parent, index] +nullability_parent(int nullability: @nullability ref, int index: int ref, int parent: @nullability ref) + +type_nullability(int id: @has_type_annotation ref, int nullability: @nullability ref); + +/** + * The nullable flow state of an expression, as determined by Roslyn. + * 0 = none (default, not populated) + * 1 = not null + * 2 = maybe null + */ +expr_flowstate(unique int id: @expr ref, int state: int ref); + +/** GENERICS **/ + +@generic = @type | @method | @local_function; + +type_parameters( + unique int id: @type_parameter ref, + int index: int ref, + int generic_id: @generic ref, + int variance: int ref /* none = 0, out = 1, in = 2 */); + +#keyset[constructed_id, index] +type_arguments( + int id: @type_or_ref ref, + int index: int ref, + int constructed_id: @generic_or_ref ref); + +@generic_or_ref = @generic | @typeref; + +constructed_generic( + unique int constructed: @generic ref, + int generic: @generic_or_ref ref); + +type_parameter_constraints( + unique int id: @type_parameter_constraints, + int param_id: @type_parameter ref); + +type_parameter_constraints_location( + int id: @type_parameter_constraints ref, + int loc: @location ref); + +general_type_parameter_constraints( + int id: @type_parameter_constraints ref, + int kind: int ref /* class = 1, struct = 2, new = 3 */); + +specific_type_parameter_constraints( + int id: @type_parameter_constraints ref, + int base_id: @type_or_ref ref); + +specific_type_parameter_nullability( + int id: @type_parameter_constraints ref, + int base_id: @type_or_ref ref, + int nullability: @nullability ref); + +/** FUNCTION POINTERS */ + +function_pointer_calling_conventions( + int id: @function_pointer_type ref, + int kind: int ref); + +#keyset[id, index] +has_unmanaged_calling_conventions( + int id: @function_pointer_type ref, + int index: int ref, + int conv_id: @type_or_ref ref); + +/** MODIFIERS */ + +@modifiable = @modifiable_direct | @event_accessor; + +@modifiable_direct = @member | @accessor | @local_function | @anonymous_function_expr; + +modifiers( + unique int id: @modifier, + string name: string ref); + +has_modifiers( + int id: @modifiable_direct ref, + int mod_id: @modifier ref); + +compiler_generated(unique int id: @modifiable_direct ref); + +/** MEMBERS **/ + +@member = @method | @constructor | @destructor | @field | @property | @event | @operator | @indexer | @type; + +@named_exprorstmt = @goto_stmt | @labeled_stmt | @expr; + +@virtualizable = @method | @property | @indexer | @event; + +exprorstmt_name( + unique int parent_id: @named_exprorstmt ref, + string name: string ref); + +nested_types( + unique int id: @type ref, + int declaring_type_id: @type ref, + int unbound_id: @type ref); + +properties( + unique int id: @property, + string name: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @property ref); + +property_location( + int id: @property ref, + int loc: @location ref); + +indexers( + unique int id: @indexer, + string name: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @indexer ref); + +indexer_location( + int id: @indexer ref, + int loc: @location ref); + +accessors( + unique int id: @accessor, + int kind: int ref, + string name: string ref, + int declaring_member_id: @member ref, + int unbound_id: @accessor ref); + +case @accessor.kind of + 1 = @getter +| 2 = @setter + ; + +init_only_accessors( + unique int id: @accessor ref); + +accessor_location( + int id: @accessor ref, + int loc: @location ref); + +events( + unique int id: @event, + string name: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @event ref); + +event_location( + int id: @event ref, + int loc: @location ref); + +event_accessors( + unique int id: @event_accessor, + int kind: int ref, + string name: string ref, + int declaring_event_id: @event ref, + int unbound_id: @event_accessor ref); + +case @event_accessor.kind of + 1 = @add_event_accessor +| 2 = @remove_event_accessor + ; + +event_accessor_location( + int id: @event_accessor ref, + int loc: @location ref); + +operators( + unique int id: @operator, + string name: string ref, + string symbol: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @operator ref); + +operator_location( + int id: @operator ref, + int loc: @location ref); + +constant_value( + int id: @variable ref, + string value: string ref); + +/** CALLABLES **/ + +@callable = @method | @constructor | @destructor | @operator | @callable_accessor | @anonymous_function_expr | @local_function; + +@callable_accessor = @accessor | @event_accessor; + +methods( + unique int id: @method, + string name: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @method ref); + +method_location( + int id: @method ref, + int loc: @location ref); + +constructors( + unique int id: @constructor, + string name: string ref, + int declaring_type_id: @type ref, + int unbound_id: @constructor ref); + +constructor_location( + int id: @constructor ref, + int loc: @location ref); + +destructors( + unique int id: @destructor, + string name: string ref, + int declaring_type_id: @type ref, + int unbound_id: @destructor ref); + +destructor_location( + int id: @destructor ref, + int loc: @location ref); + +overrides( + int id: @callable ref, + int base_id: @callable ref); + +explicitly_implements( + int id: @member ref, + int interface_id: @interface_or_ref ref); + +local_functions( + unique int id: @local_function, + string name: string ref, + int return_type: @type ref, + int unbound_id: @local_function ref); + +local_function_stmts( + unique int fn: @local_function_stmt ref, + int stmt: @local_function ref); + +/** VARIABLES **/ + +@variable = @local_scope_variable | @field; + +@local_scope_variable = @local_variable | @parameter; + +fields( + unique int id: @field, + int kind: int ref, + string name: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @field ref); + +case @field.kind of + 1 = @addressable_field +| 2 = @constant + ; + +field_location( + int id: @field ref, + int loc: @location ref); + +localvars( + unique int id: @local_variable, + int kind: int ref, + string name: string ref, + int implicitly_typed: int ref /* 0 = no, 1 = yes */, + int type_id: @type_or_ref ref, + int parent_id: @local_var_decl_expr ref); + +case @local_variable.kind of + 1 = @addressable_local_variable +| 2 = @local_constant +| 3 = @local_variable_ref + ; + +localvar_location( + unique int id: @local_variable ref, + int loc: @location ref); + +@parameterizable = @callable | @delegate_type | @indexer | @function_pointer_type; + +#keyset[name, parent_id] +#keyset[index, parent_id] +params( + unique int id: @parameter, + string name: string ref, + int type_id: @type_or_ref ref, + int index: int ref, + int mode: int ref, /* value = 0, ref = 1, out = 2, array = 3, this = 4 */ + int parent_id: @parameterizable ref, + int unbound_id: @parameter ref); + +param_location( + int id: @parameter ref, + int loc: @location ref); + +/** STATEMENTS **/ + +@exprorstmt_parent = @control_flow_element | @top_level_exprorstmt_parent; + +statements( + unique int id: @stmt, + int kind: int ref); + +#keyset[index, parent] +stmt_parent( + unique int stmt: @stmt ref, + int index: int ref, + int parent: @control_flow_element ref); + +@top_level_stmt_parent = @callable; + +// [index, parent] is not a keyset because the same parent may be compiled multiple times +stmt_parent_top_level( + unique int stmt: @stmt ref, + int index: int ref, + int parent: @top_level_stmt_parent ref); + +case @stmt.kind of + 1 = @block_stmt +| 2 = @expr_stmt +| 3 = @if_stmt +| 4 = @switch_stmt +| 5 = @while_stmt +| 6 = @do_stmt +| 7 = @for_stmt +| 8 = @foreach_stmt +| 9 = @break_stmt +| 10 = @continue_stmt +| 11 = @goto_stmt +| 12 = @goto_case_stmt +| 13 = @goto_default_stmt +| 14 = @throw_stmt +| 15 = @return_stmt +| 16 = @yield_stmt +| 17 = @try_stmt +| 18 = @checked_stmt +| 19 = @unchecked_stmt +| 20 = @lock_stmt +| 21 = @using_block_stmt +| 22 = @var_decl_stmt +| 23 = @const_decl_stmt +| 24 = @empty_stmt +| 25 = @unsafe_stmt +| 26 = @fixed_stmt +| 27 = @label_stmt +| 28 = @catch +| 29 = @case_stmt +| 30 = @local_function_stmt +| 31 = @using_decl_stmt + ; + +@using_stmt = @using_block_stmt | @using_decl_stmt; + +@labeled_stmt = @label_stmt | @case; + +@decl_stmt = @var_decl_stmt | @const_decl_stmt | @using_decl_stmt; + +@cond_stmt = @if_stmt | @switch_stmt; + +@loop_stmt = @while_stmt | @do_stmt | @for_stmt | @foreach_stmt; + +@jump_stmt = @break_stmt | @goto_any_stmt | @continue_stmt | @throw_stmt | @return_stmt + | @yield_stmt; + +@goto_any_stmt = @goto_default_stmt | @goto_case_stmt | @goto_stmt; + + +stmt_location( + unique int id: @stmt ref, + int loc: @location ref); + +catch_type( + unique int catch_id: @catch ref, + int type_id: @type_or_ref ref, + int kind: int ref /* explicit = 1, implicit = 2 */); + +/** EXPRESSIONS **/ + +expressions( + unique int id: @expr, + int kind: int ref, + int type_id: @type_or_ref ref); + +#keyset[index, parent] +expr_parent( + unique int expr: @expr ref, + int index: int ref, + int parent: @control_flow_element ref); + +@top_level_expr_parent = @attribute | @field | @property | @indexer | @parameter; + +@top_level_exprorstmt_parent = @top_level_expr_parent | @top_level_stmt_parent; + +// [index, parent] is not a keyset because the same parent may be compiled multiple times +expr_parent_top_level( + unique int expr: @expr ref, + int index: int ref, + int parent: @top_level_exprorstmt_parent ref); + +case @expr.kind of +/* literal */ + 1 = @bool_literal_expr +| 2 = @char_literal_expr +| 3 = @decimal_literal_expr +| 4 = @int_literal_expr +| 5 = @long_literal_expr +| 6 = @uint_literal_expr +| 7 = @ulong_literal_expr +| 8 = @float_literal_expr +| 9 = @double_literal_expr +| 10 = @string_literal_expr +| 11 = @null_literal_expr +/* primary & unary */ +| 12 = @this_access_expr +| 13 = @base_access_expr +| 14 = @local_variable_access_expr +| 15 = @parameter_access_expr +| 16 = @field_access_expr +| 17 = @property_access_expr +| 18 = @method_access_expr +| 19 = @event_access_expr +| 20 = @indexer_access_expr +| 21 = @array_access_expr +| 22 = @type_access_expr +| 23 = @typeof_expr +| 24 = @method_invocation_expr +| 25 = @delegate_invocation_expr +| 26 = @operator_invocation_expr +| 27 = @cast_expr +| 28 = @object_creation_expr +| 29 = @explicit_delegate_creation_expr +| 30 = @implicit_delegate_creation_expr +| 31 = @array_creation_expr +| 32 = @default_expr +| 33 = @plus_expr +| 34 = @minus_expr +| 35 = @bit_not_expr +| 36 = @log_not_expr +| 37 = @post_incr_expr +| 38 = @post_decr_expr +| 39 = @pre_incr_expr +| 40 = @pre_decr_expr +/* multiplicative */ +| 41 = @mul_expr +| 42 = @div_expr +| 43 = @rem_expr +/* additive */ +| 44 = @add_expr +| 45 = @sub_expr +/* shift */ +| 46 = @lshift_expr +| 47 = @rshift_expr +/* relational */ +| 48 = @lt_expr +| 49 = @gt_expr +| 50 = @le_expr +| 51 = @ge_expr +/* equality */ +| 52 = @eq_expr +| 53 = @ne_expr +/* logical */ +| 54 = @bit_and_expr +| 55 = @bit_xor_expr +| 56 = @bit_or_expr +| 57 = @log_and_expr +| 58 = @log_or_expr +/* type testing */ +| 59 = @is_expr +| 60 = @as_expr +/* null coalescing */ +| 61 = @null_coalescing_expr +/* conditional */ +| 62 = @conditional_expr +/* assignment */ +| 63 = @simple_assign_expr +| 64 = @assign_add_expr +| 65 = @assign_sub_expr +| 66 = @assign_mul_expr +| 67 = @assign_div_expr +| 68 = @assign_rem_expr +| 69 = @assign_and_expr +| 70 = @assign_xor_expr +| 71 = @assign_or_expr +| 72 = @assign_lshift_expr +| 73 = @assign_rshift_expr +/* more */ +| 74 = @object_init_expr +| 75 = @collection_init_expr +| 76 = @array_init_expr +| 77 = @checked_expr +| 78 = @unchecked_expr +| 79 = @constructor_init_expr +| 80 = @add_event_expr +| 81 = @remove_event_expr +| 82 = @par_expr +| 83 = @local_var_decl_expr +| 84 = @lambda_expr +| 85 = @anonymous_method_expr +| 86 = @namespace_expr +/* dynamic */ +| 92 = @dynamic_element_access_expr +| 93 = @dynamic_member_access_expr +/* unsafe */ +| 100 = @pointer_indirection_expr +| 101 = @address_of_expr +| 102 = @sizeof_expr +/* async */ +| 103 = @await_expr +/* C# 6.0 */ +| 104 = @nameof_expr +| 105 = @interpolated_string_expr +| 106 = @unknown_expr +/* C# 7.0 */ +| 107 = @throw_expr +| 108 = @tuple_expr +| 109 = @local_function_invocation_expr +| 110 = @ref_expr +| 111 = @discard_expr +/* C# 8.0 */ +| 112 = @range_expr +| 113 = @index_expr +| 114 = @switch_expr +| 115 = @recursive_pattern_expr +| 116 = @property_pattern_expr +| 117 = @positional_pattern_expr +| 118 = @switch_case_expr +| 119 = @assign_coalesce_expr +| 120 = @suppress_nullable_warning_expr +| 121 = @namespace_access_expr +/* C# 9.0 */ +| 122 = @lt_pattern_expr +| 123 = @gt_pattern_expr +| 124 = @le_pattern_expr +| 125 = @ge_pattern_expr +| 126 = @not_pattern_expr +| 129 = @function_pointer_invocation_expr +; + +@switch = @switch_stmt | @switch_expr; +@case = @case_stmt | @switch_case_expr; +@pattern_match = @case | @is_expr; +@unary_pattern_expr = @not_pattern_expr; +@relational_pattern_expr = @gt_pattern_expr | @lt_pattern_expr | @ge_pattern_expr | @le_pattern_expr; + +@integer_literal_expr = @int_literal_expr | @long_literal_expr | @uint_literal_expr | @ulong_literal_expr; +@real_literal_expr = @float_literal_expr | @double_literal_expr | @decimal_literal_expr; +@literal_expr = @bool_literal_expr | @char_literal_expr | @integer_literal_expr | @real_literal_expr + | @string_literal_expr | @null_literal_expr; + +@assign_expr = @simple_assign_expr | @assign_op_expr | @local_var_decl_expr; +@assign_op_expr = @assign_arith_expr | @assign_bitwise_expr | @assign_event_expr | @assign_coalesce_expr; +@assign_event_expr = @add_event_expr | @remove_event_expr; + +@assign_arith_expr = @assign_add_expr | @assign_sub_expr | @assign_mul_expr | @assign_div_expr + | @assign_rem_expr +@assign_bitwise_expr = @assign_and_expr | @assign_or_expr | @assign_xor_expr + | @assign_lshift_expr | @assign_rshift_expr; + +@member_access_expr = @field_access_expr | @property_access_expr | @indexer_access_expr | @event_access_expr + | @method_access_expr | @type_access_expr | @dynamic_member_access_expr; +@access_expr = @member_access_expr | @this_access_expr | @base_access_expr | @assignable_access_expr | @namespace_access_expr; +@element_access_expr = @indexer_access_expr | @array_access_expr | @dynamic_element_access_expr; + +@local_variable_access = @local_variable_access_expr | @local_var_decl_expr; +@local_scope_variable_access_expr = @parameter_access_expr | @local_variable_access; +@variable_access_expr = @local_scope_variable_access_expr | @field_access_expr; + +@assignable_access_expr = @variable_access_expr | @property_access_expr | @element_access_expr + | @event_access_expr | @dynamic_member_access_expr; + +@objectorcollection_init_expr = @object_init_expr | @collection_init_expr; + +@delegate_creation_expr = @explicit_delegate_creation_expr | @implicit_delegate_creation_expr; + +@bin_arith_op_expr = @mul_expr | @div_expr | @rem_expr | @add_expr | @sub_expr; +@incr_op_expr = @pre_incr_expr | @post_incr_expr; +@decr_op_expr = @pre_decr_expr | @post_decr_expr; +@mut_op_expr = @incr_op_expr | @decr_op_expr; +@un_arith_op_expr = @plus_expr | @minus_expr | @mut_op_expr; +@arith_op_expr = @bin_arith_op_expr | @un_arith_op_expr; + +@ternary_log_op_expr = @conditional_expr; +@bin_log_op_expr = @log_and_expr | @log_or_expr | @null_coalescing_expr; +@un_log_op_expr = @log_not_expr; +@log_expr = @un_log_op_expr | @bin_log_op_expr | @ternary_log_op_expr; + +@bin_bit_op_expr = @bit_and_expr | @bit_or_expr | @bit_xor_expr | @lshift_expr + | @rshift_expr; +@un_bit_op_expr = @bit_not_expr; +@bit_expr = @un_bit_op_expr | @bin_bit_op_expr; + +@equality_op_expr = @eq_expr | @ne_expr; +@rel_op_expr = @gt_expr | @lt_expr| @ge_expr | @le_expr; +@comp_expr = @equality_op_expr | @rel_op_expr; + +@op_expr = @assign_expr | @un_op | @bin_op | @ternary_op; + +@ternary_op = @ternary_log_op_expr; +@bin_op = @bin_arith_op_expr | @bin_log_op_expr | @bin_bit_op_expr | @comp_expr; +@un_op = @un_arith_op_expr | @un_log_op_expr | @un_bit_op_expr | @sizeof_expr + | @pointer_indirection_expr | @address_of_expr; + +@anonymous_function_expr = @lambda_expr | @anonymous_method_expr; + +@call = @method_invocation_expr | @constructor_init_expr | @operator_invocation_expr + | @delegate_invocation_expr | @object_creation_expr | @call_access_expr + | @local_function_invocation_expr | @function_pointer_invocation_expr; + +@call_access_expr = @property_access_expr | @event_access_expr | @indexer_access_expr; + +@late_bindable_expr = @dynamic_element_access_expr | @dynamic_member_access_expr + | @object_creation_expr | @method_invocation_expr | @operator_invocation_expr; + +@throw_element = @throw_expr | @throw_stmt; + +@implicitly_typeable_object_creation_expr = @object_creation_expr | @explicit_delegate_creation_expr; + +implicitly_typed_array_creation( + unique int id: @array_creation_expr ref); + +explicitly_sized_array_creation( + unique int id: @array_creation_expr ref); + +stackalloc_array_creation( + unique int id: @array_creation_expr ref); + +implicitly_typed_object_creation( + unique int id: @implicitly_typeable_object_creation_expr ref); + +mutator_invocation_mode( + unique int id: @operator_invocation_expr ref, + int mode: int ref /* prefix = 1, postfix = 2*/); + +expr_compiler_generated( + unique int id: @expr ref); + +expr_value( + unique int id: @expr ref, + string value: string ref); + +expr_call( + unique int caller_id: @expr ref, + int target_id: @callable ref); + +expr_access( + unique int accesser_id: @access_expr ref, + int target_id: @accessible ref); + +@accessible = @method | @assignable | @local_function | @namespace; + +expr_location( + unique int id: @expr ref, + int loc: @location ref); + +dynamic_member_name( + unique int id: @late_bindable_expr ref, + string name: string ref); + +@qualifiable_expr = @member_access_expr + | @method_invocation_expr + | @element_access_expr; + +conditional_access( + unique int id: @qualifiable_expr ref); + +expr_argument( + unique int id: @expr ref, + int mode: int ref); + /* mode is the same as params: value = 0, ref = 1, out = 2 */ + +expr_argument_name( + unique int id: @expr ref, + string name: string ref); + +/** CONTROL/DATA FLOW **/ + +@control_flow_element = @stmt | @expr; + +/* XML Files */ + +xmlEncoding ( + unique int id: @file ref, + string encoding: string ref); + +xmlDTDs( + unique int id: @xmldtd, + string root: string ref, + string publicId: string ref, + string systemId: string ref, + int fileid: @file ref); + +xmlElements( + unique int id: @xmlelement, + string name: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int fileid: @file ref); + +xmlAttrs( + unique int id: @xmlattribute, + int elementid: @xmlelement ref, + string name: string ref, + string value: string ref, + int idx: int ref, + int fileid: @file ref); + +xmlNs( + int id: @xmlnamespace, + string prefixName: string ref, + string URI: string ref, + int fileid: @file ref); + +xmlHasNs( + int elementId: @xmlnamespaceable ref, + int nsId: @xmlnamespace ref, + int fileid: @file ref); + +xmlComments( + unique int id: @xmlcomment, + string text: string ref, + int parentid: @xmlparent ref, + int fileid: @file ref); + +xmlChars( + unique int id: @xmlcharacters, + string text: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int isCDATA: int ref, + int fileid: @file ref); + +@xmlparent = @file | @xmlelement; +@xmlnamespaceable = @xmlelement | @xmlattribute; + +xmllocations( + int xmlElement: @xmllocatable ref, + int location: @location_default ref); + +@xmllocatable = @xmlcharacters | @xmlelement | @xmlcomment | @xmlattribute | @xmldtd | @file | @xmlnamespace; + +/* Comments */ + +commentline( + unique int id: @commentline, + int kind: int ref, + string text: string ref, + string rawtext: string ref); + +case @commentline.kind of + 0 = @singlelinecomment +| 1 = @xmldoccomment +| 2 = @multilinecomment; + +commentline_location( + unique int id: @commentline ref, + int loc: @location ref); + +commentblock( + unique int id : @commentblock); + +commentblock_location( + unique int id: @commentblock ref, + int loc: @location ref); + +commentblock_binding( + int id: @commentblock ref, + int entity: @element ref, + int bindtype: int ref); /* 0: Parent, 1: Best, 2: Before, 3: After */ + +commentblock_child( + int id: @commentblock ref, + int commentline: @commentline ref, + int index: int ref); + +/* ASP.NET */ + +case @asp_element.kind of + 0=@asp_close_tag +| 1=@asp_code +| 2=@asp_comment +| 3=@asp_data_binding +| 4=@asp_directive +| 5=@asp_open_tag +| 6=@asp_quoted_string +| 7=@asp_text +| 8=@asp_xml_directive; + +@asp_attribute = @asp_code | @asp_data_binding | @asp_quoted_string; + +asp_elements( + unique int id: @asp_element, + int kind: int ref, + int loc: @location ref); + +asp_comment_server(unique int comment: @asp_comment ref); +asp_code_inline(unique int code: @asp_code ref); +asp_directive_attribute( + int directive: @asp_directive ref, + int index: int ref, + string name: string ref, + int value: @asp_quoted_string ref); +asp_directive_name( + unique int directive: @asp_directive ref, + string name: string ref); +asp_element_body( + unique int element: @asp_element ref, + string body: string ref); +asp_tag_attribute( + int tag: @asp_open_tag ref, + int index: int ref, + string name: string ref, + int attribute: @asp_attribute ref); +asp_tag_name( + unique int tag: @asp_open_tag ref, + string name: string ref); +asp_tag_isempty(int tag: @asp_open_tag ref); + +/* Common Intermediate Language - CIL */ + +case @cil_instruction.opcode of + 0 = @cil_nop +| 1 = @cil_break +| 2 = @cil_ldarg_0 +| 3 = @cil_ldarg_1 +| 4 = @cil_ldarg_2 +| 5 = @cil_ldarg_3 +| 6 = @cil_ldloc_0 +| 7 = @cil_ldloc_1 +| 8 = @cil_ldloc_2 +| 9 = @cil_ldloc_3 +| 10 = @cil_stloc_0 +| 11 = @cil_stloc_1 +| 12 = @cil_stloc_2 +| 13 = @cil_stloc_3 +| 14 = @cil_ldarg_s +| 15 = @cil_ldarga_s +| 16 = @cil_starg_s +| 17 = @cil_ldloc_s +| 18 = @cil_ldloca_s +| 19 = @cil_stloc_s +| 20 = @cil_ldnull +| 21 = @cil_ldc_i4_m1 +| 22 = @cil_ldc_i4_0 +| 23 = @cil_ldc_i4_1 +| 24 = @cil_ldc_i4_2 +| 25 = @cil_ldc_i4_3 +| 26 = @cil_ldc_i4_4 +| 27 = @cil_ldc_i4_5 +| 28 = @cil_ldc_i4_6 +| 29 = @cil_ldc_i4_7 +| 30 = @cil_ldc_i4_8 +| 31 = @cil_ldc_i4_s +| 32 = @cil_ldc_i4 +| 33 = @cil_ldc_i8 +| 34 = @cil_ldc_r4 +| 35 = @cil_ldc_r8 +| 37 = @cil_dup +| 38 = @cil_pop +| 39 = @cil_jmp +| 40 = @cil_call +| 41 = @cil_calli +| 42 = @cil_ret +| 43 = @cil_br_s +| 44 = @cil_brfalse_s +| 45 = @cil_brtrue_s +| 46 = @cil_beq_s +| 47 = @cil_bge_s +| 48 = @cil_bgt_s +| 49 = @cil_ble_s +| 50 = @cil_blt_s +| 51 = @cil_bne_un_s +| 52 = @cil_bge_un_s +| 53 = @cil_bgt_un_s +| 54 = @cil_ble_un_s +| 55 = @cil_blt_un_s +| 56 = @cil_br +| 57 = @cil_brfalse +| 58 = @cil_brtrue +| 59 = @cil_beq +| 60 = @cil_bge +| 61 = @cil_bgt +| 62 = @cil_ble +| 63 = @cil_blt +| 64 = @cil_bne_un +| 65 = @cil_bge_un +| 66 = @cil_bgt_un +| 67 = @cil_ble_un +| 68 = @cil_blt_un +| 69 = @cil_switch +| 70 = @cil_ldind_i1 +| 71 = @cil_ldind_u1 +| 72 = @cil_ldind_i2 +| 73 = @cil_ldind_u2 +| 74 = @cil_ldind_i4 +| 75 = @cil_ldind_u4 +| 76 = @cil_ldind_i8 +| 77 = @cil_ldind_i +| 78 = @cil_ldind_r4 +| 79 = @cil_ldind_r8 +| 80 = @cil_ldind_ref +| 81 = @cil_stind_ref +| 82 = @cil_stind_i1 +| 83 = @cil_stind_i2 +| 84 = @cil_stind_i4 +| 85 = @cil_stind_i8 +| 86 = @cil_stind_r4 +| 87 = @cil_stind_r8 +| 88 = @cil_add +| 89 = @cil_sub +| 90 = @cil_mul +| 91 = @cil_div +| 92 = @cil_div_un +| 93 = @cil_rem +| 94 = @cil_rem_un +| 95 = @cil_and +| 96 = @cil_or +| 97 = @cil_xor +| 98 = @cil_shl +| 99 = @cil_shr +| 100 = @cil_shr_un +| 101 = @cil_neg +| 102 = @cil_not +| 103 = @cil_conv_i1 +| 104 = @cil_conv_i2 +| 105 = @cil_conv_i4 +| 106 = @cil_conv_i8 +| 107 = @cil_conv_r4 +| 108 = @cil_conv_r8 +| 109 = @cil_conv_u4 +| 110 = @cil_conv_u8 +| 111 = @cil_callvirt +| 112 = @cil_cpobj +| 113 = @cil_ldobj +| 114 = @cil_ldstr +| 115 = @cil_newobj +| 116 = @cil_castclass +| 117 = @cil_isinst +| 118 = @cil_conv_r_un +| 121 = @cil_unbox +| 122 = @cil_throw +| 123 = @cil_ldfld +| 124 = @cil_ldflda +| 125 = @cil_stfld +| 126 = @cil_ldsfld +| 127 = @cil_ldsflda +| 128 = @cil_stsfld +| 129 = @cil_stobj +| 130 = @cil_conv_ovf_i1_un +| 131 = @cil_conv_ovf_i2_un +| 132 = @cil_conv_ovf_i4_un +| 133 = @cil_conv_ovf_i8_un +| 134 = @cil_conv_ovf_u1_un +| 135 = @cil_conv_ovf_u2_un +| 136 = @cil_conv_ovf_u4_un +| 137 = @cil_conv_ovf_u8_un +| 138 = @cil_conv_ovf_i_un +| 139 = @cil_conv_ovf_u_un +| 140 = @cil_box +| 141 = @cil_newarr +| 142 = @cil_ldlen +| 143 = @cil_ldelema +| 144 = @cil_ldelem_i1 +| 145 = @cil_ldelem_u1 +| 146 = @cil_ldelem_i2 +| 147 = @cil_ldelem_u2 +| 148 = @cil_ldelem_i4 +| 149 = @cil_ldelem_u4 +| 150 = @cil_ldelem_i8 +| 151 = @cil_ldelem_i +| 152 = @cil_ldelem_r4 +| 153 = @cil_ldelem_r8 +| 154 = @cil_ldelem_ref +| 155 = @cil_stelem_i +| 156 = @cil_stelem_i1 +| 157 = @cil_stelem_i2 +| 158 = @cil_stelem_i4 +| 159 = @cil_stelem_i8 +| 160 = @cil_stelem_r4 +| 161 = @cil_stelem_r8 +| 162 = @cil_stelem_ref +| 163 = @cil_ldelem +| 164 = @cil_stelem +| 165 = @cil_unbox_any +| 179 = @cil_conv_ovf_i1 +| 180 = @cil_conv_ovf_u1 +| 181 = @cil_conv_ovf_i2 +| 182 = @cil_conv_ovf_u2 +| 183 = @cil_conv_ovf_i4 +| 184 = @cil_conv_ovf_u4 +| 185 = @cil_conv_ovf_i8 +| 186 = @cil_conv_ovf_u8 +| 194 = @cil_refanyval +| 195 = @cil_ckinfinite +| 198 = @cil_mkrefany +| 208 = @cil_ldtoken +| 209 = @cil_conv_u2 +| 210 = @cil_conv_u1 +| 211 = @cil_conv_i +| 212 = @cil_conv_ovf_i +| 213 = @cil_conv_ovf_u +| 214 = @cil_add_ovf +| 215 = @cil_add_ovf_un +| 216 = @cil_mul_ovf +| 217 = @cil_mul_ovf_un +| 218 = @cil_sub_ovf +| 219 = @cil_sub_ovf_un +| 220 = @cil_endfinally +| 221 = @cil_leave +| 222 = @cil_leave_s +| 223 = @cil_stind_i +| 224 = @cil_conv_u +| 65024 = @cil_arglist +| 65025 = @cil_ceq +| 65026 = @cil_cgt +| 65027 = @cil_cgt_un +| 65028 = @cil_clt +| 65029 = @cil_clt_un +| 65030 = @cil_ldftn +| 65031 = @cil_ldvirtftn +| 65033 = @cil_ldarg +| 65034 = @cil_ldarga +| 65035 = @cil_starg +| 65036 = @cil_ldloc +| 65037 = @cil_ldloca +| 65038 = @cil_stloc +| 65039 = @cil_localloc +| 65041 = @cil_endfilter +| 65042 = @cil_unaligned +| 65043 = @cil_volatile +| 65044 = @cil_tail +| 65045 = @cil_initobj +| 65046 = @cil_constrained +| 65047 = @cil_cpblk +| 65048 = @cil_initblk +| 65050 = @cil_rethrow +| 65052 = @cil_sizeof +| 65053 = @cil_refanytype +| 65054 = @cil_readonly +; + +// CIL ignored instructions + +@cil_ignore = @cil_nop | @cil_break | @cil_volatile | @cil_unaligned; + +// CIL local/parameter/field access + +@cil_ldarg_any = @cil_ldarg_0 | @cil_ldarg_1 | @cil_ldarg_2 | @cil_ldarg_3 | @cil_ldarg_s | @cil_ldarga_s | @cil_ldarg | @cil_ldarga; +@cil_starg_any = @cil_starg | @cil_starg_s; + +@cil_ldloc_any = @cil_ldloc_0 | @cil_ldloc_1 | @cil_ldloc_2 | @cil_ldloc_3 | @cil_ldloc_s | @cil_ldloca_s | @cil_ldloc | @cil_ldloca; +@cil_stloc_any = @cil_stloc_0 | @cil_stloc_1 | @cil_stloc_2 | @cil_stloc_3 | @cil_stloc_s | @cil_stloc; + +@cil_ldfld_any = @cil_ldfld | @cil_ldsfld | @cil_ldsflda | @cil_ldflda; +@cil_stfld_any = @cil_stfld | @cil_stsfld; + +@cil_local_access = @cil_stloc_any | @cil_ldloc_any; +@cil_arg_access = @cil_starg_any | @cil_ldarg_any; +@cil_read_access = @cil_ldloc_any | @cil_ldarg_any | @cil_ldfld_any; +@cil_write_access = @cil_stloc_any | @cil_starg_any | @cil_stfld_any; + +@cil_stack_access = @cil_local_access | @cil_arg_access; +@cil_field_access = @cil_ldfld_any | @cil_stfld_any; + +@cil_access = @cil_read_access | @cil_write_access; + +// CIL constant/literal instructions + +@cil_ldc_i = @cil_ldc_i4_any | @cil_ldc_i8; + +@cil_ldc_i4_any = @cil_ldc_i4_m1 | @cil_ldc_i4_0 | @cil_ldc_i4_1 | @cil_ldc_i4_2 | @cil_ldc_i4_3 | + @cil_ldc_i4_4 | @cil_ldc_i4_5 | @cil_ldc_i4_6 | @cil_ldc_i4_7 | @cil_ldc_i4_8 | @cil_ldc_i4_s | @cil_ldc_i4; + +@cil_ldc_r = @cil_ldc_r4 | @cil_ldc_r8; + +@cil_literal = @cil_ldnull | @cil_ldc_i | @cil_ldc_r | @cil_ldstr; + +// Control flow + +@cil_conditional_jump = @cil_binary_jump | @cil_unary_jump; +@cil_binary_jump = @cil_beq_s | @cil_bge_s | @cil_bgt_s | @cil_ble_s | @cil_blt_s | + @cil_bne_un_s | @cil_bge_un_s | @cil_bgt_un_s | @cil_ble_un_s | @cil_blt_un_s | + @cil_beq | @cil_bge | @cil_bgt | @cil_ble | @cil_blt | + @cil_bne_un | @cil_bge_un | @cil_bgt_un | @cil_ble_un | @cil_blt_un; +@cil_unary_jump = @cil_brfalse_s | @cil_brtrue_s | @cil_brfalse | @cil_brtrue | @cil_switch; +@cil_unconditional_jump = @cil_br | @cil_br_s | @cil_leave_any; +@cil_leave_any = @cil_leave | @cil_leave_s; +@cil_jump = @cil_unconditional_jump | @cil_conditional_jump; + +// CIL call instructions + +@cil_call_any = @cil_jmp | @cil_call | @cil_calli | @cil_tail | @cil_callvirt | @cil_newobj; + +// CIL expression instructions + +@cil_expr = @cil_literal | @cil_binary_expr | @cil_unary_expr | @cil_call_any | @cil_read_access | + @cil_newarr | @cil_ldtoken | @cil_sizeof | + @cil_ldftn | @cil_ldvirtftn | @cil_localloc | @cil_mkrefany | @cil_refanytype | @cil_arglist | @cil_dup; + +@cil_unary_expr = + @cil_conversion_operation | @cil_unary_arithmetic_operation | @cil_unary_bitwise_operation| + @cil_ldlen | @cil_isinst | @cil_box | @cil_ldobj | @cil_castclass | @cil_unbox_any | + @cil_ldind | @cil_unbox; + +@cil_conversion_operation = + @cil_conv_i1 | @cil_conv_i2 | @cil_conv_i4 | @cil_conv_i8 | + @cil_conv_u1 | @cil_conv_u2 | @cil_conv_u4 | @cil_conv_u8 | + @cil_conv_ovf_i | @cil_conv_ovf_i_un | @cil_conv_ovf_i1 | @cil_conv_ovf_i1_un | + @cil_conv_ovf_i2 | @cil_conv_ovf_i2_un | @cil_conv_ovf_i4 | @cil_conv_ovf_i4_un | + @cil_conv_ovf_i8 | @cil_conv_ovf_i8_un | @cil_conv_ovf_u | @cil_conv_ovf_u_un | + @cil_conv_ovf_u1 | @cil_conv_ovf_u1_un | @cil_conv_ovf_u2 | @cil_conv_ovf_u2_un | + @cil_conv_ovf_u4 | @cil_conv_ovf_u4_un | @cil_conv_ovf_u8 | @cil_conv_ovf_u8_un | + @cil_conv_r4 | @cil_conv_r8 | @cil_conv_ovf_u2 | @cil_conv_ovf_u2_un | + @cil_conv_i | @cil_conv_u | @cil_conv_r_un; + +@cil_ldind = @cil_ldind_i | @cil_ldind_i1 | @cil_ldind_i2 | @cil_ldind_i4 | @cil_ldind_i8 | + @cil_ldind_r4 | @cil_ldind_r8 | @cil_ldind_ref | @cil_ldind_u1 | @cil_ldind_u2 | @cil_ldind_u4; + +@cil_stind = @cil_stind_i | @cil_stind_i1 | @cil_stind_i2 | @cil_stind_i4 | @cil_stind_i8 | + @cil_stind_r4 | @cil_stind_r8 | @cil_stind_ref; + +@cil_bitwise_operation = @cil_binary_bitwise_operation | @cil_unary_bitwise_operation; + +@cil_binary_bitwise_operation = @cil_and | @cil_or | @cil_xor | @cil_shr | @cil_shr | @cil_shr_un | @cil_shl; + +@cil_binary_arithmetic_operation = @cil_add | @cil_sub | @cil_mul | @cil_div | @cil_div_un | + @cil_rem | @cil_rem_un | @cil_add_ovf | @cil_add_ovf_un | @cil_mul_ovf | @cil_mul_ovf_un | + @cil_sub_ovf | @cil_sub_ovf_un; + +@cil_unary_bitwise_operation = @cil_not; + +@cil_binary_expr = @cil_binary_arithmetic_operation | @cil_binary_bitwise_operation | @cil_read_array | @cil_comparison_operation; + +@cil_unary_arithmetic_operation = @cil_neg; + +@cil_comparison_operation = @cil_cgt_un | @cil_ceq | @cil_cgt | @cil_clt | @cil_clt_un; + +// Elements that retrieve an address of something +@cil_read_ref = @cil_ldloca_s | @cil_ldarga_s | @cil_ldflda | @cil_ldsflda | @cil_ldelema; + +// CIL array instructions + +@cil_read_array = + @cil_ldelem | @cil_ldelema | @cil_ldelem_i1 | @cil_ldelem_ref | @cil_ldelem_i | + @cil_ldelem_i1 | @cil_ldelem_i2 | @cil_ldelem_i4 | @cil_ldelem_i8 | @cil_ldelem_r4 | + @cil_ldelem_r8 | @cil_ldelem_u1 | @cil_ldelem_u2 | @cil_ldelem_u4; + +@cil_write_array = @cil_stelem | @cil_stelem_ref | + @cil_stelem_i | @cil_stelem_i1 | @cil_stelem_i2 | @cil_stelem_i4 | @cil_stelem_i8 | + @cil_stelem_r4 | @cil_stelem_r8; + +@cil_throw_any = @cil_throw | @cil_rethrow; + +#keyset[impl, index] +cil_instruction( + unique int id: @cil_instruction, + int opcode: int ref, + int index: int ref, + int impl: @cil_method_implementation ref); + +cil_jump( + unique int instruction: @cil_jump ref, + int target: @cil_instruction ref); + +cil_access( + unique int instruction: @cil_instruction ref, + int target: @cil_accessible ref); + +cil_value( + unique int instruction: @cil_literal ref, + string value: string ref); + +#keyset[instruction, index] +cil_switch( + int instruction: @cil_switch ref, + int index: int ref, + int target: @cil_instruction ref); + +cil_instruction_location( + unique int id: @cil_instruction ref, + int loc: @location ref); + +cil_type_location( + int id: @cil_type ref, + int loc: @location ref); + +cil_method_location( + int id: @cil_method ref, + int loc: @location ref); + +@cil_namespace = @namespace; + +@cil_type_container = @cil_type | @cil_namespace | @cil_method; + +case @cil_type.kind of + 0 = @cil_valueorreftype +| 1 = @cil_typeparameter +| 2 = @cil_array_type +| 3 = @cil_pointer_type +; + +cil_type( + unique int id: @cil_type, + string name: string ref, + int kind: int ref, + int parent: @cil_type_container ref, + int sourceDecl: @cil_type ref); + +cil_pointer_type( + unique int id: @cil_pointer_type ref, + int pointee: @cil_type ref); + +cil_array_type( + unique int id: @cil_array_type ref, + int element_type: @cil_type ref, + int rank: int ref); + +cil_method( + unique int id: @cil_method, + string name: string ref, + int parent: @cil_type ref, + int return_type: @cil_type ref); + +cil_method_source_declaration( + unique int method: @cil_method ref, + int source: @cil_method ref); + +cil_method_implementation( + unique int id: @cil_method_implementation, + int method: @cil_method ref, + int location: @assembly ref); + +cil_implements( + int id: @cil_method ref, + int decl: @cil_method ref); + +#keyset[parent, name] +cil_field( + unique int id: @cil_field, + int parent: @cil_type ref, + string name: string ref, + int field_type: @cil_type ref); + +@cil_element = @cil_instruction | @cil_declaration | @cil_handler | @cil_attribute | @cil_namespace; +@cil_named_element = @cil_declaration | @cil_namespace; +@cil_declaration = @cil_variable | @cil_method | @cil_type | @cil_member; +@cil_accessible = @cil_declaration; +@cil_variable = @cil_field | @cil_stack_variable; +@cil_stack_variable = @cil_local_variable | @cil_parameter; +@cil_member = @cil_method | @cil_type | @cil_field | @cil_property | @cil_event; +@cil_custom_modifier_receiver = @cil_method | @cil_property | @cil_parameter | @cil_field; // todo: add function pointer type + +#keyset[method, index] +cil_parameter( + unique int id: @cil_parameter, + int method: @cil_method ref, + int index: int ref, + int param_type: @cil_type ref); + +cil_parameter_in(unique int id: @cil_parameter ref); +cil_parameter_out(unique int id: @cil_parameter ref); + +cil_setter(unique int prop: @cil_property ref, + int method: @cil_method ref); + +#keyset[id, modifier] +cil_custom_modifiers( + int id: @cil_custom_modifier_receiver ref, + int modifier: @cil_type ref, + int kind: int ref); // modreq: 1, modopt: 0 + +cil_getter(unique int prop: @cil_property ref, + int method: @cil_method ref); + +cil_adder(unique int event: @cil_event ref, + int method: @cil_method ref); + +cil_remover(unique int event: @cil_event ref, int method: @cil_method ref); + +cil_raiser(unique int event: @cil_event ref, int method: @cil_method ref); + +cil_property( + unique int id: @cil_property, + int parent: @cil_type ref, + string name: string ref, + int property_type: @cil_type ref); + +#keyset[parent, name] +cil_event(unique int id: @cil_event, + int parent: @cil_type ref, + string name: string ref, + int event_type: @cil_type ref); + +#keyset[impl, index] +cil_local_variable( + unique int id: @cil_local_variable, + int impl: @cil_method_implementation ref, + int index: int ref, + int var_type: @cil_type ref); + +// CIL handlers (exception handlers etc). + +case @cil_handler.kind of + 0 = @cil_catch_handler +| 1 = @cil_filter_handler +| 2 = @cil_finally_handler +| 4 = @cil_fault_handler +; + +#keyset[impl, index] +cil_handler( + unique int id: @cil_handler, + int impl: @cil_method_implementation ref, + int index: int ref, + int kind: int ref, + int try_start: @cil_instruction ref, + int try_end: @cil_instruction ref, + int handler_start: @cil_instruction ref); + +cil_handler_filter( + unique int id: @cil_handler ref, + int filter_start: @cil_instruction ref); + +cil_handler_type( + unique int id: @cil_handler ref, + int catch_type: @cil_type ref); + +@cil_controlflow_node = @cil_entry_point | @cil_instruction; + +@cil_entry_point = @cil_method_implementation | @cil_handler; + +@cil_dataflow_node = @cil_instruction | @cil_variable | @cil_method; + +cil_method_stack_size( + unique int method: @cil_method_implementation ref, + int size: int ref); + +// CIL modifiers + +cil_public(int id: @cil_member ref); +cil_private(int id: @cil_member ref); +cil_protected(int id: @cil_member ref); +cil_internal(int id: @cil_member ref); +cil_static(int id: @cil_member ref); +cil_sealed(int id: @cil_member ref); +cil_virtual(int id: @cil_method ref); +cil_abstract(int id: @cil_member ref); +cil_class(int id: @cil_type ref); +cil_interface(int id: @cil_type ref); +cil_security(int id: @cil_member ref); +cil_requiresecobject(int id: @cil_method ref); +cil_specialname(int id: @cil_method ref); +cil_newslot(int id: @cil_method ref); + +cil_base_class(unique int id: @cil_type ref, int base: @cil_type ref); +cil_base_interface(int id: @cil_type ref, int base: @cil_type ref); +cil_enum_underlying_type(unique int id: @cil_type ref, int underlying: @cil_type ref); + +#keyset[unbound, index] +cil_type_parameter( + int unbound: @cil_member ref, + int index: int ref, + int param: @cil_typeparameter ref); + +#keyset[bound, index] +cil_type_argument( + int bound: @cil_member ref, + int index: int ref, + int t: @cil_type ref); + +// CIL type parameter constraints + +cil_typeparam_covariant(int tp: @cil_typeparameter ref); +cil_typeparam_contravariant(int tp: @cil_typeparameter ref); +cil_typeparam_class(int tp: @cil_typeparameter ref); +cil_typeparam_struct(int tp: @cil_typeparameter ref); +cil_typeparam_new(int tp: @cil_typeparameter ref); +cil_typeparam_constraint(int tp: @cil_typeparameter ref, int supertype: @cil_type ref); + +// CIL attributes + +cil_attribute( + unique int attributeid: @cil_attribute, + int element: @cil_declaration ref, + int constructor: @cil_method ref); + +#keyset[attribute_id, param] +cil_attribute_named_argument( + int attribute_id: @cil_attribute ref, + string param: string ref, + string value: string ref); + +#keyset[attribute_id, index] +cil_attribute_positional_argument( + int attribute_id: @cil_attribute ref, + int index: int ref, + string value: string ref); + + +// Common .Net data model covering both C# and CIL + +// Common elements +@dotnet_element = @element | @cil_element; +@dotnet_named_element = @named_element | @cil_named_element; +@dotnet_callable = @callable | @cil_method; +@dotnet_variable = @variable | @cil_variable; +@dotnet_field = @field | @cil_field; +@dotnet_parameter = @parameter | @cil_parameter; +@dotnet_declaration = @declaration | @cil_declaration; +@dotnet_member = @member | @cil_member; +@dotnet_event = @event | @cil_event; +@dotnet_property = @property | @cil_property | @indexer; + +// Common types +@dotnet_type = @type | @cil_type; +@dotnet_call = @call | @cil_call_any; +@dotnet_throw = @throw_element | @cil_throw_any; +@dotnet_valueorreftype = @cil_valueorreftype | @value_or_ref_type | @cil_array_type | @void_type; +@dotnet_typeparameter = @type_parameter | @cil_typeparameter; +@dotnet_array_type = @array_type | @cil_array_type; +@dotnet_pointer_type = @pointer_type | @cil_pointer_type; +@dotnet_type_parameter = @type_parameter | @cil_typeparameter; +@dotnet_generic = @dotnet_valueorreftype | @dotnet_callable; + +// Attributes +@dotnet_attribute = @attribute | @cil_attribute; + +// Expressions +@dotnet_expr = @expr | @cil_expr; + +// Literals +@dotnet_literal = @literal_expr | @cil_literal; +@dotnet_string_literal = @string_literal_expr | @cil_ldstr; +@dotnet_int_literal = @integer_literal_expr | @cil_ldc_i; +@dotnet_float_literal = @float_literal_expr | @cil_ldc_r; +@dotnet_null_literal = @null_literal_expr | @cil_ldnull; + +@metadata_entity = @cil_method | @cil_type | @cil_field | @cil_property | @field | @property | + @callable | @value_or_ref_type | @void_type; + +#keyset[entity, location] +metadata_handle(int entity : @metadata_entity ref, int location: @assembly ref, int handle: int ref) diff --git a/csharp/upgrades/dd813977f70fcbf737b0bbe9dc8297edff713168/semmlecode.csharp.dbscheme b/csharp/upgrades/dd813977f70fcbf737b0bbe9dc8297edff713168/semmlecode.csharp.dbscheme new file mode 100644 index 00000000000..2fb07f0b8c6 --- /dev/null +++ b/csharp/upgrades/dd813977f70fcbf737b0bbe9dc8297edff713168/semmlecode.csharp.dbscheme @@ -0,0 +1,1956 @@ + +/** + * An invocation of the compiler. Note that more than one file may be + * compiled per invocation. For example, this command compiles three + * source files: + * + * csc f1.cs f2.cs f3.cs + * + * The `id` simply identifies the invocation, while `cwd` is the working + * directory from which the compiler was invoked. + */ +compilations( + unique int id : @compilation, + string cwd : string ref +); + +/** + * The arguments that were passed to the extractor for a compiler + * invocation. If `id` is for the compiler invocation + * + * csc f1.cs f2.cs f3.cs + * + * then typically there will be rows for + * + * num | arg + * --- | --- + * 0 | --compiler + * 1 | *path to compiler* + * 2 | --cil + * 3 | f1.cs + * 4 | f2.cs + * 5 | f3.cs + */ +#keyset[id, num] +compilation_args( + int id : @compilation ref, + int num : int ref, + string arg : string ref +); + +/** + * The source files that are compiled by a compiler invocation. + * If `id` is for the compiler invocation + * + * csc f1.cs f2.cs f3.cs + * + * then there will be rows for + * + * num | arg + * --- | --- + * 0 | f1.cs + * 1 | f2.cs + * 2 | f3.cs + */ +#keyset[id, num] +compilation_compiling_files( + int id : @compilation ref, + int num : int ref, + int file : @file ref +); + +/** + * The references used by a compiler invocation. + * If `id` is for the compiler invocation + * + * csc f1.cs f2.cs f3.cs /r:ref1.dll /r:ref2.dll /r:ref3.dll + * + * then there will be rows for + * + * num | arg + * --- | --- + * 0 | ref1.dll + * 1 | ref2.dll + * 2 | ref3.dll + */ +#keyset[id, num] +compilation_referencing_files( + int id : @compilation ref, + int num : int ref, + int file : @file ref +); + +/** + * The time taken by the extractor for a compiler invocation. + * + * For each file `num`, there will be rows for + * + * kind | seconds + * ---- | --- + * 1 | CPU seconds used by the extractor frontend + * 2 | Elapsed seconds during the extractor frontend + * 3 | CPU seconds used by the extractor backend + * 4 | Elapsed seconds during the extractor backend + */ +#keyset[id, num, kind] +compilation_time( + int id : @compilation ref, + int num : int ref, + /* kind: + 1 = frontend_cpu_seconds + 2 = frontend_elapsed_seconds + 3 = extractor_cpu_seconds + 4 = extractor_elapsed_seconds + */ + int kind : int ref, + float seconds : float ref +); + +/** + * An error or warning generated by the extractor. + * The diagnostic message `diagnostic` was generated during compiler + * invocation `compilation`, and is the `file_number_diagnostic_number`th + * message generated while extracting the `file_number`th file of that + * invocation. + */ +#keyset[compilation, file_number, file_number_diagnostic_number] +diagnostic_for( + unique int diagnostic : @diagnostic ref, + int compilation : @compilation ref, + int file_number : int ref, + int file_number_diagnostic_number : int ref +); + +diagnostics( + unique int id: @diagnostic, + int severity: int ref, + string error_tag: string ref, + string error_message: string ref, + string full_error_message: string ref, + int location: @location_default ref +); + +extractor_messages( + unique int id: @extractor_message, + int severity: int ref, + string origin : string ref, + string text : string ref, + string entity : string ref, + int location: @location_default ref, + string stack_trace : string ref +); + +/** + * If extraction was successful, then `cpu_seconds` and + * `elapsed_seconds` are the CPU time and elapsed time (respectively) + * that extraction took for compiler invocation `id`. + */ +compilation_finished( + unique int id : @compilation ref, + float cpu_seconds : float ref, + float elapsed_seconds : float ref +); + +compilation_assembly( + unique int id : @compilation ref, + int assembly: @assembly ref +) + +/* + * External artifacts + */ + +externalDefects( + unique int id: @externalDefect, + string queryPath: string ref, + int location: @location ref, + string message: string ref, + float severity: float ref); + +externalMetrics( + unique int id: @externalMetric, + string queryPath: string ref, + int location: @location ref, + float value: float ref); + +externalData( + int id: @externalDataElement, + string path: string ref, + int column: int ref, + string value: string ref); + +snapshotDate( + unique date snapshotDate: date ref); + +sourceLocationPrefix( + string prefix: string ref); + +/* + * Duplicate code + */ + +duplicateCode( + unique int id: @duplication, + string relativePath: string ref, + int equivClass: int ref); + +similarCode( + unique int id: @similarity, + string relativePath: string ref, + int equivClass: int ref); + +@duplication_or_similarity = @duplication | @similarity + +tokens( + int id: @duplication_or_similarity ref, + int offset: int ref, + int beginLine: int ref, + int beginColumn: int ref, + int endLine: int ref, + int endColumn: int ref); + +/* + * C# dbscheme + */ + +/** ELEMENTS **/ + +@element = @declaration | @stmt | @expr | @modifier | @attribute | @namespace_declaration + | @using_directive | @type_parameter_constraints | @external_element + | @xmllocatable | @asp_element | @namespace; + +@declaration = @callable | @generic | @assignable | @namespace; + +@named_element = @namespace | @declaration; + +@declaration_with_accessors = @property | @indexer | @event; + +@assignable = @variable | @assignable_with_accessors | @event; + +@assignable_with_accessors = @property | @indexer; + +@external_element = @externalMetric | @externalDefect | @externalDataElement; + +@attributable = @assembly | @field | @parameter | @operator | @method | @constructor + | @destructor | @callable_accessor | @value_or_ref_type | @declaration_with_accessors + | @local_function; + +/** LOCATIONS, ASEMMBLIES, MODULES, FILES and FOLDERS **/ + +@location = @location_default | @assembly; + +locations_default( + unique int id: @location_default, + int file: @file ref, + int beginLine: int ref, + int beginColumn: int ref, + int endLine: int ref, + int endColumn: int ref); + +@sourceline = @file | @callable | @xmllocatable; + +numlines( + int element_id: @sourceline ref, + int num_lines: int ref, + int num_code: int ref, + int num_comment: int ref); + +assemblies( + unique int id: @assembly, + int file: @file ref, + string fullname: string ref, + string name: string ref, + string version: string ref); + +/* + fromSource(0) = unknown, + fromSource(1) = from source, + fromSource(2) = from library +*/ +files( + unique int id: @file, + string name: string ref, + string simple: string ref, + string ext: string ref, + int fromSource: int ref); + +folders( + unique int id: @folder, + string name: string ref, + string simple: string ref); + +@container = @folder | @file ; + +containerparent( + int parent: @container ref, + unique int child: @container ref); + +file_extraction_mode( + unique int file: @file ref, + int mode: int ref + /* 0 = normal, 1 = standalone extractor */ + ); + +/** NAMESPACES **/ + +@type_container = @namespace | @type; + +namespaces( + unique int id: @namespace, + string name: string ref); + +namespace_declarations( + unique int id: @namespace_declaration, + int namespace_id: @namespace ref); + +namespace_declaration_location( + unique int id: @namespace_declaration ref, + int loc: @location ref); + +parent_namespace( + unique int child_id: @type_container ref, + int namespace_id: @namespace ref); + +@declaration_or_directive = @namespace_declaration | @type | @using_directive; + +parent_namespace_declaration( + int child_id: @declaration_or_directive ref, // cannot be unique because of partial classes + int namespace_id: @namespace_declaration ref); + +@using_directive = @using_namespace_directive | @using_static_directive; + +using_namespace_directives( + unique int id: @using_namespace_directive, + int namespace_id: @namespace ref); + +using_static_directives( + unique int id: @using_static_directive, + int type_id: @type_or_ref ref); + +using_directive_location( + unique int id: @using_directive ref, + int loc: @location ref); + +/** TYPES **/ + +types( + unique int id: @type, + int kind: int ref, + string name: string ref); + +case @type.kind of + 1 = @bool_type +| 2 = @char_type +| 3 = @decimal_type +| 4 = @sbyte_type +| 5 = @short_type +| 6 = @int_type +| 7 = @long_type +| 8 = @byte_type +| 9 = @ushort_type +| 10 = @uint_type +| 11 = @ulong_type +| 12 = @float_type +| 13 = @double_type +| 14 = @enum_type +| 15 = @struct_type +| 17 = @class_type +| 19 = @interface_type +| 20 = @delegate_type +| 21 = @null_type +| 22 = @type_parameter +| 23 = @pointer_type +| 24 = @nullable_type +| 25 = @array_type +| 26 = @void_type +| 27 = @int_ptr_type +| 28 = @uint_ptr_type +| 29 = @dynamic_type +| 30 = @arglist_type +| 31 = @unknown_type +| 32 = @tuple_type +| 33 = @function_pointer_type + ; + +@simple_type = @bool_type | @char_type | @integral_type | @floating_point_type | @decimal_type; +@integral_type = @signed_integral_type | @unsigned_integral_type; +@signed_integral_type = @sbyte_type | @short_type | @int_type | @long_type; +@unsigned_integral_type = @byte_type | @ushort_type | @uint_type | @ulong_type; +@floating_point_type = @float_type | @double_type; +@value_type = @simple_type | @enum_type | @struct_type | @nullable_type | @int_ptr_type + | @uint_ptr_type | @tuple_type; +@ref_type = @class_type | @interface_type | @array_type | @delegate_type | @null_type + | @dynamic_type; +@value_or_ref_type = @value_type | @ref_type; + +typerefs( + unique int id: @typeref, + string name: string ref); + +typeref_type( + int id: @typeref ref, + unique int typeId: @type ref); + +@type_or_ref = @type | @typeref; + +array_element_type( + unique int array: @array_type ref, + int dimension: int ref, + int rank: int ref, + int element: @type_or_ref ref); + +nullable_underlying_type( + unique int nullable: @nullable_type ref, + int underlying: @type_or_ref ref); + +pointer_referent_type( + unique int pointer: @pointer_type ref, + int referent: @type_or_ref ref); + +enum_underlying_type( + unique int enum_id: @enum_type ref, + int underlying_type_id: @type_or_ref ref); + +delegate_return_type( + unique int delegate_id: @delegate_type ref, + int return_type_id: @type_or_ref ref); + +function_pointer_return_type( + unique int function_pointer_id: @function_pointer_type ref, + int return_type_id: @type_or_ref ref); + +extend( + unique int sub: @type ref, + int super: @type_or_ref ref); + +anonymous_types( + unique int id: @type ref); + +@interface_or_ref = @interface_type | @typeref; + +implement( + int sub: @type ref, + int super: @type_or_ref ref); + +type_location( + int id: @type ref, + int loc: @location ref); + +tuple_underlying_type( + unique int tuple: @tuple_type ref, + int struct: @type_or_ref ref); + +#keyset[tuple, index] +tuple_element( + int tuple: @tuple_type ref, + int index: int ref, + unique int field: @field ref); + +attributes( + unique int id: @attribute, + int type_id: @type_or_ref ref, + int target: @attributable ref); + +attribute_location( + int id: @attribute ref, + int loc: @location ref); + +@type_mention_parent = @element | @type_mention; + +type_mention( + unique int id: @type_mention, + int type_id: @type_or_ref ref, + int parent: @type_mention_parent ref); + +type_mention_location( + unique int id: @type_mention ref, + int loc: @location ref); + +@has_type_annotation = @assignable | @type_parameter | @callable | @expr | @delegate_type | @generic | @function_pointer_type; + +/** + * A direct annotation on an entity, for example `string? x;`. + * + * Annotations: + * 2 = reftype is not annotated "!" + * 3 = reftype is annotated "?" + * 4 = readonly ref type / in parameter + * 5 = ref type parameter, return or local variable + * 6 = out parameter + * + * Note that the annotation depends on the element it annotates. + * @assignable: The annotation is on the type of the assignable, for example the variable type. + * @type_parameter: The annotation is on the reftype constraint + * @callable: The annotation is on the return type + * @array_type: The annotation is on the element type + */ +type_annotation(int id: @has_type_annotation ref, int annotation: int ref); + +nullability(unique int nullability: @nullability, int kind: int ref); + +case @nullability.kind of + 0 = @oblivious +| 1 = @not_annotated +| 2 = @annotated +; + +#keyset[parent, index] +nullability_parent(int nullability: @nullability ref, int index: int ref, int parent: @nullability ref) + +type_nullability(int id: @has_type_annotation ref, int nullability: @nullability ref); + +/** + * The nullable flow state of an expression, as determined by Roslyn. + * 0 = none (default, not populated) + * 1 = not null + * 2 = maybe null + */ +expr_flowstate(unique int id: @expr ref, int state: int ref); + +/** GENERICS **/ + +@generic = @type | @method | @local_function; + +type_parameters( + unique int id: @type_parameter ref, + int index: int ref, + int generic_id: @generic ref, + int variance: int ref /* none = 0, out = 1, in = 2 */); + +#keyset[constructed_id, index] +type_arguments( + int id: @type_or_ref ref, + int index: int ref, + int constructed_id: @generic_or_ref ref); + +@generic_or_ref = @generic | @typeref; + +constructed_generic( + unique int constructed: @generic ref, + int generic: @generic_or_ref ref); + +type_parameter_constraints( + unique int id: @type_parameter_constraints, + int param_id: @type_parameter ref); + +type_parameter_constraints_location( + int id: @type_parameter_constraints ref, + int loc: @location ref); + +general_type_parameter_constraints( + int id: @type_parameter_constraints ref, + int kind: int ref /* class = 1, struct = 2, new = 3 */); + +specific_type_parameter_constraints( + int id: @type_parameter_constraints ref, + int base_id: @type_or_ref ref); + +specific_type_parameter_nullability( + int id: @type_parameter_constraints ref, + int base_id: @type_or_ref ref, + int nullability: @nullability ref); + +/** FUNCTION POINTERS */ + +function_pointer_calling_conventions( + int id: @function_pointer_type ref, + int kind: int ref); + +#keyset[id, index] +has_unmanaged_calling_conventions( + int id: @function_pointer_type ref, + int index: int ref, + int conv_id: @type_or_ref ref); + +/** MODIFIERS */ + +@modifiable = @modifiable_direct | @event_accessor; + +@modifiable_direct = @member | @accessor | @local_function | @anonymous_function_expr; + +modifiers( + unique int id: @modifier, + string name: string ref); + +has_modifiers( + int id: @modifiable_direct ref, + int mod_id: @modifier ref); + +compiler_generated(unique int id: @modifiable_direct ref); + +/** MEMBERS **/ + +@member = @method | @constructor | @destructor | @field | @property | @event | @operator | @indexer | @type; + +@named_exprorstmt = @goto_stmt | @labeled_stmt | @expr; + +@virtualizable = @method | @property | @indexer | @event; + +exprorstmt_name( + unique int parent_id: @named_exprorstmt ref, + string name: string ref); + +nested_types( + unique int id: @type ref, + int declaring_type_id: @type ref, + int unbound_id: @type ref); + +properties( + unique int id: @property, + string name: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @property ref); + +property_location( + int id: @property ref, + int loc: @location ref); + +indexers( + unique int id: @indexer, + string name: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @indexer ref); + +indexer_location( + int id: @indexer ref, + int loc: @location ref); + +accessors( + unique int id: @accessor, + int kind: int ref, + string name: string ref, + int declaring_member_id: @member ref, + int unbound_id: @accessor ref); + +case @accessor.kind of + 1 = @getter +| 2 = @setter + ; + +init_only_accessors( + unique int id: @accessor ref); + +accessor_location( + int id: @accessor ref, + int loc: @location ref); + +events( + unique int id: @event, + string name: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @event ref); + +event_location( + int id: @event ref, + int loc: @location ref); + +event_accessors( + unique int id: @event_accessor, + int kind: int ref, + string name: string ref, + int declaring_event_id: @event ref, + int unbound_id: @event_accessor ref); + +case @event_accessor.kind of + 1 = @add_event_accessor +| 2 = @remove_event_accessor + ; + +event_accessor_location( + int id: @event_accessor ref, + int loc: @location ref); + +operators( + unique int id: @operator, + string name: string ref, + string symbol: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @operator ref); + +operator_location( + int id: @operator ref, + int loc: @location ref); + +constant_value( + int id: @variable ref, + string value: string ref); + +/** CALLABLES **/ + +@callable = @method | @constructor | @destructor | @operator | @callable_accessor | @anonymous_function_expr | @local_function; + +@callable_accessor = @accessor | @event_accessor; + +methods( + unique int id: @method, + string name: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @method ref); + +method_location( + int id: @method ref, + int loc: @location ref); + +constructors( + unique int id: @constructor, + string name: string ref, + int declaring_type_id: @type ref, + int unbound_id: @constructor ref); + +constructor_location( + int id: @constructor ref, + int loc: @location ref); + +destructors( + unique int id: @destructor, + string name: string ref, + int declaring_type_id: @type ref, + int unbound_id: @destructor ref); + +destructor_location( + int id: @destructor ref, + int loc: @location ref); + +overrides( + int id: @callable ref, + int base_id: @callable ref); + +explicitly_implements( + int id: @member ref, + int interface_id: @interface_or_ref ref); + +local_functions( + unique int id: @local_function, + string name: string ref, + int return_type: @type ref, + int unbound_id: @local_function ref); + +local_function_stmts( + unique int fn: @local_function_stmt ref, + int stmt: @local_function ref); + +/** VARIABLES **/ + +@variable = @local_scope_variable | @field; + +@local_scope_variable = @local_variable | @parameter; + +fields( + unique int id: @field, + int kind: int ref, + string name: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @field ref); + +case @field.kind of + 1 = @addressable_field +| 2 = @constant + ; + +field_location( + int id: @field ref, + int loc: @location ref); + +localvars( + unique int id: @local_variable, + int kind: int ref, + string name: string ref, + int implicitly_typed: int ref /* 0 = no, 1 = yes */, + int type_id: @type_or_ref ref, + int parent_id: @local_var_decl_expr ref); + +case @local_variable.kind of + 1 = @addressable_local_variable +| 2 = @local_constant +| 3 = @local_variable_ref + ; + +localvar_location( + unique int id: @local_variable ref, + int loc: @location ref); + +@parameterizable = @callable | @delegate_type | @indexer | @function_pointer_type; + +#keyset[name, parent_id] +#keyset[index, parent_id] +params( + unique int id: @parameter, + string name: string ref, + int type_id: @type_or_ref ref, + int index: int ref, + int mode: int ref, /* value = 0, ref = 1, out = 2, array = 3, this = 4 */ + int parent_id: @parameterizable ref, + int unbound_id: @parameter ref); + +param_location( + int id: @parameter ref, + int loc: @location ref); + +/** STATEMENTS **/ + +@exprorstmt_parent = @control_flow_element | @top_level_exprorstmt_parent; + +statements( + unique int id: @stmt, + int kind: int ref); + +#keyset[index, parent] +stmt_parent( + unique int stmt: @stmt ref, + int index: int ref, + int parent: @control_flow_element ref); + +@top_level_stmt_parent = @callable; + +// [index, parent] is not a keyset because the same parent may be compiled multiple times +stmt_parent_top_level( + unique int stmt: @stmt ref, + int index: int ref, + int parent: @top_level_stmt_parent ref); + +case @stmt.kind of + 1 = @block_stmt +| 2 = @expr_stmt +| 3 = @if_stmt +| 4 = @switch_stmt +| 5 = @while_stmt +| 6 = @do_stmt +| 7 = @for_stmt +| 8 = @foreach_stmt +| 9 = @break_stmt +| 10 = @continue_stmt +| 11 = @goto_stmt +| 12 = @goto_case_stmt +| 13 = @goto_default_stmt +| 14 = @throw_stmt +| 15 = @return_stmt +| 16 = @yield_stmt +| 17 = @try_stmt +| 18 = @checked_stmt +| 19 = @unchecked_stmt +| 20 = @lock_stmt +| 21 = @using_block_stmt +| 22 = @var_decl_stmt +| 23 = @const_decl_stmt +| 24 = @empty_stmt +| 25 = @unsafe_stmt +| 26 = @fixed_stmt +| 27 = @label_stmt +| 28 = @catch +| 29 = @case_stmt +| 30 = @local_function_stmt +| 31 = @using_decl_stmt + ; + +@using_stmt = @using_block_stmt | @using_decl_stmt; + +@labeled_stmt = @label_stmt | @case; + +@decl_stmt = @var_decl_stmt | @const_decl_stmt | @using_decl_stmt; + +@cond_stmt = @if_stmt | @switch_stmt; + +@loop_stmt = @while_stmt | @do_stmt | @for_stmt | @foreach_stmt; + +@jump_stmt = @break_stmt | @goto_any_stmt | @continue_stmt | @throw_stmt | @return_stmt + | @yield_stmt; + +@goto_any_stmt = @goto_default_stmt | @goto_case_stmt | @goto_stmt; + + +stmt_location( + unique int id: @stmt ref, + int loc: @location ref); + +catch_type( + unique int catch_id: @catch ref, + int type_id: @type_or_ref ref, + int kind: int ref /* explicit = 1, implicit = 2 */); + +/** EXPRESSIONS **/ + +expressions( + unique int id: @expr, + int kind: int ref, + int type_id: @type_or_ref ref); + +#keyset[index, parent] +expr_parent( + unique int expr: @expr ref, + int index: int ref, + int parent: @control_flow_element ref); + +@top_level_expr_parent = @attribute | @field | @property | @indexer | @parameter; + +@top_level_exprorstmt_parent = @top_level_expr_parent | @top_level_stmt_parent; + +// [index, parent] is not a keyset because the same parent may be compiled multiple times +expr_parent_top_level( + unique int expr: @expr ref, + int index: int ref, + int parent: @top_level_exprorstmt_parent ref); + +case @expr.kind of +/* literal */ + 1 = @bool_literal_expr +| 2 = @char_literal_expr +| 3 = @decimal_literal_expr +| 4 = @int_literal_expr +| 5 = @long_literal_expr +| 6 = @uint_literal_expr +| 7 = @ulong_literal_expr +| 8 = @float_literal_expr +| 9 = @double_literal_expr +| 10 = @string_literal_expr +| 11 = @null_literal_expr +/* primary & unary */ +| 12 = @this_access_expr +| 13 = @base_access_expr +| 14 = @local_variable_access_expr +| 15 = @parameter_access_expr +| 16 = @field_access_expr +| 17 = @property_access_expr +| 18 = @method_access_expr +| 19 = @event_access_expr +| 20 = @indexer_access_expr +| 21 = @array_access_expr +| 22 = @type_access_expr +| 23 = @typeof_expr +| 24 = @method_invocation_expr +| 25 = @delegate_invocation_expr +| 26 = @operator_invocation_expr +| 27 = @cast_expr +| 28 = @object_creation_expr +| 29 = @explicit_delegate_creation_expr +| 30 = @implicit_delegate_creation_expr +| 31 = @array_creation_expr +| 32 = @default_expr +| 33 = @plus_expr +| 34 = @minus_expr +| 35 = @bit_not_expr +| 36 = @log_not_expr +| 37 = @post_incr_expr +| 38 = @post_decr_expr +| 39 = @pre_incr_expr +| 40 = @pre_decr_expr +/* multiplicative */ +| 41 = @mul_expr +| 42 = @div_expr +| 43 = @rem_expr +/* additive */ +| 44 = @add_expr +| 45 = @sub_expr +/* shift */ +| 46 = @lshift_expr +| 47 = @rshift_expr +/* relational */ +| 48 = @lt_expr +| 49 = @gt_expr +| 50 = @le_expr +| 51 = @ge_expr +/* equality */ +| 52 = @eq_expr +| 53 = @ne_expr +/* logical */ +| 54 = @bit_and_expr +| 55 = @bit_xor_expr +| 56 = @bit_or_expr +| 57 = @log_and_expr +| 58 = @log_or_expr +/* type testing */ +| 59 = @is_expr +| 60 = @as_expr +/* null coalescing */ +| 61 = @null_coalescing_expr +/* conditional */ +| 62 = @conditional_expr +/* assignment */ +| 63 = @simple_assign_expr +| 64 = @assign_add_expr +| 65 = @assign_sub_expr +| 66 = @assign_mul_expr +| 67 = @assign_div_expr +| 68 = @assign_rem_expr +| 69 = @assign_and_expr +| 70 = @assign_xor_expr +| 71 = @assign_or_expr +| 72 = @assign_lshift_expr +| 73 = @assign_rshift_expr +/* more */ +| 74 = @object_init_expr +| 75 = @collection_init_expr +| 76 = @array_init_expr +| 77 = @checked_expr +| 78 = @unchecked_expr +| 79 = @constructor_init_expr +| 80 = @add_event_expr +| 81 = @remove_event_expr +| 82 = @par_expr +| 83 = @local_var_decl_expr +| 84 = @lambda_expr +| 85 = @anonymous_method_expr +| 86 = @namespace_expr +/* dynamic */ +| 92 = @dynamic_element_access_expr +| 93 = @dynamic_member_access_expr +/* unsafe */ +| 100 = @pointer_indirection_expr +| 101 = @address_of_expr +| 102 = @sizeof_expr +/* async */ +| 103 = @await_expr +/* C# 6.0 */ +| 104 = @nameof_expr +| 105 = @interpolated_string_expr +| 106 = @unknown_expr +/* C# 7.0 */ +| 107 = @throw_expr +| 108 = @tuple_expr +| 109 = @local_function_invocation_expr +| 110 = @ref_expr +| 111 = @discard_expr +/* C# 8.0 */ +| 112 = @range_expr +| 113 = @index_expr +| 114 = @switch_expr +| 115 = @recursive_pattern_expr +| 116 = @property_pattern_expr +| 117 = @positional_pattern_expr +| 118 = @switch_case_expr +| 119 = @assign_coalesce_expr +| 120 = @suppress_nullable_warning_expr +| 121 = @namespace_access_expr +/* C# 9.0 */ +| 122 = @lt_pattern_expr +| 123 = @gt_pattern_expr +| 124 = @le_pattern_expr +| 125 = @ge_pattern_expr +| 126 = @not_pattern_expr +| 129 = @function_pointer_invocation_expr +; + +@switch = @switch_stmt | @switch_expr; +@case = @case_stmt | @switch_case_expr; +@pattern_match = @case | @is_expr; +@unary_pattern_expr = @not_pattern_expr; +@relational_pattern_expr = @gt_pattern_expr | @lt_pattern_expr | @ge_pattern_expr | @le_pattern_expr; + +@integer_literal_expr = @int_literal_expr | @long_literal_expr | @uint_literal_expr | @ulong_literal_expr; +@real_literal_expr = @float_literal_expr | @double_literal_expr | @decimal_literal_expr; +@literal_expr = @bool_literal_expr | @char_literal_expr | @integer_literal_expr | @real_literal_expr + | @string_literal_expr | @null_literal_expr; + +@assign_expr = @simple_assign_expr | @assign_op_expr | @local_var_decl_expr; +@assign_op_expr = @assign_arith_expr | @assign_bitwise_expr | @assign_event_expr | @assign_coalesce_expr; +@assign_event_expr = @add_event_expr | @remove_event_expr; + +@assign_arith_expr = @assign_add_expr | @assign_sub_expr | @assign_mul_expr | @assign_div_expr + | @assign_rem_expr +@assign_bitwise_expr = @assign_and_expr | @assign_or_expr | @assign_xor_expr + | @assign_lshift_expr | @assign_rshift_expr; + +@member_access_expr = @field_access_expr | @property_access_expr | @indexer_access_expr | @event_access_expr + | @method_access_expr | @type_access_expr | @dynamic_member_access_expr; +@access_expr = @member_access_expr | @this_access_expr | @base_access_expr | @assignable_access_expr | @namespace_access_expr; +@element_access_expr = @indexer_access_expr | @array_access_expr | @dynamic_element_access_expr; + +@local_variable_access = @local_variable_access_expr | @local_var_decl_expr; +@local_scope_variable_access_expr = @parameter_access_expr | @local_variable_access; +@variable_access_expr = @local_scope_variable_access_expr | @field_access_expr; + +@assignable_access_expr = @variable_access_expr | @property_access_expr | @element_access_expr + | @event_access_expr | @dynamic_member_access_expr; + +@objectorcollection_init_expr = @object_init_expr | @collection_init_expr; + +@delegate_creation_expr = @explicit_delegate_creation_expr | @implicit_delegate_creation_expr; + +@bin_arith_op_expr = @mul_expr | @div_expr | @rem_expr | @add_expr | @sub_expr; +@incr_op_expr = @pre_incr_expr | @post_incr_expr; +@decr_op_expr = @pre_decr_expr | @post_decr_expr; +@mut_op_expr = @incr_op_expr | @decr_op_expr; +@un_arith_op_expr = @plus_expr | @minus_expr | @mut_op_expr; +@arith_op_expr = @bin_arith_op_expr | @un_arith_op_expr; + +@ternary_log_op_expr = @conditional_expr; +@bin_log_op_expr = @log_and_expr | @log_or_expr | @null_coalescing_expr; +@un_log_op_expr = @log_not_expr; +@log_expr = @un_log_op_expr | @bin_log_op_expr | @ternary_log_op_expr; + +@bin_bit_op_expr = @bit_and_expr | @bit_or_expr | @bit_xor_expr | @lshift_expr + | @rshift_expr; +@un_bit_op_expr = @bit_not_expr; +@bit_expr = @un_bit_op_expr | @bin_bit_op_expr; + +@equality_op_expr = @eq_expr | @ne_expr; +@rel_op_expr = @gt_expr | @lt_expr| @ge_expr | @le_expr; +@comp_expr = @equality_op_expr | @rel_op_expr; + +@op_expr = @assign_expr | @un_op | @bin_op | @ternary_op; + +@ternary_op = @ternary_log_op_expr; +@bin_op = @bin_arith_op_expr | @bin_log_op_expr | @bin_bit_op_expr | @comp_expr; +@un_op = @un_arith_op_expr | @un_log_op_expr | @un_bit_op_expr | @sizeof_expr + | @pointer_indirection_expr | @address_of_expr; + +@anonymous_function_expr = @lambda_expr | @anonymous_method_expr; + +@call = @method_invocation_expr | @constructor_init_expr | @operator_invocation_expr + | @delegate_invocation_expr | @object_creation_expr | @call_access_expr + | @local_function_invocation_expr | @function_pointer_invocation_expr; + +@call_access_expr = @property_access_expr | @event_access_expr | @indexer_access_expr; + +@late_bindable_expr = @dynamic_element_access_expr | @dynamic_member_access_expr + | @object_creation_expr | @method_invocation_expr | @operator_invocation_expr; + +@throw_element = @throw_expr | @throw_stmt; + +@implicitly_typeable_object_creation_expr = @object_creation_expr | @explicit_delegate_creation_expr; + +implicitly_typed_array_creation( + unique int id: @array_creation_expr ref); + +explicitly_sized_array_creation( + unique int id: @array_creation_expr ref); + +stackalloc_array_creation( + unique int id: @array_creation_expr ref); + +implicitly_typed_object_creation( + unique int id: @implicitly_typeable_object_creation_expr ref); + +mutator_invocation_mode( + unique int id: @operator_invocation_expr ref, + int mode: int ref /* prefix = 1, postfix = 2*/); + +expr_compiler_generated( + unique int id: @expr ref); + +expr_value( + unique int id: @expr ref, + string value: string ref); + +expr_call( + unique int caller_id: @expr ref, + int target_id: @callable ref); + +expr_access( + unique int accesser_id: @access_expr ref, + int target_id: @accessible ref); + +@accessible = @method | @assignable | @local_function | @namespace; + +expr_location( + unique int id: @expr ref, + int loc: @location ref); + +dynamic_member_name( + unique int id: @late_bindable_expr ref, + string name: string ref); + +@qualifiable_expr = @member_access_expr + | @method_invocation_expr + | @element_access_expr; + +conditional_access( + unique int id: @qualifiable_expr ref); + +expr_argument( + unique int id: @expr ref, + int mode: int ref); + /* mode is the same as params: value = 0, ref = 1, out = 2 */ + +expr_argument_name( + unique int id: @expr ref, + string name: string ref); + +/** CONTROL/DATA FLOW **/ + +@control_flow_element = @stmt | @expr; + +/* XML Files */ + +xmlEncoding ( + unique int id: @file ref, + string encoding: string ref); + +xmlDTDs( + unique int id: @xmldtd, + string root: string ref, + string publicId: string ref, + string systemId: string ref, + int fileid: @file ref); + +xmlElements( + unique int id: @xmlelement, + string name: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int fileid: @file ref); + +xmlAttrs( + unique int id: @xmlattribute, + int elementid: @xmlelement ref, + string name: string ref, + string value: string ref, + int idx: int ref, + int fileid: @file ref); + +xmlNs( + int id: @xmlnamespace, + string prefixName: string ref, + string URI: string ref, + int fileid: @file ref); + +xmlHasNs( + int elementId: @xmlnamespaceable ref, + int nsId: @xmlnamespace ref, + int fileid: @file ref); + +xmlComments( + unique int id: @xmlcomment, + string text: string ref, + int parentid: @xmlparent ref, + int fileid: @file ref); + +xmlChars( + unique int id: @xmlcharacters, + string text: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int isCDATA: int ref, + int fileid: @file ref); + +@xmlparent = @file | @xmlelement; +@xmlnamespaceable = @xmlelement | @xmlattribute; + +xmllocations( + int xmlElement: @xmllocatable ref, + int location: @location_default ref); + +@xmllocatable = @xmlcharacters | @xmlelement | @xmlcomment | @xmlattribute | @xmldtd | @file | @xmlnamespace; + +/* Comments */ + +commentline( + unique int id: @commentline, + int kind: int ref, + string text: string ref, + string rawtext: string ref); + +case @commentline.kind of + 0 = @singlelinecomment +| 1 = @xmldoccomment +| 2 = @multilinecomment; + +commentline_location( + unique int id: @commentline ref, + int loc: @location ref); + +commentblock( + unique int id : @commentblock); + +commentblock_location( + unique int id: @commentblock ref, + int loc: @location ref); + +commentblock_binding( + int id: @commentblock ref, + int entity: @element ref, + int bindtype: int ref); /* 0: Parent, 1: Best, 2: Before, 3: After */ + +commentblock_child( + int id: @commentblock ref, + int commentline: @commentline ref, + int index: int ref); + +/* ASP.NET */ + +case @asp_element.kind of + 0=@asp_close_tag +| 1=@asp_code +| 2=@asp_comment +| 3=@asp_data_binding +| 4=@asp_directive +| 5=@asp_open_tag +| 6=@asp_quoted_string +| 7=@asp_text +| 8=@asp_xml_directive; + +@asp_attribute = @asp_code | @asp_data_binding | @asp_quoted_string; + +asp_elements( + unique int id: @asp_element, + int kind: int ref, + int loc: @location ref); + +asp_comment_server(unique int comment: @asp_comment ref); +asp_code_inline(unique int code: @asp_code ref); +asp_directive_attribute( + int directive: @asp_directive ref, + int index: int ref, + string name: string ref, + int value: @asp_quoted_string ref); +asp_directive_name( + unique int directive: @asp_directive ref, + string name: string ref); +asp_element_body( + unique int element: @asp_element ref, + string body: string ref); +asp_tag_attribute( + int tag: @asp_open_tag ref, + int index: int ref, + string name: string ref, + int attribute: @asp_attribute ref); +asp_tag_name( + unique int tag: @asp_open_tag ref, + string name: string ref); +asp_tag_isempty(int tag: @asp_open_tag ref); + +/* Common Intermediate Language - CIL */ + +case @cil_instruction.opcode of + 0 = @cil_nop +| 1 = @cil_break +| 2 = @cil_ldarg_0 +| 3 = @cil_ldarg_1 +| 4 = @cil_ldarg_2 +| 5 = @cil_ldarg_3 +| 6 = @cil_ldloc_0 +| 7 = @cil_ldloc_1 +| 8 = @cil_ldloc_2 +| 9 = @cil_ldloc_3 +| 10 = @cil_stloc_0 +| 11 = @cil_stloc_1 +| 12 = @cil_stloc_2 +| 13 = @cil_stloc_3 +| 14 = @cil_ldarg_s +| 15 = @cil_ldarga_s +| 16 = @cil_starg_s +| 17 = @cil_ldloc_s +| 18 = @cil_ldloca_s +| 19 = @cil_stloc_s +| 20 = @cil_ldnull +| 21 = @cil_ldc_i4_m1 +| 22 = @cil_ldc_i4_0 +| 23 = @cil_ldc_i4_1 +| 24 = @cil_ldc_i4_2 +| 25 = @cil_ldc_i4_3 +| 26 = @cil_ldc_i4_4 +| 27 = @cil_ldc_i4_5 +| 28 = @cil_ldc_i4_6 +| 29 = @cil_ldc_i4_7 +| 30 = @cil_ldc_i4_8 +| 31 = @cil_ldc_i4_s +| 32 = @cil_ldc_i4 +| 33 = @cil_ldc_i8 +| 34 = @cil_ldc_r4 +| 35 = @cil_ldc_r8 +| 37 = @cil_dup +| 38 = @cil_pop +| 39 = @cil_jmp +| 40 = @cil_call +| 41 = @cil_calli +| 42 = @cil_ret +| 43 = @cil_br_s +| 44 = @cil_brfalse_s +| 45 = @cil_brtrue_s +| 46 = @cil_beq_s +| 47 = @cil_bge_s +| 48 = @cil_bgt_s +| 49 = @cil_ble_s +| 50 = @cil_blt_s +| 51 = @cil_bne_un_s +| 52 = @cil_bge_un_s +| 53 = @cil_bgt_un_s +| 54 = @cil_ble_un_s +| 55 = @cil_blt_un_s +| 56 = @cil_br +| 57 = @cil_brfalse +| 58 = @cil_brtrue +| 59 = @cil_beq +| 60 = @cil_bge +| 61 = @cil_bgt +| 62 = @cil_ble +| 63 = @cil_blt +| 64 = @cil_bne_un +| 65 = @cil_bge_un +| 66 = @cil_bgt_un +| 67 = @cil_ble_un +| 68 = @cil_blt_un +| 69 = @cil_switch +| 70 = @cil_ldind_i1 +| 71 = @cil_ldind_u1 +| 72 = @cil_ldind_i2 +| 73 = @cil_ldind_u2 +| 74 = @cil_ldind_i4 +| 75 = @cil_ldind_u4 +| 76 = @cil_ldind_i8 +| 77 = @cil_ldind_i +| 78 = @cil_ldind_r4 +| 79 = @cil_ldind_r8 +| 80 = @cil_ldind_ref +| 81 = @cil_stind_ref +| 82 = @cil_stind_i1 +| 83 = @cil_stind_i2 +| 84 = @cil_stind_i4 +| 85 = @cil_stind_i8 +| 86 = @cil_stind_r4 +| 87 = @cil_stind_r8 +| 88 = @cil_add +| 89 = @cil_sub +| 90 = @cil_mul +| 91 = @cil_div +| 92 = @cil_div_un +| 93 = @cil_rem +| 94 = @cil_rem_un +| 95 = @cil_and +| 96 = @cil_or +| 97 = @cil_xor +| 98 = @cil_shl +| 99 = @cil_shr +| 100 = @cil_shr_un +| 101 = @cil_neg +| 102 = @cil_not +| 103 = @cil_conv_i1 +| 104 = @cil_conv_i2 +| 105 = @cil_conv_i4 +| 106 = @cil_conv_i8 +| 107 = @cil_conv_r4 +| 108 = @cil_conv_r8 +| 109 = @cil_conv_u4 +| 110 = @cil_conv_u8 +| 111 = @cil_callvirt +| 112 = @cil_cpobj +| 113 = @cil_ldobj +| 114 = @cil_ldstr +| 115 = @cil_newobj +| 116 = @cil_castclass +| 117 = @cil_isinst +| 118 = @cil_conv_r_un +| 121 = @cil_unbox +| 122 = @cil_throw +| 123 = @cil_ldfld +| 124 = @cil_ldflda +| 125 = @cil_stfld +| 126 = @cil_ldsfld +| 127 = @cil_ldsflda +| 128 = @cil_stsfld +| 129 = @cil_stobj +| 130 = @cil_conv_ovf_i1_un +| 131 = @cil_conv_ovf_i2_un +| 132 = @cil_conv_ovf_i4_un +| 133 = @cil_conv_ovf_i8_un +| 134 = @cil_conv_ovf_u1_un +| 135 = @cil_conv_ovf_u2_un +| 136 = @cil_conv_ovf_u4_un +| 137 = @cil_conv_ovf_u8_un +| 138 = @cil_conv_ovf_i_un +| 139 = @cil_conv_ovf_u_un +| 140 = @cil_box +| 141 = @cil_newarr +| 142 = @cil_ldlen +| 143 = @cil_ldelema +| 144 = @cil_ldelem_i1 +| 145 = @cil_ldelem_u1 +| 146 = @cil_ldelem_i2 +| 147 = @cil_ldelem_u2 +| 148 = @cil_ldelem_i4 +| 149 = @cil_ldelem_u4 +| 150 = @cil_ldelem_i8 +| 151 = @cil_ldelem_i +| 152 = @cil_ldelem_r4 +| 153 = @cil_ldelem_r8 +| 154 = @cil_ldelem_ref +| 155 = @cil_stelem_i +| 156 = @cil_stelem_i1 +| 157 = @cil_stelem_i2 +| 158 = @cil_stelem_i4 +| 159 = @cil_stelem_i8 +| 160 = @cil_stelem_r4 +| 161 = @cil_stelem_r8 +| 162 = @cil_stelem_ref +| 163 = @cil_ldelem +| 164 = @cil_stelem +| 165 = @cil_unbox_any +| 179 = @cil_conv_ovf_i1 +| 180 = @cil_conv_ovf_u1 +| 181 = @cil_conv_ovf_i2 +| 182 = @cil_conv_ovf_u2 +| 183 = @cil_conv_ovf_i4 +| 184 = @cil_conv_ovf_u4 +| 185 = @cil_conv_ovf_i8 +| 186 = @cil_conv_ovf_u8 +| 194 = @cil_refanyval +| 195 = @cil_ckinfinite +| 198 = @cil_mkrefany +| 208 = @cil_ldtoken +| 209 = @cil_conv_u2 +| 210 = @cil_conv_u1 +| 211 = @cil_conv_i +| 212 = @cil_conv_ovf_i +| 213 = @cil_conv_ovf_u +| 214 = @cil_add_ovf +| 215 = @cil_add_ovf_un +| 216 = @cil_mul_ovf +| 217 = @cil_mul_ovf_un +| 218 = @cil_sub_ovf +| 219 = @cil_sub_ovf_un +| 220 = @cil_endfinally +| 221 = @cil_leave +| 222 = @cil_leave_s +| 223 = @cil_stind_i +| 224 = @cil_conv_u +| 65024 = @cil_arglist +| 65025 = @cil_ceq +| 65026 = @cil_cgt +| 65027 = @cil_cgt_un +| 65028 = @cil_clt +| 65029 = @cil_clt_un +| 65030 = @cil_ldftn +| 65031 = @cil_ldvirtftn +| 65033 = @cil_ldarg +| 65034 = @cil_ldarga +| 65035 = @cil_starg +| 65036 = @cil_ldloc +| 65037 = @cil_ldloca +| 65038 = @cil_stloc +| 65039 = @cil_localloc +| 65041 = @cil_endfilter +| 65042 = @cil_unaligned +| 65043 = @cil_volatile +| 65044 = @cil_tail +| 65045 = @cil_initobj +| 65046 = @cil_constrained +| 65047 = @cil_cpblk +| 65048 = @cil_initblk +| 65050 = @cil_rethrow +| 65052 = @cil_sizeof +| 65053 = @cil_refanytype +| 65054 = @cil_readonly +; + +// CIL ignored instructions + +@cil_ignore = @cil_nop | @cil_break | @cil_volatile | @cil_unaligned; + +// CIL local/parameter/field access + +@cil_ldarg_any = @cil_ldarg_0 | @cil_ldarg_1 | @cil_ldarg_2 | @cil_ldarg_3 | @cil_ldarg_s | @cil_ldarga_s | @cil_ldarg | @cil_ldarga; +@cil_starg_any = @cil_starg | @cil_starg_s; + +@cil_ldloc_any = @cil_ldloc_0 | @cil_ldloc_1 | @cil_ldloc_2 | @cil_ldloc_3 | @cil_ldloc_s | @cil_ldloca_s | @cil_ldloc | @cil_ldloca; +@cil_stloc_any = @cil_stloc_0 | @cil_stloc_1 | @cil_stloc_2 | @cil_stloc_3 | @cil_stloc_s | @cil_stloc; + +@cil_ldfld_any = @cil_ldfld | @cil_ldsfld | @cil_ldsflda | @cil_ldflda; +@cil_stfld_any = @cil_stfld | @cil_stsfld; + +@cil_local_access = @cil_stloc_any | @cil_ldloc_any; +@cil_arg_access = @cil_starg_any | @cil_ldarg_any; +@cil_read_access = @cil_ldloc_any | @cil_ldarg_any | @cil_ldfld_any; +@cil_write_access = @cil_stloc_any | @cil_starg_any | @cil_stfld_any; + +@cil_stack_access = @cil_local_access | @cil_arg_access; +@cil_field_access = @cil_ldfld_any | @cil_stfld_any; + +@cil_access = @cil_read_access | @cil_write_access; + +// CIL constant/literal instructions + +@cil_ldc_i = @cil_ldc_i4_any | @cil_ldc_i8; + +@cil_ldc_i4_any = @cil_ldc_i4_m1 | @cil_ldc_i4_0 | @cil_ldc_i4_1 | @cil_ldc_i4_2 | @cil_ldc_i4_3 | + @cil_ldc_i4_4 | @cil_ldc_i4_5 | @cil_ldc_i4_6 | @cil_ldc_i4_7 | @cil_ldc_i4_8 | @cil_ldc_i4_s | @cil_ldc_i4; + +@cil_ldc_r = @cil_ldc_r4 | @cil_ldc_r8; + +@cil_literal = @cil_ldnull | @cil_ldc_i | @cil_ldc_r | @cil_ldstr; + +// Control flow + +@cil_conditional_jump = @cil_binary_jump | @cil_unary_jump; +@cil_binary_jump = @cil_beq_s | @cil_bge_s | @cil_bgt_s | @cil_ble_s | @cil_blt_s | + @cil_bne_un_s | @cil_bge_un_s | @cil_bgt_un_s | @cil_ble_un_s | @cil_blt_un_s | + @cil_beq | @cil_bge | @cil_bgt | @cil_ble | @cil_blt | + @cil_bne_un | @cil_bge_un | @cil_bgt_un | @cil_ble_un | @cil_blt_un; +@cil_unary_jump = @cil_brfalse_s | @cil_brtrue_s | @cil_brfalse | @cil_brtrue | @cil_switch; +@cil_unconditional_jump = @cil_br | @cil_br_s | @cil_leave_any; +@cil_leave_any = @cil_leave | @cil_leave_s; +@cil_jump = @cil_unconditional_jump | @cil_conditional_jump; + +// CIL call instructions + +@cil_call_any = @cil_jmp | @cil_call | @cil_calli | @cil_tail | @cil_callvirt | @cil_newobj; + +// CIL expression instructions + +@cil_expr = @cil_literal | @cil_binary_expr | @cil_unary_expr | @cil_call_any | @cil_read_access | + @cil_newarr | @cil_ldtoken | @cil_sizeof | + @cil_ldftn | @cil_ldvirtftn | @cil_localloc | @cil_mkrefany | @cil_refanytype | @cil_arglist | @cil_dup; + +@cil_unary_expr = + @cil_conversion_operation | @cil_unary_arithmetic_operation | @cil_unary_bitwise_operation| + @cil_ldlen | @cil_isinst | @cil_box | @cil_ldobj | @cil_castclass | @cil_unbox_any | + @cil_ldind | @cil_unbox; + +@cil_conversion_operation = + @cil_conv_i1 | @cil_conv_i2 | @cil_conv_i4 | @cil_conv_i8 | + @cil_conv_u1 | @cil_conv_u2 | @cil_conv_u4 | @cil_conv_u8 | + @cil_conv_ovf_i | @cil_conv_ovf_i_un | @cil_conv_ovf_i1 | @cil_conv_ovf_i1_un | + @cil_conv_ovf_i2 | @cil_conv_ovf_i2_un | @cil_conv_ovf_i4 | @cil_conv_ovf_i4_un | + @cil_conv_ovf_i8 | @cil_conv_ovf_i8_un | @cil_conv_ovf_u | @cil_conv_ovf_u_un | + @cil_conv_ovf_u1 | @cil_conv_ovf_u1_un | @cil_conv_ovf_u2 | @cil_conv_ovf_u2_un | + @cil_conv_ovf_u4 | @cil_conv_ovf_u4_un | @cil_conv_ovf_u8 | @cil_conv_ovf_u8_un | + @cil_conv_r4 | @cil_conv_r8 | @cil_conv_ovf_u2 | @cil_conv_ovf_u2_un | + @cil_conv_i | @cil_conv_u | @cil_conv_r_un; + +@cil_ldind = @cil_ldind_i | @cil_ldind_i1 | @cil_ldind_i2 | @cil_ldind_i4 | @cil_ldind_i8 | + @cil_ldind_r4 | @cil_ldind_r8 | @cil_ldind_ref | @cil_ldind_u1 | @cil_ldind_u2 | @cil_ldind_u4; + +@cil_stind = @cil_stind_i | @cil_stind_i1 | @cil_stind_i2 | @cil_stind_i4 | @cil_stind_i8 | + @cil_stind_r4 | @cil_stind_r8 | @cil_stind_ref; + +@cil_bitwise_operation = @cil_binary_bitwise_operation | @cil_unary_bitwise_operation; + +@cil_binary_bitwise_operation = @cil_and | @cil_or | @cil_xor | @cil_shr | @cil_shr | @cil_shr_un | @cil_shl; + +@cil_binary_arithmetic_operation = @cil_add | @cil_sub | @cil_mul | @cil_div | @cil_div_un | + @cil_rem | @cil_rem_un | @cil_add_ovf | @cil_add_ovf_un | @cil_mul_ovf | @cil_mul_ovf_un | + @cil_sub_ovf | @cil_sub_ovf_un; + +@cil_unary_bitwise_operation = @cil_not; + +@cil_binary_expr = @cil_binary_arithmetic_operation | @cil_binary_bitwise_operation | @cil_read_array | @cil_comparison_operation; + +@cil_unary_arithmetic_operation = @cil_neg; + +@cil_comparison_operation = @cil_cgt_un | @cil_ceq | @cil_cgt | @cil_clt | @cil_clt_un; + +// Elements that retrieve an address of something +@cil_read_ref = @cil_ldloca_s | @cil_ldarga_s | @cil_ldflda | @cil_ldsflda | @cil_ldelema; + +// CIL array instructions + +@cil_read_array = + @cil_ldelem | @cil_ldelema | @cil_ldelem_i1 | @cil_ldelem_ref | @cil_ldelem_i | + @cil_ldelem_i1 | @cil_ldelem_i2 | @cil_ldelem_i4 | @cil_ldelem_i8 | @cil_ldelem_r4 | + @cil_ldelem_r8 | @cil_ldelem_u1 | @cil_ldelem_u2 | @cil_ldelem_u4; + +@cil_write_array = @cil_stelem | @cil_stelem_ref | + @cil_stelem_i | @cil_stelem_i1 | @cil_stelem_i2 | @cil_stelem_i4 | @cil_stelem_i8 | + @cil_stelem_r4 | @cil_stelem_r8; + +@cil_throw_any = @cil_throw | @cil_rethrow; + +#keyset[impl, index] +cil_instruction( + unique int id: @cil_instruction, + int opcode: int ref, + int index: int ref, + int impl: @cil_method_implementation ref); + +cil_jump( + unique int instruction: @cil_jump ref, + int target: @cil_instruction ref); + +cil_access( + unique int instruction: @cil_instruction ref, + int target: @cil_accessible ref); + +cil_value( + unique int instruction: @cil_literal ref, + string value: string ref); + +#keyset[instruction, index] +cil_switch( + int instruction: @cil_switch ref, + int index: int ref, + int target: @cil_instruction ref); + +cil_instruction_location( + unique int id: @cil_instruction ref, + int loc: @location ref); + +cil_type_location( + int id: @cil_type ref, + int loc: @location ref); + +cil_method_location( + int id: @cil_method ref, + int loc: @location ref); + +@cil_namespace = @namespace; + +@cil_type_container = @cil_type | @cil_namespace | @cil_method; + +case @cil_type.kind of + 0 = @cil_valueorreftype +| 1 = @cil_typeparameter +| 2 = @cil_array_type +| 3 = @cil_pointer_type +| 4 = @cil_function_pointer_type +; + +cil_type( + unique int id: @cil_type, + string name: string ref, + int kind: int ref, + int parent: @cil_type_container ref, + int sourceDecl: @cil_type ref); + +cil_pointer_type( + unique int id: @cil_pointer_type ref, + int pointee: @cil_type ref); + +cil_array_type( + unique int id: @cil_array_type ref, + int element_type: @cil_type ref, + int rank: int ref); + +cil_function_pointer_return_type( + unique int id: @cil_function_pointer_type ref, + int return_type: @cil_type ref); + +cil_method( + unique int id: @cil_method, + string name: string ref, + int parent: @cil_type ref, + int return_type: @cil_type ref); + +cil_method_source_declaration( + unique int method: @cil_method ref, + int source: @cil_method ref); + +cil_method_implementation( + unique int id: @cil_method_implementation, + int method: @cil_method ref, + int location: @assembly ref); + +cil_implements( + int id: @cil_method ref, + int decl: @cil_method ref); + +#keyset[parent, name] +cil_field( + unique int id: @cil_field, + int parent: @cil_type ref, + string name: string ref, + int field_type: @cil_type ref); + +@cil_element = @cil_instruction | @cil_declaration | @cil_handler | @cil_attribute | @cil_namespace; +@cil_named_element = @cil_declaration | @cil_namespace; +@cil_declaration = @cil_variable | @cil_method | @cil_type | @cil_member; +@cil_accessible = @cil_declaration; +@cil_variable = @cil_field | @cil_stack_variable; +@cil_stack_variable = @cil_local_variable | @cil_parameter; +@cil_member = @cil_method | @cil_type | @cil_field | @cil_property | @cil_event; +@cil_custom_modifier_receiver = @cil_method | @cil_property | @cil_parameter | @cil_field | @cil_function_pointer_type; +@cil_parameterizable = @cil_method | @cil_function_pointer_type; +@cil_has_type_annotation = @cil_stack_variable | @cil_property | @cil_method | @cil_function_pointer_type; + +#keyset[parameterizable, index] +cil_parameter( + unique int id: @cil_parameter, + int parameterizable: @cil_parameterizable ref, + int index: int ref, + int param_type: @cil_type ref); + +cil_parameter_in(unique int id: @cil_parameter ref); +cil_parameter_out(unique int id: @cil_parameter ref); + +cil_setter(unique int prop: @cil_property ref, + int method: @cil_method ref); + +#keyset[id, modifier] +cil_custom_modifiers( + int id: @cil_custom_modifier_receiver ref, + int modifier: @cil_type ref, + int kind: int ref); // modreq: 1, modopt: 0 + +cil_type_annotation( + int id: @cil_has_type_annotation ref, + int annotation: int ref); + +cil_getter(unique int prop: @cil_property ref, + int method: @cil_method ref); + +cil_adder(unique int event: @cil_event ref, + int method: @cil_method ref); + +cil_remover(unique int event: @cil_event ref, int method: @cil_method ref); + +cil_raiser(unique int event: @cil_event ref, int method: @cil_method ref); + +cil_property( + unique int id: @cil_property, + int parent: @cil_type ref, + string name: string ref, + int property_type: @cil_type ref); + +#keyset[parent, name] +cil_event(unique int id: @cil_event, + int parent: @cil_type ref, + string name: string ref, + int event_type: @cil_type ref); + +#keyset[impl, index] +cil_local_variable( + unique int id: @cil_local_variable, + int impl: @cil_method_implementation ref, + int index: int ref, + int var_type: @cil_type ref); + +cil_function_pointer_calling_conventions( + int id: @cil_function_pointer_type ref, + int kind: int ref); + +// CIL handlers (exception handlers etc). + +case @cil_handler.kind of + 0 = @cil_catch_handler +| 1 = @cil_filter_handler +| 2 = @cil_finally_handler +| 4 = @cil_fault_handler +; + +#keyset[impl, index] +cil_handler( + unique int id: @cil_handler, + int impl: @cil_method_implementation ref, + int index: int ref, + int kind: int ref, + int try_start: @cil_instruction ref, + int try_end: @cil_instruction ref, + int handler_start: @cil_instruction ref); + +cil_handler_filter( + unique int id: @cil_handler ref, + int filter_start: @cil_instruction ref); + +cil_handler_type( + unique int id: @cil_handler ref, + int catch_type: @cil_type ref); + +@cil_controlflow_node = @cil_entry_point | @cil_instruction; + +@cil_entry_point = @cil_method_implementation | @cil_handler; + +@cil_dataflow_node = @cil_instruction | @cil_variable | @cil_method; + +cil_method_stack_size( + unique int method: @cil_method_implementation ref, + int size: int ref); + +// CIL modifiers + +cil_public(int id: @cil_member ref); +cil_private(int id: @cil_member ref); +cil_protected(int id: @cil_member ref); +cil_internal(int id: @cil_member ref); +cil_static(int id: @cil_member ref); +cil_sealed(int id: @cil_member ref); +cil_virtual(int id: @cil_method ref); +cil_abstract(int id: @cil_member ref); +cil_class(int id: @cil_type ref); +cil_interface(int id: @cil_type ref); +cil_security(int id: @cil_member ref); +cil_requiresecobject(int id: @cil_method ref); +cil_specialname(int id: @cil_method ref); +cil_newslot(int id: @cil_method ref); + +cil_base_class(unique int id: @cil_type ref, int base: @cil_type ref); +cil_base_interface(int id: @cil_type ref, int base: @cil_type ref); +cil_enum_underlying_type(unique int id: @cil_type ref, int underlying: @cil_type ref); + +#keyset[unbound, index] +cil_type_parameter( + int unbound: @cil_member ref, + int index: int ref, + int param: @cil_typeparameter ref); + +#keyset[bound, index] +cil_type_argument( + int bound: @cil_member ref, + int index: int ref, + int t: @cil_type ref); + +// CIL type parameter constraints + +cil_typeparam_covariant(int tp: @cil_typeparameter ref); +cil_typeparam_contravariant(int tp: @cil_typeparameter ref); +cil_typeparam_class(int tp: @cil_typeparameter ref); +cil_typeparam_struct(int tp: @cil_typeparameter ref); +cil_typeparam_new(int tp: @cil_typeparameter ref); +cil_typeparam_constraint(int tp: @cil_typeparameter ref, int supertype: @cil_type ref); + +// CIL attributes + +cil_attribute( + unique int attributeid: @cil_attribute, + int element: @cil_declaration ref, + int constructor: @cil_method ref); + +#keyset[attribute_id, param] +cil_attribute_named_argument( + int attribute_id: @cil_attribute ref, + string param: string ref, + string value: string ref); + +#keyset[attribute_id, index] +cil_attribute_positional_argument( + int attribute_id: @cil_attribute ref, + int index: int ref, + string value: string ref); + + +// Common .Net data model covering both C# and CIL + +// Common elements +@dotnet_element = @element | @cil_element; +@dotnet_named_element = @named_element | @cil_named_element; +@dotnet_callable = @callable | @cil_method; +@dotnet_variable = @variable | @cil_variable; +@dotnet_field = @field | @cil_field; +@dotnet_parameter = @parameter | @cil_parameter; +@dotnet_declaration = @declaration | @cil_declaration; +@dotnet_member = @member | @cil_member; +@dotnet_event = @event | @cil_event; +@dotnet_property = @property | @cil_property | @indexer; +@dotnet_parameterizable = @parameterizable | @cil_parameterizable; + +// Common types +@dotnet_type = @type | @cil_type; +@dotnet_call = @call | @cil_call_any; +@dotnet_throw = @throw_element | @cil_throw_any; +@dotnet_valueorreftype = @cil_valueorreftype | @value_or_ref_type | @cil_array_type | @void_type; +@dotnet_typeparameter = @type_parameter | @cil_typeparameter; +@dotnet_array_type = @array_type | @cil_array_type; +@dotnet_pointer_type = @pointer_type | @cil_pointer_type; +@dotnet_type_parameter = @type_parameter | @cil_typeparameter; +@dotnet_generic = @dotnet_valueorreftype | @dotnet_callable; + +// Attributes +@dotnet_attribute = @attribute | @cil_attribute; + +// Expressions +@dotnet_expr = @expr | @cil_expr; + +// Literals +@dotnet_literal = @literal_expr | @cil_literal; +@dotnet_string_literal = @string_literal_expr | @cil_ldstr; +@dotnet_int_literal = @integer_literal_expr | @cil_ldc_i; +@dotnet_float_literal = @float_literal_expr | @cil_ldc_r; +@dotnet_null_literal = @null_literal_expr | @cil_ldnull; + +@metadata_entity = @cil_method | @cil_type | @cil_field | @cil_property | @field | @property | + @callable | @value_or_ref_type | @void_type; + +#keyset[entity, location] +metadata_handle(int entity : @metadata_entity ref, int location: @assembly ref, int handle: int ref) diff --git a/csharp/upgrades/dd813977f70fcbf737b0bbe9dc8297edff713168/upgrade.properties b/csharp/upgrades/dd813977f70fcbf737b0bbe9dc8297edff713168/upgrade.properties new file mode 100644 index 00000000000..76895754bd0 --- /dev/null +++ b/csharp/upgrades/dd813977f70fcbf737b0bbe9dc8297edff713168/upgrade.properties @@ -0,0 +1,4 @@ +description: Added '@cil_function_pointer_type' and related relations ('cil_function_pointer_return_type', +'cil_function_pointer_calling_conventions'). Introduced 'cil_type_annotation' and '@cil_has_type_annotation' +to store by-reference type annotation. Added '@cil_parameterizable' to represent methods and type parameters. +compatibility: backwards diff --git a/csharp/upgrades/e6442d16b7e3786d0918597c2c9fbd871ca06f77/old.dbscheme b/csharp/upgrades/e6442d16b7e3786d0918597c2c9fbd871ca06f77/old.dbscheme new file mode 100644 index 00000000000..e6442d16b7e --- /dev/null +++ b/csharp/upgrades/e6442d16b7e3786d0918597c2c9fbd871ca06f77/old.dbscheme @@ -0,0 +1,1914 @@ + +/** + * An invocation of the compiler. Note that more than one file may be + * compiled per invocation. For example, this command compiles three + * source files: + * + * csc f1.cs f2.cs f3.cs + * + * The `id` simply identifies the invocation, while `cwd` is the working + * directory from which the compiler was invoked. + */ +compilations( + unique int id : @compilation, + string cwd : string ref +); + +/** + * The arguments that were passed to the extractor for a compiler + * invocation. If `id` is for the compiler invocation + * + * csc f1.cs f2.cs f3.cs + * + * then typically there will be rows for + * + * num | arg + * --- | --- + * 0 | --compiler + * 1 | *path to compiler* + * 2 | --cil + * 3 | f1.cs + * 4 | f2.cs + * 5 | f3.cs + */ +#keyset[id, num] +compilation_args( + int id : @compilation ref, + int num : int ref, + string arg : string ref +); + +/** + * The source files that are compiled by a compiler invocation. + * If `id` is for the compiler invocation + * + * csc f1.cs f2.cs f3.cs + * + * then there will be rows for + * + * num | arg + * --- | --- + * 0 | f1.cs + * 1 | f2.cs + * 2 | f3.cs + */ +#keyset[id, num] +compilation_compiling_files( + int id : @compilation ref, + int num : int ref, + int file : @file ref +); + +/** + * The references used by a compiler invocation. + * If `id` is for the compiler invocation + * + * csc f1.cs f2.cs f3.cs /r:ref1.dll /r:ref2.dll /r:ref3.dll + * + * then there will be rows for + * + * num | arg + * --- | --- + * 0 | ref1.dll + * 1 | ref2.dll + * 2 | ref3.dll + */ +#keyset[id, num] +compilation_referencing_files( + int id : @compilation ref, + int num : int ref, + int file : @file ref +); + +/** + * The time taken by the extractor for a compiler invocation. + * + * For each file `num`, there will be rows for + * + * kind | seconds + * ---- | --- + * 1 | CPU seconds used by the extractor frontend + * 2 | Elapsed seconds during the extractor frontend + * 3 | CPU seconds used by the extractor backend + * 4 | Elapsed seconds during the extractor backend + */ +#keyset[id, num, kind] +compilation_time( + int id : @compilation ref, + int num : int ref, + /* kind: + 1 = frontend_cpu_seconds + 2 = frontend_elapsed_seconds + 3 = extractor_cpu_seconds + 4 = extractor_elapsed_seconds + */ + int kind : int ref, + float seconds : float ref +); + +/** + * An error or warning generated by the extractor. + * The diagnostic message `diagnostic` was generated during compiler + * invocation `compilation`, and is the `file_number_diagnostic_number`th + * message generated while extracting the `file_number`th file of that + * invocation. + */ +#keyset[compilation, file_number, file_number_diagnostic_number] +diagnostic_for( + unique int diagnostic : @diagnostic ref, + int compilation : @compilation ref, + int file_number : int ref, + int file_number_diagnostic_number : int ref +); + +diagnostics( + unique int id: @diagnostic, + int severity: int ref, + string error_tag: string ref, + string error_message: string ref, + string full_error_message: string ref, + int location: @location_default ref +); + +extractor_messages( + unique int id: @extractor_message, + int severity: int ref, + string origin : string ref, + string text : string ref, + string entity : string ref, + int location: @location_default ref, + string stack_trace : string ref +); + +/** + * If extraction was successful, then `cpu_seconds` and + * `elapsed_seconds` are the CPU time and elapsed time (respectively) + * that extraction took for compiler invocation `id`. + */ +compilation_finished( + unique int id : @compilation ref, + float cpu_seconds : float ref, + float elapsed_seconds : float ref +); + +compilation_assembly( + unique int id : @compilation ref, + int assembly: @assembly ref +) + +/* + * External artifacts + */ + +externalDefects( + unique int id: @externalDefect, + string queryPath: string ref, + int location: @location ref, + string message: string ref, + float severity: float ref); + +externalMetrics( + unique int id: @externalMetric, + string queryPath: string ref, + int location: @location ref, + float value: float ref); + +externalData( + int id: @externalDataElement, + string path: string ref, + int column: int ref, + string value: string ref); + +snapshotDate( + unique date snapshotDate: date ref); + +sourceLocationPrefix( + string prefix: string ref); + +/* + * Duplicate code + */ + +duplicateCode( + unique int id: @duplication, + string relativePath: string ref, + int equivClass: int ref); + +similarCode( + unique int id: @similarity, + string relativePath: string ref, + int equivClass: int ref); + +@duplication_or_similarity = @duplication | @similarity + +tokens( + int id: @duplication_or_similarity ref, + int offset: int ref, + int beginLine: int ref, + int beginColumn: int ref, + int endLine: int ref, + int endColumn: int ref); + +/* + * C# dbscheme + */ + +/** ELEMENTS **/ + +@element = @declaration | @stmt | @expr | @modifier | @attribute | @namespace_declaration + | @using_directive | @type_parameter_constraints | @external_element + | @xmllocatable | @asp_element | @namespace; + +@declaration = @callable | @generic | @assignable | @namespace; + +@named_element = @namespace | @declaration; + +@declaration_with_accessors = @property | @indexer | @event; + +@assignable = @variable | @assignable_with_accessors | @event; + +@assignable_with_accessors = @property | @indexer; + +@external_element = @externalMetric | @externalDefect | @externalDataElement; + +@attributable = @assembly | @field | @parameter | @operator | @method | @constructor + | @destructor | @callable_accessor | @value_or_ref_type | @declaration_with_accessors + | @local_function; + +/** LOCATIONS, ASEMMBLIES, MODULES, FILES and FOLDERS **/ + +@location = @location_default | @assembly; + +locations_default( + unique int id: @location_default, + int file: @file ref, + int beginLine: int ref, + int beginColumn: int ref, + int endLine: int ref, + int endColumn: int ref); + +@sourceline = @file | @callable | @xmllocatable; + +numlines( + int element_id: @sourceline ref, + int num_lines: int ref, + int num_code: int ref, + int num_comment: int ref); + +assemblies( + unique int id: @assembly, + int file: @file ref, + string fullname: string ref, + string name: string ref, + string version: string ref); + +/* + fromSource(0) = unknown, + fromSource(1) = from source, + fromSource(2) = from library +*/ +files( + unique int id: @file, + string name: string ref, + string simple: string ref, + string ext: string ref, + int fromSource: int ref); + +folders( + unique int id: @folder, + string name: string ref, + string simple: string ref); + +@container = @folder | @file ; + +containerparent( + int parent: @container ref, + unique int child: @container ref); + +file_extraction_mode( + unique int file: @file ref, + int mode: int ref + /* 0 = normal, 1 = standalone extractor */ + ); + +/** NAMESPACES **/ + +@type_container = @namespace | @type; + +namespaces( + unique int id: @namespace, + string name: string ref); + +namespace_declarations( + unique int id: @namespace_declaration, + int namespace_id: @namespace ref); + +namespace_declaration_location( + unique int id: @namespace_declaration ref, + int loc: @location ref); + +parent_namespace( + unique int child_id: @type_container ref, + int namespace_id: @namespace ref); + +@declaration_or_directive = @namespace_declaration | @type | @using_directive; + +parent_namespace_declaration( + int child_id: @declaration_or_directive ref, // cannot be unique because of partial classes + int namespace_id: @namespace_declaration ref); + +@using_directive = @using_namespace_directive | @using_static_directive; + +using_namespace_directives( + unique int id: @using_namespace_directive, + int namespace_id: @namespace ref); + +using_static_directives( + unique int id: @using_static_directive, + int type_id: @type_or_ref ref); + +using_directive_location( + unique int id: @using_directive ref, + int loc: @location ref); + +/** TYPES **/ + +types( + unique int id: @type, + int kind: int ref, + string name: string ref); + +case @type.kind of + 1 = @bool_type +| 2 = @char_type +| 3 = @decimal_type +| 4 = @sbyte_type +| 5 = @short_type +| 6 = @int_type +| 7 = @long_type +| 8 = @byte_type +| 9 = @ushort_type +| 10 = @uint_type +| 11 = @ulong_type +| 12 = @float_type +| 13 = @double_type +| 14 = @enum_type +| 15 = @struct_type +| 17 = @class_type +| 19 = @interface_type +| 20 = @delegate_type +| 21 = @null_type +| 22 = @type_parameter +| 23 = @pointer_type +| 24 = @nullable_type +| 25 = @array_type +| 26 = @void_type +| 27 = @int_ptr_type +| 28 = @uint_ptr_type +| 29 = @dynamic_type +| 30 = @arglist_type +| 31 = @unknown_type +| 32 = @tuple_type + ; + +@simple_type = @bool_type | @char_type | @integral_type | @floating_point_type | @decimal_type; +@integral_type = @signed_integral_type | @unsigned_integral_type; +@signed_integral_type = @sbyte_type | @short_type | @int_type | @long_type; +@unsigned_integral_type = @byte_type | @ushort_type | @uint_type | @ulong_type; +@floating_point_type = @float_type | @double_type; +@value_type = @simple_type | @enum_type | @struct_type | @nullable_type | @int_ptr_type + | @uint_ptr_type | @tuple_type; +@ref_type = @class_type | @interface_type | @array_type | @delegate_type | @null_type + | @dynamic_type; +@value_or_ref_type = @value_type | @ref_type; + +typerefs( + unique int id: @typeref, + string name: string ref); + +typeref_type( + int id: @typeref ref, + unique int typeId: @type ref); + +@type_or_ref = @type | @typeref; + +array_element_type( + unique int array: @array_type ref, + int dimension: int ref, + int rank: int ref, + int element: @type_or_ref ref); + +nullable_underlying_type( + unique int nullable: @nullable_type ref, + int underlying: @type_or_ref ref); + +pointer_referent_type( + unique int pointer: @pointer_type ref, + int referent: @type_or_ref ref); + +enum_underlying_type( + unique int enum_id: @enum_type ref, + int underlying_type_id: @type_or_ref ref); + +delegate_return_type( + unique int delegate_id: @delegate_type ref, + int return_type_id: @type_or_ref ref); + +extend( + unique int sub: @type ref, + int super: @type_or_ref ref); + +anonymous_types( + unique int id: @type ref); + +@interface_or_ref = @interface_type | @typeref; + +implement( + int sub: @type ref, + int super: @type_or_ref ref); + +type_location( + int id: @type ref, + int loc: @location ref); + +tuple_underlying_type( + unique int tuple: @tuple_type ref, + int struct: @type_or_ref ref); + +#keyset[tuple, index] +tuple_element( + int tuple: @tuple_type ref, + int index: int ref, + unique int field: @field ref); + +attributes( + unique int id: @attribute, + int type_id: @type_or_ref ref, + int target: @attributable ref); + +attribute_location( + int id: @attribute ref, + int loc: @location ref); + +@type_mention_parent = @element | @type_mention; + +type_mention( + unique int id: @type_mention, + int type_id: @type_or_ref ref, + int parent: @type_mention_parent ref); + +type_mention_location( + unique int id: @type_mention ref, + int loc: @location ref); + +@has_type_annotation = @assignable | @type_parameter | @callable | @expr | @delegate_type | @generic; + +/** + * A direct annotation on an entity, for example `string? x;`. + * + * Annotations: + * 2 = reftype is not annotated "!" + * 3 = reftype is annotated "?" + * 4 = readonly ref type / in parameter + * 5 = ref type parameter, return or local variable + * 6 = out parameter + * + * Note that the annotation depends on the element it annotates. + * @assignable: The annotation is on the type of the assignable, for example the variable type. + * @type_parameter: The annotation is on the reftype constraint + * @callable: The annotation is on the return type + * @array_type: The annotation is on the element type + */ +type_annotation(int id: @has_type_annotation ref, int annotation: int ref); + +nullability(unique int nullability: @nullability, int kind: int ref); + +case @nullability.kind of + 0 = @oblivious +| 1 = @not_annotated +| 2 = @annotated +; + +#keyset[parent, index] +nullability_parent(int nullability: @nullability ref, int index: int ref, int parent: @nullability ref) + +type_nullability(int id: @has_type_annotation ref, int nullability: @nullability ref); + +/** + * The nullable flow state of an expression, as determined by Roslyn. + * 0 = none (default, not populated) + * 1 = not null + * 2 = maybe null + */ +expr_flowstate(unique int id: @expr ref, int state: int ref); + +/** GENERICS **/ + +@generic = @type | @method | @local_function; + +type_parameters( + unique int id: @type_parameter ref, + int index: int ref, + int generic_id: @generic ref, + int variance: int ref /* none = 0, out = 1, in = 2 */); + +#keyset[constructed_id, index] +type_arguments( + int id: @type_or_ref ref, + int index: int ref, + int constructed_id: @generic_or_ref ref); + +@generic_or_ref = @generic | @typeref; + +constructed_generic( + unique int constructed: @generic ref, + int generic: @generic_or_ref ref); + +type_parameter_constraints( + unique int id: @type_parameter_constraints, + int param_id: @type_parameter ref); + +type_parameter_constraints_location( + int id: @type_parameter_constraints ref, + int loc: @location ref); + +general_type_parameter_constraints( + int id: @type_parameter_constraints ref, + int kind: int ref /* class = 1, struct = 2, new = 3 */); + +specific_type_parameter_constraints( + int id: @type_parameter_constraints ref, + int base_id: @type_or_ref ref); + +specific_type_parameter_nullability( + int id: @type_parameter_constraints ref, + int base_id: @type_or_ref ref, + int nullability: @nullability ref); + +/** MODIFIERS */ + +@modifiable = @modifiable_direct | @event_accessor; + +@modifiable_direct = @member | @accessor | @local_function | @anonymous_function_expr; + +modifiers( + unique int id: @modifier, + string name: string ref); + +has_modifiers( + int id: @modifiable_direct ref, + int mod_id: @modifier ref); + +compiler_generated(unique int id: @modifiable_direct ref); + +/** MEMBERS **/ + +@member = @method | @constructor | @destructor | @field | @property | @event | @operator | @indexer | @type; + +@named_exprorstmt = @goto_stmt | @labeled_stmt | @expr; + +@virtualizable = @method | @property | @indexer | @event; + +exprorstmt_name( + unique int parent_id: @named_exprorstmt ref, + string name: string ref); + +nested_types( + unique int id: @type ref, + int declaring_type_id: @type ref, + int unbound_id: @type ref); + +properties( + unique int id: @property, + string name: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @property ref); + +property_location( + int id: @property ref, + int loc: @location ref); + +indexers( + unique int id: @indexer, + string name: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @indexer ref); + +indexer_location( + int id: @indexer ref, + int loc: @location ref); + +accessors( + unique int id: @accessor, + int kind: int ref, + string name: string ref, + int declaring_member_id: @member ref, + int unbound_id: @accessor ref); + +case @accessor.kind of + 1 = @getter +| 2 = @setter + ; + +init_only_accessors( + unique int id: @accessor ref); + +accessor_location( + int id: @accessor ref, + int loc: @location ref); + +events( + unique int id: @event, + string name: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @event ref); + +event_location( + int id: @event ref, + int loc: @location ref); + +event_accessors( + unique int id: @event_accessor, + int kind: int ref, + string name: string ref, + int declaring_event_id: @event ref, + int unbound_id: @event_accessor ref); + +case @event_accessor.kind of + 1 = @add_event_accessor +| 2 = @remove_event_accessor + ; + +event_accessor_location( + int id: @event_accessor ref, + int loc: @location ref); + +operators( + unique int id: @operator, + string name: string ref, + string symbol: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @operator ref); + +operator_location( + int id: @operator ref, + int loc: @location ref); + +constant_value( + int id: @variable ref, + string value: string ref); + +/** CALLABLES **/ + +@callable = @method | @constructor | @destructor | @operator | @callable_accessor | @anonymous_function_expr | @local_function; + +@callable_accessor = @accessor | @event_accessor; + +methods( + unique int id: @method, + string name: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @method ref); + +method_location( + int id: @method ref, + int loc: @location ref); + +constructors( + unique int id: @constructor, + string name: string ref, + int declaring_type_id: @type ref, + int unbound_id: @constructor ref); + +constructor_location( + int id: @constructor ref, + int loc: @location ref); + +destructors( + unique int id: @destructor, + string name: string ref, + int declaring_type_id: @type ref, + int unbound_id: @destructor ref); + +destructor_location( + int id: @destructor ref, + int loc: @location ref); + +overrides( + int id: @callable ref, + int base_id: @callable ref); + +explicitly_implements( + int id: @member ref, + int interface_id: @interface_or_ref ref); + +local_functions( + unique int id: @local_function, + string name: string ref, + int return_type: @type ref, + int unbound_id: @local_function ref); + +local_function_stmts( + unique int fn: @local_function_stmt ref, + int stmt: @local_function ref); + +/** VARIABLES **/ + +@variable = @local_scope_variable | @field; + +@local_scope_variable = @local_variable | @parameter; + +fields( + unique int id: @field, + int kind: int ref, + string name: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @field ref); + +case @field.kind of + 1 = @addressable_field +| 2 = @constant + ; + +field_location( + int id: @field ref, + int loc: @location ref); + +localvars( + unique int id: @local_variable, + int kind: int ref, + string name: string ref, + int implicitly_typed: int ref /* 0 = no, 1 = yes */, + int type_id: @type_or_ref ref, + int parent_id: @local_var_decl_expr ref); + +case @local_variable.kind of + 1 = @addressable_local_variable +| 2 = @local_constant +| 3 = @local_variable_ref + ; + +localvar_location( + unique int id: @local_variable ref, + int loc: @location ref); + +@parameterizable = @callable | @delegate_type | @indexer; + +#keyset[name, parent_id] +#keyset[index, parent_id] +params( + unique int id: @parameter, + string name: string ref, + int type_id: @type_or_ref ref, + int index: int ref, + int mode: int ref, /* value = 0, ref = 1, out = 2, array = 3, this = 4 */ + int parent_id: @parameterizable ref, + int unbound_id: @parameter ref); + +param_location( + int id: @parameter ref, + int loc: @location ref); + +/** STATEMENTS **/ + +@exprorstmt_parent = @control_flow_element | @top_level_exprorstmt_parent; + +statements( + unique int id: @stmt, + int kind: int ref); + +#keyset[index, parent] +stmt_parent( + unique int stmt: @stmt ref, + int index: int ref, + int parent: @control_flow_element ref); + +@top_level_stmt_parent = @callable; + +// [index, parent] is not a keyset because the same parent may be compiled multiple times +stmt_parent_top_level( + unique int stmt: @stmt ref, + int index: int ref, + int parent: @top_level_stmt_parent ref); + +case @stmt.kind of + 1 = @block_stmt +| 2 = @expr_stmt +| 3 = @if_stmt +| 4 = @switch_stmt +| 5 = @while_stmt +| 6 = @do_stmt +| 7 = @for_stmt +| 8 = @foreach_stmt +| 9 = @break_stmt +| 10 = @continue_stmt +| 11 = @goto_stmt +| 12 = @goto_case_stmt +| 13 = @goto_default_stmt +| 14 = @throw_stmt +| 15 = @return_stmt +| 16 = @yield_stmt +| 17 = @try_stmt +| 18 = @checked_stmt +| 19 = @unchecked_stmt +| 20 = @lock_stmt +| 21 = @using_block_stmt +| 22 = @var_decl_stmt +| 23 = @const_decl_stmt +| 24 = @empty_stmt +| 25 = @unsafe_stmt +| 26 = @fixed_stmt +| 27 = @label_stmt +| 28 = @catch +| 29 = @case_stmt +| 30 = @local_function_stmt +| 31 = @using_decl_stmt + ; + +@using_stmt = @using_block_stmt | @using_decl_stmt; + +@labeled_stmt = @label_stmt | @case; + +@decl_stmt = @var_decl_stmt | @const_decl_stmt | @using_decl_stmt; + +@cond_stmt = @if_stmt | @switch_stmt; + +@loop_stmt = @while_stmt | @do_stmt | @for_stmt | @foreach_stmt; + +@jump_stmt = @break_stmt | @goto_any_stmt | @continue_stmt | @throw_stmt | @return_stmt + | @yield_stmt; + +@goto_any_stmt = @goto_default_stmt | @goto_case_stmt | @goto_stmt; + + +stmt_location( + unique int id: @stmt ref, + int loc: @location ref); + +catch_type( + unique int catch_id: @catch ref, + int type_id: @type_or_ref ref, + int kind: int ref /* explicit = 1, implicit = 2 */); + +/** EXPRESSIONS **/ + +expressions( + unique int id: @expr, + int kind: int ref, + int type_id: @type_or_ref ref); + +#keyset[index, parent] +expr_parent( + unique int expr: @expr ref, + int index: int ref, + int parent: @control_flow_element ref); + +@top_level_expr_parent = @attribute | @field | @property | @indexer | @parameter; + +@top_level_exprorstmt_parent = @top_level_expr_parent | @top_level_stmt_parent; + +// [index, parent] is not a keyset because the same parent may be compiled multiple times +expr_parent_top_level( + unique int expr: @expr ref, + int index: int ref, + int parent: @top_level_exprorstmt_parent ref); + +case @expr.kind of +/* literal */ + 1 = @bool_literal_expr +| 2 = @char_literal_expr +| 3 = @decimal_literal_expr +| 4 = @int_literal_expr +| 5 = @long_literal_expr +| 6 = @uint_literal_expr +| 7 = @ulong_literal_expr +| 8 = @float_literal_expr +| 9 = @double_literal_expr +| 10 = @string_literal_expr +| 11 = @null_literal_expr +/* primary & unary */ +| 12 = @this_access_expr +| 13 = @base_access_expr +| 14 = @local_variable_access_expr +| 15 = @parameter_access_expr +| 16 = @field_access_expr +| 17 = @property_access_expr +| 18 = @method_access_expr +| 19 = @event_access_expr +| 20 = @indexer_access_expr +| 21 = @array_access_expr +| 22 = @type_access_expr +| 23 = @typeof_expr +| 24 = @method_invocation_expr +| 25 = @delegate_invocation_expr +| 26 = @operator_invocation_expr +| 27 = @cast_expr +| 28 = @object_creation_expr +| 29 = @explicit_delegate_creation_expr +| 30 = @implicit_delegate_creation_expr +| 31 = @array_creation_expr +| 32 = @default_expr +| 33 = @plus_expr +| 34 = @minus_expr +| 35 = @bit_not_expr +| 36 = @log_not_expr +| 37 = @post_incr_expr +| 38 = @post_decr_expr +| 39 = @pre_incr_expr +| 40 = @pre_decr_expr +/* multiplicative */ +| 41 = @mul_expr +| 42 = @div_expr +| 43 = @rem_expr +/* additive */ +| 44 = @add_expr +| 45 = @sub_expr +/* shift */ +| 46 = @lshift_expr +| 47 = @rshift_expr +/* relational */ +| 48 = @lt_expr +| 49 = @gt_expr +| 50 = @le_expr +| 51 = @ge_expr +/* equality */ +| 52 = @eq_expr +| 53 = @ne_expr +/* logical */ +| 54 = @bit_and_expr +| 55 = @bit_xor_expr +| 56 = @bit_or_expr +| 57 = @log_and_expr +| 58 = @log_or_expr +/* type testing */ +| 59 = @is_expr +| 60 = @as_expr +/* null coalescing */ +| 61 = @null_coalescing_expr +/* conditional */ +| 62 = @conditional_expr +/* assignment */ +| 63 = @simple_assign_expr +| 64 = @assign_add_expr +| 65 = @assign_sub_expr +| 66 = @assign_mul_expr +| 67 = @assign_div_expr +| 68 = @assign_rem_expr +| 69 = @assign_and_expr +| 70 = @assign_xor_expr +| 71 = @assign_or_expr +| 72 = @assign_lshift_expr +| 73 = @assign_rshift_expr +/* more */ +| 74 = @object_init_expr +| 75 = @collection_init_expr +| 76 = @array_init_expr +| 77 = @checked_expr +| 78 = @unchecked_expr +| 79 = @constructor_init_expr +| 80 = @add_event_expr +| 81 = @remove_event_expr +| 82 = @par_expr +| 83 = @local_var_decl_expr +| 84 = @lambda_expr +| 85 = @anonymous_method_expr +| 86 = @namespace_expr +/* dynamic */ +| 92 = @dynamic_element_access_expr +| 93 = @dynamic_member_access_expr +/* unsafe */ +| 100 = @pointer_indirection_expr +| 101 = @address_of_expr +| 102 = @sizeof_expr +/* async */ +| 103 = @await_expr +/* C# 6.0 */ +| 104 = @nameof_expr +| 105 = @interpolated_string_expr +| 106 = @unknown_expr +/* C# 7.0 */ +| 107 = @throw_expr +| 108 = @tuple_expr +| 109 = @local_function_invocation_expr +| 110 = @ref_expr +| 111 = @discard_expr +/* C# 8.0 */ +| 112 = @range_expr +| 113 = @index_expr +| 114 = @switch_expr +| 115 = @recursive_pattern_expr +| 116 = @property_pattern_expr +| 117 = @positional_pattern_expr +| 118 = @switch_case_expr +| 119 = @assign_coalesce_expr +| 120 = @suppress_nullable_warning_expr +| 121 = @namespace_access_expr +; + +@switch = @switch_stmt | @switch_expr; +@case = @case_stmt | @switch_case_expr; +@pattern_match = @case | @is_expr; + +@integer_literal_expr = @int_literal_expr | @long_literal_expr | @uint_literal_expr | @ulong_literal_expr; +@real_literal_expr = @float_literal_expr | @double_literal_expr | @decimal_literal_expr; +@literal_expr = @bool_literal_expr | @char_literal_expr | @integer_literal_expr | @real_literal_expr + | @string_literal_expr | @null_literal_expr; + +@assign_expr = @simple_assign_expr | @assign_op_expr | @local_var_decl_expr; +@assign_op_expr = @assign_arith_expr | @assign_bitwise_expr | @assign_event_expr | @assign_coalesce_expr; +@assign_event_expr = @add_event_expr | @remove_event_expr; + +@assign_arith_expr = @assign_add_expr | @assign_sub_expr | @assign_mul_expr | @assign_div_expr + | @assign_rem_expr +@assign_bitwise_expr = @assign_and_expr | @assign_or_expr | @assign_xor_expr + | @assign_lshift_expr | @assign_rshift_expr; + +@member_access_expr = @field_access_expr | @property_access_expr | @indexer_access_expr | @event_access_expr + | @method_access_expr | @type_access_expr | @dynamic_member_access_expr; +@access_expr = @member_access_expr | @this_access_expr | @base_access_expr | @assignable_access_expr | @namespace_access_expr; +@element_access_expr = @indexer_access_expr | @array_access_expr | @dynamic_element_access_expr; + +@local_variable_access = @local_variable_access_expr | @local_var_decl_expr; +@local_scope_variable_access_expr = @parameter_access_expr | @local_variable_access; +@variable_access_expr = @local_scope_variable_access_expr | @field_access_expr; + +@assignable_access_expr = @variable_access_expr | @property_access_expr | @element_access_expr + | @event_access_expr | @dynamic_member_access_expr; + +@objectorcollection_init_expr = @object_init_expr | @collection_init_expr; + +@delegate_creation_expr = @explicit_delegate_creation_expr | @implicit_delegate_creation_expr; + +@bin_arith_op_expr = @mul_expr | @div_expr | @rem_expr | @add_expr | @sub_expr; +@incr_op_expr = @pre_incr_expr | @post_incr_expr; +@decr_op_expr = @pre_decr_expr | @post_decr_expr; +@mut_op_expr = @incr_op_expr | @decr_op_expr; +@un_arith_op_expr = @plus_expr | @minus_expr | @mut_op_expr; +@arith_op_expr = @bin_arith_op_expr | @un_arith_op_expr; + +@ternary_log_op_expr = @conditional_expr; +@bin_log_op_expr = @log_and_expr | @log_or_expr | @null_coalescing_expr; +@un_log_op_expr = @log_not_expr; +@log_expr = @un_log_op_expr | @bin_log_op_expr | @ternary_log_op_expr; + +@bin_bit_op_expr = @bit_and_expr | @bit_or_expr | @bit_xor_expr | @lshift_expr + | @rshift_expr; +@un_bit_op_expr = @bit_not_expr; +@bit_expr = @un_bit_op_expr | @bin_bit_op_expr; + +@equality_op_expr = @eq_expr | @ne_expr; +@rel_op_expr = @gt_expr | @lt_expr| @ge_expr | @le_expr; +@comp_expr = @equality_op_expr | @rel_op_expr; + +@op_expr = @assign_expr | @un_op | @bin_op | @ternary_op; + +@ternary_op = @ternary_log_op_expr; +@bin_op = @bin_arith_op_expr | @bin_log_op_expr | @bin_bit_op_expr | @comp_expr; +@un_op = @un_arith_op_expr | @un_log_op_expr | @un_bit_op_expr | @sizeof_expr + | @pointer_indirection_expr | @address_of_expr; + +@anonymous_function_expr = @lambda_expr | @anonymous_method_expr; + +@call = @method_invocation_expr | @constructor_init_expr | @operator_invocation_expr + | @delegate_invocation_expr | @object_creation_expr | @call_access_expr + | @local_function_invocation_expr; + +@call_access_expr = @property_access_expr | @event_access_expr | @indexer_access_expr; + +@late_bindable_expr = @dynamic_element_access_expr | @dynamic_member_access_expr + | @object_creation_expr | @method_invocation_expr | @operator_invocation_expr; + +@throw_element = @throw_expr | @throw_stmt; + +@implicitly_typeable_object_creation_expr = @object_creation_expr | @explicit_delegate_creation_expr; + +implicitly_typed_array_creation( + unique int id: @array_creation_expr ref); + +explicitly_sized_array_creation( + unique int id: @array_creation_expr ref); + +stackalloc_array_creation( + unique int id: @array_creation_expr ref); + +implicitly_typed_object_creation( + unique int id: @implicitly_typeable_object_creation_expr ref); + +mutator_invocation_mode( + unique int id: @operator_invocation_expr ref, + int mode: int ref /* prefix = 1, postfix = 2*/); + +expr_compiler_generated( + unique int id: @expr ref); + +expr_value( + unique int id: @expr ref, + string value: string ref); + +expr_call( + unique int caller_id: @expr ref, + int target_id: @callable ref); + +expr_access( + unique int accesser_id: @access_expr ref, + int target_id: @accessible ref); + +@accessible = @method | @assignable | @local_function | @namespace; + +expr_location( + unique int id: @expr ref, + int loc: @location ref); + +dynamic_member_name( + unique int id: @late_bindable_expr ref, + string name: string ref); + +@qualifiable_expr = @member_access_expr + | @method_invocation_expr + | @element_access_expr; + +conditional_access( + unique int id: @qualifiable_expr ref); + +expr_argument( + unique int id: @expr ref, + int mode: int ref); + /* mode is the same as params: value = 0, ref = 1, out = 2 */ + +expr_argument_name( + unique int id: @expr ref, + string name: string ref); + +/** CONTROL/DATA FLOW **/ + +@control_flow_element = @stmt | @expr; + +/* XML Files */ + +xmlEncoding ( + unique int id: @file ref, + string encoding: string ref); + +xmlDTDs( + unique int id: @xmldtd, + string root: string ref, + string publicId: string ref, + string systemId: string ref, + int fileid: @file ref); + +xmlElements( + unique int id: @xmlelement, + string name: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int fileid: @file ref); + +xmlAttrs( + unique int id: @xmlattribute, + int elementid: @xmlelement ref, + string name: string ref, + string value: string ref, + int idx: int ref, + int fileid: @file ref); + +xmlNs( + int id: @xmlnamespace, + string prefixName: string ref, + string URI: string ref, + int fileid: @file ref); + +xmlHasNs( + int elementId: @xmlnamespaceable ref, + int nsId: @xmlnamespace ref, + int fileid: @file ref); + +xmlComments( + unique int id: @xmlcomment, + string text: string ref, + int parentid: @xmlparent ref, + int fileid: @file ref); + +xmlChars( + unique int id: @xmlcharacters, + string text: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int isCDATA: int ref, + int fileid: @file ref); + +@xmlparent = @file | @xmlelement; +@xmlnamespaceable = @xmlelement | @xmlattribute; + +xmllocations( + int xmlElement: @xmllocatable ref, + int location: @location_default ref); + +@xmllocatable = @xmlcharacters | @xmlelement | @xmlcomment | @xmlattribute | @xmldtd | @file | @xmlnamespace; + +/* Comments */ + +commentline( + unique int id: @commentline, + int kind: int ref, + string text: string ref, + string rawtext: string ref); + +case @commentline.kind of + 0 = @singlelinecomment +| 1 = @xmldoccomment +| 2 = @multilinecomment; + +commentline_location( + unique int id: @commentline ref, + int loc: @location ref); + +commentblock( + unique int id : @commentblock); + +commentblock_location( + unique int id: @commentblock ref, + int loc: @location ref); + +commentblock_binding( + int id: @commentblock ref, + int entity: @element ref, + int bindtype: int ref); /* 0: Parent, 1: Best, 2: Before, 3: After */ + +commentblock_child( + int id: @commentblock ref, + int commentline: @commentline ref, + int index: int ref); + +/* ASP.NET */ + +case @asp_element.kind of + 0=@asp_close_tag +| 1=@asp_code +| 2=@asp_comment +| 3=@asp_data_binding +| 4=@asp_directive +| 5=@asp_open_tag +| 6=@asp_quoted_string +| 7=@asp_text +| 8=@asp_xml_directive; + +@asp_attribute = @asp_code | @asp_data_binding | @asp_quoted_string; + +asp_elements( + unique int id: @asp_element, + int kind: int ref, + int loc: @location ref); + +asp_comment_server(unique int comment: @asp_comment ref); +asp_code_inline(unique int code: @asp_code ref); +asp_directive_attribute( + int directive: @asp_directive ref, + int index: int ref, + string name: string ref, + int value: @asp_quoted_string ref); +asp_directive_name( + unique int directive: @asp_directive ref, + string name: string ref); +asp_element_body( + unique int element: @asp_element ref, + string body: string ref); +asp_tag_attribute( + int tag: @asp_open_tag ref, + int index: int ref, + string name: string ref, + int attribute: @asp_attribute ref); +asp_tag_name( + unique int tag: @asp_open_tag ref, + string name: string ref); +asp_tag_isempty(int tag: @asp_open_tag ref); + +/* Common Intermediate Language - CIL */ + +case @cil_instruction.opcode of + 0 = @cil_nop +| 1 = @cil_break +| 2 = @cil_ldarg_0 +| 3 = @cil_ldarg_1 +| 4 = @cil_ldarg_2 +| 5 = @cil_ldarg_3 +| 6 = @cil_ldloc_0 +| 7 = @cil_ldloc_1 +| 8 = @cil_ldloc_2 +| 9 = @cil_ldloc_3 +| 10 = @cil_stloc_0 +| 11 = @cil_stloc_1 +| 12 = @cil_stloc_2 +| 13 = @cil_stloc_3 +| 14 = @cil_ldarg_s +| 15 = @cil_ldarga_s +| 16 = @cil_starg_s +| 17 = @cil_ldloc_s +| 18 = @cil_ldloca_s +| 19 = @cil_stloc_s +| 20 = @cil_ldnull +| 21 = @cil_ldc_i4_m1 +| 22 = @cil_ldc_i4_0 +| 23 = @cil_ldc_i4_1 +| 24 = @cil_ldc_i4_2 +| 25 = @cil_ldc_i4_3 +| 26 = @cil_ldc_i4_4 +| 27 = @cil_ldc_i4_5 +| 28 = @cil_ldc_i4_6 +| 29 = @cil_ldc_i4_7 +| 30 = @cil_ldc_i4_8 +| 31 = @cil_ldc_i4_s +| 32 = @cil_ldc_i4 +| 33 = @cil_ldc_i8 +| 34 = @cil_ldc_r4 +| 35 = @cil_ldc_r8 +| 37 = @cil_dup +| 38 = @cil_pop +| 39 = @cil_jmp +| 40 = @cil_call +| 41 = @cil_calli +| 42 = @cil_ret +| 43 = @cil_br_s +| 44 = @cil_brfalse_s +| 45 = @cil_brtrue_s +| 46 = @cil_beq_s +| 47 = @cil_bge_s +| 48 = @cil_bgt_s +| 49 = @cil_ble_s +| 50 = @cil_blt_s +| 51 = @cil_bne_un_s +| 52 = @cil_bge_un_s +| 53 = @cil_bgt_un_s +| 54 = @cil_ble_un_s +| 55 = @cil_blt_un_s +| 56 = @cil_br +| 57 = @cil_brfalse +| 58 = @cil_brtrue +| 59 = @cil_beq +| 60 = @cil_bge +| 61 = @cil_bgt +| 62 = @cil_ble +| 63 = @cil_blt +| 64 = @cil_bne_un +| 65 = @cil_bge_un +| 66 = @cil_bgt_un +| 67 = @cil_ble_un +| 68 = @cil_blt_un +| 69 = @cil_switch +| 70 = @cil_ldind_i1 +| 71 = @cil_ldind_u1 +| 72 = @cil_ldind_i2 +| 73 = @cil_ldind_u2 +| 74 = @cil_ldind_i4 +| 75 = @cil_ldind_u4 +| 76 = @cil_ldind_i8 +| 77 = @cil_ldind_i +| 78 = @cil_ldind_r4 +| 79 = @cil_ldind_r8 +| 80 = @cil_ldind_ref +| 81 = @cil_stind_ref +| 82 = @cil_stind_i1 +| 83 = @cil_stind_i2 +| 84 = @cil_stind_i4 +| 85 = @cil_stind_i8 +| 86 = @cil_stind_r4 +| 87 = @cil_stind_r8 +| 88 = @cil_add +| 89 = @cil_sub +| 90 = @cil_mul +| 91 = @cil_div +| 92 = @cil_div_un +| 93 = @cil_rem +| 94 = @cil_rem_un +| 95 = @cil_and +| 96 = @cil_or +| 97 = @cil_xor +| 98 = @cil_shl +| 99 = @cil_shr +| 100 = @cil_shr_un +| 101 = @cil_neg +| 102 = @cil_not +| 103 = @cil_conv_i1 +| 104 = @cil_conv_i2 +| 105 = @cil_conv_i4 +| 106 = @cil_conv_i8 +| 107 = @cil_conv_r4 +| 108 = @cil_conv_r8 +| 109 = @cil_conv_u4 +| 110 = @cil_conv_u8 +| 111 = @cil_callvirt +| 112 = @cil_cpobj +| 113 = @cil_ldobj +| 114 = @cil_ldstr +| 115 = @cil_newobj +| 116 = @cil_castclass +| 117 = @cil_isinst +| 118 = @cil_conv_r_un +| 121 = @cil_unbox +| 122 = @cil_throw +| 123 = @cil_ldfld +| 124 = @cil_ldflda +| 125 = @cil_stfld +| 126 = @cil_ldsfld +| 127 = @cil_ldsflda +| 128 = @cil_stsfld +| 129 = @cil_stobj +| 130 = @cil_conv_ovf_i1_un +| 131 = @cil_conv_ovf_i2_un +| 132 = @cil_conv_ovf_i4_un +| 133 = @cil_conv_ovf_i8_un +| 134 = @cil_conv_ovf_u1_un +| 135 = @cil_conv_ovf_u2_un +| 136 = @cil_conv_ovf_u4_un +| 137 = @cil_conv_ovf_u8_un +| 138 = @cil_conv_ovf_i_un +| 139 = @cil_conv_ovf_u_un +| 140 = @cil_box +| 141 = @cil_newarr +| 142 = @cil_ldlen +| 143 = @cil_ldelema +| 144 = @cil_ldelem_i1 +| 145 = @cil_ldelem_u1 +| 146 = @cil_ldelem_i2 +| 147 = @cil_ldelem_u2 +| 148 = @cil_ldelem_i4 +| 149 = @cil_ldelem_u4 +| 150 = @cil_ldelem_i8 +| 151 = @cil_ldelem_i +| 152 = @cil_ldelem_r4 +| 153 = @cil_ldelem_r8 +| 154 = @cil_ldelem_ref +| 155 = @cil_stelem_i +| 156 = @cil_stelem_i1 +| 157 = @cil_stelem_i2 +| 158 = @cil_stelem_i4 +| 159 = @cil_stelem_i8 +| 160 = @cil_stelem_r4 +| 161 = @cil_stelem_r8 +| 162 = @cil_stelem_ref +| 163 = @cil_ldelem +| 164 = @cil_stelem +| 165 = @cil_unbox_any +| 179 = @cil_conv_ovf_i1 +| 180 = @cil_conv_ovf_u1 +| 181 = @cil_conv_ovf_i2 +| 182 = @cil_conv_ovf_u2 +| 183 = @cil_conv_ovf_i4 +| 184 = @cil_conv_ovf_u4 +| 185 = @cil_conv_ovf_i8 +| 186 = @cil_conv_ovf_u8 +| 194 = @cil_refanyval +| 195 = @cil_ckinfinite +| 198 = @cil_mkrefany +| 208 = @cil_ldtoken +| 209 = @cil_conv_u2 +| 210 = @cil_conv_u1 +| 211 = @cil_conv_i +| 212 = @cil_conv_ovf_i +| 213 = @cil_conv_ovf_u +| 214 = @cil_add_ovf +| 215 = @cil_add_ovf_un +| 216 = @cil_mul_ovf +| 217 = @cil_mul_ovf_un +| 218 = @cil_sub_ovf +| 219 = @cil_sub_ovf_un +| 220 = @cil_endfinally +| 221 = @cil_leave +| 222 = @cil_leave_s +| 223 = @cil_stind_i +| 224 = @cil_conv_u +| 65024 = @cil_arglist +| 65025 = @cil_ceq +| 65026 = @cil_cgt +| 65027 = @cil_cgt_un +| 65028 = @cil_clt +| 65029 = @cil_clt_un +| 65030 = @cil_ldftn +| 65031 = @cil_ldvirtftn +| 65033 = @cil_ldarg +| 65034 = @cil_ldarga +| 65035 = @cil_starg +| 65036 = @cil_ldloc +| 65037 = @cil_ldloca +| 65038 = @cil_stloc +| 65039 = @cil_localloc +| 65041 = @cil_endfilter +| 65042 = @cil_unaligned +| 65043 = @cil_volatile +| 65044 = @cil_tail +| 65045 = @cil_initobj +| 65046 = @cil_constrained +| 65047 = @cil_cpblk +| 65048 = @cil_initblk +| 65050 = @cil_rethrow +| 65052 = @cil_sizeof +| 65053 = @cil_refanytype +| 65054 = @cil_readonly +; + +// CIL ignored instructions + +@cil_ignore = @cil_nop | @cil_break | @cil_volatile | @cil_unaligned; + +// CIL local/parameter/field access + +@cil_ldarg_any = @cil_ldarg_0 | @cil_ldarg_1 | @cil_ldarg_2 | @cil_ldarg_3 | @cil_ldarg_s | @cil_ldarga_s | @cil_ldarg | @cil_ldarga; +@cil_starg_any = @cil_starg | @cil_starg_s; + +@cil_ldloc_any = @cil_ldloc_0 | @cil_ldloc_1 | @cil_ldloc_2 | @cil_ldloc_3 | @cil_ldloc_s | @cil_ldloca_s | @cil_ldloc | @cil_ldloca; +@cil_stloc_any = @cil_stloc_0 | @cil_stloc_1 | @cil_stloc_2 | @cil_stloc_3 | @cil_stloc_s | @cil_stloc; + +@cil_ldfld_any = @cil_ldfld | @cil_ldsfld | @cil_ldsflda | @cil_ldflda; +@cil_stfld_any = @cil_stfld | @cil_stsfld; + +@cil_local_access = @cil_stloc_any | @cil_ldloc_any; +@cil_arg_access = @cil_starg_any | @cil_ldarg_any; +@cil_read_access = @cil_ldloc_any | @cil_ldarg_any | @cil_ldfld_any; +@cil_write_access = @cil_stloc_any | @cil_starg_any | @cil_stfld_any; + +@cil_stack_access = @cil_local_access | @cil_arg_access; +@cil_field_access = @cil_ldfld_any | @cil_stfld_any; + +@cil_access = @cil_read_access | @cil_write_access; + +// CIL constant/literal instructions + +@cil_ldc_i = @cil_ldc_i4_any | @cil_ldc_i8; + +@cil_ldc_i4_any = @cil_ldc_i4_m1 | @cil_ldc_i4_0 | @cil_ldc_i4_1 | @cil_ldc_i4_2 | @cil_ldc_i4_3 | + @cil_ldc_i4_4 | @cil_ldc_i4_5 | @cil_ldc_i4_6 | @cil_ldc_i4_7 | @cil_ldc_i4_8 | @cil_ldc_i4_s | @cil_ldc_i4; + +@cil_ldc_r = @cil_ldc_r4 | @cil_ldc_r8; + +@cil_literal = @cil_ldnull | @cil_ldc_i | @cil_ldc_r | @cil_ldstr; + +// Control flow + +@cil_conditional_jump = @cil_binary_jump | @cil_unary_jump; +@cil_binary_jump = @cil_beq_s | @cil_bge_s | @cil_bgt_s | @cil_ble_s | @cil_blt_s | + @cil_bne_un_s | @cil_bge_un_s | @cil_bgt_un_s | @cil_ble_un_s | @cil_blt_un_s | + @cil_beq | @cil_bge | @cil_bgt | @cil_ble | @cil_blt | + @cil_bne_un | @cil_bge_un | @cil_bgt_un | @cil_ble_un | @cil_blt_un; +@cil_unary_jump = @cil_brfalse_s | @cil_brtrue_s | @cil_brfalse | @cil_brtrue | @cil_switch; +@cil_unconditional_jump = @cil_br | @cil_br_s | @cil_leave_any; +@cil_leave_any = @cil_leave | @cil_leave_s; +@cil_jump = @cil_unconditional_jump | @cil_conditional_jump; + +// CIL call instructions + +@cil_call_any = @cil_jmp | @cil_call | @cil_calli | @cil_tail | @cil_callvirt | @cil_newobj; + +// CIL expression instructions + +@cil_expr = @cil_literal | @cil_binary_expr | @cil_unary_expr | @cil_call_any | @cil_read_access | + @cil_newarr | @cil_ldtoken | @cil_sizeof | + @cil_ldftn | @cil_ldvirtftn | @cil_localloc | @cil_mkrefany | @cil_refanytype | @cil_arglist | @cil_dup; + +@cil_unary_expr = + @cil_conversion_operation | @cil_unary_arithmetic_operation | @cil_unary_bitwise_operation| + @cil_ldlen | @cil_isinst | @cil_box | @cil_ldobj | @cil_castclass | @cil_unbox_any | + @cil_ldind | @cil_unbox; + +@cil_conversion_operation = + @cil_conv_i1 | @cil_conv_i2 | @cil_conv_i4 | @cil_conv_i8 | + @cil_conv_u1 | @cil_conv_u2 | @cil_conv_u4 | @cil_conv_u8 | + @cil_conv_ovf_i | @cil_conv_ovf_i_un | @cil_conv_ovf_i1 | @cil_conv_ovf_i1_un | + @cil_conv_ovf_i2 | @cil_conv_ovf_i2_un | @cil_conv_ovf_i4 | @cil_conv_ovf_i4_un | + @cil_conv_ovf_i8 | @cil_conv_ovf_i8_un | @cil_conv_ovf_u | @cil_conv_ovf_u_un | + @cil_conv_ovf_u1 | @cil_conv_ovf_u1_un | @cil_conv_ovf_u2 | @cil_conv_ovf_u2_un | + @cil_conv_ovf_u4 | @cil_conv_ovf_u4_un | @cil_conv_ovf_u8 | @cil_conv_ovf_u8_un | + @cil_conv_r4 | @cil_conv_r8 | @cil_conv_ovf_u2 | @cil_conv_ovf_u2_un | + @cil_conv_i | @cil_conv_u | @cil_conv_r_un; + +@cil_ldind = @cil_ldind_i | @cil_ldind_i1 | @cil_ldind_i2 | @cil_ldind_i4 | @cil_ldind_i8 | + @cil_ldind_r4 | @cil_ldind_r8 | @cil_ldind_ref | @cil_ldind_u1 | @cil_ldind_u2 | @cil_ldind_u4; + +@cil_stind = @cil_stind_i | @cil_stind_i1 | @cil_stind_i2 | @cil_stind_i4 | @cil_stind_i8 | + @cil_stind_r4 | @cil_stind_r8 | @cil_stind_ref; + +@cil_bitwise_operation = @cil_binary_bitwise_operation | @cil_unary_bitwise_operation; + +@cil_binary_bitwise_operation = @cil_and | @cil_or | @cil_xor | @cil_shr | @cil_shr | @cil_shr_un | @cil_shl; + +@cil_binary_arithmetic_operation = @cil_add | @cil_sub | @cil_mul | @cil_div | @cil_div_un | + @cil_rem | @cil_rem_un | @cil_add_ovf | @cil_add_ovf_un | @cil_mul_ovf | @cil_mul_ovf_un | + @cil_sub_ovf | @cil_sub_ovf_un; + +@cil_unary_bitwise_operation = @cil_not; + +@cil_binary_expr = @cil_binary_arithmetic_operation | @cil_binary_bitwise_operation | @cil_read_array | @cil_comparison_operation; + +@cil_unary_arithmetic_operation = @cil_neg; + +@cil_comparison_operation = @cil_cgt_un | @cil_ceq | @cil_cgt | @cil_clt | @cil_clt_un; + +// Elements that retrieve an address of something +@cil_read_ref = @cil_ldloca_s | @cil_ldarga_s | @cil_ldflda | @cil_ldsflda | @cil_ldelema; + +// CIL array instructions + +@cil_read_array = + @cil_ldelem | @cil_ldelema | @cil_ldelem_i1 | @cil_ldelem_ref | @cil_ldelem_i | + @cil_ldelem_i1 | @cil_ldelem_i2 | @cil_ldelem_i4 | @cil_ldelem_i8 | @cil_ldelem_r4 | + @cil_ldelem_r8 | @cil_ldelem_u1 | @cil_ldelem_u2 | @cil_ldelem_u4; + +@cil_write_array = @cil_stelem | @cil_stelem_ref | + @cil_stelem_i | @cil_stelem_i1 | @cil_stelem_i2 | @cil_stelem_i4 | @cil_stelem_i8 | + @cil_stelem_r4 | @cil_stelem_r8; + +@cil_throw_any = @cil_throw | @cil_rethrow; + +#keyset[impl, index] +cil_instruction( + unique int id: @cil_instruction, + int opcode: int ref, + int index: int ref, + int impl: @cil_method_implementation ref); + +cil_jump( + unique int instruction: @cil_jump ref, + int target: @cil_instruction ref); + +cil_access( + unique int instruction: @cil_instruction ref, + int target: @cil_accessible ref); + +cil_value( + unique int instruction: @cil_literal ref, + string value: string ref); + +#keyset[instruction, index] +cil_switch( + int instruction: @cil_switch ref, + int index: int ref, + int target: @cil_instruction ref); + +cil_instruction_location( + unique int id: @cil_instruction ref, + int loc: @location ref); + +cil_type_location( + int id: @cil_type ref, + int loc: @location ref); + +cil_method_location( + int id: @cil_method ref, + int loc: @location ref); + +@cil_namespace = @namespace; + +@cil_type_container = @cil_type | @cil_namespace | @cil_method; + +case @cil_type.kind of + 0 = @cil_valueorreftype +| 1 = @cil_typeparameter +| 2 = @cil_array_type +| 3 = @cil_pointer_type +; + +cil_type( + unique int id: @cil_type, + string name: string ref, + int kind: int ref, + int parent: @cil_type_container ref, + int sourceDecl: @cil_type ref); + +cil_pointer_type( + unique int id: @cil_pointer_type ref, + int pointee: @cil_type ref); + +cil_array_type( + unique int id: @cil_array_type ref, + int element_type: @cil_type ref, + int rank: int ref); + +cil_method( + unique int id: @cil_method, + string name: string ref, + int parent: @cil_type ref, + int return_type: @cil_type ref); + +cil_method_source_declaration( + unique int method: @cil_method ref, + int source: @cil_method ref); + +cil_method_implementation( + unique int id: @cil_method_implementation, + int method: @cil_method ref, + int location: @assembly ref); + +cil_implements( + int id: @cil_method ref, + int decl: @cil_method ref); + +#keyset[parent, name] +cil_field( + unique int id: @cil_field, + int parent: @cil_type ref, + string name: string ref, + int field_type: @cil_type ref); + +@cil_element = @cil_instruction | @cil_declaration | @cil_handler | @cil_attribute | @cil_namespace; +@cil_named_element = @cil_declaration | @cil_namespace; +@cil_declaration = @cil_variable | @cil_method | @cil_type | @cil_member; +@cil_accessible = @cil_declaration; +@cil_variable = @cil_field | @cil_stack_variable; +@cil_stack_variable = @cil_local_variable | @cil_parameter; +@cil_member = @cil_method | @cil_type | @cil_field | @cil_property | @cil_event; +@cil_custom_modifier_receiver = @cil_method | @cil_property | @cil_parameter | @cil_field; // todo: add function pointer type + +#keyset[method, index] +cil_parameter( + unique int id: @cil_parameter, + int method: @cil_method ref, + int index: int ref, + int param_type: @cil_type ref); + +cil_parameter_in(unique int id: @cil_parameter ref); +cil_parameter_out(unique int id: @cil_parameter ref); + +cil_setter(unique int prop: @cil_property ref, + int method: @cil_method ref); + +#keyset[id, modifier] +cil_custom_modifiers( + int id: @cil_custom_modifier_receiver ref, + int modifier: @cil_type ref, + int kind: int ref); // modreq: 1, modopt: 0 + +cil_getter(unique int prop: @cil_property ref, + int method: @cil_method ref); + +cil_adder(unique int event: @cil_event ref, + int method: @cil_method ref); + +cil_remover(unique int event: @cil_event ref, int method: @cil_method ref); + +cil_raiser(unique int event: @cil_event ref, int method: @cil_method ref); + +cil_property( + unique int id: @cil_property, + int parent: @cil_type ref, + string name: string ref, + int property_type: @cil_type ref); + +#keyset[parent, name] +cil_event(unique int id: @cil_event, + int parent: @cil_type ref, + string name: string ref, + int event_type: @cil_type ref); + +#keyset[impl, index] +cil_local_variable( + unique int id: @cil_local_variable, + int impl: @cil_method_implementation ref, + int index: int ref, + int var_type: @cil_type ref); + +// CIL handlers (exception handlers etc). + +case @cil_handler.kind of + 0 = @cil_catch_handler +| 1 = @cil_filter_handler +| 2 = @cil_finally_handler +| 4 = @cil_fault_handler +; + +#keyset[impl, index] +cil_handler( + unique int id: @cil_handler, + int impl: @cil_method_implementation ref, + int index: int ref, + int kind: int ref, + int try_start: @cil_instruction ref, + int try_end: @cil_instruction ref, + int handler_start: @cil_instruction ref); + +cil_handler_filter( + unique int id: @cil_handler ref, + int filter_start: @cil_instruction ref); + +cil_handler_type( + unique int id: @cil_handler ref, + int catch_type: @cil_type ref); + +@cil_controlflow_node = @cil_entry_point | @cil_instruction; + +@cil_entry_point = @cil_method_implementation | @cil_handler; + +@cil_dataflow_node = @cil_instruction | @cil_variable | @cil_method; + +cil_method_stack_size( + unique int method: @cil_method_implementation ref, + int size: int ref); + +// CIL modifiers + +cil_public(int id: @cil_member ref); +cil_private(int id: @cil_member ref); +cil_protected(int id: @cil_member ref); +cil_internal(int id: @cil_member ref); +cil_static(int id: @cil_member ref); +cil_sealed(int id: @cil_member ref); +cil_virtual(int id: @cil_method ref); +cil_abstract(int id: @cil_member ref); +cil_class(int id: @cil_type ref); +cil_interface(int id: @cil_type ref); +cil_security(int id: @cil_member ref); +cil_requiresecobject(int id: @cil_method ref); +cil_specialname(int id: @cil_method ref); +cil_newslot(int id: @cil_method ref); + +cil_base_class(unique int id: @cil_type ref, int base: @cil_type ref); +cil_base_interface(int id: @cil_type ref, int base: @cil_type ref); +cil_enum_underlying_type(unique int id: @cil_type ref, int underlying: @cil_type ref); + +#keyset[unbound, index] +cil_type_parameter( + int unbound: @cil_member ref, + int index: int ref, + int param: @cil_typeparameter ref); + +#keyset[bound, index] +cil_type_argument( + int bound: @cil_member ref, + int index: int ref, + int t: @cil_type ref); + +// CIL type parameter constraints + +cil_typeparam_covariant(int tp: @cil_typeparameter ref); +cil_typeparam_contravariant(int tp: @cil_typeparameter ref); +cil_typeparam_class(int tp: @cil_typeparameter ref); +cil_typeparam_struct(int tp: @cil_typeparameter ref); +cil_typeparam_new(int tp: @cil_typeparameter ref); +cil_typeparam_constraint(int tp: @cil_typeparameter ref, int supertype: @cil_type ref); + +// CIL attributes + +cil_attribute( + unique int attributeid: @cil_attribute, + int element: @cil_declaration ref, + int constructor: @cil_method ref); + +#keyset[attribute_id, param] +cil_attribute_named_argument( + int attribute_id: @cil_attribute ref, + string param: string ref, + string value: string ref); + +#keyset[attribute_id, index] +cil_attribute_positional_argument( + int attribute_id: @cil_attribute ref, + int index: int ref, + string value: string ref); + + +// Common .Net data model covering both C# and CIL + +// Common elements +@dotnet_element = @element | @cil_element; +@dotnet_named_element = @named_element | @cil_named_element; +@dotnet_callable = @callable | @cil_method; +@dotnet_variable = @variable | @cil_variable; +@dotnet_field = @field | @cil_field; +@dotnet_parameter = @parameter | @cil_parameter; +@dotnet_declaration = @declaration | @cil_declaration; +@dotnet_member = @member | @cil_member; +@dotnet_event = @event | @cil_event; +@dotnet_property = @property | @cil_property | @indexer; + +// Common types +@dotnet_type = @type | @cil_type; +@dotnet_call = @call | @cil_call_any; +@dotnet_throw = @throw_element | @cil_throw_any; +@dotnet_valueorreftype = @cil_valueorreftype | @value_or_ref_type | @cil_array_type | @void_type; +@dotnet_typeparameter = @type_parameter | @cil_typeparameter; +@dotnet_array_type = @array_type | @cil_array_type; +@dotnet_pointer_type = @pointer_type | @cil_pointer_type; +@dotnet_type_parameter = @type_parameter | @cil_typeparameter; +@dotnet_generic = @dotnet_valueorreftype | @dotnet_callable; + +// Attributes +@dotnet_attribute = @attribute | @cil_attribute; + +// Expressions +@dotnet_expr = @expr | @cil_expr; + +// Literals +@dotnet_literal = @literal_expr | @cil_literal; +@dotnet_string_literal = @string_literal_expr | @cil_ldstr; +@dotnet_int_literal = @integer_literal_expr | @cil_ldc_i; +@dotnet_float_literal = @float_literal_expr | @cil_ldc_r; +@dotnet_null_literal = @null_literal_expr | @cil_ldnull; + +@metadata_entity = @cil_method | @cil_type | @cil_field | @cil_property | @field | @property | + @callable | @value_or_ref_type | @void_type; + +#keyset[entity, location] +metadata_handle(int entity : @metadata_entity ref, int location: @assembly ref, int handle: int ref) diff --git a/csharp/upgrades/e6442d16b7e3786d0918597c2c9fbd871ca06f77/semmlecode.csharp.dbscheme b/csharp/upgrades/e6442d16b7e3786d0918597c2c9fbd871ca06f77/semmlecode.csharp.dbscheme new file mode 100644 index 00000000000..5f6770a8a17 --- /dev/null +++ b/csharp/upgrades/e6442d16b7e3786d0918597c2c9fbd871ca06f77/semmlecode.csharp.dbscheme @@ -0,0 +1,1917 @@ + +/** + * An invocation of the compiler. Note that more than one file may be + * compiled per invocation. For example, this command compiles three + * source files: + * + * csc f1.cs f2.cs f3.cs + * + * The `id` simply identifies the invocation, while `cwd` is the working + * directory from which the compiler was invoked. + */ +compilations( + unique int id : @compilation, + string cwd : string ref +); + +/** + * The arguments that were passed to the extractor for a compiler + * invocation. If `id` is for the compiler invocation + * + * csc f1.cs f2.cs f3.cs + * + * then typically there will be rows for + * + * num | arg + * --- | --- + * 0 | --compiler + * 1 | *path to compiler* + * 2 | --cil + * 3 | f1.cs + * 4 | f2.cs + * 5 | f3.cs + */ +#keyset[id, num] +compilation_args( + int id : @compilation ref, + int num : int ref, + string arg : string ref +); + +/** + * The source files that are compiled by a compiler invocation. + * If `id` is for the compiler invocation + * + * csc f1.cs f2.cs f3.cs + * + * then there will be rows for + * + * num | arg + * --- | --- + * 0 | f1.cs + * 1 | f2.cs + * 2 | f3.cs + */ +#keyset[id, num] +compilation_compiling_files( + int id : @compilation ref, + int num : int ref, + int file : @file ref +); + +/** + * The references used by a compiler invocation. + * If `id` is for the compiler invocation + * + * csc f1.cs f2.cs f3.cs /r:ref1.dll /r:ref2.dll /r:ref3.dll + * + * then there will be rows for + * + * num | arg + * --- | --- + * 0 | ref1.dll + * 1 | ref2.dll + * 2 | ref3.dll + */ +#keyset[id, num] +compilation_referencing_files( + int id : @compilation ref, + int num : int ref, + int file : @file ref +); + +/** + * The time taken by the extractor for a compiler invocation. + * + * For each file `num`, there will be rows for + * + * kind | seconds + * ---- | --- + * 1 | CPU seconds used by the extractor frontend + * 2 | Elapsed seconds during the extractor frontend + * 3 | CPU seconds used by the extractor backend + * 4 | Elapsed seconds during the extractor backend + */ +#keyset[id, num, kind] +compilation_time( + int id : @compilation ref, + int num : int ref, + /* kind: + 1 = frontend_cpu_seconds + 2 = frontend_elapsed_seconds + 3 = extractor_cpu_seconds + 4 = extractor_elapsed_seconds + */ + int kind : int ref, + float seconds : float ref +); + +/** + * An error or warning generated by the extractor. + * The diagnostic message `diagnostic` was generated during compiler + * invocation `compilation`, and is the `file_number_diagnostic_number`th + * message generated while extracting the `file_number`th file of that + * invocation. + */ +#keyset[compilation, file_number, file_number_diagnostic_number] +diagnostic_for( + unique int diagnostic : @diagnostic ref, + int compilation : @compilation ref, + int file_number : int ref, + int file_number_diagnostic_number : int ref +); + +diagnostics( + unique int id: @diagnostic, + int severity: int ref, + string error_tag: string ref, + string error_message: string ref, + string full_error_message: string ref, + int location: @location_default ref +); + +extractor_messages( + unique int id: @extractor_message, + int severity: int ref, + string origin : string ref, + string text : string ref, + string entity : string ref, + int location: @location_default ref, + string stack_trace : string ref +); + +/** + * If extraction was successful, then `cpu_seconds` and + * `elapsed_seconds` are the CPU time and elapsed time (respectively) + * that extraction took for compiler invocation `id`. + */ +compilation_finished( + unique int id : @compilation ref, + float cpu_seconds : float ref, + float elapsed_seconds : float ref +); + +compilation_assembly( + unique int id : @compilation ref, + int assembly: @assembly ref +) + +/* + * External artifacts + */ + +externalDefects( + unique int id: @externalDefect, + string queryPath: string ref, + int location: @location ref, + string message: string ref, + float severity: float ref); + +externalMetrics( + unique int id: @externalMetric, + string queryPath: string ref, + int location: @location ref, + float value: float ref); + +externalData( + int id: @externalDataElement, + string path: string ref, + int column: int ref, + string value: string ref); + +snapshotDate( + unique date snapshotDate: date ref); + +sourceLocationPrefix( + string prefix: string ref); + +/* + * Duplicate code + */ + +duplicateCode( + unique int id: @duplication, + string relativePath: string ref, + int equivClass: int ref); + +similarCode( + unique int id: @similarity, + string relativePath: string ref, + int equivClass: int ref); + +@duplication_or_similarity = @duplication | @similarity + +tokens( + int id: @duplication_or_similarity ref, + int offset: int ref, + int beginLine: int ref, + int beginColumn: int ref, + int endLine: int ref, + int endColumn: int ref); + +/* + * C# dbscheme + */ + +/** ELEMENTS **/ + +@element = @declaration | @stmt | @expr | @modifier | @attribute | @namespace_declaration + | @using_directive | @type_parameter_constraints | @external_element + | @xmllocatable | @asp_element | @namespace; + +@declaration = @callable | @generic | @assignable | @namespace; + +@named_element = @namespace | @declaration; + +@declaration_with_accessors = @property | @indexer | @event; + +@assignable = @variable | @assignable_with_accessors | @event; + +@assignable_with_accessors = @property | @indexer; + +@external_element = @externalMetric | @externalDefect | @externalDataElement; + +@attributable = @assembly | @field | @parameter | @operator | @method | @constructor + | @destructor | @callable_accessor | @value_or_ref_type | @declaration_with_accessors + | @local_function; + +/** LOCATIONS, ASEMMBLIES, MODULES, FILES and FOLDERS **/ + +@location = @location_default | @assembly; + +locations_default( + unique int id: @location_default, + int file: @file ref, + int beginLine: int ref, + int beginColumn: int ref, + int endLine: int ref, + int endColumn: int ref); + +@sourceline = @file | @callable | @xmllocatable; + +numlines( + int element_id: @sourceline ref, + int num_lines: int ref, + int num_code: int ref, + int num_comment: int ref); + +assemblies( + unique int id: @assembly, + int file: @file ref, + string fullname: string ref, + string name: string ref, + string version: string ref); + +/* + fromSource(0) = unknown, + fromSource(1) = from source, + fromSource(2) = from library +*/ +files( + unique int id: @file, + string name: string ref, + string simple: string ref, + string ext: string ref, + int fromSource: int ref); + +folders( + unique int id: @folder, + string name: string ref, + string simple: string ref); + +@container = @folder | @file ; + +containerparent( + int parent: @container ref, + unique int child: @container ref); + +file_extraction_mode( + unique int file: @file ref, + int mode: int ref + /* 0 = normal, 1 = standalone extractor */ + ); + +/** NAMESPACES **/ + +@type_container = @namespace | @type; + +namespaces( + unique int id: @namespace, + string name: string ref); + +namespace_declarations( + unique int id: @namespace_declaration, + int namespace_id: @namespace ref); + +namespace_declaration_location( + unique int id: @namespace_declaration ref, + int loc: @location ref); + +parent_namespace( + unique int child_id: @type_container ref, + int namespace_id: @namespace ref); + +@declaration_or_directive = @namespace_declaration | @type | @using_directive; + +parent_namespace_declaration( + int child_id: @declaration_or_directive ref, // cannot be unique because of partial classes + int namespace_id: @namespace_declaration ref); + +@using_directive = @using_namespace_directive | @using_static_directive; + +using_namespace_directives( + unique int id: @using_namespace_directive, + int namespace_id: @namespace ref); + +using_static_directives( + unique int id: @using_static_directive, + int type_id: @type_or_ref ref); + +using_directive_location( + unique int id: @using_directive ref, + int loc: @location ref); + +/** TYPES **/ + +types( + unique int id: @type, + int kind: int ref, + string name: string ref); + +case @type.kind of + 1 = @bool_type +| 2 = @char_type +| 3 = @decimal_type +| 4 = @sbyte_type +| 5 = @short_type +| 6 = @int_type +| 7 = @long_type +| 8 = @byte_type +| 9 = @ushort_type +| 10 = @uint_type +| 11 = @ulong_type +| 12 = @float_type +| 13 = @double_type +| 14 = @enum_type +| 15 = @struct_type +| 17 = @class_type +| 19 = @interface_type +| 20 = @delegate_type +| 21 = @null_type +| 22 = @type_parameter +| 23 = @pointer_type +| 24 = @nullable_type +| 25 = @array_type +| 26 = @void_type +| 27 = @int_ptr_type +| 28 = @uint_ptr_type +| 29 = @dynamic_type +| 30 = @arglist_type +| 31 = @unknown_type +| 32 = @tuple_type + ; + +@simple_type = @bool_type | @char_type | @integral_type | @floating_point_type | @decimal_type; +@integral_type = @signed_integral_type | @unsigned_integral_type; +@signed_integral_type = @sbyte_type | @short_type | @int_type | @long_type; +@unsigned_integral_type = @byte_type | @ushort_type | @uint_type | @ulong_type; +@floating_point_type = @float_type | @double_type; +@value_type = @simple_type | @enum_type | @struct_type | @nullable_type | @int_ptr_type + | @uint_ptr_type | @tuple_type; +@ref_type = @class_type | @interface_type | @array_type | @delegate_type | @null_type + | @dynamic_type; +@value_or_ref_type = @value_type | @ref_type; + +typerefs( + unique int id: @typeref, + string name: string ref); + +typeref_type( + int id: @typeref ref, + unique int typeId: @type ref); + +@type_or_ref = @type | @typeref; + +array_element_type( + unique int array: @array_type ref, + int dimension: int ref, + int rank: int ref, + int element: @type_or_ref ref); + +nullable_underlying_type( + unique int nullable: @nullable_type ref, + int underlying: @type_or_ref ref); + +pointer_referent_type( + unique int pointer: @pointer_type ref, + int referent: @type_or_ref ref); + +enum_underlying_type( + unique int enum_id: @enum_type ref, + int underlying_type_id: @type_or_ref ref); + +delegate_return_type( + unique int delegate_id: @delegate_type ref, + int return_type_id: @type_or_ref ref); + +extend( + unique int sub: @type ref, + int super: @type_or_ref ref); + +anonymous_types( + unique int id: @type ref); + +@interface_or_ref = @interface_type | @typeref; + +implement( + int sub: @type ref, + int super: @type_or_ref ref); + +type_location( + int id: @type ref, + int loc: @location ref); + +tuple_underlying_type( + unique int tuple: @tuple_type ref, + int struct: @type_or_ref ref); + +#keyset[tuple, index] +tuple_element( + int tuple: @tuple_type ref, + int index: int ref, + unique int field: @field ref); + +attributes( + unique int id: @attribute, + int type_id: @type_or_ref ref, + int target: @attributable ref); + +attribute_location( + int id: @attribute ref, + int loc: @location ref); + +@type_mention_parent = @element | @type_mention; + +type_mention( + unique int id: @type_mention, + int type_id: @type_or_ref ref, + int parent: @type_mention_parent ref); + +type_mention_location( + unique int id: @type_mention ref, + int loc: @location ref); + +@has_type_annotation = @assignable | @type_parameter | @callable | @expr | @delegate_type | @generic; + +/** + * A direct annotation on an entity, for example `string? x;`. + * + * Annotations: + * 2 = reftype is not annotated "!" + * 3 = reftype is annotated "?" + * 4 = readonly ref type / in parameter + * 5 = ref type parameter, return or local variable + * 6 = out parameter + * + * Note that the annotation depends on the element it annotates. + * @assignable: The annotation is on the type of the assignable, for example the variable type. + * @type_parameter: The annotation is on the reftype constraint + * @callable: The annotation is on the return type + * @array_type: The annotation is on the element type + */ +type_annotation(int id: @has_type_annotation ref, int annotation: int ref); + +nullability(unique int nullability: @nullability, int kind: int ref); + +case @nullability.kind of + 0 = @oblivious +| 1 = @not_annotated +| 2 = @annotated +; + +#keyset[parent, index] +nullability_parent(int nullability: @nullability ref, int index: int ref, int parent: @nullability ref) + +type_nullability(int id: @has_type_annotation ref, int nullability: @nullability ref); + +/** + * The nullable flow state of an expression, as determined by Roslyn. + * 0 = none (default, not populated) + * 1 = not null + * 2 = maybe null + */ +expr_flowstate(unique int id: @expr ref, int state: int ref); + +/** GENERICS **/ + +@generic = @type | @method | @local_function; + +type_parameters( + unique int id: @type_parameter ref, + int index: int ref, + int generic_id: @generic ref, + int variance: int ref /* none = 0, out = 1, in = 2 */); + +#keyset[constructed_id, index] +type_arguments( + int id: @type_or_ref ref, + int index: int ref, + int constructed_id: @generic_or_ref ref); + +@generic_or_ref = @generic | @typeref; + +constructed_generic( + unique int constructed: @generic ref, + int generic: @generic_or_ref ref); + +type_parameter_constraints( + unique int id: @type_parameter_constraints, + int param_id: @type_parameter ref); + +type_parameter_constraints_location( + int id: @type_parameter_constraints ref, + int loc: @location ref); + +general_type_parameter_constraints( + int id: @type_parameter_constraints ref, + int kind: int ref /* class = 1, struct = 2, new = 3 */); + +specific_type_parameter_constraints( + int id: @type_parameter_constraints ref, + int base_id: @type_or_ref ref); + +specific_type_parameter_nullability( + int id: @type_parameter_constraints ref, + int base_id: @type_or_ref ref, + int nullability: @nullability ref); + +/** MODIFIERS */ + +@modifiable = @modifiable_direct | @event_accessor; + +@modifiable_direct = @member | @accessor | @local_function | @anonymous_function_expr; + +modifiers( + unique int id: @modifier, + string name: string ref); + +has_modifiers( + int id: @modifiable_direct ref, + int mod_id: @modifier ref); + +compiler_generated(unique int id: @modifiable_direct ref); + +/** MEMBERS **/ + +@member = @method | @constructor | @destructor | @field | @property | @event | @operator | @indexer | @type; + +@named_exprorstmt = @goto_stmt | @labeled_stmt | @expr; + +@virtualizable = @method | @property | @indexer | @event; + +exprorstmt_name( + unique int parent_id: @named_exprorstmt ref, + string name: string ref); + +nested_types( + unique int id: @type ref, + int declaring_type_id: @type ref, + int unbound_id: @type ref); + +properties( + unique int id: @property, + string name: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @property ref); + +property_location( + int id: @property ref, + int loc: @location ref); + +indexers( + unique int id: @indexer, + string name: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @indexer ref); + +indexer_location( + int id: @indexer ref, + int loc: @location ref); + +accessors( + unique int id: @accessor, + int kind: int ref, + string name: string ref, + int declaring_member_id: @member ref, + int unbound_id: @accessor ref); + +case @accessor.kind of + 1 = @getter +| 2 = @setter + ; + +init_only_accessors( + unique int id: @accessor ref); + +accessor_location( + int id: @accessor ref, + int loc: @location ref); + +events( + unique int id: @event, + string name: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @event ref); + +event_location( + int id: @event ref, + int loc: @location ref); + +event_accessors( + unique int id: @event_accessor, + int kind: int ref, + string name: string ref, + int declaring_event_id: @event ref, + int unbound_id: @event_accessor ref); + +case @event_accessor.kind of + 1 = @add_event_accessor +| 2 = @remove_event_accessor + ; + +event_accessor_location( + int id: @event_accessor ref, + int loc: @location ref); + +operators( + unique int id: @operator, + string name: string ref, + string symbol: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @operator ref); + +operator_location( + int id: @operator ref, + int loc: @location ref); + +constant_value( + int id: @variable ref, + string value: string ref); + +/** CALLABLES **/ + +@callable = @method | @constructor | @destructor | @operator | @callable_accessor | @anonymous_function_expr | @local_function; + +@callable_accessor = @accessor | @event_accessor; + +methods( + unique int id: @method, + string name: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @method ref); + +method_location( + int id: @method ref, + int loc: @location ref); + +constructors( + unique int id: @constructor, + string name: string ref, + int declaring_type_id: @type ref, + int unbound_id: @constructor ref); + +constructor_location( + int id: @constructor ref, + int loc: @location ref); + +destructors( + unique int id: @destructor, + string name: string ref, + int declaring_type_id: @type ref, + int unbound_id: @destructor ref); + +destructor_location( + int id: @destructor ref, + int loc: @location ref); + +overrides( + int id: @callable ref, + int base_id: @callable ref); + +explicitly_implements( + int id: @member ref, + int interface_id: @interface_or_ref ref); + +local_functions( + unique int id: @local_function, + string name: string ref, + int return_type: @type ref, + int unbound_id: @local_function ref); + +local_function_stmts( + unique int fn: @local_function_stmt ref, + int stmt: @local_function ref); + +/** VARIABLES **/ + +@variable = @local_scope_variable | @field; + +@local_scope_variable = @local_variable | @parameter; + +fields( + unique int id: @field, + int kind: int ref, + string name: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @field ref); + +case @field.kind of + 1 = @addressable_field +| 2 = @constant + ; + +field_location( + int id: @field ref, + int loc: @location ref); + +localvars( + unique int id: @local_variable, + int kind: int ref, + string name: string ref, + int implicitly_typed: int ref /* 0 = no, 1 = yes */, + int type_id: @type_or_ref ref, + int parent_id: @local_var_decl_expr ref); + +case @local_variable.kind of + 1 = @addressable_local_variable +| 2 = @local_constant +| 3 = @local_variable_ref + ; + +localvar_location( + unique int id: @local_variable ref, + int loc: @location ref); + +@parameterizable = @callable | @delegate_type | @indexer; + +#keyset[name, parent_id] +#keyset[index, parent_id] +params( + unique int id: @parameter, + string name: string ref, + int type_id: @type_or_ref ref, + int index: int ref, + int mode: int ref, /* value = 0, ref = 1, out = 2, array = 3, this = 4 */ + int parent_id: @parameterizable ref, + int unbound_id: @parameter ref); + +param_location( + int id: @parameter ref, + int loc: @location ref); + +/** STATEMENTS **/ + +@exprorstmt_parent = @control_flow_element | @top_level_exprorstmt_parent; + +statements( + unique int id: @stmt, + int kind: int ref); + +#keyset[index, parent] +stmt_parent( + unique int stmt: @stmt ref, + int index: int ref, + int parent: @control_flow_element ref); + +@top_level_stmt_parent = @callable; + +// [index, parent] is not a keyset because the same parent may be compiled multiple times +stmt_parent_top_level( + unique int stmt: @stmt ref, + int index: int ref, + int parent: @top_level_stmt_parent ref); + +case @stmt.kind of + 1 = @block_stmt +| 2 = @expr_stmt +| 3 = @if_stmt +| 4 = @switch_stmt +| 5 = @while_stmt +| 6 = @do_stmt +| 7 = @for_stmt +| 8 = @foreach_stmt +| 9 = @break_stmt +| 10 = @continue_stmt +| 11 = @goto_stmt +| 12 = @goto_case_stmt +| 13 = @goto_default_stmt +| 14 = @throw_stmt +| 15 = @return_stmt +| 16 = @yield_stmt +| 17 = @try_stmt +| 18 = @checked_stmt +| 19 = @unchecked_stmt +| 20 = @lock_stmt +| 21 = @using_block_stmt +| 22 = @var_decl_stmt +| 23 = @const_decl_stmt +| 24 = @empty_stmt +| 25 = @unsafe_stmt +| 26 = @fixed_stmt +| 27 = @label_stmt +| 28 = @catch +| 29 = @case_stmt +| 30 = @local_function_stmt +| 31 = @using_decl_stmt + ; + +@using_stmt = @using_block_stmt | @using_decl_stmt; + +@labeled_stmt = @label_stmt | @case; + +@decl_stmt = @var_decl_stmt | @const_decl_stmt | @using_decl_stmt; + +@cond_stmt = @if_stmt | @switch_stmt; + +@loop_stmt = @while_stmt | @do_stmt | @for_stmt | @foreach_stmt; + +@jump_stmt = @break_stmt | @goto_any_stmt | @continue_stmt | @throw_stmt | @return_stmt + | @yield_stmt; + +@goto_any_stmt = @goto_default_stmt | @goto_case_stmt | @goto_stmt; + + +stmt_location( + unique int id: @stmt ref, + int loc: @location ref); + +catch_type( + unique int catch_id: @catch ref, + int type_id: @type_or_ref ref, + int kind: int ref /* explicit = 1, implicit = 2 */); + +/** EXPRESSIONS **/ + +expressions( + unique int id: @expr, + int kind: int ref, + int type_id: @type_or_ref ref); + +#keyset[index, parent] +expr_parent( + unique int expr: @expr ref, + int index: int ref, + int parent: @control_flow_element ref); + +@top_level_expr_parent = @attribute | @field | @property | @indexer | @parameter; + +@top_level_exprorstmt_parent = @top_level_expr_parent | @top_level_stmt_parent; + +// [index, parent] is not a keyset because the same parent may be compiled multiple times +expr_parent_top_level( + unique int expr: @expr ref, + int index: int ref, + int parent: @top_level_exprorstmt_parent ref); + +case @expr.kind of +/* literal */ + 1 = @bool_literal_expr +| 2 = @char_literal_expr +| 3 = @decimal_literal_expr +| 4 = @int_literal_expr +| 5 = @long_literal_expr +| 6 = @uint_literal_expr +| 7 = @ulong_literal_expr +| 8 = @float_literal_expr +| 9 = @double_literal_expr +| 10 = @string_literal_expr +| 11 = @null_literal_expr +/* primary & unary */ +| 12 = @this_access_expr +| 13 = @base_access_expr +| 14 = @local_variable_access_expr +| 15 = @parameter_access_expr +| 16 = @field_access_expr +| 17 = @property_access_expr +| 18 = @method_access_expr +| 19 = @event_access_expr +| 20 = @indexer_access_expr +| 21 = @array_access_expr +| 22 = @type_access_expr +| 23 = @typeof_expr +| 24 = @method_invocation_expr +| 25 = @delegate_invocation_expr +| 26 = @operator_invocation_expr +| 27 = @cast_expr +| 28 = @object_creation_expr +| 29 = @explicit_delegate_creation_expr +| 30 = @implicit_delegate_creation_expr +| 31 = @array_creation_expr +| 32 = @default_expr +| 33 = @plus_expr +| 34 = @minus_expr +| 35 = @bit_not_expr +| 36 = @log_not_expr +| 37 = @post_incr_expr +| 38 = @post_decr_expr +| 39 = @pre_incr_expr +| 40 = @pre_decr_expr +/* multiplicative */ +| 41 = @mul_expr +| 42 = @div_expr +| 43 = @rem_expr +/* additive */ +| 44 = @add_expr +| 45 = @sub_expr +/* shift */ +| 46 = @lshift_expr +| 47 = @rshift_expr +/* relational */ +| 48 = @lt_expr +| 49 = @gt_expr +| 50 = @le_expr +| 51 = @ge_expr +/* equality */ +| 52 = @eq_expr +| 53 = @ne_expr +/* logical */ +| 54 = @bit_and_expr +| 55 = @bit_xor_expr +| 56 = @bit_or_expr +| 57 = @log_and_expr +| 58 = @log_or_expr +/* type testing */ +| 59 = @is_expr +| 60 = @as_expr +/* null coalescing */ +| 61 = @null_coalescing_expr +/* conditional */ +| 62 = @conditional_expr +/* assignment */ +| 63 = @simple_assign_expr +| 64 = @assign_add_expr +| 65 = @assign_sub_expr +| 66 = @assign_mul_expr +| 67 = @assign_div_expr +| 68 = @assign_rem_expr +| 69 = @assign_and_expr +| 70 = @assign_xor_expr +| 71 = @assign_or_expr +| 72 = @assign_lshift_expr +| 73 = @assign_rshift_expr +/* more */ +| 74 = @object_init_expr +| 75 = @collection_init_expr +| 76 = @array_init_expr +| 77 = @checked_expr +| 78 = @unchecked_expr +| 79 = @constructor_init_expr +| 80 = @add_event_expr +| 81 = @remove_event_expr +| 82 = @par_expr +| 83 = @local_var_decl_expr +| 84 = @lambda_expr +| 85 = @anonymous_method_expr +| 86 = @namespace_expr +/* dynamic */ +| 92 = @dynamic_element_access_expr +| 93 = @dynamic_member_access_expr +/* unsafe */ +| 100 = @pointer_indirection_expr +| 101 = @address_of_expr +| 102 = @sizeof_expr +/* async */ +| 103 = @await_expr +/* C# 6.0 */ +| 104 = @nameof_expr +| 105 = @interpolated_string_expr +| 106 = @unknown_expr +/* C# 7.0 */ +| 107 = @throw_expr +| 108 = @tuple_expr +| 109 = @local_function_invocation_expr +| 110 = @ref_expr +| 111 = @discard_expr +/* C# 8.0 */ +| 112 = @range_expr +| 113 = @index_expr +| 114 = @switch_expr +| 115 = @recursive_pattern_expr +| 116 = @property_pattern_expr +| 117 = @positional_pattern_expr +| 118 = @switch_case_expr +| 119 = @assign_coalesce_expr +| 120 = @suppress_nullable_warning_expr +| 121 = @namespace_access_expr +/* C# 9.0 */ +| 126 = @not_pattern_expr +; + +@switch = @switch_stmt | @switch_expr; +@case = @case_stmt | @switch_case_expr; +@pattern_match = @case | @is_expr; +@unary_pattern_expr = @not_pattern_expr; + +@integer_literal_expr = @int_literal_expr | @long_literal_expr | @uint_literal_expr | @ulong_literal_expr; +@real_literal_expr = @float_literal_expr | @double_literal_expr | @decimal_literal_expr; +@literal_expr = @bool_literal_expr | @char_literal_expr | @integer_literal_expr | @real_literal_expr + | @string_literal_expr | @null_literal_expr; + +@assign_expr = @simple_assign_expr | @assign_op_expr | @local_var_decl_expr; +@assign_op_expr = @assign_arith_expr | @assign_bitwise_expr | @assign_event_expr | @assign_coalesce_expr; +@assign_event_expr = @add_event_expr | @remove_event_expr; + +@assign_arith_expr = @assign_add_expr | @assign_sub_expr | @assign_mul_expr | @assign_div_expr + | @assign_rem_expr +@assign_bitwise_expr = @assign_and_expr | @assign_or_expr | @assign_xor_expr + | @assign_lshift_expr | @assign_rshift_expr; + +@member_access_expr = @field_access_expr | @property_access_expr | @indexer_access_expr | @event_access_expr + | @method_access_expr | @type_access_expr | @dynamic_member_access_expr; +@access_expr = @member_access_expr | @this_access_expr | @base_access_expr | @assignable_access_expr | @namespace_access_expr; +@element_access_expr = @indexer_access_expr | @array_access_expr | @dynamic_element_access_expr; + +@local_variable_access = @local_variable_access_expr | @local_var_decl_expr; +@local_scope_variable_access_expr = @parameter_access_expr | @local_variable_access; +@variable_access_expr = @local_scope_variable_access_expr | @field_access_expr; + +@assignable_access_expr = @variable_access_expr | @property_access_expr | @element_access_expr + | @event_access_expr | @dynamic_member_access_expr; + +@objectorcollection_init_expr = @object_init_expr | @collection_init_expr; + +@delegate_creation_expr = @explicit_delegate_creation_expr | @implicit_delegate_creation_expr; + +@bin_arith_op_expr = @mul_expr | @div_expr | @rem_expr | @add_expr | @sub_expr; +@incr_op_expr = @pre_incr_expr | @post_incr_expr; +@decr_op_expr = @pre_decr_expr | @post_decr_expr; +@mut_op_expr = @incr_op_expr | @decr_op_expr; +@un_arith_op_expr = @plus_expr | @minus_expr | @mut_op_expr; +@arith_op_expr = @bin_arith_op_expr | @un_arith_op_expr; + +@ternary_log_op_expr = @conditional_expr; +@bin_log_op_expr = @log_and_expr | @log_or_expr | @null_coalescing_expr; +@un_log_op_expr = @log_not_expr; +@log_expr = @un_log_op_expr | @bin_log_op_expr | @ternary_log_op_expr; + +@bin_bit_op_expr = @bit_and_expr | @bit_or_expr | @bit_xor_expr | @lshift_expr + | @rshift_expr; +@un_bit_op_expr = @bit_not_expr; +@bit_expr = @un_bit_op_expr | @bin_bit_op_expr; + +@equality_op_expr = @eq_expr | @ne_expr; +@rel_op_expr = @gt_expr | @lt_expr| @ge_expr | @le_expr; +@comp_expr = @equality_op_expr | @rel_op_expr; + +@op_expr = @assign_expr | @un_op | @bin_op | @ternary_op; + +@ternary_op = @ternary_log_op_expr; +@bin_op = @bin_arith_op_expr | @bin_log_op_expr | @bin_bit_op_expr | @comp_expr; +@un_op = @un_arith_op_expr | @un_log_op_expr | @un_bit_op_expr | @sizeof_expr + | @pointer_indirection_expr | @address_of_expr; + +@anonymous_function_expr = @lambda_expr | @anonymous_method_expr; + +@call = @method_invocation_expr | @constructor_init_expr | @operator_invocation_expr + | @delegate_invocation_expr | @object_creation_expr | @call_access_expr + | @local_function_invocation_expr; + +@call_access_expr = @property_access_expr | @event_access_expr | @indexer_access_expr; + +@late_bindable_expr = @dynamic_element_access_expr | @dynamic_member_access_expr + | @object_creation_expr | @method_invocation_expr | @operator_invocation_expr; + +@throw_element = @throw_expr | @throw_stmt; + +@implicitly_typeable_object_creation_expr = @object_creation_expr | @explicit_delegate_creation_expr; + +implicitly_typed_array_creation( + unique int id: @array_creation_expr ref); + +explicitly_sized_array_creation( + unique int id: @array_creation_expr ref); + +stackalloc_array_creation( + unique int id: @array_creation_expr ref); + +implicitly_typed_object_creation( + unique int id: @implicitly_typeable_object_creation_expr ref); + +mutator_invocation_mode( + unique int id: @operator_invocation_expr ref, + int mode: int ref /* prefix = 1, postfix = 2*/); + +expr_compiler_generated( + unique int id: @expr ref); + +expr_value( + unique int id: @expr ref, + string value: string ref); + +expr_call( + unique int caller_id: @expr ref, + int target_id: @callable ref); + +expr_access( + unique int accesser_id: @access_expr ref, + int target_id: @accessible ref); + +@accessible = @method | @assignable | @local_function | @namespace; + +expr_location( + unique int id: @expr ref, + int loc: @location ref); + +dynamic_member_name( + unique int id: @late_bindable_expr ref, + string name: string ref); + +@qualifiable_expr = @member_access_expr + | @method_invocation_expr + | @element_access_expr; + +conditional_access( + unique int id: @qualifiable_expr ref); + +expr_argument( + unique int id: @expr ref, + int mode: int ref); + /* mode is the same as params: value = 0, ref = 1, out = 2 */ + +expr_argument_name( + unique int id: @expr ref, + string name: string ref); + +/** CONTROL/DATA FLOW **/ + +@control_flow_element = @stmt | @expr; + +/* XML Files */ + +xmlEncoding ( + unique int id: @file ref, + string encoding: string ref); + +xmlDTDs( + unique int id: @xmldtd, + string root: string ref, + string publicId: string ref, + string systemId: string ref, + int fileid: @file ref); + +xmlElements( + unique int id: @xmlelement, + string name: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int fileid: @file ref); + +xmlAttrs( + unique int id: @xmlattribute, + int elementid: @xmlelement ref, + string name: string ref, + string value: string ref, + int idx: int ref, + int fileid: @file ref); + +xmlNs( + int id: @xmlnamespace, + string prefixName: string ref, + string URI: string ref, + int fileid: @file ref); + +xmlHasNs( + int elementId: @xmlnamespaceable ref, + int nsId: @xmlnamespace ref, + int fileid: @file ref); + +xmlComments( + unique int id: @xmlcomment, + string text: string ref, + int parentid: @xmlparent ref, + int fileid: @file ref); + +xmlChars( + unique int id: @xmlcharacters, + string text: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int isCDATA: int ref, + int fileid: @file ref); + +@xmlparent = @file | @xmlelement; +@xmlnamespaceable = @xmlelement | @xmlattribute; + +xmllocations( + int xmlElement: @xmllocatable ref, + int location: @location_default ref); + +@xmllocatable = @xmlcharacters | @xmlelement | @xmlcomment | @xmlattribute | @xmldtd | @file | @xmlnamespace; + +/* Comments */ + +commentline( + unique int id: @commentline, + int kind: int ref, + string text: string ref, + string rawtext: string ref); + +case @commentline.kind of + 0 = @singlelinecomment +| 1 = @xmldoccomment +| 2 = @multilinecomment; + +commentline_location( + unique int id: @commentline ref, + int loc: @location ref); + +commentblock( + unique int id : @commentblock); + +commentblock_location( + unique int id: @commentblock ref, + int loc: @location ref); + +commentblock_binding( + int id: @commentblock ref, + int entity: @element ref, + int bindtype: int ref); /* 0: Parent, 1: Best, 2: Before, 3: After */ + +commentblock_child( + int id: @commentblock ref, + int commentline: @commentline ref, + int index: int ref); + +/* ASP.NET */ + +case @asp_element.kind of + 0=@asp_close_tag +| 1=@asp_code +| 2=@asp_comment +| 3=@asp_data_binding +| 4=@asp_directive +| 5=@asp_open_tag +| 6=@asp_quoted_string +| 7=@asp_text +| 8=@asp_xml_directive; + +@asp_attribute = @asp_code | @asp_data_binding | @asp_quoted_string; + +asp_elements( + unique int id: @asp_element, + int kind: int ref, + int loc: @location ref); + +asp_comment_server(unique int comment: @asp_comment ref); +asp_code_inline(unique int code: @asp_code ref); +asp_directive_attribute( + int directive: @asp_directive ref, + int index: int ref, + string name: string ref, + int value: @asp_quoted_string ref); +asp_directive_name( + unique int directive: @asp_directive ref, + string name: string ref); +asp_element_body( + unique int element: @asp_element ref, + string body: string ref); +asp_tag_attribute( + int tag: @asp_open_tag ref, + int index: int ref, + string name: string ref, + int attribute: @asp_attribute ref); +asp_tag_name( + unique int tag: @asp_open_tag ref, + string name: string ref); +asp_tag_isempty(int tag: @asp_open_tag ref); + +/* Common Intermediate Language - CIL */ + +case @cil_instruction.opcode of + 0 = @cil_nop +| 1 = @cil_break +| 2 = @cil_ldarg_0 +| 3 = @cil_ldarg_1 +| 4 = @cil_ldarg_2 +| 5 = @cil_ldarg_3 +| 6 = @cil_ldloc_0 +| 7 = @cil_ldloc_1 +| 8 = @cil_ldloc_2 +| 9 = @cil_ldloc_3 +| 10 = @cil_stloc_0 +| 11 = @cil_stloc_1 +| 12 = @cil_stloc_2 +| 13 = @cil_stloc_3 +| 14 = @cil_ldarg_s +| 15 = @cil_ldarga_s +| 16 = @cil_starg_s +| 17 = @cil_ldloc_s +| 18 = @cil_ldloca_s +| 19 = @cil_stloc_s +| 20 = @cil_ldnull +| 21 = @cil_ldc_i4_m1 +| 22 = @cil_ldc_i4_0 +| 23 = @cil_ldc_i4_1 +| 24 = @cil_ldc_i4_2 +| 25 = @cil_ldc_i4_3 +| 26 = @cil_ldc_i4_4 +| 27 = @cil_ldc_i4_5 +| 28 = @cil_ldc_i4_6 +| 29 = @cil_ldc_i4_7 +| 30 = @cil_ldc_i4_8 +| 31 = @cil_ldc_i4_s +| 32 = @cil_ldc_i4 +| 33 = @cil_ldc_i8 +| 34 = @cil_ldc_r4 +| 35 = @cil_ldc_r8 +| 37 = @cil_dup +| 38 = @cil_pop +| 39 = @cil_jmp +| 40 = @cil_call +| 41 = @cil_calli +| 42 = @cil_ret +| 43 = @cil_br_s +| 44 = @cil_brfalse_s +| 45 = @cil_brtrue_s +| 46 = @cil_beq_s +| 47 = @cil_bge_s +| 48 = @cil_bgt_s +| 49 = @cil_ble_s +| 50 = @cil_blt_s +| 51 = @cil_bne_un_s +| 52 = @cil_bge_un_s +| 53 = @cil_bgt_un_s +| 54 = @cil_ble_un_s +| 55 = @cil_blt_un_s +| 56 = @cil_br +| 57 = @cil_brfalse +| 58 = @cil_brtrue +| 59 = @cil_beq +| 60 = @cil_bge +| 61 = @cil_bgt +| 62 = @cil_ble +| 63 = @cil_blt +| 64 = @cil_bne_un +| 65 = @cil_bge_un +| 66 = @cil_bgt_un +| 67 = @cil_ble_un +| 68 = @cil_blt_un +| 69 = @cil_switch +| 70 = @cil_ldind_i1 +| 71 = @cil_ldind_u1 +| 72 = @cil_ldind_i2 +| 73 = @cil_ldind_u2 +| 74 = @cil_ldind_i4 +| 75 = @cil_ldind_u4 +| 76 = @cil_ldind_i8 +| 77 = @cil_ldind_i +| 78 = @cil_ldind_r4 +| 79 = @cil_ldind_r8 +| 80 = @cil_ldind_ref +| 81 = @cil_stind_ref +| 82 = @cil_stind_i1 +| 83 = @cil_stind_i2 +| 84 = @cil_stind_i4 +| 85 = @cil_stind_i8 +| 86 = @cil_stind_r4 +| 87 = @cil_stind_r8 +| 88 = @cil_add +| 89 = @cil_sub +| 90 = @cil_mul +| 91 = @cil_div +| 92 = @cil_div_un +| 93 = @cil_rem +| 94 = @cil_rem_un +| 95 = @cil_and +| 96 = @cil_or +| 97 = @cil_xor +| 98 = @cil_shl +| 99 = @cil_shr +| 100 = @cil_shr_un +| 101 = @cil_neg +| 102 = @cil_not +| 103 = @cil_conv_i1 +| 104 = @cil_conv_i2 +| 105 = @cil_conv_i4 +| 106 = @cil_conv_i8 +| 107 = @cil_conv_r4 +| 108 = @cil_conv_r8 +| 109 = @cil_conv_u4 +| 110 = @cil_conv_u8 +| 111 = @cil_callvirt +| 112 = @cil_cpobj +| 113 = @cil_ldobj +| 114 = @cil_ldstr +| 115 = @cil_newobj +| 116 = @cil_castclass +| 117 = @cil_isinst +| 118 = @cil_conv_r_un +| 121 = @cil_unbox +| 122 = @cil_throw +| 123 = @cil_ldfld +| 124 = @cil_ldflda +| 125 = @cil_stfld +| 126 = @cil_ldsfld +| 127 = @cil_ldsflda +| 128 = @cil_stsfld +| 129 = @cil_stobj +| 130 = @cil_conv_ovf_i1_un +| 131 = @cil_conv_ovf_i2_un +| 132 = @cil_conv_ovf_i4_un +| 133 = @cil_conv_ovf_i8_un +| 134 = @cil_conv_ovf_u1_un +| 135 = @cil_conv_ovf_u2_un +| 136 = @cil_conv_ovf_u4_un +| 137 = @cil_conv_ovf_u8_un +| 138 = @cil_conv_ovf_i_un +| 139 = @cil_conv_ovf_u_un +| 140 = @cil_box +| 141 = @cil_newarr +| 142 = @cil_ldlen +| 143 = @cil_ldelema +| 144 = @cil_ldelem_i1 +| 145 = @cil_ldelem_u1 +| 146 = @cil_ldelem_i2 +| 147 = @cil_ldelem_u2 +| 148 = @cil_ldelem_i4 +| 149 = @cil_ldelem_u4 +| 150 = @cil_ldelem_i8 +| 151 = @cil_ldelem_i +| 152 = @cil_ldelem_r4 +| 153 = @cil_ldelem_r8 +| 154 = @cil_ldelem_ref +| 155 = @cil_stelem_i +| 156 = @cil_stelem_i1 +| 157 = @cil_stelem_i2 +| 158 = @cil_stelem_i4 +| 159 = @cil_stelem_i8 +| 160 = @cil_stelem_r4 +| 161 = @cil_stelem_r8 +| 162 = @cil_stelem_ref +| 163 = @cil_ldelem +| 164 = @cil_stelem +| 165 = @cil_unbox_any +| 179 = @cil_conv_ovf_i1 +| 180 = @cil_conv_ovf_u1 +| 181 = @cil_conv_ovf_i2 +| 182 = @cil_conv_ovf_u2 +| 183 = @cil_conv_ovf_i4 +| 184 = @cil_conv_ovf_u4 +| 185 = @cil_conv_ovf_i8 +| 186 = @cil_conv_ovf_u8 +| 194 = @cil_refanyval +| 195 = @cil_ckinfinite +| 198 = @cil_mkrefany +| 208 = @cil_ldtoken +| 209 = @cil_conv_u2 +| 210 = @cil_conv_u1 +| 211 = @cil_conv_i +| 212 = @cil_conv_ovf_i +| 213 = @cil_conv_ovf_u +| 214 = @cil_add_ovf +| 215 = @cil_add_ovf_un +| 216 = @cil_mul_ovf +| 217 = @cil_mul_ovf_un +| 218 = @cil_sub_ovf +| 219 = @cil_sub_ovf_un +| 220 = @cil_endfinally +| 221 = @cil_leave +| 222 = @cil_leave_s +| 223 = @cil_stind_i +| 224 = @cil_conv_u +| 65024 = @cil_arglist +| 65025 = @cil_ceq +| 65026 = @cil_cgt +| 65027 = @cil_cgt_un +| 65028 = @cil_clt +| 65029 = @cil_clt_un +| 65030 = @cil_ldftn +| 65031 = @cil_ldvirtftn +| 65033 = @cil_ldarg +| 65034 = @cil_ldarga +| 65035 = @cil_starg +| 65036 = @cil_ldloc +| 65037 = @cil_ldloca +| 65038 = @cil_stloc +| 65039 = @cil_localloc +| 65041 = @cil_endfilter +| 65042 = @cil_unaligned +| 65043 = @cil_volatile +| 65044 = @cil_tail +| 65045 = @cil_initobj +| 65046 = @cil_constrained +| 65047 = @cil_cpblk +| 65048 = @cil_initblk +| 65050 = @cil_rethrow +| 65052 = @cil_sizeof +| 65053 = @cil_refanytype +| 65054 = @cil_readonly +; + +// CIL ignored instructions + +@cil_ignore = @cil_nop | @cil_break | @cil_volatile | @cil_unaligned; + +// CIL local/parameter/field access + +@cil_ldarg_any = @cil_ldarg_0 | @cil_ldarg_1 | @cil_ldarg_2 | @cil_ldarg_3 | @cil_ldarg_s | @cil_ldarga_s | @cil_ldarg | @cil_ldarga; +@cil_starg_any = @cil_starg | @cil_starg_s; + +@cil_ldloc_any = @cil_ldloc_0 | @cil_ldloc_1 | @cil_ldloc_2 | @cil_ldloc_3 | @cil_ldloc_s | @cil_ldloca_s | @cil_ldloc | @cil_ldloca; +@cil_stloc_any = @cil_stloc_0 | @cil_stloc_1 | @cil_stloc_2 | @cil_stloc_3 | @cil_stloc_s | @cil_stloc; + +@cil_ldfld_any = @cil_ldfld | @cil_ldsfld | @cil_ldsflda | @cil_ldflda; +@cil_stfld_any = @cil_stfld | @cil_stsfld; + +@cil_local_access = @cil_stloc_any | @cil_ldloc_any; +@cil_arg_access = @cil_starg_any | @cil_ldarg_any; +@cil_read_access = @cil_ldloc_any | @cil_ldarg_any | @cil_ldfld_any; +@cil_write_access = @cil_stloc_any | @cil_starg_any | @cil_stfld_any; + +@cil_stack_access = @cil_local_access | @cil_arg_access; +@cil_field_access = @cil_ldfld_any | @cil_stfld_any; + +@cil_access = @cil_read_access | @cil_write_access; + +// CIL constant/literal instructions + +@cil_ldc_i = @cil_ldc_i4_any | @cil_ldc_i8; + +@cil_ldc_i4_any = @cil_ldc_i4_m1 | @cil_ldc_i4_0 | @cil_ldc_i4_1 | @cil_ldc_i4_2 | @cil_ldc_i4_3 | + @cil_ldc_i4_4 | @cil_ldc_i4_5 | @cil_ldc_i4_6 | @cil_ldc_i4_7 | @cil_ldc_i4_8 | @cil_ldc_i4_s | @cil_ldc_i4; + +@cil_ldc_r = @cil_ldc_r4 | @cil_ldc_r8; + +@cil_literal = @cil_ldnull | @cil_ldc_i | @cil_ldc_r | @cil_ldstr; + +// Control flow + +@cil_conditional_jump = @cil_binary_jump | @cil_unary_jump; +@cil_binary_jump = @cil_beq_s | @cil_bge_s | @cil_bgt_s | @cil_ble_s | @cil_blt_s | + @cil_bne_un_s | @cil_bge_un_s | @cil_bgt_un_s | @cil_ble_un_s | @cil_blt_un_s | + @cil_beq | @cil_bge | @cil_bgt | @cil_ble | @cil_blt | + @cil_bne_un | @cil_bge_un | @cil_bgt_un | @cil_ble_un | @cil_blt_un; +@cil_unary_jump = @cil_brfalse_s | @cil_brtrue_s | @cil_brfalse | @cil_brtrue | @cil_switch; +@cil_unconditional_jump = @cil_br | @cil_br_s | @cil_leave_any; +@cil_leave_any = @cil_leave | @cil_leave_s; +@cil_jump = @cil_unconditional_jump | @cil_conditional_jump; + +// CIL call instructions + +@cil_call_any = @cil_jmp | @cil_call | @cil_calli | @cil_tail | @cil_callvirt | @cil_newobj; + +// CIL expression instructions + +@cil_expr = @cil_literal | @cil_binary_expr | @cil_unary_expr | @cil_call_any | @cil_read_access | + @cil_newarr | @cil_ldtoken | @cil_sizeof | + @cil_ldftn | @cil_ldvirtftn | @cil_localloc | @cil_mkrefany | @cil_refanytype | @cil_arglist | @cil_dup; + +@cil_unary_expr = + @cil_conversion_operation | @cil_unary_arithmetic_operation | @cil_unary_bitwise_operation| + @cil_ldlen | @cil_isinst | @cil_box | @cil_ldobj | @cil_castclass | @cil_unbox_any | + @cil_ldind | @cil_unbox; + +@cil_conversion_operation = + @cil_conv_i1 | @cil_conv_i2 | @cil_conv_i4 | @cil_conv_i8 | + @cil_conv_u1 | @cil_conv_u2 | @cil_conv_u4 | @cil_conv_u8 | + @cil_conv_ovf_i | @cil_conv_ovf_i_un | @cil_conv_ovf_i1 | @cil_conv_ovf_i1_un | + @cil_conv_ovf_i2 | @cil_conv_ovf_i2_un | @cil_conv_ovf_i4 | @cil_conv_ovf_i4_un | + @cil_conv_ovf_i8 | @cil_conv_ovf_i8_un | @cil_conv_ovf_u | @cil_conv_ovf_u_un | + @cil_conv_ovf_u1 | @cil_conv_ovf_u1_un | @cil_conv_ovf_u2 | @cil_conv_ovf_u2_un | + @cil_conv_ovf_u4 | @cil_conv_ovf_u4_un | @cil_conv_ovf_u8 | @cil_conv_ovf_u8_un | + @cil_conv_r4 | @cil_conv_r8 | @cil_conv_ovf_u2 | @cil_conv_ovf_u2_un | + @cil_conv_i | @cil_conv_u | @cil_conv_r_un; + +@cil_ldind = @cil_ldind_i | @cil_ldind_i1 | @cil_ldind_i2 | @cil_ldind_i4 | @cil_ldind_i8 | + @cil_ldind_r4 | @cil_ldind_r8 | @cil_ldind_ref | @cil_ldind_u1 | @cil_ldind_u2 | @cil_ldind_u4; + +@cil_stind = @cil_stind_i | @cil_stind_i1 | @cil_stind_i2 | @cil_stind_i4 | @cil_stind_i8 | + @cil_stind_r4 | @cil_stind_r8 | @cil_stind_ref; + +@cil_bitwise_operation = @cil_binary_bitwise_operation | @cil_unary_bitwise_operation; + +@cil_binary_bitwise_operation = @cil_and | @cil_or | @cil_xor | @cil_shr | @cil_shr | @cil_shr_un | @cil_shl; + +@cil_binary_arithmetic_operation = @cil_add | @cil_sub | @cil_mul | @cil_div | @cil_div_un | + @cil_rem | @cil_rem_un | @cil_add_ovf | @cil_add_ovf_un | @cil_mul_ovf | @cil_mul_ovf_un | + @cil_sub_ovf | @cil_sub_ovf_un; + +@cil_unary_bitwise_operation = @cil_not; + +@cil_binary_expr = @cil_binary_arithmetic_operation | @cil_binary_bitwise_operation | @cil_read_array | @cil_comparison_operation; + +@cil_unary_arithmetic_operation = @cil_neg; + +@cil_comparison_operation = @cil_cgt_un | @cil_ceq | @cil_cgt | @cil_clt | @cil_clt_un; + +// Elements that retrieve an address of something +@cil_read_ref = @cil_ldloca_s | @cil_ldarga_s | @cil_ldflda | @cil_ldsflda | @cil_ldelema; + +// CIL array instructions + +@cil_read_array = + @cil_ldelem | @cil_ldelema | @cil_ldelem_i1 | @cil_ldelem_ref | @cil_ldelem_i | + @cil_ldelem_i1 | @cil_ldelem_i2 | @cil_ldelem_i4 | @cil_ldelem_i8 | @cil_ldelem_r4 | + @cil_ldelem_r8 | @cil_ldelem_u1 | @cil_ldelem_u2 | @cil_ldelem_u4; + +@cil_write_array = @cil_stelem | @cil_stelem_ref | + @cil_stelem_i | @cil_stelem_i1 | @cil_stelem_i2 | @cil_stelem_i4 | @cil_stelem_i8 | + @cil_stelem_r4 | @cil_stelem_r8; + +@cil_throw_any = @cil_throw | @cil_rethrow; + +#keyset[impl, index] +cil_instruction( + unique int id: @cil_instruction, + int opcode: int ref, + int index: int ref, + int impl: @cil_method_implementation ref); + +cil_jump( + unique int instruction: @cil_jump ref, + int target: @cil_instruction ref); + +cil_access( + unique int instruction: @cil_instruction ref, + int target: @cil_accessible ref); + +cil_value( + unique int instruction: @cil_literal ref, + string value: string ref); + +#keyset[instruction, index] +cil_switch( + int instruction: @cil_switch ref, + int index: int ref, + int target: @cil_instruction ref); + +cil_instruction_location( + unique int id: @cil_instruction ref, + int loc: @location ref); + +cil_type_location( + int id: @cil_type ref, + int loc: @location ref); + +cil_method_location( + int id: @cil_method ref, + int loc: @location ref); + +@cil_namespace = @namespace; + +@cil_type_container = @cil_type | @cil_namespace | @cil_method; + +case @cil_type.kind of + 0 = @cil_valueorreftype +| 1 = @cil_typeparameter +| 2 = @cil_array_type +| 3 = @cil_pointer_type +; + +cil_type( + unique int id: @cil_type, + string name: string ref, + int kind: int ref, + int parent: @cil_type_container ref, + int sourceDecl: @cil_type ref); + +cil_pointer_type( + unique int id: @cil_pointer_type ref, + int pointee: @cil_type ref); + +cil_array_type( + unique int id: @cil_array_type ref, + int element_type: @cil_type ref, + int rank: int ref); + +cil_method( + unique int id: @cil_method, + string name: string ref, + int parent: @cil_type ref, + int return_type: @cil_type ref); + +cil_method_source_declaration( + unique int method: @cil_method ref, + int source: @cil_method ref); + +cil_method_implementation( + unique int id: @cil_method_implementation, + int method: @cil_method ref, + int location: @assembly ref); + +cil_implements( + int id: @cil_method ref, + int decl: @cil_method ref); + +#keyset[parent, name] +cil_field( + unique int id: @cil_field, + int parent: @cil_type ref, + string name: string ref, + int field_type: @cil_type ref); + +@cil_element = @cil_instruction | @cil_declaration | @cil_handler | @cil_attribute | @cil_namespace; +@cil_named_element = @cil_declaration | @cil_namespace; +@cil_declaration = @cil_variable | @cil_method | @cil_type | @cil_member; +@cil_accessible = @cil_declaration; +@cil_variable = @cil_field | @cil_stack_variable; +@cil_stack_variable = @cil_local_variable | @cil_parameter; +@cil_member = @cil_method | @cil_type | @cil_field | @cil_property | @cil_event; +@cil_custom_modifier_receiver = @cil_method | @cil_property | @cil_parameter | @cil_field; // todo: add function pointer type + +#keyset[method, index] +cil_parameter( + unique int id: @cil_parameter, + int method: @cil_method ref, + int index: int ref, + int param_type: @cil_type ref); + +cil_parameter_in(unique int id: @cil_parameter ref); +cil_parameter_out(unique int id: @cil_parameter ref); + +cil_setter(unique int prop: @cil_property ref, + int method: @cil_method ref); + +#keyset[id, modifier] +cil_custom_modifiers( + int id: @cil_custom_modifier_receiver ref, + int modifier: @cil_type ref, + int kind: int ref); // modreq: 1, modopt: 0 + +cil_getter(unique int prop: @cil_property ref, + int method: @cil_method ref); + +cil_adder(unique int event: @cil_event ref, + int method: @cil_method ref); + +cil_remover(unique int event: @cil_event ref, int method: @cil_method ref); + +cil_raiser(unique int event: @cil_event ref, int method: @cil_method ref); + +cil_property( + unique int id: @cil_property, + int parent: @cil_type ref, + string name: string ref, + int property_type: @cil_type ref); + +#keyset[parent, name] +cil_event(unique int id: @cil_event, + int parent: @cil_type ref, + string name: string ref, + int event_type: @cil_type ref); + +#keyset[impl, index] +cil_local_variable( + unique int id: @cil_local_variable, + int impl: @cil_method_implementation ref, + int index: int ref, + int var_type: @cil_type ref); + +// CIL handlers (exception handlers etc). + +case @cil_handler.kind of + 0 = @cil_catch_handler +| 1 = @cil_filter_handler +| 2 = @cil_finally_handler +| 4 = @cil_fault_handler +; + +#keyset[impl, index] +cil_handler( + unique int id: @cil_handler, + int impl: @cil_method_implementation ref, + int index: int ref, + int kind: int ref, + int try_start: @cil_instruction ref, + int try_end: @cil_instruction ref, + int handler_start: @cil_instruction ref); + +cil_handler_filter( + unique int id: @cil_handler ref, + int filter_start: @cil_instruction ref); + +cil_handler_type( + unique int id: @cil_handler ref, + int catch_type: @cil_type ref); + +@cil_controlflow_node = @cil_entry_point | @cil_instruction; + +@cil_entry_point = @cil_method_implementation | @cil_handler; + +@cil_dataflow_node = @cil_instruction | @cil_variable | @cil_method; + +cil_method_stack_size( + unique int method: @cil_method_implementation ref, + int size: int ref); + +// CIL modifiers + +cil_public(int id: @cil_member ref); +cil_private(int id: @cil_member ref); +cil_protected(int id: @cil_member ref); +cil_internal(int id: @cil_member ref); +cil_static(int id: @cil_member ref); +cil_sealed(int id: @cil_member ref); +cil_virtual(int id: @cil_method ref); +cil_abstract(int id: @cil_member ref); +cil_class(int id: @cil_type ref); +cil_interface(int id: @cil_type ref); +cil_security(int id: @cil_member ref); +cil_requiresecobject(int id: @cil_method ref); +cil_specialname(int id: @cil_method ref); +cil_newslot(int id: @cil_method ref); + +cil_base_class(unique int id: @cil_type ref, int base: @cil_type ref); +cil_base_interface(int id: @cil_type ref, int base: @cil_type ref); +cil_enum_underlying_type(unique int id: @cil_type ref, int underlying: @cil_type ref); + +#keyset[unbound, index] +cil_type_parameter( + int unbound: @cil_member ref, + int index: int ref, + int param: @cil_typeparameter ref); + +#keyset[bound, index] +cil_type_argument( + int bound: @cil_member ref, + int index: int ref, + int t: @cil_type ref); + +// CIL type parameter constraints + +cil_typeparam_covariant(int tp: @cil_typeparameter ref); +cil_typeparam_contravariant(int tp: @cil_typeparameter ref); +cil_typeparam_class(int tp: @cil_typeparameter ref); +cil_typeparam_struct(int tp: @cil_typeparameter ref); +cil_typeparam_new(int tp: @cil_typeparameter ref); +cil_typeparam_constraint(int tp: @cil_typeparameter ref, int supertype: @cil_type ref); + +// CIL attributes + +cil_attribute( + unique int attributeid: @cil_attribute, + int element: @cil_declaration ref, + int constructor: @cil_method ref); + +#keyset[attribute_id, param] +cil_attribute_named_argument( + int attribute_id: @cil_attribute ref, + string param: string ref, + string value: string ref); + +#keyset[attribute_id, index] +cil_attribute_positional_argument( + int attribute_id: @cil_attribute ref, + int index: int ref, + string value: string ref); + + +// Common .Net data model covering both C# and CIL + +// Common elements +@dotnet_element = @element | @cil_element; +@dotnet_named_element = @named_element | @cil_named_element; +@dotnet_callable = @callable | @cil_method; +@dotnet_variable = @variable | @cil_variable; +@dotnet_field = @field | @cil_field; +@dotnet_parameter = @parameter | @cil_parameter; +@dotnet_declaration = @declaration | @cil_declaration; +@dotnet_member = @member | @cil_member; +@dotnet_event = @event | @cil_event; +@dotnet_property = @property | @cil_property | @indexer; + +// Common types +@dotnet_type = @type | @cil_type; +@dotnet_call = @call | @cil_call_any; +@dotnet_throw = @throw_element | @cil_throw_any; +@dotnet_valueorreftype = @cil_valueorreftype | @value_or_ref_type | @cil_array_type | @void_type; +@dotnet_typeparameter = @type_parameter | @cil_typeparameter; +@dotnet_array_type = @array_type | @cil_array_type; +@dotnet_pointer_type = @pointer_type | @cil_pointer_type; +@dotnet_type_parameter = @type_parameter | @cil_typeparameter; +@dotnet_generic = @dotnet_valueorreftype | @dotnet_callable; + +// Attributes +@dotnet_attribute = @attribute | @cil_attribute; + +// Expressions +@dotnet_expr = @expr | @cil_expr; + +// Literals +@dotnet_literal = @literal_expr | @cil_literal; +@dotnet_string_literal = @string_literal_expr | @cil_ldstr; +@dotnet_int_literal = @integer_literal_expr | @cil_ldc_i; +@dotnet_float_literal = @float_literal_expr | @cil_ldc_r; +@dotnet_null_literal = @null_literal_expr | @cil_ldnull; + +@metadata_entity = @cil_method | @cil_type | @cil_field | @cil_property | @field | @property | + @callable | @value_or_ref_type | @void_type; + +#keyset[entity, location] +metadata_handle(int entity : @metadata_entity ref, int location: @assembly ref, int handle: int ref) diff --git a/csharp/upgrades/e6442d16b7e3786d0918597c2c9fbd871ca06f77/upgrade.properties b/csharp/upgrades/e6442d16b7e3786d0918597c2c9fbd871ca06f77/upgrade.properties new file mode 100644 index 00000000000..dd386a913cd --- /dev/null +++ b/csharp/upgrades/e6442d16b7e3786d0918597c2c9fbd871ca06f77/upgrade.properties @@ -0,0 +1,2 @@ +description: Add 'not_pattern_expr' to the list of 'expr' types. +compatibility: backwards diff --git a/csharp/upgrades/eedef9359e1e4e1ebcf2a1dc9d2ae75d4ea4d160/old.dbscheme b/csharp/upgrades/eedef9359e1e4e1ebcf2a1dc9d2ae75d4ea4d160/old.dbscheme new file mode 100644 index 00000000000..eedef9359e1 --- /dev/null +++ b/csharp/upgrades/eedef9359e1e4e1ebcf2a1dc9d2ae75d4ea4d160/old.dbscheme @@ -0,0 +1,1890 @@ + +/** + * An invocation of the compiler. Note that more than one file may be + * compiled per invocation. For example, this command compiles three + * source files: + * + * csc f1.cs f2.cs f3.cs + * + * The `id` simply identifies the invocation, while `cwd` is the working + * directory from which the compiler was invoked. + */ +compilations( + unique int id : @compilation, + string cwd : string ref +); + +/** + * The arguments that were passed to the extractor for a compiler + * invocation. If `id` is for the compiler invocation + * + * csc f1.cs f2.cs f3.cs + * + * then typically there will be rows for + * + * num | arg + * --- | --- + * 0 | --compiler + * 1 | *path to compiler* + * 2 | --cil + * 3 | f1.cs + * 4 | f2.cs + * 5 | f3.cs + */ +#keyset[id, num] +compilation_args( + int id : @compilation ref, + int num : int ref, + string arg : string ref +); + +/** + * The source files that are compiled by a compiler invocation. + * If `id` is for the compiler invocation + * + * csc f1.cs f2.cs f3.cs + * + * then there will be rows for + * + * num | arg + * --- | --- + * 0 | f1.cs + * 1 | f2.cs + * 2 | f3.cs + */ +#keyset[id, num] +compilation_compiling_files( + int id : @compilation ref, + int num : int ref, + int file : @file ref +); + +/** + * The references used by a compiler invocation. + * If `id` is for the compiler invocation + * + * csc f1.cs f2.cs f3.cs /r:ref1.dll /r:ref2.dll /r:ref3.dll + * + * then there will be rows for + * + * num | arg + * --- | --- + * 0 | ref1.dll + * 1 | ref2.dll + * 2 | ref3.dll + */ +#keyset[id, num] +compilation_referencing_files( + int id : @compilation ref, + int num : int ref, + int file : @file ref +); + +/** + * The time taken by the extractor for a compiler invocation. + * + * For each file `num`, there will be rows for + * + * kind | seconds + * ---- | --- + * 1 | CPU seconds used by the extractor frontend + * 2 | Elapsed seconds during the extractor frontend + * 3 | CPU seconds used by the extractor backend + * 4 | Elapsed seconds during the extractor backend + */ +#keyset[id, num, kind] +compilation_time( + int id : @compilation ref, + int num : int ref, + /* kind: + 1 = frontend_cpu_seconds + 2 = frontend_elapsed_seconds + 3 = extractor_cpu_seconds + 4 = extractor_elapsed_seconds + */ + int kind : int ref, + float seconds : float ref +); + +/** + * An error or warning generated by the extractor. + * The diagnostic message `diagnostic` was generated during compiler + * invocation `compilation`, and is the `file_number_diagnostic_number`th + * message generated while extracting the `file_number`th file of that + * invocation. + */ +#keyset[compilation, file_number, file_number_diagnostic_number] +diagnostic_for( + unique int diagnostic : @diagnostic ref, + int compilation : @compilation ref, + int file_number : int ref, + int file_number_diagnostic_number : int ref +); + +diagnostics( + unique int id: @diagnostic, + int severity: int ref, + string error_tag: string ref, + string error_message: string ref, + string full_error_message: string ref, + int location: @location_default ref +); + +extractor_messages( + unique int id: @extractor_message, + int severity: int ref, + string origin : string ref, + string text : string ref, + string entity : string ref, + int location: @location_default ref, + string stack_trace : string ref +); + +/** + * If extraction was successful, then `cpu_seconds` and + * `elapsed_seconds` are the CPU time and elapsed time (respectively) + * that extraction took for compiler invocation `id`. + */ +compilation_finished( + unique int id : @compilation ref, + float cpu_seconds : float ref, + float elapsed_seconds : float ref +); + +/* + * External artifacts + */ + +externalDefects( + unique int id: @externalDefect, + string queryPath: string ref, + int location: @location ref, + string message: string ref, + float severity: float ref); + +externalMetrics( + unique int id: @externalMetric, + string queryPath: string ref, + int location: @location ref, + float value: float ref); + +externalData( + int id: @externalDataElement, + string path: string ref, + int column: int ref, + string value: string ref); + +snapshotDate( + unique date snapshotDate: date ref); + +sourceLocationPrefix( + string prefix: string ref); + +/* + * Duplicate code + */ + +duplicateCode( + unique int id: @duplication, + string relativePath: string ref, + int equivClass: int ref); + +similarCode( + unique int id: @similarity, + string relativePath: string ref, + int equivClass: int ref); + +@duplication_or_similarity = @duplication | @similarity + +tokens( + int id: @duplication_or_similarity ref, + int offset: int ref, + int beginLine: int ref, + int beginColumn: int ref, + int endLine: int ref, + int endColumn: int ref); + +/* + * C# dbscheme + */ + +/** ELEMENTS **/ + +@element = @declaration | @stmt | @expr | @modifier | @attribute | @namespace_declaration + | @using_directive | @type_parameter_constraints | @external_element + | @xmllocatable | @asp_element | @namespace; + +@declaration = @callable | @generic | @assignable | @namespace; + +@named_element = @namespace | @declaration; + +@declaration_with_accessors = @property | @indexer | @event; + +@assignable = @variable | @assignable_with_accessors | @event; + +@assignable_with_accessors = @property | @indexer; + +@external_element = @externalMetric | @externalDefect | @externalDataElement; + +@attributable = @assembly | @field | @parameter | @operator | @method | @constructor + | @destructor | @callable_accessor | @value_or_ref_type | @declaration_with_accessors + | @local_function; + +/** LOCATIONS, ASEMMBLIES, MODULES, FILES and FOLDERS **/ + +@location = @location_default | @assembly; + +locations_default( + unique int id: @location_default, + int file: @file ref, + int beginLine: int ref, + int beginColumn: int ref, + int endLine: int ref, + int endColumn: int ref); + +@sourceline = @file | @callable | @xmllocatable; + +numlines( + int element_id: @sourceline ref, + int num_lines: int ref, + int num_code: int ref, + int num_comment: int ref); + +assemblies( + unique int id: @assembly, + int file: @file ref, + string fullname: string ref, + string name: string ref, + string version: string ref); + +/* + fromSource(0) = unknown, + fromSource(1) = from source, + fromSource(2) = from library +*/ +files( + unique int id: @file, + string name: string ref, + string simple: string ref, + string ext: string ref, + int fromSource: int ref); + +folders( + unique int id: @folder, + string name: string ref, + string simple: string ref); + +@container = @folder | @file ; + +containerparent( + int parent: @container ref, + unique int child: @container ref); + +file_extraction_mode( + unique int file: @file ref, + int mode: int ref + /* 0 = normal, 1 = standalone extractor */ + ); + +/** NAMESPACES **/ + +@type_container = @namespace | @type; + +namespaces( + unique int id: @namespace, + string name: string ref); + +namespace_declarations( + unique int id: @namespace_declaration, + int namespace_id: @namespace ref); + +namespace_declaration_location( + unique int id: @namespace_declaration ref, + int loc: @location ref); + +parent_namespace( + unique int child_id: @type_container ref, + int namespace_id: @namespace ref); + +@declaration_or_directive = @namespace_declaration | @type | @using_directive; + +parent_namespace_declaration( + int child_id: @declaration_or_directive ref, // cannot be unique because of partial classes + int namespace_id: @namespace_declaration ref); + +@using_directive = @using_namespace_directive | @using_static_directive; + +using_namespace_directives( + unique int id: @using_namespace_directive, + int namespace_id: @namespace ref); + +using_static_directives( + unique int id: @using_static_directive, + int type_id: @type_or_ref ref); + +using_directive_location( + unique int id: @using_directive ref, + int loc: @location ref); + +/** TYPES **/ + +types( + unique int id: @type, + int kind: int ref, + string name: string ref); + +case @type.kind of + 1 = @bool_type +| 2 = @char_type +| 3 = @decimal_type +| 4 = @sbyte_type +| 5 = @short_type +| 6 = @int_type +| 7 = @long_type +| 8 = @byte_type +| 9 = @ushort_type +| 10 = @uint_type +| 11 = @ulong_type +| 12 = @float_type +| 13 = @double_type +| 14 = @enum_type +| 15 = @struct_type +| 17 = @class_type +| 19 = @interface_type +| 20 = @delegate_type +| 21 = @null_type +| 22 = @type_parameter +| 23 = @pointer_type +| 24 = @nullable_type +| 25 = @array_type +| 26 = @void_type +| 27 = @int_ptr_type +| 28 = @uint_ptr_type +| 29 = @dynamic_type +| 30 = @arglist_type +| 31 = @unknown_type +| 32 = @tuple_type + ; + +@simple_type = @bool_type | @char_type | @integral_type | @floating_point_type | @decimal_type; +@integral_type = @signed_integral_type | @unsigned_integral_type; +@signed_integral_type = @sbyte_type | @short_type | @int_type | @long_type; +@unsigned_integral_type = @byte_type | @ushort_type | @uint_type | @ulong_type; +@floating_point_type = @float_type | @double_type; +@value_type = @simple_type | @enum_type | @struct_type | @nullable_type | @int_ptr_type + | @uint_ptr_type | @tuple_type; +@ref_type = @class_type | @interface_type | @array_type | @delegate_type | @null_type + | @dynamic_type; +@value_or_ref_type = @value_type | @ref_type; + +typerefs( + unique int id: @typeref, + string name: string ref); + +typeref_type( + int id: @typeref ref, + unique int typeId: @type ref); + +@type_or_ref = @type | @typeref; + +array_element_type( + unique int array: @array_type ref, + int dimension: int ref, + int rank: int ref, + int element: @type_or_ref ref); + +nullable_underlying_type( + unique int nullable: @nullable_type ref, + int underlying: @type_or_ref ref); + +pointer_referent_type( + unique int pointer: @pointer_type ref, + int referent: @type_or_ref ref); + +enum_underlying_type( + unique int enum_id: @enum_type ref, + int underlying_type_id: @type_or_ref ref); + +delegate_return_type( + unique int delegate_id: @delegate_type ref, + int return_type_id: @type_or_ref ref); + +extend( + unique int sub: @type ref, + int super: @type_or_ref ref); + +@interface_or_ref = @interface_type | @typeref; + +implement( + int sub: @type ref, + int super: @type_or_ref ref); + +type_location( + int id: @type ref, + int loc: @location ref); + +tuple_underlying_type( + unique int tuple: @tuple_type ref, + int struct: @type_or_ref ref); + +#keyset[tuple, index] +tuple_element( + int tuple: @tuple_type ref, + int index: int ref, + unique int field: @field ref); + +attributes( + unique int id: @attribute, + int type_id: @type_or_ref ref, + int target: @attributable ref); + +attribute_location( + int id: @attribute ref, + int loc: @location ref); + +@type_mention_parent = @element | @type_mention; + +type_mention( + unique int id: @type_mention, + int type_id: @type_or_ref ref, + int parent: @type_mention_parent ref); + +type_mention_location( + unique int id: @type_mention ref, + int loc: @location ref); + +@has_type_annotation = @assignable | @type_parameter | @callable | @expr | @delegate_type | @generic; + +/** + * A direct annotation on an entity, for example `string? x;`. + * + * Annotations: + * 2 = reftype is not annotated "!" + * 3 = reftype is annotated "?" + * 4 = readonly ref type / in parameter + * 5 = ref type parameter, return or local variable + * 6 = out parameter + * + * Note that the annotation depends on the element it annotates. + * @assignable: The annotation is on the type of the assignable, for example the variable type. + * @type_parameter: The annotation is on the reftype constraint + * @callable: The annotation is on the return type + * @array_type: The annotation is on the element type + */ +type_annotation(int id: @has_type_annotation ref, int annotation: int ref); + +nullability(unique int nullability: @nullability, int kind: int ref); + +case @nullability.kind of + 0 = @oblivious +| 1 = @not_annotated +| 2 = @annotated +; + +#keyset[parent, index] +nullability_parent(int nullability: @nullability ref, int index: int ref, int parent: @nullability ref) + +type_nullability(int id: @has_type_annotation ref, int nullability: @nullability ref); + +/** + * The nullable flow state of an expression, as determined by Roslyn. + * 0 = none (default, not populated) + * 1 = not null + * 2 = maybe null + */ +expr_flowstate(unique int id: @expr ref, int state: int ref); + +/** GENERICS **/ + +@generic = @type | @method | @local_function; + +type_parameters( + unique int id: @type_parameter ref, + int index: int ref, + int generic_id: @generic ref, + int variance: int ref /* none = 0, out = 1, in = 2 */); + +#keyset[constructed_id, index] +type_arguments( + int id: @type_or_ref ref, + int index: int ref, + int constructed_id: @generic_or_ref ref); + +@generic_or_ref = @generic | @typeref; + +constructed_generic( + unique int constructed: @generic ref, + int generic: @generic_or_ref ref); + +type_parameter_constraints( + unique int id: @type_parameter_constraints, + int param_id: @type_parameter ref); + +type_parameter_constraints_location( + int id: @type_parameter_constraints ref, + int loc: @location ref); + +general_type_parameter_constraints( + int id: @type_parameter_constraints ref, + int kind: int ref /* class = 1, struct = 2, new = 3 */); + +specific_type_parameter_constraints( + int id: @type_parameter_constraints ref, + int base_id: @type_or_ref ref); + +specific_type_parameter_nullability( + int id: @type_parameter_constraints ref, + int base_id: @type_or_ref ref, + int nullability: @nullability ref); + +/** MODIFIERS */ + +@modifiable = @modifiable_direct | @event_accessor; + +@modifiable_direct = @member | @accessor | @local_function | @anonymous_function_expr; + +modifiers( + unique int id: @modifier, + string name: string ref); + +has_modifiers( + int id: @modifiable_direct ref, + int mod_id: @modifier ref); + +compiler_generated(unique int id: @modifiable_direct ref); + +/** MEMBERS **/ + +@member = @method | @constructor | @destructor | @field | @property | @event | @operator | @indexer | @type; + +@named_exprorstmt = @goto_stmt | @labeled_stmt | @expr; + +@virtualizable = @method | @property | @indexer | @event; + +exprorstmt_name( + unique int parent_id: @named_exprorstmt ref, + string name: string ref); + +nested_types( + unique int id: @type ref, + int declaring_type_id: @type ref, + int unbound_id: @type ref); + +properties( + unique int id: @property, + string name: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @property ref); + +property_location( + int id: @property ref, + int loc: @location ref); + +indexers( + unique int id: @indexer, + string name: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @indexer ref); + +indexer_location( + int id: @indexer ref, + int loc: @location ref); + +accessors( + unique int id: @accessor, + int kind: int ref, + string name: string ref, + int declaring_member_id: @member ref, + int unbound_id: @accessor ref); + +case @accessor.kind of + 1 = @getter +| 2 = @setter + ; + +accessor_location( + int id: @accessor ref, + int loc: @location ref); + +events( + unique int id: @event, + string name: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @event ref); + +event_location( + int id: @event ref, + int loc: @location ref); + +event_accessors( + unique int id: @event_accessor, + int kind: int ref, + string name: string ref, + int declaring_event_id: @event ref, + int unbound_id: @event_accessor ref); + +case @event_accessor.kind of + 1 = @add_event_accessor +| 2 = @remove_event_accessor + ; + +event_accessor_location( + int id: @event_accessor ref, + int loc: @location ref); + +operators( + unique int id: @operator, + string name: string ref, + string symbol: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @operator ref); + +operator_location( + int id: @operator ref, + int loc: @location ref); + +constant_value( + int id: @variable ref, + string value: string ref); + +/** CALLABLES **/ + +@callable = @method | @constructor | @destructor | @operator | @callable_accessor | @anonymous_function_expr | @local_function; + +@callable_accessor = @accessor | @event_accessor; + +methods( + unique int id: @method, + string name: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @method ref); + +method_location( + int id: @method ref, + int loc: @location ref); + +constructors( + unique int id: @constructor, + string name: string ref, + int declaring_type_id: @type ref, + int unbound_id: @constructor ref); + +constructor_location( + int id: @constructor ref, + int loc: @location ref); + +destructors( + unique int id: @destructor, + string name: string ref, + int declaring_type_id: @type ref, + int unbound_id: @destructor ref); + +destructor_location( + int id: @destructor ref, + int loc: @location ref); + +overrides( + int id: @callable ref, + int base_id: @callable ref); + +explicitly_implements( + int id: @member ref, + int interface_id: @interface_or_ref ref); + +local_functions( + unique int id: @local_function, + string name: string ref, + int return_type: @type ref, + int unbound_id: @local_function ref); + +local_function_stmts( + unique int fn: @local_function_stmt ref, + int stmt: @local_function ref); + +/** VARIABLES **/ + +@variable = @local_scope_variable | @field; + +@local_scope_variable = @local_variable | @parameter; + +fields( + unique int id: @field, + int kind: int ref, + string name: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @field ref); + +case @field.kind of + 1 = @addressable_field +| 2 = @constant + ; + +field_location( + int id: @field ref, + int loc: @location ref); + +localvars( + unique int id: @local_variable, + int kind: int ref, + string name: string ref, + int implicitly_typed: int ref /* 0 = no, 1 = yes */, + int type_id: @type_or_ref ref, + int parent_id: @local_var_decl_expr ref); + +case @local_variable.kind of + 1 = @addressable_local_variable +| 2 = @local_constant +| 3 = @local_variable_ref + ; + +localvar_location( + unique int id: @local_variable ref, + int loc: @location ref); + +@parameterizable = @callable | @delegate_type | @indexer; + +#keyset[name, parent_id] +#keyset[index, parent_id] +params( + unique int id: @parameter, + string name: string ref, + int type_id: @type_or_ref ref, + int index: int ref, + int mode: int ref, /* value = 0, ref = 1, out = 2, array = 3, this = 4 */ + int parent_id: @parameterizable ref, + int unbound_id: @parameter ref); + +param_location( + int id: @parameter ref, + int loc: @location ref); + +/** STATEMENTS **/ + +@exprorstmt_parent = @control_flow_element | @top_level_exprorstmt_parent; + +statements( + unique int id: @stmt, + int kind: int ref); + +#keyset[index, parent] +stmt_parent( + unique int stmt: @stmt ref, + int index: int ref, + int parent: @control_flow_element ref); + +@top_level_stmt_parent = @callable; + +// [index, parent] is not a keyset because the same parent may be compiled multiple times +stmt_parent_top_level( + unique int stmt: @stmt ref, + int index: int ref, + int parent: @top_level_stmt_parent ref); + +case @stmt.kind of + 1 = @block_stmt +| 2 = @expr_stmt +| 3 = @if_stmt +| 4 = @switch_stmt +| 5 = @while_stmt +| 6 = @do_stmt +| 7 = @for_stmt +| 8 = @foreach_stmt +| 9 = @break_stmt +| 10 = @continue_stmt +| 11 = @goto_stmt +| 12 = @goto_case_stmt +| 13 = @goto_default_stmt +| 14 = @throw_stmt +| 15 = @return_stmt +| 16 = @yield_stmt +| 17 = @try_stmt +| 18 = @checked_stmt +| 19 = @unchecked_stmt +| 20 = @lock_stmt +| 21 = @using_block_stmt +| 22 = @var_decl_stmt +| 23 = @const_decl_stmt +| 24 = @empty_stmt +| 25 = @unsafe_stmt +| 26 = @fixed_stmt +| 27 = @label_stmt +| 28 = @catch +| 29 = @case_stmt +| 30 = @local_function_stmt +| 31 = @using_decl_stmt + ; + +@using_stmt = @using_block_stmt | @using_decl_stmt; + +@labeled_stmt = @label_stmt | @case; + +@decl_stmt = @var_decl_stmt | @const_decl_stmt | @using_decl_stmt; + +@cond_stmt = @if_stmt | @switch_stmt; + +@loop_stmt = @while_stmt | @do_stmt | @for_stmt | @foreach_stmt; + +@jump_stmt = @break_stmt | @goto_any_stmt | @continue_stmt | @throw_stmt | @return_stmt + | @yield_stmt; + +@goto_any_stmt = @goto_default_stmt | @goto_case_stmt | @goto_stmt; + + +stmt_location( + unique int id: @stmt ref, + int loc: @location ref); + +catch_type( + unique int catch_id: @catch ref, + int type_id: @type_or_ref ref, + int kind: int ref /* explicit = 1, implicit = 2 */); + +/** EXPRESSIONS **/ + +expressions( + unique int id: @expr, + int kind: int ref, + int type_id: @type_or_ref ref); + +#keyset[index, parent] +expr_parent( + unique int expr: @expr ref, + int index: int ref, + int parent: @control_flow_element ref); + +@top_level_expr_parent = @attribute | @field | @property | @indexer | @parameter; + +@top_level_exprorstmt_parent = @top_level_expr_parent | @top_level_stmt_parent; + +// [index, parent] is not a keyset because the same parent may be compiled multiple times +expr_parent_top_level( + unique int expr: @expr ref, + int index: int ref, + int parent: @top_level_exprorstmt_parent ref); + +case @expr.kind of +/* literal */ + 1 = @bool_literal_expr +| 2 = @char_literal_expr +| 3 = @decimal_literal_expr +| 4 = @int_literal_expr +| 5 = @long_literal_expr +| 6 = @uint_literal_expr +| 7 = @ulong_literal_expr +| 8 = @float_literal_expr +| 9 = @double_literal_expr +| 10 = @string_literal_expr +| 11 = @null_literal_expr +/* primary & unary */ +| 12 = @this_access_expr +| 13 = @base_access_expr +| 14 = @local_variable_access_expr +| 15 = @parameter_access_expr +| 16 = @field_access_expr +| 17 = @property_access_expr +| 18 = @method_access_expr +| 19 = @event_access_expr +| 20 = @indexer_access_expr +| 21 = @array_access_expr +| 22 = @type_access_expr +| 23 = @typeof_expr +| 24 = @method_invocation_expr +| 25 = @delegate_invocation_expr +| 26 = @operator_invocation_expr +| 27 = @cast_expr +| 28 = @object_creation_expr +| 29 = @explicit_delegate_creation_expr +| 30 = @implicit_delegate_creation_expr +| 31 = @array_creation_expr +| 32 = @default_expr +| 33 = @plus_expr +| 34 = @minus_expr +| 35 = @bit_not_expr +| 36 = @log_not_expr +| 37 = @post_incr_expr +| 38 = @post_decr_expr +| 39 = @pre_incr_expr +| 40 = @pre_decr_expr +/* multiplicative */ +| 41 = @mul_expr +| 42 = @div_expr +| 43 = @rem_expr +/* additive */ +| 44 = @add_expr +| 45 = @sub_expr +/* shift */ +| 46 = @lshift_expr +| 47 = @rshift_expr +/* relational */ +| 48 = @lt_expr +| 49 = @gt_expr +| 50 = @le_expr +| 51 = @ge_expr +/* equality */ +| 52 = @eq_expr +| 53 = @ne_expr +/* logical */ +| 54 = @bit_and_expr +| 55 = @bit_xor_expr +| 56 = @bit_or_expr +| 57 = @log_and_expr +| 58 = @log_or_expr +/* type testing */ +| 59 = @is_expr +| 60 = @as_expr +/* null coalescing */ +| 61 = @null_coalescing_expr +/* conditional */ +| 62 = @conditional_expr +/* assignment */ +| 63 = @simple_assign_expr +| 64 = @assign_add_expr +| 65 = @assign_sub_expr +| 66 = @assign_mul_expr +| 67 = @assign_div_expr +| 68 = @assign_rem_expr +| 69 = @assign_and_expr +| 70 = @assign_xor_expr +| 71 = @assign_or_expr +| 72 = @assign_lshift_expr +| 73 = @assign_rshift_expr +/* more */ +| 74 = @object_init_expr +| 75 = @collection_init_expr +| 76 = @array_init_expr +| 77 = @checked_expr +| 78 = @unchecked_expr +| 79 = @constructor_init_expr +| 80 = @add_event_expr +| 81 = @remove_event_expr +| 82 = @par_expr +| 83 = @local_var_decl_expr +| 84 = @lambda_expr +| 85 = @anonymous_method_expr +| 86 = @namespace_expr +/* dynamic */ +| 92 = @dynamic_element_access_expr +| 93 = @dynamic_member_access_expr +/* unsafe */ +| 100 = @pointer_indirection_expr +| 101 = @address_of_expr +| 102 = @sizeof_expr +/* async */ +| 103 = @await_expr +/* C# 6.0 */ +| 104 = @nameof_expr +| 105 = @interpolated_string_expr +| 106 = @unknown_expr +/* C# 7.0 */ +| 107 = @throw_expr +| 108 = @tuple_expr +| 109 = @local_function_invocation_expr +| 110 = @ref_expr +| 111 = @discard_expr +/* C# 8.0 */ +| 112 = @range_expr +| 113 = @index_expr +| 114 = @switch_expr +| 115 = @recursive_pattern_expr +| 116 = @property_pattern_expr +| 117 = @positional_pattern_expr +| 118 = @switch_case_expr +| 119 = @assign_coalesce_expr +| 120 = @suppress_nullable_warning_expr +| 121 = @namespace_access_expr +; + +@switch = @switch_stmt | @switch_expr; +@case = @case_stmt | @switch_case_expr; +@pattern_match = @case | @is_expr; + +@integer_literal_expr = @int_literal_expr | @long_literal_expr | @uint_literal_expr | @ulong_literal_expr; +@real_literal_expr = @float_literal_expr | @double_literal_expr | @decimal_literal_expr; +@literal_expr = @bool_literal_expr | @char_literal_expr | @integer_literal_expr | @real_literal_expr + | @string_literal_expr | @null_literal_expr; + +@assign_expr = @simple_assign_expr | @assign_op_expr | @local_var_decl_expr; +@assign_op_expr = @assign_arith_expr | @assign_bitwise_expr | @assign_event_expr | @assign_coalesce_expr; +@assign_event_expr = @add_event_expr | @remove_event_expr; + +@assign_arith_expr = @assign_add_expr | @assign_sub_expr | @assign_mul_expr | @assign_div_expr + | @assign_rem_expr +@assign_bitwise_expr = @assign_and_expr | @assign_or_expr | @assign_xor_expr + | @assign_lshift_expr | @assign_rshift_expr; + +@member_access_expr = @field_access_expr | @property_access_expr | @indexer_access_expr | @event_access_expr + | @method_access_expr | @type_access_expr | @dynamic_member_access_expr; +@access_expr = @member_access_expr | @this_access_expr | @base_access_expr | @assignable_access_expr | @namespace_access_expr; +@element_access_expr = @indexer_access_expr | @array_access_expr | @dynamic_element_access_expr; + +@local_variable_access = @local_variable_access_expr | @local_var_decl_expr; +@local_scope_variable_access_expr = @parameter_access_expr | @local_variable_access; +@variable_access_expr = @local_scope_variable_access_expr | @field_access_expr; + +@assignable_access_expr = @variable_access_expr | @property_access_expr | @element_access_expr + | @event_access_expr | @dynamic_member_access_expr; + +@objectorcollection_init_expr = @object_init_expr | @collection_init_expr; + +@delegate_creation_expr = @explicit_delegate_creation_expr | @implicit_delegate_creation_expr; + +@bin_arith_op_expr = @mul_expr | @div_expr | @rem_expr | @add_expr | @sub_expr; +@incr_op_expr = @pre_incr_expr | @post_incr_expr; +@decr_op_expr = @pre_decr_expr | @post_decr_expr; +@mut_op_expr = @incr_op_expr | @decr_op_expr; +@un_arith_op_expr = @plus_expr | @minus_expr | @mut_op_expr; +@arith_op_expr = @bin_arith_op_expr | @un_arith_op_expr; + +@ternary_log_op_expr = @conditional_expr; +@bin_log_op_expr = @log_and_expr | @log_or_expr | @null_coalescing_expr; +@un_log_op_expr = @log_not_expr; +@log_expr = @un_log_op_expr | @bin_log_op_expr | @ternary_log_op_expr; + +@bin_bit_op_expr = @bit_and_expr | @bit_or_expr | @bit_xor_expr | @lshift_expr + | @rshift_expr; +@un_bit_op_expr = @bit_not_expr; +@bit_expr = @un_bit_op_expr | @bin_bit_op_expr; + +@equality_op_expr = @eq_expr | @ne_expr; +@rel_op_expr = @gt_expr | @lt_expr| @ge_expr | @le_expr; +@comp_expr = @equality_op_expr | @rel_op_expr; + +@op_expr = @assign_expr | @un_op | @bin_op | @ternary_op; + +@ternary_op = @ternary_log_op_expr; +@bin_op = @bin_arith_op_expr | @bin_log_op_expr | @bin_bit_op_expr | @comp_expr; +@un_op = @un_arith_op_expr | @un_log_op_expr | @un_bit_op_expr | @sizeof_expr + | @pointer_indirection_expr | @address_of_expr; + +@anonymous_function_expr = @lambda_expr | @anonymous_method_expr; + +@call = @method_invocation_expr | @constructor_init_expr | @operator_invocation_expr + | @delegate_invocation_expr | @object_creation_expr | @call_access_expr + | @local_function_invocation_expr; + +@call_access_expr = @property_access_expr | @event_access_expr | @indexer_access_expr; + +@late_bindable_expr = @dynamic_element_access_expr | @dynamic_member_access_expr + | @object_creation_expr | @method_invocation_expr | @operator_invocation_expr; + +@throw_element = @throw_expr | @throw_stmt; + +implicitly_typed_array_creation( + unique int id: @array_creation_expr ref); + +explicitly_sized_array_creation( + unique int id: @array_creation_expr ref); + +stackalloc_array_creation( + unique int id: @array_creation_expr ref); + +mutator_invocation_mode( + unique int id: @operator_invocation_expr ref, + int mode: int ref /* prefix = 1, postfix = 2*/); + +expr_compiler_generated( + unique int id: @expr ref); + +expr_value( + unique int id: @expr ref, + string value: string ref); + +expr_call( + unique int caller_id: @expr ref, + int target_id: @callable ref); + +expr_access( + unique int accesser_id: @access_expr ref, + int target_id: @accessible ref); + +@accessible = @method | @assignable | @local_function | @namespace; + +expr_location( + unique int id: @expr ref, + int loc: @location ref); + +dynamic_member_name( + unique int id: @late_bindable_expr ref, + string name: string ref); + +@qualifiable_expr = @member_access_expr + | @method_invocation_expr + | @element_access_expr; + +conditional_access( + unique int id: @qualifiable_expr ref); + +expr_argument( + unique int id: @expr ref, + int mode: int ref); + /* mode is the same as params: value = 0, ref = 1, out = 2 */ + +expr_argument_name( + unique int id: @expr ref, + string name: string ref); + +/** CONTROL/DATA FLOW **/ + +@control_flow_element = @stmt | @expr; + +/* XML Files */ + +xmlEncoding ( + unique int id: @file ref, + string encoding: string ref); + +xmlDTDs( + unique int id: @xmldtd, + string root: string ref, + string publicId: string ref, + string systemId: string ref, + int fileid: @file ref); + +xmlElements( + unique int id: @xmlelement, + string name: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int fileid: @file ref); + +xmlAttrs( + unique int id: @xmlattribute, + int elementid: @xmlelement ref, + string name: string ref, + string value: string ref, + int idx: int ref, + int fileid: @file ref); + +xmlNs( + int id: @xmlnamespace, + string prefixName: string ref, + string URI: string ref, + int fileid: @file ref); + +xmlHasNs( + int elementId: @xmlnamespaceable ref, + int nsId: @xmlnamespace ref, + int fileid: @file ref); + +xmlComments( + unique int id: @xmlcomment, + string text: string ref, + int parentid: @xmlparent ref, + int fileid: @file ref); + +xmlChars( + unique int id: @xmlcharacters, + string text: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int isCDATA: int ref, + int fileid: @file ref); + +@xmlparent = @file | @xmlelement; +@xmlnamespaceable = @xmlelement | @xmlattribute; + +xmllocations( + int xmlElement: @xmllocatable ref, + int location: @location_default ref); + +@xmllocatable = @xmlcharacters | @xmlelement | @xmlcomment | @xmlattribute | @xmldtd | @file | @xmlnamespace; + +/* Comments */ + +commentline( + unique int id: @commentline, + int kind: int ref, + string text: string ref, + string rawtext: string ref); + +case @commentline.kind of + 0 = @singlelinecomment +| 1 = @xmldoccomment +| 2 = @multilinecomment; + +commentline_location( + unique int id: @commentline ref, + int loc: @location ref); + +commentblock( + unique int id : @commentblock); + +commentblock_location( + unique int id: @commentblock ref, + int loc: @location ref); + +commentblock_binding( + int id: @commentblock ref, + int entity: @element ref, + int bindtype: int ref); /* 0: Parent, 1: Best, 2: Before, 3: After */ + +commentblock_child( + int id: @commentblock ref, + int commentline: @commentline ref, + int index: int ref); + +/* ASP.NET */ + +case @asp_element.kind of + 0=@asp_close_tag +| 1=@asp_code +| 2=@asp_comment +| 3=@asp_data_binding +| 4=@asp_directive +| 5=@asp_open_tag +| 6=@asp_quoted_string +| 7=@asp_text +| 8=@asp_xml_directive; + +@asp_attribute = @asp_code | @asp_data_binding | @asp_quoted_string; + +asp_elements( + unique int id: @asp_element, + int kind: int ref, + int loc: @location ref); + +asp_comment_server(unique int comment: @asp_comment ref); +asp_code_inline(unique int code: @asp_code ref); +asp_directive_attribute( + int directive: @asp_directive ref, + int index: int ref, + string name: string ref, + int value: @asp_quoted_string ref); +asp_directive_name( + unique int directive: @asp_directive ref, + string name: string ref); +asp_element_body( + unique int element: @asp_element ref, + string body: string ref); +asp_tag_attribute( + int tag: @asp_open_tag ref, + int index: int ref, + string name: string ref, + int attribute: @asp_attribute ref); +asp_tag_name( + unique int tag: @asp_open_tag ref, + string name: string ref); +asp_tag_isempty(int tag: @asp_open_tag ref); + +/* Common Intermediate Language - CIL */ + +case @cil_instruction.opcode of + 0 = @cil_nop +| 1 = @cil_break +| 2 = @cil_ldarg_0 +| 3 = @cil_ldarg_1 +| 4 = @cil_ldarg_2 +| 5 = @cil_ldarg_3 +| 6 = @cil_ldloc_0 +| 7 = @cil_ldloc_1 +| 8 = @cil_ldloc_2 +| 9 = @cil_ldloc_3 +| 10 = @cil_stloc_0 +| 11 = @cil_stloc_1 +| 12 = @cil_stloc_2 +| 13 = @cil_stloc_3 +| 14 = @cil_ldarg_s +| 15 = @cil_ldarga_s +| 16 = @cil_starg_s +| 17 = @cil_ldloc_s +| 18 = @cil_ldloca_s +| 19 = @cil_stloc_s +| 20 = @cil_ldnull +| 21 = @cil_ldc_i4_m1 +| 22 = @cil_ldc_i4_0 +| 23 = @cil_ldc_i4_1 +| 24 = @cil_ldc_i4_2 +| 25 = @cil_ldc_i4_3 +| 26 = @cil_ldc_i4_4 +| 27 = @cil_ldc_i4_5 +| 28 = @cil_ldc_i4_6 +| 29 = @cil_ldc_i4_7 +| 30 = @cil_ldc_i4_8 +| 31 = @cil_ldc_i4_s +| 32 = @cil_ldc_i4 +| 33 = @cil_ldc_i8 +| 34 = @cil_ldc_r4 +| 35 = @cil_ldc_r8 +| 37 = @cil_dup +| 38 = @cil_pop +| 39 = @cil_jmp +| 40 = @cil_call +| 41 = @cil_calli +| 42 = @cil_ret +| 43 = @cil_br_s +| 44 = @cil_brfalse_s +| 45 = @cil_brtrue_s +| 46 = @cil_beq_s +| 47 = @cil_bge_s +| 48 = @cil_bgt_s +| 49 = @cil_ble_s +| 50 = @cil_blt_s +| 51 = @cil_bne_un_s +| 52 = @cil_bge_un_s +| 53 = @cil_bgt_un_s +| 54 = @cil_ble_un_s +| 55 = @cil_blt_un_s +| 56 = @cil_br +| 57 = @cil_brfalse +| 58 = @cil_brtrue +| 59 = @cil_beq +| 60 = @cil_bge +| 61 = @cil_bgt +| 62 = @cil_ble +| 63 = @cil_blt +| 64 = @cil_bne_un +| 65 = @cil_bge_un +| 66 = @cil_bgt_un +| 67 = @cil_ble_un +| 68 = @cil_blt_un +| 69 = @cil_switch +| 70 = @cil_ldind_i1 +| 71 = @cil_ldind_u1 +| 72 = @cil_ldind_i2 +| 73 = @cil_ldind_u2 +| 74 = @cil_ldind_i4 +| 75 = @cil_ldind_u4 +| 76 = @cil_ldind_i8 +| 77 = @cil_ldind_i +| 78 = @cil_ldind_r4 +| 79 = @cil_ldind_r8 +| 80 = @cil_ldind_ref +| 81 = @cil_stind_ref +| 82 = @cil_stind_i1 +| 83 = @cil_stind_i2 +| 84 = @cil_stind_i4 +| 85 = @cil_stind_i8 +| 86 = @cil_stind_r4 +| 87 = @cil_stind_r8 +| 88 = @cil_add +| 89 = @cil_sub +| 90 = @cil_mul +| 91 = @cil_div +| 92 = @cil_div_un +| 93 = @cil_rem +| 94 = @cil_rem_un +| 95 = @cil_and +| 96 = @cil_or +| 97 = @cil_xor +| 98 = @cil_shl +| 99 = @cil_shr +| 100 = @cil_shr_un +| 101 = @cil_neg +| 102 = @cil_not +| 103 = @cil_conv_i1 +| 104 = @cil_conv_i2 +| 105 = @cil_conv_i4 +| 106 = @cil_conv_i8 +| 107 = @cil_conv_r4 +| 108 = @cil_conv_r8 +| 109 = @cil_conv_u4 +| 110 = @cil_conv_u8 +| 111 = @cil_callvirt +| 112 = @cil_cpobj +| 113 = @cil_ldobj +| 114 = @cil_ldstr +| 115 = @cil_newobj +| 116 = @cil_castclass +| 117 = @cil_isinst +| 118 = @cil_conv_r_un +| 121 = @cil_unbox +| 122 = @cil_throw +| 123 = @cil_ldfld +| 124 = @cil_ldflda +| 125 = @cil_stfld +| 126 = @cil_ldsfld +| 127 = @cil_ldsflda +| 128 = @cil_stsfld +| 129 = @cil_stobj +| 130 = @cil_conv_ovf_i1_un +| 131 = @cil_conv_ovf_i2_un +| 132 = @cil_conv_ovf_i4_un +| 133 = @cil_conv_ovf_i8_un +| 134 = @cil_conv_ovf_u1_un +| 135 = @cil_conv_ovf_u2_un +| 136 = @cil_conv_ovf_u4_un +| 137 = @cil_conv_ovf_u8_un +| 138 = @cil_conv_ovf_i_un +| 139 = @cil_conv_ovf_u_un +| 140 = @cil_box +| 141 = @cil_newarr +| 142 = @cil_ldlen +| 143 = @cil_ldelema +| 144 = @cil_ldelem_i1 +| 145 = @cil_ldelem_u1 +| 146 = @cil_ldelem_i2 +| 147 = @cil_ldelem_u2 +| 148 = @cil_ldelem_i4 +| 149 = @cil_ldelem_u4 +| 150 = @cil_ldelem_i8 +| 151 = @cil_ldelem_i +| 152 = @cil_ldelem_r4 +| 153 = @cil_ldelem_r8 +| 154 = @cil_ldelem_ref +| 155 = @cil_stelem_i +| 156 = @cil_stelem_i1 +| 157 = @cil_stelem_i2 +| 158 = @cil_stelem_i4 +| 159 = @cil_stelem_i8 +| 160 = @cil_stelem_r4 +| 161 = @cil_stelem_r8 +| 162 = @cil_stelem_ref +| 163 = @cil_ldelem +| 164 = @cil_stelem +| 165 = @cil_unbox_any +| 179 = @cil_conv_ovf_i1 +| 180 = @cil_conv_ovf_u1 +| 181 = @cil_conv_ovf_i2 +| 182 = @cil_conv_ovf_u2 +| 183 = @cil_conv_ovf_i4 +| 184 = @cil_conv_ovf_u4 +| 185 = @cil_conv_ovf_i8 +| 186 = @cil_conv_ovf_u8 +| 194 = @cil_refanyval +| 195 = @cil_ckinfinite +| 198 = @cil_mkrefany +| 208 = @cil_ldtoken +| 209 = @cil_conv_u2 +| 210 = @cil_conv_u1 +| 211 = @cil_conv_i +| 212 = @cil_conv_ovf_i +| 213 = @cil_conv_ovf_u +| 214 = @cil_add_ovf +| 215 = @cil_add_ovf_un +| 216 = @cil_mul_ovf +| 217 = @cil_mul_ovf_un +| 218 = @cil_sub_ovf +| 219 = @cil_sub_ovf_un +| 220 = @cil_endfinally +| 221 = @cil_leave +| 222 = @cil_leave_s +| 223 = @cil_stind_i +| 224 = @cil_conv_u +| 65024 = @cil_arglist +| 65025 = @cil_ceq +| 65026 = @cil_cgt +| 65027 = @cil_cgt_un +| 65028 = @cil_clt +| 65029 = @cil_clt_un +| 65030 = @cil_ldftn +| 65031 = @cil_ldvirtftn +| 65033 = @cil_ldarg +| 65034 = @cil_ldarga +| 65035 = @cil_starg +| 65036 = @cil_ldloc +| 65037 = @cil_ldloca +| 65038 = @cil_stloc +| 65039 = @cil_localloc +| 65041 = @cil_endfilter +| 65042 = @cil_unaligned +| 65043 = @cil_volatile +| 65044 = @cil_tail +| 65045 = @cil_initobj +| 65046 = @cil_constrained +| 65047 = @cil_cpblk +| 65048 = @cil_initblk +| 65050 = @cil_rethrow +| 65052 = @cil_sizeof +| 65053 = @cil_refanytype +| 65054 = @cil_readonly +; + +// CIL ignored instructions + +@cil_ignore = @cil_nop | @cil_break | @cil_volatile | @cil_unaligned; + +// CIL local/parameter/field access + +@cil_ldarg_any = @cil_ldarg_0 | @cil_ldarg_1 | @cil_ldarg_2 | @cil_ldarg_3 | @cil_ldarg_s | @cil_ldarga_s | @cil_ldarg | @cil_ldarga; +@cil_starg_any = @cil_starg | @cil_starg_s; + +@cil_ldloc_any = @cil_ldloc_0 | @cil_ldloc_1 | @cil_ldloc_2 | @cil_ldloc_3 | @cil_ldloc_s | @cil_ldloca_s | @cil_ldloc | @cil_ldloca; +@cil_stloc_any = @cil_stloc_0 | @cil_stloc_1 | @cil_stloc_2 | @cil_stloc_3 | @cil_stloc_s | @cil_stloc; + +@cil_ldfld_any = @cil_ldfld | @cil_ldsfld | @cil_ldsflda | @cil_ldflda; +@cil_stfld_any = @cil_stfld | @cil_stsfld; + +@cil_local_access = @cil_stloc_any | @cil_ldloc_any; +@cil_arg_access = @cil_starg_any | @cil_ldarg_any; +@cil_read_access = @cil_ldloc_any | @cil_ldarg_any | @cil_ldfld_any; +@cil_write_access = @cil_stloc_any | @cil_starg_any | @cil_stfld_any; + +@cil_stack_access = @cil_local_access | @cil_arg_access; +@cil_field_access = @cil_ldfld_any | @cil_stfld_any; + +@cil_access = @cil_read_access | @cil_write_access; + +// CIL constant/literal instructions + +@cil_ldc_i = @cil_ldc_i4_any | @cil_ldc_i8; + +@cil_ldc_i4_any = @cil_ldc_i4_m1 | @cil_ldc_i4_0 | @cil_ldc_i4_1 | @cil_ldc_i4_2 | @cil_ldc_i4_3 | + @cil_ldc_i4_4 | @cil_ldc_i4_5 | @cil_ldc_i4_6 | @cil_ldc_i4_7 | @cil_ldc_i4_8 | @cil_ldc_i4_s | @cil_ldc_i4; + +@cil_ldc_r = @cil_ldc_r4 | @cil_ldc_r8; + +@cil_literal = @cil_ldnull | @cil_ldc_i | @cil_ldc_r | @cil_ldstr; + +// Control flow + +@cil_conditional_jump = @cil_binary_jump | @cil_unary_jump; +@cil_binary_jump = @cil_beq_s | @cil_bge_s | @cil_bgt_s | @cil_ble_s | @cil_blt_s | + @cil_bne_un_s | @cil_bge_un_s | @cil_bgt_un_s | @cil_ble_un_s | @cil_blt_un_s | + @cil_beq | @cil_bge | @cil_bgt | @cil_ble | @cil_blt | + @cil_bne_un | @cil_bge_un | @cil_bgt_un | @cil_ble_un | @cil_blt_un; +@cil_unary_jump = @cil_brfalse_s | @cil_brtrue_s | @cil_brfalse | @cil_brtrue | @cil_switch; +@cil_unconditional_jump = @cil_br | @cil_br_s | @cil_leave_any; +@cil_leave_any = @cil_leave | @cil_leave_s; +@cil_jump = @cil_unconditional_jump | @cil_conditional_jump; + +// CIL call instructions + +@cil_call_any = @cil_jmp | @cil_call | @cil_calli | @cil_tail | @cil_callvirt | @cil_newobj; + +// CIL expression instructions + +@cil_expr = @cil_literal | @cil_binary_expr | @cil_unary_expr | @cil_call_any | @cil_read_access | + @cil_newarr | @cil_ldtoken | @cil_sizeof | + @cil_ldftn | @cil_ldvirtftn | @cil_localloc | @cil_mkrefany | @cil_refanytype | @cil_arglist | @cil_dup; + +@cil_unary_expr = + @cil_conversion_operation | @cil_unary_arithmetic_operation | @cil_unary_bitwise_operation| + @cil_ldlen | @cil_isinst | @cil_box | @cil_ldobj | @cil_castclass | @cil_unbox_any | + @cil_ldind | @cil_unbox; + +@cil_conversion_operation = + @cil_conv_i1 | @cil_conv_i2 | @cil_conv_i4 | @cil_conv_i8 | + @cil_conv_u1 | @cil_conv_u2 | @cil_conv_u4 | @cil_conv_u8 | + @cil_conv_ovf_i | @cil_conv_ovf_i_un | @cil_conv_ovf_i1 | @cil_conv_ovf_i1_un | + @cil_conv_ovf_i2 | @cil_conv_ovf_i2_un | @cil_conv_ovf_i4 | @cil_conv_ovf_i4_un | + @cil_conv_ovf_i8 | @cil_conv_ovf_i8_un | @cil_conv_ovf_u | @cil_conv_ovf_u_un | + @cil_conv_ovf_u1 | @cil_conv_ovf_u1_un | @cil_conv_ovf_u2 | @cil_conv_ovf_u2_un | + @cil_conv_ovf_u4 | @cil_conv_ovf_u4_un | @cil_conv_ovf_u8 | @cil_conv_ovf_u8_un | + @cil_conv_r4 | @cil_conv_r8 | @cil_conv_ovf_u2 | @cil_conv_ovf_u2_un | + @cil_conv_i | @cil_conv_u | @cil_conv_r_un; + +@cil_ldind = @cil_ldind_i | @cil_ldind_i1 | @cil_ldind_i2 | @cil_ldind_i4 | @cil_ldind_i8 | + @cil_ldind_r4 | @cil_ldind_r8 | @cil_ldind_ref | @cil_ldind_u1 | @cil_ldind_u2 | @cil_ldind_u4; + +@cil_stind = @cil_stind_i | @cil_stind_i1 | @cil_stind_i2 | @cil_stind_i4 | @cil_stind_i8 | + @cil_stind_r4 | @cil_stind_r8 | @cil_stind_ref; + +@cil_bitwise_operation = @cil_binary_bitwise_operation | @cil_unary_bitwise_operation; + +@cil_binary_bitwise_operation = @cil_and | @cil_or | @cil_xor | @cil_shr | @cil_shr | @cil_shr_un | @cil_shl; + +@cil_binary_arithmetic_operation = @cil_add | @cil_sub | @cil_mul | @cil_div | @cil_div_un | + @cil_rem | @cil_rem_un | @cil_add_ovf | @cil_add_ovf_un | @cil_mul_ovf | @cil_mul_ovf_un | + @cil_sub_ovf | @cil_sub_ovf_un; + +@cil_unary_bitwise_operation = @cil_not; + +@cil_binary_expr = @cil_binary_arithmetic_operation | @cil_binary_bitwise_operation | @cil_read_array | @cil_comparison_operation; + +@cil_unary_arithmetic_operation = @cil_neg; + +@cil_comparison_operation = @cil_cgt_un | @cil_ceq | @cil_cgt | @cil_clt | @cil_clt_un; + +// Elements that retrieve an address of something +@cil_read_ref = @cil_ldloca_s | @cil_ldarga_s | @cil_ldflda | @cil_ldsflda | @cil_ldelema; + +// CIL array instructions + +@cil_read_array = + @cil_ldelem | @cil_ldelema | @cil_ldelem_i1 | @cil_ldelem_ref | @cil_ldelem_i | + @cil_ldelem_i1 | @cil_ldelem_i2 | @cil_ldelem_i4 | @cil_ldelem_i8 | @cil_ldelem_r4 | + @cil_ldelem_r8 | @cil_ldelem_u1 | @cil_ldelem_u2 | @cil_ldelem_u4; + +@cil_write_array = @cil_stelem | @cil_stelem_ref | + @cil_stelem_i | @cil_stelem_i1 | @cil_stelem_i2 | @cil_stelem_i4 | @cil_stelem_i8 | + @cil_stelem_r4 | @cil_stelem_r8; + +@cil_throw_any = @cil_throw | @cil_rethrow; + +#keyset[impl, index] +cil_instruction( + unique int id: @cil_instruction, + int opcode: int ref, + int index: int ref, + int impl: @cil_method_implementation ref); + +cil_jump( + unique int instruction: @cil_jump ref, + int target: @cil_instruction ref); + +cil_access( + unique int instruction: @cil_instruction ref, + int target: @cil_accessible ref); + +cil_value( + unique int instruction: @cil_literal ref, + string value: string ref); + +#keyset[instruction, index] +cil_switch( + int instruction: @cil_switch ref, + int index: int ref, + int target: @cil_instruction ref); + +cil_instruction_location( + unique int id: @cil_instruction ref, + int loc: @location ref); + +cil_type_location( + int id: @cil_type ref, + int loc: @location ref); + +cil_method_location( + int id: @cil_method ref, + int loc: @location ref); + +@cil_namespace = @namespace; + +@cil_type_container = @cil_type | @cil_namespace | @cil_method; + +case @cil_type.kind of + 0 = @cil_valueorreftype +| 1 = @cil_typeparameter +| 2 = @cil_array_type +| 3 = @cil_pointer_type +; + +cil_type( + unique int id: @cil_type, + string name: string ref, + int kind: int ref, + int parent: @cil_type_container ref, + int sourceDecl: @cil_type ref); + +cil_pointer_type( + unique int id: @cil_pointer_type ref, + int pointee: @cil_type ref); + +cil_array_type( + unique int id: @cil_array_type ref, + int element_type: @cil_type ref, + int rank: int ref); + +cil_method( + unique int id: @cil_method, + string name: string ref, + int parent: @cil_type ref, + int return_type: @cil_type ref); + +cil_method_source_declaration( + unique int method: @cil_method ref, + int source: @cil_method ref); + +cil_method_implementation( + unique int id: @cil_method_implementation, + int method: @cil_method ref, + int location: @assembly ref); + +cil_implements( + int id: @cil_method ref, + int decl: @cil_method ref); + +#keyset[parent, name] +cil_field( + unique int id: @cil_field, + int parent: @cil_type ref, + string name: string ref, + int field_type: @cil_type ref); + +@cil_element = @cil_instruction | @cil_declaration | @cil_handler | @cil_attribute | @cil_namespace; +@cil_named_element = @cil_declaration | @cil_namespace; +@cil_declaration = @cil_variable | @cil_method | @cil_type | @cil_member; +@cil_accessible = @cil_declaration; +@cil_variable = @cil_field | @cil_stack_variable; +@cil_stack_variable = @cil_local_variable | @cil_parameter; +@cil_member = @cil_method | @cil_type | @cil_field | @cil_property | @cil_event; + +#keyset[method, index] +cil_parameter( + unique int id: @cil_parameter, + int method: @cil_method ref, + int index: int ref, + int param_type: @cil_type ref); + +cil_parameter_in(unique int id: @cil_parameter ref); +cil_parameter_out(unique int id: @cil_parameter ref); + +cil_setter(unique int prop: @cil_property ref, + int method: @cil_method ref); + +cil_getter(unique int prop: @cil_property ref, + int method: @cil_method ref); + +cil_adder(unique int event: @cil_event ref, + int method: @cil_method ref); + +cil_remover(unique int event: @cil_event ref, int method: @cil_method ref); + +cil_raiser(unique int event: @cil_event ref, int method: @cil_method ref); + +cil_property( + unique int id: @cil_property, + int parent: @cil_type ref, + string name: string ref, + int property_type: @cil_type ref); + +#keyset[parent, name] +cil_event(unique int id: @cil_event, + int parent: @cil_type ref, + string name: string ref, + int event_type: @cil_type ref); + +#keyset[impl, index] +cil_local_variable( + unique int id: @cil_local_variable, + int impl: @cil_method_implementation ref, + int index: int ref, + int var_type: @cil_type ref); + +// CIL handlers (exception handlers etc). + +case @cil_handler.kind of + 0 = @cil_catch_handler +| 1 = @cil_filter_handler +| 2 = @cil_finally_handler +| 4 = @cil_fault_handler +; + +#keyset[impl, index] +cil_handler( + unique int id: @cil_handler, + int impl: @cil_method_implementation ref, + int index: int ref, + int kind: int ref, + int try_start: @cil_instruction ref, + int try_end: @cil_instruction ref, + int handler_start: @cil_instruction ref); + +cil_handler_filter( + unique int id: @cil_handler ref, + int filter_start: @cil_instruction ref); + +cil_handler_type( + unique int id: @cil_handler ref, + int catch_type: @cil_type ref); + +@cil_controlflow_node = @cil_entry_point | @cil_instruction; + +@cil_entry_point = @cil_method_implementation | @cil_handler; + +@cil_dataflow_node = @cil_instruction | @cil_variable | @cil_method; + +cil_method_stack_size( + unique int method: @cil_method_implementation ref, + int size: int ref); + +// CIL modifiers + +cil_public(int id: @cil_member ref); +cil_private(int id: @cil_member ref); +cil_protected(int id: @cil_member ref); +cil_internal(int id: @cil_member ref); +cil_static(int id: @cil_member ref); +cil_sealed(int id: @cil_member ref); +cil_virtual(int id: @cil_method ref); +cil_abstract(int id: @cil_member ref); +cil_class(int id: @cil_type ref); +cil_interface(int id: @cil_type ref); +cil_security(int id: @cil_member ref); +cil_requiresecobject(int id: @cil_method ref); +cil_specialname(int id: @cil_method ref); +cil_newslot(int id: @cil_method ref); + +cil_base_class(unique int id: @cil_type ref, int base: @cil_type ref); +cil_base_interface(int id: @cil_type ref, int base: @cil_type ref); + +#keyset[unbound, index] +cil_type_parameter( + int unbound: @cil_member ref, + int index: int ref, + int param: @cil_typeparameter ref); + +#keyset[bound, index] +cil_type_argument( + int bound: @cil_member ref, + int index: int ref, + int t: @cil_type ref); + +// CIL type parameter constraints + +cil_typeparam_covariant(int tp: @cil_typeparameter ref); +cil_typeparam_contravariant(int tp: @cil_typeparameter ref); +cil_typeparam_class(int tp: @cil_typeparameter ref); +cil_typeparam_struct(int tp: @cil_typeparameter ref); +cil_typeparam_new(int tp: @cil_typeparameter ref); +cil_typeparam_constraint(int tp: @cil_typeparameter ref, int supertype: @cil_type ref); + +// CIL attributes + +cil_attribute( + unique int attributeid: @cil_attribute, + int element: @cil_declaration ref, + int constructor: @cil_method ref); + +#keyset[attribute_id, param] +cil_attribute_named_argument( + int attribute_id: @cil_attribute ref, + string param: string ref, + string value: string ref); + +#keyset[attribute_id, index] +cil_attribute_positional_argument( + int attribute_id: @cil_attribute ref, + int index: int ref, + string value: string ref); + + +// Common .Net data model covering both C# and CIL + +// Common elements +@dotnet_element = @element | @cil_element; +@dotnet_named_element = @named_element | @cil_named_element; +@dotnet_callable = @callable | @cil_method; +@dotnet_variable = @variable | @cil_variable; +@dotnet_field = @field | @cil_field; +@dotnet_parameter = @parameter | @cil_parameter; +@dotnet_declaration = @declaration | @cil_declaration; +@dotnet_member = @member | @cil_member; +@dotnet_event = @event | @cil_event; +@dotnet_property = @property | @cil_property | @indexer; + +// Common types +@dotnet_type = @type | @cil_type; +@dotnet_call = @call | @cil_call_any; +@dotnet_throw = @throw_element | @cil_throw_any; +@dotnet_valueorreftype = @cil_valueorreftype | @value_or_ref_type | @cil_array_type | @void_type; +@dotnet_typeparameter = @type_parameter | @cil_typeparameter; +@dotnet_array_type = @array_type | @cil_array_type; +@dotnet_pointer_type = @pointer_type | @cil_pointer_type; +@dotnet_type_parameter = @type_parameter | @cil_typeparameter; +@dotnet_generic = @dotnet_valueorreftype | @dotnet_callable; + +// Attributes +@dotnet_attribute = @attribute | @cil_attribute; + +// Expressions +@dotnet_expr = @expr | @cil_expr; + +// Literals +@dotnet_literal = @literal_expr | @cil_literal; +@dotnet_string_literal = @string_literal_expr | @cil_ldstr; +@dotnet_int_literal = @integer_literal_expr | @cil_ldc_i; +@dotnet_float_literal = @float_literal_expr | @cil_ldc_r; +@dotnet_null_literal = @null_literal_expr | @cil_ldnull; + +@metadata_entity = @cil_method | @cil_type | @cil_field | @cil_property | @field | @property | + @callable | @value_or_ref_type | @void_type; + +#keyset[entity, location] +metadata_handle(int entity : @metadata_entity ref, int location: @assembly ref, int handle: int ref) diff --git a/csharp/upgrades/eedef9359e1e4e1ebcf2a1dc9d2ae75d4ea4d160/semmlecode.csharp.dbscheme b/csharp/upgrades/eedef9359e1e4e1ebcf2a1dc9d2ae75d4ea4d160/semmlecode.csharp.dbscheme new file mode 100644 index 00000000000..cfaa4e90da2 --- /dev/null +++ b/csharp/upgrades/eedef9359e1e4e1ebcf2a1dc9d2ae75d4ea4d160/semmlecode.csharp.dbscheme @@ -0,0 +1,1891 @@ + +/** + * An invocation of the compiler. Note that more than one file may be + * compiled per invocation. For example, this command compiles three + * source files: + * + * csc f1.cs f2.cs f3.cs + * + * The `id` simply identifies the invocation, while `cwd` is the working + * directory from which the compiler was invoked. + */ +compilations( + unique int id : @compilation, + string cwd : string ref +); + +/** + * The arguments that were passed to the extractor for a compiler + * invocation. If `id` is for the compiler invocation + * + * csc f1.cs f2.cs f3.cs + * + * then typically there will be rows for + * + * num | arg + * --- | --- + * 0 | --compiler + * 1 | *path to compiler* + * 2 | --cil + * 3 | f1.cs + * 4 | f2.cs + * 5 | f3.cs + */ +#keyset[id, num] +compilation_args( + int id : @compilation ref, + int num : int ref, + string arg : string ref +); + +/** + * The source files that are compiled by a compiler invocation. + * If `id` is for the compiler invocation + * + * csc f1.cs f2.cs f3.cs + * + * then there will be rows for + * + * num | arg + * --- | --- + * 0 | f1.cs + * 1 | f2.cs + * 2 | f3.cs + */ +#keyset[id, num] +compilation_compiling_files( + int id : @compilation ref, + int num : int ref, + int file : @file ref +); + +/** + * The references used by a compiler invocation. + * If `id` is for the compiler invocation + * + * csc f1.cs f2.cs f3.cs /r:ref1.dll /r:ref2.dll /r:ref3.dll + * + * then there will be rows for + * + * num | arg + * --- | --- + * 0 | ref1.dll + * 1 | ref2.dll + * 2 | ref3.dll + */ +#keyset[id, num] +compilation_referencing_files( + int id : @compilation ref, + int num : int ref, + int file : @file ref +); + +/** + * The time taken by the extractor for a compiler invocation. + * + * For each file `num`, there will be rows for + * + * kind | seconds + * ---- | --- + * 1 | CPU seconds used by the extractor frontend + * 2 | Elapsed seconds during the extractor frontend + * 3 | CPU seconds used by the extractor backend + * 4 | Elapsed seconds during the extractor backend + */ +#keyset[id, num, kind] +compilation_time( + int id : @compilation ref, + int num : int ref, + /* kind: + 1 = frontend_cpu_seconds + 2 = frontend_elapsed_seconds + 3 = extractor_cpu_seconds + 4 = extractor_elapsed_seconds + */ + int kind : int ref, + float seconds : float ref +); + +/** + * An error or warning generated by the extractor. + * The diagnostic message `diagnostic` was generated during compiler + * invocation `compilation`, and is the `file_number_diagnostic_number`th + * message generated while extracting the `file_number`th file of that + * invocation. + */ +#keyset[compilation, file_number, file_number_diagnostic_number] +diagnostic_for( + unique int diagnostic : @diagnostic ref, + int compilation : @compilation ref, + int file_number : int ref, + int file_number_diagnostic_number : int ref +); + +diagnostics( + unique int id: @diagnostic, + int severity: int ref, + string error_tag: string ref, + string error_message: string ref, + string full_error_message: string ref, + int location: @location_default ref +); + +extractor_messages( + unique int id: @extractor_message, + int severity: int ref, + string origin : string ref, + string text : string ref, + string entity : string ref, + int location: @location_default ref, + string stack_trace : string ref +); + +/** + * If extraction was successful, then `cpu_seconds` and + * `elapsed_seconds` are the CPU time and elapsed time (respectively) + * that extraction took for compiler invocation `id`. + */ +compilation_finished( + unique int id : @compilation ref, + float cpu_seconds : float ref, + float elapsed_seconds : float ref +); + +/* + * External artifacts + */ + +externalDefects( + unique int id: @externalDefect, + string queryPath: string ref, + int location: @location ref, + string message: string ref, + float severity: float ref); + +externalMetrics( + unique int id: @externalMetric, + string queryPath: string ref, + int location: @location ref, + float value: float ref); + +externalData( + int id: @externalDataElement, + string path: string ref, + int column: int ref, + string value: string ref); + +snapshotDate( + unique date snapshotDate: date ref); + +sourceLocationPrefix( + string prefix: string ref); + +/* + * Duplicate code + */ + +duplicateCode( + unique int id: @duplication, + string relativePath: string ref, + int equivClass: int ref); + +similarCode( + unique int id: @similarity, + string relativePath: string ref, + int equivClass: int ref); + +@duplication_or_similarity = @duplication | @similarity + +tokens( + int id: @duplication_or_similarity ref, + int offset: int ref, + int beginLine: int ref, + int beginColumn: int ref, + int endLine: int ref, + int endColumn: int ref); + +/* + * C# dbscheme + */ + +/** ELEMENTS **/ + +@element = @declaration | @stmt | @expr | @modifier | @attribute | @namespace_declaration + | @using_directive | @type_parameter_constraints | @external_element + | @xmllocatable | @asp_element | @namespace; + +@declaration = @callable | @generic | @assignable | @namespace; + +@named_element = @namespace | @declaration; + +@declaration_with_accessors = @property | @indexer | @event; + +@assignable = @variable | @assignable_with_accessors | @event; + +@assignable_with_accessors = @property | @indexer; + +@external_element = @externalMetric | @externalDefect | @externalDataElement; + +@attributable = @assembly | @field | @parameter | @operator | @method | @constructor + | @destructor | @callable_accessor | @value_or_ref_type | @declaration_with_accessors + | @local_function; + +/** LOCATIONS, ASEMMBLIES, MODULES, FILES and FOLDERS **/ + +@location = @location_default | @assembly; + +locations_default( + unique int id: @location_default, + int file: @file ref, + int beginLine: int ref, + int beginColumn: int ref, + int endLine: int ref, + int endColumn: int ref); + +@sourceline = @file | @callable | @xmllocatable; + +numlines( + int element_id: @sourceline ref, + int num_lines: int ref, + int num_code: int ref, + int num_comment: int ref); + +assemblies( + unique int id: @assembly, + int file: @file ref, + string fullname: string ref, + string name: string ref, + string version: string ref); + +/* + fromSource(0) = unknown, + fromSource(1) = from source, + fromSource(2) = from library +*/ +files( + unique int id: @file, + string name: string ref, + string simple: string ref, + string ext: string ref, + int fromSource: int ref); + +folders( + unique int id: @folder, + string name: string ref, + string simple: string ref); + +@container = @folder | @file ; + +containerparent( + int parent: @container ref, + unique int child: @container ref); + +file_extraction_mode( + unique int file: @file ref, + int mode: int ref + /* 0 = normal, 1 = standalone extractor */ + ); + +/** NAMESPACES **/ + +@type_container = @namespace | @type; + +namespaces( + unique int id: @namespace, + string name: string ref); + +namespace_declarations( + unique int id: @namespace_declaration, + int namespace_id: @namespace ref); + +namespace_declaration_location( + unique int id: @namespace_declaration ref, + int loc: @location ref); + +parent_namespace( + unique int child_id: @type_container ref, + int namespace_id: @namespace ref); + +@declaration_or_directive = @namespace_declaration | @type | @using_directive; + +parent_namespace_declaration( + int child_id: @declaration_or_directive ref, // cannot be unique because of partial classes + int namespace_id: @namespace_declaration ref); + +@using_directive = @using_namespace_directive | @using_static_directive; + +using_namespace_directives( + unique int id: @using_namespace_directive, + int namespace_id: @namespace ref); + +using_static_directives( + unique int id: @using_static_directive, + int type_id: @type_or_ref ref); + +using_directive_location( + unique int id: @using_directive ref, + int loc: @location ref); + +/** TYPES **/ + +types( + unique int id: @type, + int kind: int ref, + string name: string ref); + +case @type.kind of + 1 = @bool_type +| 2 = @char_type +| 3 = @decimal_type +| 4 = @sbyte_type +| 5 = @short_type +| 6 = @int_type +| 7 = @long_type +| 8 = @byte_type +| 9 = @ushort_type +| 10 = @uint_type +| 11 = @ulong_type +| 12 = @float_type +| 13 = @double_type +| 14 = @enum_type +| 15 = @struct_type +| 17 = @class_type +| 19 = @interface_type +| 20 = @delegate_type +| 21 = @null_type +| 22 = @type_parameter +| 23 = @pointer_type +| 24 = @nullable_type +| 25 = @array_type +| 26 = @void_type +| 27 = @int_ptr_type +| 28 = @uint_ptr_type +| 29 = @dynamic_type +| 30 = @arglist_type +| 31 = @unknown_type +| 32 = @tuple_type + ; + +@simple_type = @bool_type | @char_type | @integral_type | @floating_point_type | @decimal_type; +@integral_type = @signed_integral_type | @unsigned_integral_type; +@signed_integral_type = @sbyte_type | @short_type | @int_type | @long_type; +@unsigned_integral_type = @byte_type | @ushort_type | @uint_type | @ulong_type; +@floating_point_type = @float_type | @double_type; +@value_type = @simple_type | @enum_type | @struct_type | @nullable_type | @int_ptr_type + | @uint_ptr_type | @tuple_type; +@ref_type = @class_type | @interface_type | @array_type | @delegate_type | @null_type + | @dynamic_type; +@value_or_ref_type = @value_type | @ref_type; + +typerefs( + unique int id: @typeref, + string name: string ref); + +typeref_type( + int id: @typeref ref, + unique int typeId: @type ref); + +@type_or_ref = @type | @typeref; + +array_element_type( + unique int array: @array_type ref, + int dimension: int ref, + int rank: int ref, + int element: @type_or_ref ref); + +nullable_underlying_type( + unique int nullable: @nullable_type ref, + int underlying: @type_or_ref ref); + +pointer_referent_type( + unique int pointer: @pointer_type ref, + int referent: @type_or_ref ref); + +enum_underlying_type( + unique int enum_id: @enum_type ref, + int underlying_type_id: @type_or_ref ref); + +delegate_return_type( + unique int delegate_id: @delegate_type ref, + int return_type_id: @type_or_ref ref); + +extend( + unique int sub: @type ref, + int super: @type_or_ref ref); + +@interface_or_ref = @interface_type | @typeref; + +implement( + int sub: @type ref, + int super: @type_or_ref ref); + +type_location( + int id: @type ref, + int loc: @location ref); + +tuple_underlying_type( + unique int tuple: @tuple_type ref, + int struct: @type_or_ref ref); + +#keyset[tuple, index] +tuple_element( + int tuple: @tuple_type ref, + int index: int ref, + unique int field: @field ref); + +attributes( + unique int id: @attribute, + int type_id: @type_or_ref ref, + int target: @attributable ref); + +attribute_location( + int id: @attribute ref, + int loc: @location ref); + +@type_mention_parent = @element | @type_mention; + +type_mention( + unique int id: @type_mention, + int type_id: @type_or_ref ref, + int parent: @type_mention_parent ref); + +type_mention_location( + unique int id: @type_mention ref, + int loc: @location ref); + +@has_type_annotation = @assignable | @type_parameter | @callable | @expr | @delegate_type | @generic; + +/** + * A direct annotation on an entity, for example `string? x;`. + * + * Annotations: + * 2 = reftype is not annotated "!" + * 3 = reftype is annotated "?" + * 4 = readonly ref type / in parameter + * 5 = ref type parameter, return or local variable + * 6 = out parameter + * + * Note that the annotation depends on the element it annotates. + * @assignable: The annotation is on the type of the assignable, for example the variable type. + * @type_parameter: The annotation is on the reftype constraint + * @callable: The annotation is on the return type + * @array_type: The annotation is on the element type + */ +type_annotation(int id: @has_type_annotation ref, int annotation: int ref); + +nullability(unique int nullability: @nullability, int kind: int ref); + +case @nullability.kind of + 0 = @oblivious +| 1 = @not_annotated +| 2 = @annotated +; + +#keyset[parent, index] +nullability_parent(int nullability: @nullability ref, int index: int ref, int parent: @nullability ref) + +type_nullability(int id: @has_type_annotation ref, int nullability: @nullability ref); + +/** + * The nullable flow state of an expression, as determined by Roslyn. + * 0 = none (default, not populated) + * 1 = not null + * 2 = maybe null + */ +expr_flowstate(unique int id: @expr ref, int state: int ref); + +/** GENERICS **/ + +@generic = @type | @method | @local_function; + +type_parameters( + unique int id: @type_parameter ref, + int index: int ref, + int generic_id: @generic ref, + int variance: int ref /* none = 0, out = 1, in = 2 */); + +#keyset[constructed_id, index] +type_arguments( + int id: @type_or_ref ref, + int index: int ref, + int constructed_id: @generic_or_ref ref); + +@generic_or_ref = @generic | @typeref; + +constructed_generic( + unique int constructed: @generic ref, + int generic: @generic_or_ref ref); + +type_parameter_constraints( + unique int id: @type_parameter_constraints, + int param_id: @type_parameter ref); + +type_parameter_constraints_location( + int id: @type_parameter_constraints ref, + int loc: @location ref); + +general_type_parameter_constraints( + int id: @type_parameter_constraints ref, + int kind: int ref /* class = 1, struct = 2, new = 3 */); + +specific_type_parameter_constraints( + int id: @type_parameter_constraints ref, + int base_id: @type_or_ref ref); + +specific_type_parameter_nullability( + int id: @type_parameter_constraints ref, + int base_id: @type_or_ref ref, + int nullability: @nullability ref); + +/** MODIFIERS */ + +@modifiable = @modifiable_direct | @event_accessor; + +@modifiable_direct = @member | @accessor | @local_function | @anonymous_function_expr; + +modifiers( + unique int id: @modifier, + string name: string ref); + +has_modifiers( + int id: @modifiable_direct ref, + int mod_id: @modifier ref); + +compiler_generated(unique int id: @modifiable_direct ref); + +/** MEMBERS **/ + +@member = @method | @constructor | @destructor | @field | @property | @event | @operator | @indexer | @type; + +@named_exprorstmt = @goto_stmt | @labeled_stmt | @expr; + +@virtualizable = @method | @property | @indexer | @event; + +exprorstmt_name( + unique int parent_id: @named_exprorstmt ref, + string name: string ref); + +nested_types( + unique int id: @type ref, + int declaring_type_id: @type ref, + int unbound_id: @type ref); + +properties( + unique int id: @property, + string name: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @property ref); + +property_location( + int id: @property ref, + int loc: @location ref); + +indexers( + unique int id: @indexer, + string name: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @indexer ref); + +indexer_location( + int id: @indexer ref, + int loc: @location ref); + +accessors( + unique int id: @accessor, + int kind: int ref, + string name: string ref, + int declaring_member_id: @member ref, + int unbound_id: @accessor ref); + +case @accessor.kind of + 1 = @getter +| 2 = @setter + ; + +accessor_location( + int id: @accessor ref, + int loc: @location ref); + +events( + unique int id: @event, + string name: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @event ref); + +event_location( + int id: @event ref, + int loc: @location ref); + +event_accessors( + unique int id: @event_accessor, + int kind: int ref, + string name: string ref, + int declaring_event_id: @event ref, + int unbound_id: @event_accessor ref); + +case @event_accessor.kind of + 1 = @add_event_accessor +| 2 = @remove_event_accessor + ; + +event_accessor_location( + int id: @event_accessor ref, + int loc: @location ref); + +operators( + unique int id: @operator, + string name: string ref, + string symbol: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @operator ref); + +operator_location( + int id: @operator ref, + int loc: @location ref); + +constant_value( + int id: @variable ref, + string value: string ref); + +/** CALLABLES **/ + +@callable = @method | @constructor | @destructor | @operator | @callable_accessor | @anonymous_function_expr | @local_function; + +@callable_accessor = @accessor | @event_accessor; + +methods( + unique int id: @method, + string name: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @method ref); + +method_location( + int id: @method ref, + int loc: @location ref); + +constructors( + unique int id: @constructor, + string name: string ref, + int declaring_type_id: @type ref, + int unbound_id: @constructor ref); + +constructor_location( + int id: @constructor ref, + int loc: @location ref); + +destructors( + unique int id: @destructor, + string name: string ref, + int declaring_type_id: @type ref, + int unbound_id: @destructor ref); + +destructor_location( + int id: @destructor ref, + int loc: @location ref); + +overrides( + int id: @callable ref, + int base_id: @callable ref); + +explicitly_implements( + int id: @member ref, + int interface_id: @interface_or_ref ref); + +local_functions( + unique int id: @local_function, + string name: string ref, + int return_type: @type ref, + int unbound_id: @local_function ref); + +local_function_stmts( + unique int fn: @local_function_stmt ref, + int stmt: @local_function ref); + +/** VARIABLES **/ + +@variable = @local_scope_variable | @field; + +@local_scope_variable = @local_variable | @parameter; + +fields( + unique int id: @field, + int kind: int ref, + string name: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @field ref); + +case @field.kind of + 1 = @addressable_field +| 2 = @constant + ; + +field_location( + int id: @field ref, + int loc: @location ref); + +localvars( + unique int id: @local_variable, + int kind: int ref, + string name: string ref, + int implicitly_typed: int ref /* 0 = no, 1 = yes */, + int type_id: @type_or_ref ref, + int parent_id: @local_var_decl_expr ref); + +case @local_variable.kind of + 1 = @addressable_local_variable +| 2 = @local_constant +| 3 = @local_variable_ref + ; + +localvar_location( + unique int id: @local_variable ref, + int loc: @location ref); + +@parameterizable = @callable | @delegate_type | @indexer; + +#keyset[name, parent_id] +#keyset[index, parent_id] +params( + unique int id: @parameter, + string name: string ref, + int type_id: @type_or_ref ref, + int index: int ref, + int mode: int ref, /* value = 0, ref = 1, out = 2, array = 3, this = 4 */ + int parent_id: @parameterizable ref, + int unbound_id: @parameter ref); + +param_location( + int id: @parameter ref, + int loc: @location ref); + +/** STATEMENTS **/ + +@exprorstmt_parent = @control_flow_element | @top_level_exprorstmt_parent; + +statements( + unique int id: @stmt, + int kind: int ref); + +#keyset[index, parent] +stmt_parent( + unique int stmt: @stmt ref, + int index: int ref, + int parent: @control_flow_element ref); + +@top_level_stmt_parent = @callable; + +// [index, parent] is not a keyset because the same parent may be compiled multiple times +stmt_parent_top_level( + unique int stmt: @stmt ref, + int index: int ref, + int parent: @top_level_stmt_parent ref); + +case @stmt.kind of + 1 = @block_stmt +| 2 = @expr_stmt +| 3 = @if_stmt +| 4 = @switch_stmt +| 5 = @while_stmt +| 6 = @do_stmt +| 7 = @for_stmt +| 8 = @foreach_stmt +| 9 = @break_stmt +| 10 = @continue_stmt +| 11 = @goto_stmt +| 12 = @goto_case_stmt +| 13 = @goto_default_stmt +| 14 = @throw_stmt +| 15 = @return_stmt +| 16 = @yield_stmt +| 17 = @try_stmt +| 18 = @checked_stmt +| 19 = @unchecked_stmt +| 20 = @lock_stmt +| 21 = @using_block_stmt +| 22 = @var_decl_stmt +| 23 = @const_decl_stmt +| 24 = @empty_stmt +| 25 = @unsafe_stmt +| 26 = @fixed_stmt +| 27 = @label_stmt +| 28 = @catch +| 29 = @case_stmt +| 30 = @local_function_stmt +| 31 = @using_decl_stmt + ; + +@using_stmt = @using_block_stmt | @using_decl_stmt; + +@labeled_stmt = @label_stmt | @case; + +@decl_stmt = @var_decl_stmt | @const_decl_stmt | @using_decl_stmt; + +@cond_stmt = @if_stmt | @switch_stmt; + +@loop_stmt = @while_stmt | @do_stmt | @for_stmt | @foreach_stmt; + +@jump_stmt = @break_stmt | @goto_any_stmt | @continue_stmt | @throw_stmt | @return_stmt + | @yield_stmt; + +@goto_any_stmt = @goto_default_stmt | @goto_case_stmt | @goto_stmt; + + +stmt_location( + unique int id: @stmt ref, + int loc: @location ref); + +catch_type( + unique int catch_id: @catch ref, + int type_id: @type_or_ref ref, + int kind: int ref /* explicit = 1, implicit = 2 */); + +/** EXPRESSIONS **/ + +expressions( + unique int id: @expr, + int kind: int ref, + int type_id: @type_or_ref ref); + +#keyset[index, parent] +expr_parent( + unique int expr: @expr ref, + int index: int ref, + int parent: @control_flow_element ref); + +@top_level_expr_parent = @attribute | @field | @property | @indexer | @parameter; + +@top_level_exprorstmt_parent = @top_level_expr_parent | @top_level_stmt_parent; + +// [index, parent] is not a keyset because the same parent may be compiled multiple times +expr_parent_top_level( + unique int expr: @expr ref, + int index: int ref, + int parent: @top_level_exprorstmt_parent ref); + +case @expr.kind of +/* literal */ + 1 = @bool_literal_expr +| 2 = @char_literal_expr +| 3 = @decimal_literal_expr +| 4 = @int_literal_expr +| 5 = @long_literal_expr +| 6 = @uint_literal_expr +| 7 = @ulong_literal_expr +| 8 = @float_literal_expr +| 9 = @double_literal_expr +| 10 = @string_literal_expr +| 11 = @null_literal_expr +/* primary & unary */ +| 12 = @this_access_expr +| 13 = @base_access_expr +| 14 = @local_variable_access_expr +| 15 = @parameter_access_expr +| 16 = @field_access_expr +| 17 = @property_access_expr +| 18 = @method_access_expr +| 19 = @event_access_expr +| 20 = @indexer_access_expr +| 21 = @array_access_expr +| 22 = @type_access_expr +| 23 = @typeof_expr +| 24 = @method_invocation_expr +| 25 = @delegate_invocation_expr +| 26 = @operator_invocation_expr +| 27 = @cast_expr +| 28 = @object_creation_expr +| 29 = @explicit_delegate_creation_expr +| 30 = @implicit_delegate_creation_expr +| 31 = @array_creation_expr +| 32 = @default_expr +| 33 = @plus_expr +| 34 = @minus_expr +| 35 = @bit_not_expr +| 36 = @log_not_expr +| 37 = @post_incr_expr +| 38 = @post_decr_expr +| 39 = @pre_incr_expr +| 40 = @pre_decr_expr +/* multiplicative */ +| 41 = @mul_expr +| 42 = @div_expr +| 43 = @rem_expr +/* additive */ +| 44 = @add_expr +| 45 = @sub_expr +/* shift */ +| 46 = @lshift_expr +| 47 = @rshift_expr +/* relational */ +| 48 = @lt_expr +| 49 = @gt_expr +| 50 = @le_expr +| 51 = @ge_expr +/* equality */ +| 52 = @eq_expr +| 53 = @ne_expr +/* logical */ +| 54 = @bit_and_expr +| 55 = @bit_xor_expr +| 56 = @bit_or_expr +| 57 = @log_and_expr +| 58 = @log_or_expr +/* type testing */ +| 59 = @is_expr +| 60 = @as_expr +/* null coalescing */ +| 61 = @null_coalescing_expr +/* conditional */ +| 62 = @conditional_expr +/* assignment */ +| 63 = @simple_assign_expr +| 64 = @assign_add_expr +| 65 = @assign_sub_expr +| 66 = @assign_mul_expr +| 67 = @assign_div_expr +| 68 = @assign_rem_expr +| 69 = @assign_and_expr +| 70 = @assign_xor_expr +| 71 = @assign_or_expr +| 72 = @assign_lshift_expr +| 73 = @assign_rshift_expr +/* more */ +| 74 = @object_init_expr +| 75 = @collection_init_expr +| 76 = @array_init_expr +| 77 = @checked_expr +| 78 = @unchecked_expr +| 79 = @constructor_init_expr +| 80 = @add_event_expr +| 81 = @remove_event_expr +| 82 = @par_expr +| 83 = @local_var_decl_expr +| 84 = @lambda_expr +| 85 = @anonymous_method_expr +| 86 = @namespace_expr +/* dynamic */ +| 92 = @dynamic_element_access_expr +| 93 = @dynamic_member_access_expr +/* unsafe */ +| 100 = @pointer_indirection_expr +| 101 = @address_of_expr +| 102 = @sizeof_expr +/* async */ +| 103 = @await_expr +/* C# 6.0 */ +| 104 = @nameof_expr +| 105 = @interpolated_string_expr +| 106 = @unknown_expr +/* C# 7.0 */ +| 107 = @throw_expr +| 108 = @tuple_expr +| 109 = @local_function_invocation_expr +| 110 = @ref_expr +| 111 = @discard_expr +/* C# 8.0 */ +| 112 = @range_expr +| 113 = @index_expr +| 114 = @switch_expr +| 115 = @recursive_pattern_expr +| 116 = @property_pattern_expr +| 117 = @positional_pattern_expr +| 118 = @switch_case_expr +| 119 = @assign_coalesce_expr +| 120 = @suppress_nullable_warning_expr +| 121 = @namespace_access_expr +; + +@switch = @switch_stmt | @switch_expr; +@case = @case_stmt | @switch_case_expr; +@pattern_match = @case | @is_expr; + +@integer_literal_expr = @int_literal_expr | @long_literal_expr | @uint_literal_expr | @ulong_literal_expr; +@real_literal_expr = @float_literal_expr | @double_literal_expr | @decimal_literal_expr; +@literal_expr = @bool_literal_expr | @char_literal_expr | @integer_literal_expr | @real_literal_expr + | @string_literal_expr | @null_literal_expr; + +@assign_expr = @simple_assign_expr | @assign_op_expr | @local_var_decl_expr; +@assign_op_expr = @assign_arith_expr | @assign_bitwise_expr | @assign_event_expr | @assign_coalesce_expr; +@assign_event_expr = @add_event_expr | @remove_event_expr; + +@assign_arith_expr = @assign_add_expr | @assign_sub_expr | @assign_mul_expr | @assign_div_expr + | @assign_rem_expr +@assign_bitwise_expr = @assign_and_expr | @assign_or_expr | @assign_xor_expr + | @assign_lshift_expr | @assign_rshift_expr; + +@member_access_expr = @field_access_expr | @property_access_expr | @indexer_access_expr | @event_access_expr + | @method_access_expr | @type_access_expr | @dynamic_member_access_expr; +@access_expr = @member_access_expr | @this_access_expr | @base_access_expr | @assignable_access_expr | @namespace_access_expr; +@element_access_expr = @indexer_access_expr | @array_access_expr | @dynamic_element_access_expr; + +@local_variable_access = @local_variable_access_expr | @local_var_decl_expr; +@local_scope_variable_access_expr = @parameter_access_expr | @local_variable_access; +@variable_access_expr = @local_scope_variable_access_expr | @field_access_expr; + +@assignable_access_expr = @variable_access_expr | @property_access_expr | @element_access_expr + | @event_access_expr | @dynamic_member_access_expr; + +@objectorcollection_init_expr = @object_init_expr | @collection_init_expr; + +@delegate_creation_expr = @explicit_delegate_creation_expr | @implicit_delegate_creation_expr; + +@bin_arith_op_expr = @mul_expr | @div_expr | @rem_expr | @add_expr | @sub_expr; +@incr_op_expr = @pre_incr_expr | @post_incr_expr; +@decr_op_expr = @pre_decr_expr | @post_decr_expr; +@mut_op_expr = @incr_op_expr | @decr_op_expr; +@un_arith_op_expr = @plus_expr | @minus_expr | @mut_op_expr; +@arith_op_expr = @bin_arith_op_expr | @un_arith_op_expr; + +@ternary_log_op_expr = @conditional_expr; +@bin_log_op_expr = @log_and_expr | @log_or_expr | @null_coalescing_expr; +@un_log_op_expr = @log_not_expr; +@log_expr = @un_log_op_expr | @bin_log_op_expr | @ternary_log_op_expr; + +@bin_bit_op_expr = @bit_and_expr | @bit_or_expr | @bit_xor_expr | @lshift_expr + | @rshift_expr; +@un_bit_op_expr = @bit_not_expr; +@bit_expr = @un_bit_op_expr | @bin_bit_op_expr; + +@equality_op_expr = @eq_expr | @ne_expr; +@rel_op_expr = @gt_expr | @lt_expr| @ge_expr | @le_expr; +@comp_expr = @equality_op_expr | @rel_op_expr; + +@op_expr = @assign_expr | @un_op | @bin_op | @ternary_op; + +@ternary_op = @ternary_log_op_expr; +@bin_op = @bin_arith_op_expr | @bin_log_op_expr | @bin_bit_op_expr | @comp_expr; +@un_op = @un_arith_op_expr | @un_log_op_expr | @un_bit_op_expr | @sizeof_expr + | @pointer_indirection_expr | @address_of_expr; + +@anonymous_function_expr = @lambda_expr | @anonymous_method_expr; + +@call = @method_invocation_expr | @constructor_init_expr | @operator_invocation_expr + | @delegate_invocation_expr | @object_creation_expr | @call_access_expr + | @local_function_invocation_expr; + +@call_access_expr = @property_access_expr | @event_access_expr | @indexer_access_expr; + +@late_bindable_expr = @dynamic_element_access_expr | @dynamic_member_access_expr + | @object_creation_expr | @method_invocation_expr | @operator_invocation_expr; + +@throw_element = @throw_expr | @throw_stmt; + +implicitly_typed_array_creation( + unique int id: @array_creation_expr ref); + +explicitly_sized_array_creation( + unique int id: @array_creation_expr ref); + +stackalloc_array_creation( + unique int id: @array_creation_expr ref); + +mutator_invocation_mode( + unique int id: @operator_invocation_expr ref, + int mode: int ref /* prefix = 1, postfix = 2*/); + +expr_compiler_generated( + unique int id: @expr ref); + +expr_value( + unique int id: @expr ref, + string value: string ref); + +expr_call( + unique int caller_id: @expr ref, + int target_id: @callable ref); + +expr_access( + unique int accesser_id: @access_expr ref, + int target_id: @accessible ref); + +@accessible = @method | @assignable | @local_function | @namespace; + +expr_location( + unique int id: @expr ref, + int loc: @location ref); + +dynamic_member_name( + unique int id: @late_bindable_expr ref, + string name: string ref); + +@qualifiable_expr = @member_access_expr + | @method_invocation_expr + | @element_access_expr; + +conditional_access( + unique int id: @qualifiable_expr ref); + +expr_argument( + unique int id: @expr ref, + int mode: int ref); + /* mode is the same as params: value = 0, ref = 1, out = 2 */ + +expr_argument_name( + unique int id: @expr ref, + string name: string ref); + +/** CONTROL/DATA FLOW **/ + +@control_flow_element = @stmt | @expr; + +/* XML Files */ + +xmlEncoding ( + unique int id: @file ref, + string encoding: string ref); + +xmlDTDs( + unique int id: @xmldtd, + string root: string ref, + string publicId: string ref, + string systemId: string ref, + int fileid: @file ref); + +xmlElements( + unique int id: @xmlelement, + string name: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int fileid: @file ref); + +xmlAttrs( + unique int id: @xmlattribute, + int elementid: @xmlelement ref, + string name: string ref, + string value: string ref, + int idx: int ref, + int fileid: @file ref); + +xmlNs( + int id: @xmlnamespace, + string prefixName: string ref, + string URI: string ref, + int fileid: @file ref); + +xmlHasNs( + int elementId: @xmlnamespaceable ref, + int nsId: @xmlnamespace ref, + int fileid: @file ref); + +xmlComments( + unique int id: @xmlcomment, + string text: string ref, + int parentid: @xmlparent ref, + int fileid: @file ref); + +xmlChars( + unique int id: @xmlcharacters, + string text: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int isCDATA: int ref, + int fileid: @file ref); + +@xmlparent = @file | @xmlelement; +@xmlnamespaceable = @xmlelement | @xmlattribute; + +xmllocations( + int xmlElement: @xmllocatable ref, + int location: @location_default ref); + +@xmllocatable = @xmlcharacters | @xmlelement | @xmlcomment | @xmlattribute | @xmldtd | @file | @xmlnamespace; + +/* Comments */ + +commentline( + unique int id: @commentline, + int kind: int ref, + string text: string ref, + string rawtext: string ref); + +case @commentline.kind of + 0 = @singlelinecomment +| 1 = @xmldoccomment +| 2 = @multilinecomment; + +commentline_location( + unique int id: @commentline ref, + int loc: @location ref); + +commentblock( + unique int id : @commentblock); + +commentblock_location( + unique int id: @commentblock ref, + int loc: @location ref); + +commentblock_binding( + int id: @commentblock ref, + int entity: @element ref, + int bindtype: int ref); /* 0: Parent, 1: Best, 2: Before, 3: After */ + +commentblock_child( + int id: @commentblock ref, + int commentline: @commentline ref, + int index: int ref); + +/* ASP.NET */ + +case @asp_element.kind of + 0=@asp_close_tag +| 1=@asp_code +| 2=@asp_comment +| 3=@asp_data_binding +| 4=@asp_directive +| 5=@asp_open_tag +| 6=@asp_quoted_string +| 7=@asp_text +| 8=@asp_xml_directive; + +@asp_attribute = @asp_code | @asp_data_binding | @asp_quoted_string; + +asp_elements( + unique int id: @asp_element, + int kind: int ref, + int loc: @location ref); + +asp_comment_server(unique int comment: @asp_comment ref); +asp_code_inline(unique int code: @asp_code ref); +asp_directive_attribute( + int directive: @asp_directive ref, + int index: int ref, + string name: string ref, + int value: @asp_quoted_string ref); +asp_directive_name( + unique int directive: @asp_directive ref, + string name: string ref); +asp_element_body( + unique int element: @asp_element ref, + string body: string ref); +asp_tag_attribute( + int tag: @asp_open_tag ref, + int index: int ref, + string name: string ref, + int attribute: @asp_attribute ref); +asp_tag_name( + unique int tag: @asp_open_tag ref, + string name: string ref); +asp_tag_isempty(int tag: @asp_open_tag ref); + +/* Common Intermediate Language - CIL */ + +case @cil_instruction.opcode of + 0 = @cil_nop +| 1 = @cil_break +| 2 = @cil_ldarg_0 +| 3 = @cil_ldarg_1 +| 4 = @cil_ldarg_2 +| 5 = @cil_ldarg_3 +| 6 = @cil_ldloc_0 +| 7 = @cil_ldloc_1 +| 8 = @cil_ldloc_2 +| 9 = @cil_ldloc_3 +| 10 = @cil_stloc_0 +| 11 = @cil_stloc_1 +| 12 = @cil_stloc_2 +| 13 = @cil_stloc_3 +| 14 = @cil_ldarg_s +| 15 = @cil_ldarga_s +| 16 = @cil_starg_s +| 17 = @cil_ldloc_s +| 18 = @cil_ldloca_s +| 19 = @cil_stloc_s +| 20 = @cil_ldnull +| 21 = @cil_ldc_i4_m1 +| 22 = @cil_ldc_i4_0 +| 23 = @cil_ldc_i4_1 +| 24 = @cil_ldc_i4_2 +| 25 = @cil_ldc_i4_3 +| 26 = @cil_ldc_i4_4 +| 27 = @cil_ldc_i4_5 +| 28 = @cil_ldc_i4_6 +| 29 = @cil_ldc_i4_7 +| 30 = @cil_ldc_i4_8 +| 31 = @cil_ldc_i4_s +| 32 = @cil_ldc_i4 +| 33 = @cil_ldc_i8 +| 34 = @cil_ldc_r4 +| 35 = @cil_ldc_r8 +| 37 = @cil_dup +| 38 = @cil_pop +| 39 = @cil_jmp +| 40 = @cil_call +| 41 = @cil_calli +| 42 = @cil_ret +| 43 = @cil_br_s +| 44 = @cil_brfalse_s +| 45 = @cil_brtrue_s +| 46 = @cil_beq_s +| 47 = @cil_bge_s +| 48 = @cil_bgt_s +| 49 = @cil_ble_s +| 50 = @cil_blt_s +| 51 = @cil_bne_un_s +| 52 = @cil_bge_un_s +| 53 = @cil_bgt_un_s +| 54 = @cil_ble_un_s +| 55 = @cil_blt_un_s +| 56 = @cil_br +| 57 = @cil_brfalse +| 58 = @cil_brtrue +| 59 = @cil_beq +| 60 = @cil_bge +| 61 = @cil_bgt +| 62 = @cil_ble +| 63 = @cil_blt +| 64 = @cil_bne_un +| 65 = @cil_bge_un +| 66 = @cil_bgt_un +| 67 = @cil_ble_un +| 68 = @cil_blt_un +| 69 = @cil_switch +| 70 = @cil_ldind_i1 +| 71 = @cil_ldind_u1 +| 72 = @cil_ldind_i2 +| 73 = @cil_ldind_u2 +| 74 = @cil_ldind_i4 +| 75 = @cil_ldind_u4 +| 76 = @cil_ldind_i8 +| 77 = @cil_ldind_i +| 78 = @cil_ldind_r4 +| 79 = @cil_ldind_r8 +| 80 = @cil_ldind_ref +| 81 = @cil_stind_ref +| 82 = @cil_stind_i1 +| 83 = @cil_stind_i2 +| 84 = @cil_stind_i4 +| 85 = @cil_stind_i8 +| 86 = @cil_stind_r4 +| 87 = @cil_stind_r8 +| 88 = @cil_add +| 89 = @cil_sub +| 90 = @cil_mul +| 91 = @cil_div +| 92 = @cil_div_un +| 93 = @cil_rem +| 94 = @cil_rem_un +| 95 = @cil_and +| 96 = @cil_or +| 97 = @cil_xor +| 98 = @cil_shl +| 99 = @cil_shr +| 100 = @cil_shr_un +| 101 = @cil_neg +| 102 = @cil_not +| 103 = @cil_conv_i1 +| 104 = @cil_conv_i2 +| 105 = @cil_conv_i4 +| 106 = @cil_conv_i8 +| 107 = @cil_conv_r4 +| 108 = @cil_conv_r8 +| 109 = @cil_conv_u4 +| 110 = @cil_conv_u8 +| 111 = @cil_callvirt +| 112 = @cil_cpobj +| 113 = @cil_ldobj +| 114 = @cil_ldstr +| 115 = @cil_newobj +| 116 = @cil_castclass +| 117 = @cil_isinst +| 118 = @cil_conv_r_un +| 121 = @cil_unbox +| 122 = @cil_throw +| 123 = @cil_ldfld +| 124 = @cil_ldflda +| 125 = @cil_stfld +| 126 = @cil_ldsfld +| 127 = @cil_ldsflda +| 128 = @cil_stsfld +| 129 = @cil_stobj +| 130 = @cil_conv_ovf_i1_un +| 131 = @cil_conv_ovf_i2_un +| 132 = @cil_conv_ovf_i4_un +| 133 = @cil_conv_ovf_i8_un +| 134 = @cil_conv_ovf_u1_un +| 135 = @cil_conv_ovf_u2_un +| 136 = @cil_conv_ovf_u4_un +| 137 = @cil_conv_ovf_u8_un +| 138 = @cil_conv_ovf_i_un +| 139 = @cil_conv_ovf_u_un +| 140 = @cil_box +| 141 = @cil_newarr +| 142 = @cil_ldlen +| 143 = @cil_ldelema +| 144 = @cil_ldelem_i1 +| 145 = @cil_ldelem_u1 +| 146 = @cil_ldelem_i2 +| 147 = @cil_ldelem_u2 +| 148 = @cil_ldelem_i4 +| 149 = @cil_ldelem_u4 +| 150 = @cil_ldelem_i8 +| 151 = @cil_ldelem_i +| 152 = @cil_ldelem_r4 +| 153 = @cil_ldelem_r8 +| 154 = @cil_ldelem_ref +| 155 = @cil_stelem_i +| 156 = @cil_stelem_i1 +| 157 = @cil_stelem_i2 +| 158 = @cil_stelem_i4 +| 159 = @cil_stelem_i8 +| 160 = @cil_stelem_r4 +| 161 = @cil_stelem_r8 +| 162 = @cil_stelem_ref +| 163 = @cil_ldelem +| 164 = @cil_stelem +| 165 = @cil_unbox_any +| 179 = @cil_conv_ovf_i1 +| 180 = @cil_conv_ovf_u1 +| 181 = @cil_conv_ovf_i2 +| 182 = @cil_conv_ovf_u2 +| 183 = @cil_conv_ovf_i4 +| 184 = @cil_conv_ovf_u4 +| 185 = @cil_conv_ovf_i8 +| 186 = @cil_conv_ovf_u8 +| 194 = @cil_refanyval +| 195 = @cil_ckinfinite +| 198 = @cil_mkrefany +| 208 = @cil_ldtoken +| 209 = @cil_conv_u2 +| 210 = @cil_conv_u1 +| 211 = @cil_conv_i +| 212 = @cil_conv_ovf_i +| 213 = @cil_conv_ovf_u +| 214 = @cil_add_ovf +| 215 = @cil_add_ovf_un +| 216 = @cil_mul_ovf +| 217 = @cil_mul_ovf_un +| 218 = @cil_sub_ovf +| 219 = @cil_sub_ovf_un +| 220 = @cil_endfinally +| 221 = @cil_leave +| 222 = @cil_leave_s +| 223 = @cil_stind_i +| 224 = @cil_conv_u +| 65024 = @cil_arglist +| 65025 = @cil_ceq +| 65026 = @cil_cgt +| 65027 = @cil_cgt_un +| 65028 = @cil_clt +| 65029 = @cil_clt_un +| 65030 = @cil_ldftn +| 65031 = @cil_ldvirtftn +| 65033 = @cil_ldarg +| 65034 = @cil_ldarga +| 65035 = @cil_starg +| 65036 = @cil_ldloc +| 65037 = @cil_ldloca +| 65038 = @cil_stloc +| 65039 = @cil_localloc +| 65041 = @cil_endfilter +| 65042 = @cil_unaligned +| 65043 = @cil_volatile +| 65044 = @cil_tail +| 65045 = @cil_initobj +| 65046 = @cil_constrained +| 65047 = @cil_cpblk +| 65048 = @cil_initblk +| 65050 = @cil_rethrow +| 65052 = @cil_sizeof +| 65053 = @cil_refanytype +| 65054 = @cil_readonly +; + +// CIL ignored instructions + +@cil_ignore = @cil_nop | @cil_break | @cil_volatile | @cil_unaligned; + +// CIL local/parameter/field access + +@cil_ldarg_any = @cil_ldarg_0 | @cil_ldarg_1 | @cil_ldarg_2 | @cil_ldarg_3 | @cil_ldarg_s | @cil_ldarga_s | @cil_ldarg | @cil_ldarga; +@cil_starg_any = @cil_starg | @cil_starg_s; + +@cil_ldloc_any = @cil_ldloc_0 | @cil_ldloc_1 | @cil_ldloc_2 | @cil_ldloc_3 | @cil_ldloc_s | @cil_ldloca_s | @cil_ldloc | @cil_ldloca; +@cil_stloc_any = @cil_stloc_0 | @cil_stloc_1 | @cil_stloc_2 | @cil_stloc_3 | @cil_stloc_s | @cil_stloc; + +@cil_ldfld_any = @cil_ldfld | @cil_ldsfld | @cil_ldsflda | @cil_ldflda; +@cil_stfld_any = @cil_stfld | @cil_stsfld; + +@cil_local_access = @cil_stloc_any | @cil_ldloc_any; +@cil_arg_access = @cil_starg_any | @cil_ldarg_any; +@cil_read_access = @cil_ldloc_any | @cil_ldarg_any | @cil_ldfld_any; +@cil_write_access = @cil_stloc_any | @cil_starg_any | @cil_stfld_any; + +@cil_stack_access = @cil_local_access | @cil_arg_access; +@cil_field_access = @cil_ldfld_any | @cil_stfld_any; + +@cil_access = @cil_read_access | @cil_write_access; + +// CIL constant/literal instructions + +@cil_ldc_i = @cil_ldc_i4_any | @cil_ldc_i8; + +@cil_ldc_i4_any = @cil_ldc_i4_m1 | @cil_ldc_i4_0 | @cil_ldc_i4_1 | @cil_ldc_i4_2 | @cil_ldc_i4_3 | + @cil_ldc_i4_4 | @cil_ldc_i4_5 | @cil_ldc_i4_6 | @cil_ldc_i4_7 | @cil_ldc_i4_8 | @cil_ldc_i4_s | @cil_ldc_i4; + +@cil_ldc_r = @cil_ldc_r4 | @cil_ldc_r8; + +@cil_literal = @cil_ldnull | @cil_ldc_i | @cil_ldc_r | @cil_ldstr; + +// Control flow + +@cil_conditional_jump = @cil_binary_jump | @cil_unary_jump; +@cil_binary_jump = @cil_beq_s | @cil_bge_s | @cil_bgt_s | @cil_ble_s | @cil_blt_s | + @cil_bne_un_s | @cil_bge_un_s | @cil_bgt_un_s | @cil_ble_un_s | @cil_blt_un_s | + @cil_beq | @cil_bge | @cil_bgt | @cil_ble | @cil_blt | + @cil_bne_un | @cil_bge_un | @cil_bgt_un | @cil_ble_un | @cil_blt_un; +@cil_unary_jump = @cil_brfalse_s | @cil_brtrue_s | @cil_brfalse | @cil_brtrue | @cil_switch; +@cil_unconditional_jump = @cil_br | @cil_br_s | @cil_leave_any; +@cil_leave_any = @cil_leave | @cil_leave_s; +@cil_jump = @cil_unconditional_jump | @cil_conditional_jump; + +// CIL call instructions + +@cil_call_any = @cil_jmp | @cil_call | @cil_calli | @cil_tail | @cil_callvirt | @cil_newobj; + +// CIL expression instructions + +@cil_expr = @cil_literal | @cil_binary_expr | @cil_unary_expr | @cil_call_any | @cil_read_access | + @cil_newarr | @cil_ldtoken | @cil_sizeof | + @cil_ldftn | @cil_ldvirtftn | @cil_localloc | @cil_mkrefany | @cil_refanytype | @cil_arglist | @cil_dup; + +@cil_unary_expr = + @cil_conversion_operation | @cil_unary_arithmetic_operation | @cil_unary_bitwise_operation| + @cil_ldlen | @cil_isinst | @cil_box | @cil_ldobj | @cil_castclass | @cil_unbox_any | + @cil_ldind | @cil_unbox; + +@cil_conversion_operation = + @cil_conv_i1 | @cil_conv_i2 | @cil_conv_i4 | @cil_conv_i8 | + @cil_conv_u1 | @cil_conv_u2 | @cil_conv_u4 | @cil_conv_u8 | + @cil_conv_ovf_i | @cil_conv_ovf_i_un | @cil_conv_ovf_i1 | @cil_conv_ovf_i1_un | + @cil_conv_ovf_i2 | @cil_conv_ovf_i2_un | @cil_conv_ovf_i4 | @cil_conv_ovf_i4_un | + @cil_conv_ovf_i8 | @cil_conv_ovf_i8_un | @cil_conv_ovf_u | @cil_conv_ovf_u_un | + @cil_conv_ovf_u1 | @cil_conv_ovf_u1_un | @cil_conv_ovf_u2 | @cil_conv_ovf_u2_un | + @cil_conv_ovf_u4 | @cil_conv_ovf_u4_un | @cil_conv_ovf_u8 | @cil_conv_ovf_u8_un | + @cil_conv_r4 | @cil_conv_r8 | @cil_conv_ovf_u2 | @cil_conv_ovf_u2_un | + @cil_conv_i | @cil_conv_u | @cil_conv_r_un; + +@cil_ldind = @cil_ldind_i | @cil_ldind_i1 | @cil_ldind_i2 | @cil_ldind_i4 | @cil_ldind_i8 | + @cil_ldind_r4 | @cil_ldind_r8 | @cil_ldind_ref | @cil_ldind_u1 | @cil_ldind_u2 | @cil_ldind_u4; + +@cil_stind = @cil_stind_i | @cil_stind_i1 | @cil_stind_i2 | @cil_stind_i4 | @cil_stind_i8 | + @cil_stind_r4 | @cil_stind_r8 | @cil_stind_ref; + +@cil_bitwise_operation = @cil_binary_bitwise_operation | @cil_unary_bitwise_operation; + +@cil_binary_bitwise_operation = @cil_and | @cil_or | @cil_xor | @cil_shr | @cil_shr | @cil_shr_un | @cil_shl; + +@cil_binary_arithmetic_operation = @cil_add | @cil_sub | @cil_mul | @cil_div | @cil_div_un | + @cil_rem | @cil_rem_un | @cil_add_ovf | @cil_add_ovf_un | @cil_mul_ovf | @cil_mul_ovf_un | + @cil_sub_ovf | @cil_sub_ovf_un; + +@cil_unary_bitwise_operation = @cil_not; + +@cil_binary_expr = @cil_binary_arithmetic_operation | @cil_binary_bitwise_operation | @cil_read_array | @cil_comparison_operation; + +@cil_unary_arithmetic_operation = @cil_neg; + +@cil_comparison_operation = @cil_cgt_un | @cil_ceq | @cil_cgt | @cil_clt | @cil_clt_un; + +// Elements that retrieve an address of something +@cil_read_ref = @cil_ldloca_s | @cil_ldarga_s | @cil_ldflda | @cil_ldsflda | @cil_ldelema; + +// CIL array instructions + +@cil_read_array = + @cil_ldelem | @cil_ldelema | @cil_ldelem_i1 | @cil_ldelem_ref | @cil_ldelem_i | + @cil_ldelem_i1 | @cil_ldelem_i2 | @cil_ldelem_i4 | @cil_ldelem_i8 | @cil_ldelem_r4 | + @cil_ldelem_r8 | @cil_ldelem_u1 | @cil_ldelem_u2 | @cil_ldelem_u4; + +@cil_write_array = @cil_stelem | @cil_stelem_ref | + @cil_stelem_i | @cil_stelem_i1 | @cil_stelem_i2 | @cil_stelem_i4 | @cil_stelem_i8 | + @cil_stelem_r4 | @cil_stelem_r8; + +@cil_throw_any = @cil_throw | @cil_rethrow; + +#keyset[impl, index] +cil_instruction( + unique int id: @cil_instruction, + int opcode: int ref, + int index: int ref, + int impl: @cil_method_implementation ref); + +cil_jump( + unique int instruction: @cil_jump ref, + int target: @cil_instruction ref); + +cil_access( + unique int instruction: @cil_instruction ref, + int target: @cil_accessible ref); + +cil_value( + unique int instruction: @cil_literal ref, + string value: string ref); + +#keyset[instruction, index] +cil_switch( + int instruction: @cil_switch ref, + int index: int ref, + int target: @cil_instruction ref); + +cil_instruction_location( + unique int id: @cil_instruction ref, + int loc: @location ref); + +cil_type_location( + int id: @cil_type ref, + int loc: @location ref); + +cil_method_location( + int id: @cil_method ref, + int loc: @location ref); + +@cil_namespace = @namespace; + +@cil_type_container = @cil_type | @cil_namespace | @cil_method; + +case @cil_type.kind of + 0 = @cil_valueorreftype +| 1 = @cil_typeparameter +| 2 = @cil_array_type +| 3 = @cil_pointer_type +; + +cil_type( + unique int id: @cil_type, + string name: string ref, + int kind: int ref, + int parent: @cil_type_container ref, + int sourceDecl: @cil_type ref); + +cil_pointer_type( + unique int id: @cil_pointer_type ref, + int pointee: @cil_type ref); + +cil_array_type( + unique int id: @cil_array_type ref, + int element_type: @cil_type ref, + int rank: int ref); + +cil_method( + unique int id: @cil_method, + string name: string ref, + int parent: @cil_type ref, + int return_type: @cil_type ref); + +cil_method_source_declaration( + unique int method: @cil_method ref, + int source: @cil_method ref); + +cil_method_implementation( + unique int id: @cil_method_implementation, + int method: @cil_method ref, + int location: @assembly ref); + +cil_implements( + int id: @cil_method ref, + int decl: @cil_method ref); + +#keyset[parent, name] +cil_field( + unique int id: @cil_field, + int parent: @cil_type ref, + string name: string ref, + int field_type: @cil_type ref); + +@cil_element = @cil_instruction | @cil_declaration | @cil_handler | @cil_attribute | @cil_namespace; +@cil_named_element = @cil_declaration | @cil_namespace; +@cil_declaration = @cil_variable | @cil_method | @cil_type | @cil_member; +@cil_accessible = @cil_declaration; +@cil_variable = @cil_field | @cil_stack_variable; +@cil_stack_variable = @cil_local_variable | @cil_parameter; +@cil_member = @cil_method | @cil_type | @cil_field | @cil_property | @cil_event; + +#keyset[method, index] +cil_parameter( + unique int id: @cil_parameter, + int method: @cil_method ref, + int index: int ref, + int param_type: @cil_type ref); + +cil_parameter_in(unique int id: @cil_parameter ref); +cil_parameter_out(unique int id: @cil_parameter ref); + +cil_setter(unique int prop: @cil_property ref, + int method: @cil_method ref); + +cil_getter(unique int prop: @cil_property ref, + int method: @cil_method ref); + +cil_adder(unique int event: @cil_event ref, + int method: @cil_method ref); + +cil_remover(unique int event: @cil_event ref, int method: @cil_method ref); + +cil_raiser(unique int event: @cil_event ref, int method: @cil_method ref); + +cil_property( + unique int id: @cil_property, + int parent: @cil_type ref, + string name: string ref, + int property_type: @cil_type ref); + +#keyset[parent, name] +cil_event(unique int id: @cil_event, + int parent: @cil_type ref, + string name: string ref, + int event_type: @cil_type ref); + +#keyset[impl, index] +cil_local_variable( + unique int id: @cil_local_variable, + int impl: @cil_method_implementation ref, + int index: int ref, + int var_type: @cil_type ref); + +// CIL handlers (exception handlers etc). + +case @cil_handler.kind of + 0 = @cil_catch_handler +| 1 = @cil_filter_handler +| 2 = @cil_finally_handler +| 4 = @cil_fault_handler +; + +#keyset[impl, index] +cil_handler( + unique int id: @cil_handler, + int impl: @cil_method_implementation ref, + int index: int ref, + int kind: int ref, + int try_start: @cil_instruction ref, + int try_end: @cil_instruction ref, + int handler_start: @cil_instruction ref); + +cil_handler_filter( + unique int id: @cil_handler ref, + int filter_start: @cil_instruction ref); + +cil_handler_type( + unique int id: @cil_handler ref, + int catch_type: @cil_type ref); + +@cil_controlflow_node = @cil_entry_point | @cil_instruction; + +@cil_entry_point = @cil_method_implementation | @cil_handler; + +@cil_dataflow_node = @cil_instruction | @cil_variable | @cil_method; + +cil_method_stack_size( + unique int method: @cil_method_implementation ref, + int size: int ref); + +// CIL modifiers + +cil_public(int id: @cil_member ref); +cil_private(int id: @cil_member ref); +cil_protected(int id: @cil_member ref); +cil_internal(int id: @cil_member ref); +cil_static(int id: @cil_member ref); +cil_sealed(int id: @cil_member ref); +cil_virtual(int id: @cil_method ref); +cil_abstract(int id: @cil_member ref); +cil_class(int id: @cil_type ref); +cil_interface(int id: @cil_type ref); +cil_security(int id: @cil_member ref); +cil_requiresecobject(int id: @cil_method ref); +cil_specialname(int id: @cil_method ref); +cil_newslot(int id: @cil_method ref); + +cil_base_class(unique int id: @cil_type ref, int base: @cil_type ref); +cil_base_interface(int id: @cil_type ref, int base: @cil_type ref); +cil_enum_underlying_type(unique int id: @cil_type ref, int underlying: @cil_type ref); + +#keyset[unbound, index] +cil_type_parameter( + int unbound: @cil_member ref, + int index: int ref, + int param: @cil_typeparameter ref); + +#keyset[bound, index] +cil_type_argument( + int bound: @cil_member ref, + int index: int ref, + int t: @cil_type ref); + +// CIL type parameter constraints + +cil_typeparam_covariant(int tp: @cil_typeparameter ref); +cil_typeparam_contravariant(int tp: @cil_typeparameter ref); +cil_typeparam_class(int tp: @cil_typeparameter ref); +cil_typeparam_struct(int tp: @cil_typeparameter ref); +cil_typeparam_new(int tp: @cil_typeparameter ref); +cil_typeparam_constraint(int tp: @cil_typeparameter ref, int supertype: @cil_type ref); + +// CIL attributes + +cil_attribute( + unique int attributeid: @cil_attribute, + int element: @cil_declaration ref, + int constructor: @cil_method ref); + +#keyset[attribute_id, param] +cil_attribute_named_argument( + int attribute_id: @cil_attribute ref, + string param: string ref, + string value: string ref); + +#keyset[attribute_id, index] +cil_attribute_positional_argument( + int attribute_id: @cil_attribute ref, + int index: int ref, + string value: string ref); + + +// Common .Net data model covering both C# and CIL + +// Common elements +@dotnet_element = @element | @cil_element; +@dotnet_named_element = @named_element | @cil_named_element; +@dotnet_callable = @callable | @cil_method; +@dotnet_variable = @variable | @cil_variable; +@dotnet_field = @field | @cil_field; +@dotnet_parameter = @parameter | @cil_parameter; +@dotnet_declaration = @declaration | @cil_declaration; +@dotnet_member = @member | @cil_member; +@dotnet_event = @event | @cil_event; +@dotnet_property = @property | @cil_property | @indexer; + +// Common types +@dotnet_type = @type | @cil_type; +@dotnet_call = @call | @cil_call_any; +@dotnet_throw = @throw_element | @cil_throw_any; +@dotnet_valueorreftype = @cil_valueorreftype | @value_or_ref_type | @cil_array_type | @void_type; +@dotnet_typeparameter = @type_parameter | @cil_typeparameter; +@dotnet_array_type = @array_type | @cil_array_type; +@dotnet_pointer_type = @pointer_type | @cil_pointer_type; +@dotnet_type_parameter = @type_parameter | @cil_typeparameter; +@dotnet_generic = @dotnet_valueorreftype | @dotnet_callable; + +// Attributes +@dotnet_attribute = @attribute | @cil_attribute; + +// Expressions +@dotnet_expr = @expr | @cil_expr; + +// Literals +@dotnet_literal = @literal_expr | @cil_literal; +@dotnet_string_literal = @string_literal_expr | @cil_ldstr; +@dotnet_int_literal = @integer_literal_expr | @cil_ldc_i; +@dotnet_float_literal = @float_literal_expr | @cil_ldc_r; +@dotnet_null_literal = @null_literal_expr | @cil_ldnull; + +@metadata_entity = @cil_method | @cil_type | @cil_field | @cil_property | @field | @property | + @callable | @value_or_ref_type | @void_type; + +#keyset[entity, location] +metadata_handle(int entity : @metadata_entity ref, int location: @assembly ref, int handle: int ref) diff --git a/csharp/upgrades/eedef9359e1e4e1ebcf2a1dc9d2ae75d4ea4d160/upgrade.properties b/csharp/upgrades/eedef9359e1e4e1ebcf2a1dc9d2ae75d4ea4d160/upgrade.properties new file mode 100644 index 00000000000..fdaaf2f3f09 --- /dev/null +++ b/csharp/upgrades/eedef9359e1e4e1ebcf2a1dc9d2ae75d4ea4d160/upgrade.properties @@ -0,0 +1,2 @@ +description: Add 'cil_enum_underlying_type' to store underlying type of 'enum' declarations. +compatibility: backwards diff --git a/csharp/upgrades/efcd69e086a26dd33395f2ddb3113b2849399040/old.dbscheme b/csharp/upgrades/efcd69e086a26dd33395f2ddb3113b2849399040/old.dbscheme new file mode 100644 index 00000000000..efcd69e086a --- /dev/null +++ b/csharp/upgrades/efcd69e086a26dd33395f2ddb3113b2849399040/old.dbscheme @@ -0,0 +1,1959 @@ + +/** + * An invocation of the compiler. Note that more than one file may be + * compiled per invocation. For example, this command compiles three + * source files: + * + * csc f1.cs f2.cs f3.cs + * + * The `id` simply identifies the invocation, while `cwd` is the working + * directory from which the compiler was invoked. + */ +compilations( + unique int id : @compilation, + string cwd : string ref +); + +/** + * The arguments that were passed to the extractor for a compiler + * invocation. If `id` is for the compiler invocation + * + * csc f1.cs f2.cs f3.cs + * + * then typically there will be rows for + * + * num | arg + * --- | --- + * 0 | --compiler + * 1 | *path to compiler* + * 2 | --cil + * 3 | f1.cs + * 4 | f2.cs + * 5 | f3.cs + */ +#keyset[id, num] +compilation_args( + int id : @compilation ref, + int num : int ref, + string arg : string ref +); + +/** + * The source files that are compiled by a compiler invocation. + * If `id` is for the compiler invocation + * + * csc f1.cs f2.cs f3.cs + * + * then there will be rows for + * + * num | arg + * --- | --- + * 0 | f1.cs + * 1 | f2.cs + * 2 | f3.cs + */ +#keyset[id, num] +compilation_compiling_files( + int id : @compilation ref, + int num : int ref, + int file : @file ref +); + +/** + * The references used by a compiler invocation. + * If `id` is for the compiler invocation + * + * csc f1.cs f2.cs f3.cs /r:ref1.dll /r:ref2.dll /r:ref3.dll + * + * then there will be rows for + * + * num | arg + * --- | --- + * 0 | ref1.dll + * 1 | ref2.dll + * 2 | ref3.dll + */ +#keyset[id, num] +compilation_referencing_files( + int id : @compilation ref, + int num : int ref, + int file : @file ref +); + +/** + * The time taken by the extractor for a compiler invocation. + * + * For each file `num`, there will be rows for + * + * kind | seconds + * ---- | --- + * 1 | CPU seconds used by the extractor frontend + * 2 | Elapsed seconds during the extractor frontend + * 3 | CPU seconds used by the extractor backend + * 4 | Elapsed seconds during the extractor backend + */ +#keyset[id, num, kind] +compilation_time( + int id : @compilation ref, + int num : int ref, + /* kind: + 1 = frontend_cpu_seconds + 2 = frontend_elapsed_seconds + 3 = extractor_cpu_seconds + 4 = extractor_elapsed_seconds + */ + int kind : int ref, + float seconds : float ref +); + +/** + * An error or warning generated by the extractor. + * The diagnostic message `diagnostic` was generated during compiler + * invocation `compilation`, and is the `file_number_diagnostic_number`th + * message generated while extracting the `file_number`th file of that + * invocation. + */ +#keyset[compilation, file_number, file_number_diagnostic_number] +diagnostic_for( + unique int diagnostic : @diagnostic ref, + int compilation : @compilation ref, + int file_number : int ref, + int file_number_diagnostic_number : int ref +); + +diagnostics( + unique int id: @diagnostic, + int severity: int ref, + string error_tag: string ref, + string error_message: string ref, + string full_error_message: string ref, + int location: @location_default ref +); + +extractor_messages( + unique int id: @extractor_message, + int severity: int ref, + string origin : string ref, + string text : string ref, + string entity : string ref, + int location: @location_default ref, + string stack_trace : string ref +); + +/** + * If extraction was successful, then `cpu_seconds` and + * `elapsed_seconds` are the CPU time and elapsed time (respectively) + * that extraction took for compiler invocation `id`. + */ +compilation_finished( + unique int id : @compilation ref, + float cpu_seconds : float ref, + float elapsed_seconds : float ref +); + +compilation_assembly( + unique int id : @compilation ref, + int assembly: @assembly ref +) + +/* + * External artifacts + */ + +externalDefects( + unique int id: @externalDefect, + string queryPath: string ref, + int location: @location ref, + string message: string ref, + float severity: float ref); + +externalMetrics( + unique int id: @externalMetric, + string queryPath: string ref, + int location: @location ref, + float value: float ref); + +externalData( + int id: @externalDataElement, + string path: string ref, + int column: int ref, + string value: string ref); + +snapshotDate( + unique date snapshotDate: date ref); + +sourceLocationPrefix( + string prefix: string ref); + +/* + * Duplicate code + */ + +duplicateCode( + unique int id: @duplication, + string relativePath: string ref, + int equivClass: int ref); + +similarCode( + unique int id: @similarity, + string relativePath: string ref, + int equivClass: int ref); + +@duplication_or_similarity = @duplication | @similarity + +tokens( + int id: @duplication_or_similarity ref, + int offset: int ref, + int beginLine: int ref, + int beginColumn: int ref, + int endLine: int ref, + int endColumn: int ref); + +/* + * C# dbscheme + */ + +/** ELEMENTS **/ + +@element = @declaration | @stmt | @expr | @modifier | @attribute | @namespace_declaration + | @using_directive | @type_parameter_constraints | @external_element + | @xmllocatable | @asp_element | @namespace; + +@declaration = @callable | @generic | @assignable | @namespace; + +@named_element = @namespace | @declaration; + +@declaration_with_accessors = @property | @indexer | @event; + +@assignable = @variable | @assignable_with_accessors | @event; + +@assignable_with_accessors = @property | @indexer; + +@external_element = @externalMetric | @externalDefect | @externalDataElement; + +@attributable = @assembly | @field | @parameter | @operator | @method | @constructor + | @destructor | @callable_accessor | @value_or_ref_type | @declaration_with_accessors + | @local_function; + +/** LOCATIONS, ASEMMBLIES, MODULES, FILES and FOLDERS **/ + +@location = @location_default | @assembly; + +locations_default( + unique int id: @location_default, + int file: @file ref, + int beginLine: int ref, + int beginColumn: int ref, + int endLine: int ref, + int endColumn: int ref); + +@sourceline = @file | @callable | @xmllocatable; + +numlines( + int element_id: @sourceline ref, + int num_lines: int ref, + int num_code: int ref, + int num_comment: int ref); + +assemblies( + unique int id: @assembly, + int file: @file ref, + string fullname: string ref, + string name: string ref, + string version: string ref); + +/* + fromSource(0) = unknown, + fromSource(1) = from source, + fromSource(2) = from library +*/ +files( + unique int id: @file, + string name: string ref, + string simple: string ref, + string ext: string ref, + int fromSource: int ref); + +folders( + unique int id: @folder, + string name: string ref, + string simple: string ref); + +@container = @folder | @file ; + +containerparent( + int parent: @container ref, + unique int child: @container ref); + +file_extraction_mode( + unique int file: @file ref, + int mode: int ref + /* 0 = normal, 1 = standalone extractor */ + ); + +/** NAMESPACES **/ + +@type_container = @namespace | @type; + +namespaces( + unique int id: @namespace, + string name: string ref); + +namespace_declarations( + unique int id: @namespace_declaration, + int namespace_id: @namespace ref); + +namespace_declaration_location( + unique int id: @namespace_declaration ref, + int loc: @location ref); + +parent_namespace( + unique int child_id: @type_container ref, + int namespace_id: @namespace ref); + +@declaration_or_directive = @namespace_declaration | @type | @using_directive; + +parent_namespace_declaration( + int child_id: @declaration_or_directive ref, // cannot be unique because of partial classes + int namespace_id: @namespace_declaration ref); + +@using_directive = @using_namespace_directive | @using_static_directive; + +using_namespace_directives( + unique int id: @using_namespace_directive, + int namespace_id: @namespace ref); + +using_static_directives( + unique int id: @using_static_directive, + int type_id: @type_or_ref ref); + +using_directive_location( + unique int id: @using_directive ref, + int loc: @location ref); + +/** TYPES **/ + +types( + unique int id: @type, + int kind: int ref, + string name: string ref); + +case @type.kind of + 1 = @bool_type +| 2 = @char_type +| 3 = @decimal_type +| 4 = @sbyte_type +| 5 = @short_type +| 6 = @int_type +| 7 = @long_type +| 8 = @byte_type +| 9 = @ushort_type +| 10 = @uint_type +| 11 = @ulong_type +| 12 = @float_type +| 13 = @double_type +| 14 = @enum_type +| 15 = @struct_type +| 17 = @class_type +| 19 = @interface_type +| 20 = @delegate_type +| 21 = @null_type +| 22 = @type_parameter +| 23 = @pointer_type +| 24 = @nullable_type +| 25 = @array_type +| 26 = @void_type +| 27 = @int_ptr_type +| 28 = @uint_ptr_type +| 29 = @dynamic_type +| 30 = @arglist_type +| 31 = @unknown_type +| 32 = @tuple_type +| 33 = @function_pointer_type + ; + +@simple_type = @bool_type | @char_type | @integral_type | @floating_point_type | @decimal_type; +@integral_type = @signed_integral_type | @unsigned_integral_type; +@signed_integral_type = @sbyte_type | @short_type | @int_type | @long_type; +@unsigned_integral_type = @byte_type | @ushort_type | @uint_type | @ulong_type; +@floating_point_type = @float_type | @double_type; +@value_type = @simple_type | @enum_type | @struct_type | @nullable_type | @int_ptr_type + | @uint_ptr_type | @tuple_type; +@ref_type = @class_type | @interface_type | @array_type | @delegate_type | @null_type + | @dynamic_type; +@value_or_ref_type = @value_type | @ref_type; + +typerefs( + unique int id: @typeref, + string name: string ref); + +typeref_type( + int id: @typeref ref, + unique int typeId: @type ref); + +@type_or_ref = @type | @typeref; + +array_element_type( + unique int array: @array_type ref, + int dimension: int ref, + int rank: int ref, + int element: @type_or_ref ref); + +nullable_underlying_type( + unique int nullable: @nullable_type ref, + int underlying: @type_or_ref ref); + +pointer_referent_type( + unique int pointer: @pointer_type ref, + int referent: @type_or_ref ref); + +enum_underlying_type( + unique int enum_id: @enum_type ref, + int underlying_type_id: @type_or_ref ref); + +delegate_return_type( + unique int delegate_id: @delegate_type ref, + int return_type_id: @type_or_ref ref); + +function_pointer_return_type( + unique int function_pointer_id: @function_pointer_type ref, + int return_type_id: @type_or_ref ref); + +extend( + unique int sub: @type ref, + int super: @type_or_ref ref); + +anonymous_types( + unique int id: @type ref); + +@interface_or_ref = @interface_type | @typeref; + +implement( + int sub: @type ref, + int super: @type_or_ref ref); + +type_location( + int id: @type ref, + int loc: @location ref); + +tuple_underlying_type( + unique int tuple: @tuple_type ref, + int struct: @type_or_ref ref); + +#keyset[tuple, index] +tuple_element( + int tuple: @tuple_type ref, + int index: int ref, + unique int field: @field ref); + +attributes( + unique int id: @attribute, + int type_id: @type_or_ref ref, + int target: @attributable ref); + +attribute_location( + int id: @attribute ref, + int loc: @location ref); + +@type_mention_parent = @element | @type_mention; + +type_mention( + unique int id: @type_mention, + int type_id: @type_or_ref ref, + int parent: @type_mention_parent ref); + +type_mention_location( + unique int id: @type_mention ref, + int loc: @location ref); + +@has_type_annotation = @assignable | @type_parameter | @callable | @expr | @delegate_type | @generic | @function_pointer_type; + +/** + * A direct annotation on an entity, for example `string? x;`. + * + * Annotations: + * 2 = reftype is not annotated "!" + * 3 = reftype is annotated "?" + * 4 = readonly ref type / in parameter + * 5 = ref type parameter, return or local variable + * 6 = out parameter + * + * Note that the annotation depends on the element it annotates. + * @assignable: The annotation is on the type of the assignable, for example the variable type. + * @type_parameter: The annotation is on the reftype constraint + * @callable: The annotation is on the return type + * @array_type: The annotation is on the element type + */ +type_annotation(int id: @has_type_annotation ref, int annotation: int ref); + +nullability(unique int nullability: @nullability, int kind: int ref); + +case @nullability.kind of + 0 = @oblivious +| 1 = @not_annotated +| 2 = @annotated +; + +#keyset[parent, index] +nullability_parent(int nullability: @nullability ref, int index: int ref, int parent: @nullability ref) + +type_nullability(int id: @has_type_annotation ref, int nullability: @nullability ref); + +/** + * The nullable flow state of an expression, as determined by Roslyn. + * 0 = none (default, not populated) + * 1 = not null + * 2 = maybe null + */ +expr_flowstate(unique int id: @expr ref, int state: int ref); + +/** GENERICS **/ + +@generic = @type | @method | @local_function; + +type_parameters( + unique int id: @type_parameter ref, + int index: int ref, + int generic_id: @generic ref, + int variance: int ref /* none = 0, out = 1, in = 2 */); + +#keyset[constructed_id, index] +type_arguments( + int id: @type_or_ref ref, + int index: int ref, + int constructed_id: @generic_or_ref ref); + +@generic_or_ref = @generic | @typeref; + +constructed_generic( + unique int constructed: @generic ref, + int generic: @generic_or_ref ref); + +type_parameter_constraints( + unique int id: @type_parameter_constraints, + int param_id: @type_parameter ref); + +type_parameter_constraints_location( + int id: @type_parameter_constraints ref, + int loc: @location ref); + +general_type_parameter_constraints( + int id: @type_parameter_constraints ref, + int kind: int ref /* class = 1, struct = 2, new = 3 */); + +specific_type_parameter_constraints( + int id: @type_parameter_constraints ref, + int base_id: @type_or_ref ref); + +specific_type_parameter_nullability( + int id: @type_parameter_constraints ref, + int base_id: @type_or_ref ref, + int nullability: @nullability ref); + +/** FUNCTION POINTERS */ + +function_pointer_calling_conventions( + int id: @function_pointer_type ref, + int kind: int ref); + +#keyset[id, index] +has_unmanaged_calling_conventions( + int id: @function_pointer_type ref, + int index: int ref, + int conv_id: @type_or_ref ref); + +/** MODIFIERS */ + +@modifiable = @modifiable_direct | @event_accessor; + +@modifiable_direct = @member | @accessor | @local_function | @anonymous_function_expr; + +modifiers( + unique int id: @modifier, + string name: string ref); + +has_modifiers( + int id: @modifiable_direct ref, + int mod_id: @modifier ref); + +compiler_generated(unique int id: @modifiable_direct ref); + +/** MEMBERS **/ + +@member = @method | @constructor | @destructor | @field | @property | @event | @operator | @indexer | @type; + +@named_exprorstmt = @goto_stmt | @labeled_stmt | @expr; + +@virtualizable = @method | @property | @indexer | @event; + +exprorstmt_name( + unique int parent_id: @named_exprorstmt ref, + string name: string ref); + +nested_types( + unique int id: @type ref, + int declaring_type_id: @type ref, + int unbound_id: @type ref); + +properties( + unique int id: @property, + string name: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @property ref); + +property_location( + int id: @property ref, + int loc: @location ref); + +indexers( + unique int id: @indexer, + string name: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @indexer ref); + +indexer_location( + int id: @indexer ref, + int loc: @location ref); + +accessors( + unique int id: @accessor, + int kind: int ref, + string name: string ref, + int declaring_member_id: @member ref, + int unbound_id: @accessor ref); + +case @accessor.kind of + 1 = @getter +| 2 = @setter + ; + +init_only_accessors( + unique int id: @accessor ref); + +accessor_location( + int id: @accessor ref, + int loc: @location ref); + +events( + unique int id: @event, + string name: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @event ref); + +event_location( + int id: @event ref, + int loc: @location ref); + +event_accessors( + unique int id: @event_accessor, + int kind: int ref, + string name: string ref, + int declaring_event_id: @event ref, + int unbound_id: @event_accessor ref); + +case @event_accessor.kind of + 1 = @add_event_accessor +| 2 = @remove_event_accessor + ; + +event_accessor_location( + int id: @event_accessor ref, + int loc: @location ref); + +operators( + unique int id: @operator, + string name: string ref, + string symbol: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @operator ref); + +operator_location( + int id: @operator ref, + int loc: @location ref); + +constant_value( + int id: @variable ref, + string value: string ref); + +/** CALLABLES **/ + +@callable = @method | @constructor | @destructor | @operator | @callable_accessor | @anonymous_function_expr | @local_function; + +@callable_accessor = @accessor | @event_accessor; + +methods( + unique int id: @method, + string name: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @method ref); + +method_location( + int id: @method ref, + int loc: @location ref); + +constructors( + unique int id: @constructor, + string name: string ref, + int declaring_type_id: @type ref, + int unbound_id: @constructor ref); + +constructor_location( + int id: @constructor ref, + int loc: @location ref); + +destructors( + unique int id: @destructor, + string name: string ref, + int declaring_type_id: @type ref, + int unbound_id: @destructor ref); + +destructor_location( + int id: @destructor ref, + int loc: @location ref); + +overrides( + int id: @callable ref, + int base_id: @callable ref); + +explicitly_implements( + int id: @member ref, + int interface_id: @interface_or_ref ref); + +local_functions( + unique int id: @local_function, + string name: string ref, + int return_type: @type ref, + int unbound_id: @local_function ref); + +local_function_stmts( + unique int fn: @local_function_stmt ref, + int stmt: @local_function ref); + +/** VARIABLES **/ + +@variable = @local_scope_variable | @field; + +@local_scope_variable = @local_variable | @parameter; + +fields( + unique int id: @field, + int kind: int ref, + string name: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @field ref); + +case @field.kind of + 1 = @addressable_field +| 2 = @constant + ; + +field_location( + int id: @field ref, + int loc: @location ref); + +localvars( + unique int id: @local_variable, + int kind: int ref, + string name: string ref, + int implicitly_typed: int ref /* 0 = no, 1 = yes */, + int type_id: @type_or_ref ref, + int parent_id: @local_var_decl_expr ref); + +case @local_variable.kind of + 1 = @addressable_local_variable +| 2 = @local_constant +| 3 = @local_variable_ref + ; + +localvar_location( + unique int id: @local_variable ref, + int loc: @location ref); + +@parameterizable = @callable | @delegate_type | @indexer | @function_pointer_type; + +#keyset[name, parent_id] +#keyset[index, parent_id] +params( + unique int id: @parameter, + string name: string ref, + int type_id: @type_or_ref ref, + int index: int ref, + int mode: int ref, /* value = 0, ref = 1, out = 2, array = 3, this = 4 */ + int parent_id: @parameterizable ref, + int unbound_id: @parameter ref); + +param_location( + int id: @parameter ref, + int loc: @location ref); + +/** STATEMENTS **/ + +@exprorstmt_parent = @control_flow_element | @top_level_exprorstmt_parent; + +statements( + unique int id: @stmt, + int kind: int ref); + +#keyset[index, parent] +stmt_parent( + unique int stmt: @stmt ref, + int index: int ref, + int parent: @control_flow_element ref); + +@top_level_stmt_parent = @callable; + +// [index, parent] is not a keyset because the same parent may be compiled multiple times +stmt_parent_top_level( + unique int stmt: @stmt ref, + int index: int ref, + int parent: @top_level_stmt_parent ref); + +case @stmt.kind of + 1 = @block_stmt +| 2 = @expr_stmt +| 3 = @if_stmt +| 4 = @switch_stmt +| 5 = @while_stmt +| 6 = @do_stmt +| 7 = @for_stmt +| 8 = @foreach_stmt +| 9 = @break_stmt +| 10 = @continue_stmt +| 11 = @goto_stmt +| 12 = @goto_case_stmt +| 13 = @goto_default_stmt +| 14 = @throw_stmt +| 15 = @return_stmt +| 16 = @yield_stmt +| 17 = @try_stmt +| 18 = @checked_stmt +| 19 = @unchecked_stmt +| 20 = @lock_stmt +| 21 = @using_block_stmt +| 22 = @var_decl_stmt +| 23 = @const_decl_stmt +| 24 = @empty_stmt +| 25 = @unsafe_stmt +| 26 = @fixed_stmt +| 27 = @label_stmt +| 28 = @catch +| 29 = @case_stmt +| 30 = @local_function_stmt +| 31 = @using_decl_stmt + ; + +@using_stmt = @using_block_stmt | @using_decl_stmt; + +@labeled_stmt = @label_stmt | @case; + +@decl_stmt = @var_decl_stmt | @const_decl_stmt | @using_decl_stmt; + +@cond_stmt = @if_stmt | @switch_stmt; + +@loop_stmt = @while_stmt | @do_stmt | @for_stmt | @foreach_stmt; + +@jump_stmt = @break_stmt | @goto_any_stmt | @continue_stmt | @throw_stmt | @return_stmt + | @yield_stmt; + +@goto_any_stmt = @goto_default_stmt | @goto_case_stmt | @goto_stmt; + + +stmt_location( + unique int id: @stmt ref, + int loc: @location ref); + +catch_type( + unique int catch_id: @catch ref, + int type_id: @type_or_ref ref, + int kind: int ref /* explicit = 1, implicit = 2 */); + +/** EXPRESSIONS **/ + +expressions( + unique int id: @expr, + int kind: int ref, + int type_id: @type_or_ref ref); + +#keyset[index, parent] +expr_parent( + unique int expr: @expr ref, + int index: int ref, + int parent: @control_flow_element ref); + +@top_level_expr_parent = @attribute | @field | @property | @indexer | @parameter; + +@top_level_exprorstmt_parent = @top_level_expr_parent | @top_level_stmt_parent; + +// [index, parent] is not a keyset because the same parent may be compiled multiple times +expr_parent_top_level( + unique int expr: @expr ref, + int index: int ref, + int parent: @top_level_exprorstmt_parent ref); + +case @expr.kind of +/* literal */ + 1 = @bool_literal_expr +| 2 = @char_literal_expr +| 3 = @decimal_literal_expr +| 4 = @int_literal_expr +| 5 = @long_literal_expr +| 6 = @uint_literal_expr +| 7 = @ulong_literal_expr +| 8 = @float_literal_expr +| 9 = @double_literal_expr +| 10 = @string_literal_expr +| 11 = @null_literal_expr +/* primary & unary */ +| 12 = @this_access_expr +| 13 = @base_access_expr +| 14 = @local_variable_access_expr +| 15 = @parameter_access_expr +| 16 = @field_access_expr +| 17 = @property_access_expr +| 18 = @method_access_expr +| 19 = @event_access_expr +| 20 = @indexer_access_expr +| 21 = @array_access_expr +| 22 = @type_access_expr +| 23 = @typeof_expr +| 24 = @method_invocation_expr +| 25 = @delegate_invocation_expr +| 26 = @operator_invocation_expr +| 27 = @cast_expr +| 28 = @object_creation_expr +| 29 = @explicit_delegate_creation_expr +| 30 = @implicit_delegate_creation_expr +| 31 = @array_creation_expr +| 32 = @default_expr +| 33 = @plus_expr +| 34 = @minus_expr +| 35 = @bit_not_expr +| 36 = @log_not_expr +| 37 = @post_incr_expr +| 38 = @post_decr_expr +| 39 = @pre_incr_expr +| 40 = @pre_decr_expr +/* multiplicative */ +| 41 = @mul_expr +| 42 = @div_expr +| 43 = @rem_expr +/* additive */ +| 44 = @add_expr +| 45 = @sub_expr +/* shift */ +| 46 = @lshift_expr +| 47 = @rshift_expr +/* relational */ +| 48 = @lt_expr +| 49 = @gt_expr +| 50 = @le_expr +| 51 = @ge_expr +/* equality */ +| 52 = @eq_expr +| 53 = @ne_expr +/* logical */ +| 54 = @bit_and_expr +| 55 = @bit_xor_expr +| 56 = @bit_or_expr +| 57 = @log_and_expr +| 58 = @log_or_expr +/* type testing */ +| 59 = @is_expr +| 60 = @as_expr +/* null coalescing */ +| 61 = @null_coalescing_expr +/* conditional */ +| 62 = @conditional_expr +/* assignment */ +| 63 = @simple_assign_expr +| 64 = @assign_add_expr +| 65 = @assign_sub_expr +| 66 = @assign_mul_expr +| 67 = @assign_div_expr +| 68 = @assign_rem_expr +| 69 = @assign_and_expr +| 70 = @assign_xor_expr +| 71 = @assign_or_expr +| 72 = @assign_lshift_expr +| 73 = @assign_rshift_expr +/* more */ +| 74 = @object_init_expr +| 75 = @collection_init_expr +| 76 = @array_init_expr +| 77 = @checked_expr +| 78 = @unchecked_expr +| 79 = @constructor_init_expr +| 80 = @add_event_expr +| 81 = @remove_event_expr +| 82 = @par_expr +| 83 = @local_var_decl_expr +| 84 = @lambda_expr +| 85 = @anonymous_method_expr +| 86 = @namespace_expr +/* dynamic */ +| 92 = @dynamic_element_access_expr +| 93 = @dynamic_member_access_expr +/* unsafe */ +| 100 = @pointer_indirection_expr +| 101 = @address_of_expr +| 102 = @sizeof_expr +/* async */ +| 103 = @await_expr +/* C# 6.0 */ +| 104 = @nameof_expr +| 105 = @interpolated_string_expr +| 106 = @unknown_expr +/* C# 7.0 */ +| 107 = @throw_expr +| 108 = @tuple_expr +| 109 = @local_function_invocation_expr +| 110 = @ref_expr +| 111 = @discard_expr +/* C# 8.0 */ +| 112 = @range_expr +| 113 = @index_expr +| 114 = @switch_expr +| 115 = @recursive_pattern_expr +| 116 = @property_pattern_expr +| 117 = @positional_pattern_expr +| 118 = @switch_case_expr +| 119 = @assign_coalesce_expr +| 120 = @suppress_nullable_warning_expr +| 121 = @namespace_access_expr +/* C# 9.0 */ +| 122 = @lt_pattern_expr +| 123 = @gt_pattern_expr +| 124 = @le_pattern_expr +| 125 = @ge_pattern_expr +| 126 = @not_pattern_expr +| 127 = @and_pattern_expr +| 128 = @or_pattern_expr +| 129 = @function_pointer_invocation_expr +; + +@switch = @switch_stmt | @switch_expr; +@case = @case_stmt | @switch_case_expr; +@pattern_match = @case | @is_expr; +@unary_pattern_expr = @not_pattern_expr; +@relational_pattern_expr = @gt_pattern_expr | @lt_pattern_expr | @ge_pattern_expr | @le_pattern_expr; +@binary_pattern_expr = @and_pattern_expr | @or_pattern_expr; + +@integer_literal_expr = @int_literal_expr | @long_literal_expr | @uint_literal_expr | @ulong_literal_expr; +@real_literal_expr = @float_literal_expr | @double_literal_expr | @decimal_literal_expr; +@literal_expr = @bool_literal_expr | @char_literal_expr | @integer_literal_expr | @real_literal_expr + | @string_literal_expr | @null_literal_expr; + +@assign_expr = @simple_assign_expr | @assign_op_expr | @local_var_decl_expr; +@assign_op_expr = @assign_arith_expr | @assign_bitwise_expr | @assign_event_expr | @assign_coalesce_expr; +@assign_event_expr = @add_event_expr | @remove_event_expr; + +@assign_arith_expr = @assign_add_expr | @assign_sub_expr | @assign_mul_expr | @assign_div_expr + | @assign_rem_expr +@assign_bitwise_expr = @assign_and_expr | @assign_or_expr | @assign_xor_expr + | @assign_lshift_expr | @assign_rshift_expr; + +@member_access_expr = @field_access_expr | @property_access_expr | @indexer_access_expr | @event_access_expr + | @method_access_expr | @type_access_expr | @dynamic_member_access_expr; +@access_expr = @member_access_expr | @this_access_expr | @base_access_expr | @assignable_access_expr | @namespace_access_expr; +@element_access_expr = @indexer_access_expr | @array_access_expr | @dynamic_element_access_expr; + +@local_variable_access = @local_variable_access_expr | @local_var_decl_expr; +@local_scope_variable_access_expr = @parameter_access_expr | @local_variable_access; +@variable_access_expr = @local_scope_variable_access_expr | @field_access_expr; + +@assignable_access_expr = @variable_access_expr | @property_access_expr | @element_access_expr + | @event_access_expr | @dynamic_member_access_expr; + +@objectorcollection_init_expr = @object_init_expr | @collection_init_expr; + +@delegate_creation_expr = @explicit_delegate_creation_expr | @implicit_delegate_creation_expr; + +@bin_arith_op_expr = @mul_expr | @div_expr | @rem_expr | @add_expr | @sub_expr; +@incr_op_expr = @pre_incr_expr | @post_incr_expr; +@decr_op_expr = @pre_decr_expr | @post_decr_expr; +@mut_op_expr = @incr_op_expr | @decr_op_expr; +@un_arith_op_expr = @plus_expr | @minus_expr | @mut_op_expr; +@arith_op_expr = @bin_arith_op_expr | @un_arith_op_expr; + +@ternary_log_op_expr = @conditional_expr; +@bin_log_op_expr = @log_and_expr | @log_or_expr | @null_coalescing_expr; +@un_log_op_expr = @log_not_expr; +@log_expr = @un_log_op_expr | @bin_log_op_expr | @ternary_log_op_expr; + +@bin_bit_op_expr = @bit_and_expr | @bit_or_expr | @bit_xor_expr | @lshift_expr + | @rshift_expr; +@un_bit_op_expr = @bit_not_expr; +@bit_expr = @un_bit_op_expr | @bin_bit_op_expr; + +@equality_op_expr = @eq_expr | @ne_expr; +@rel_op_expr = @gt_expr | @lt_expr| @ge_expr | @le_expr; +@comp_expr = @equality_op_expr | @rel_op_expr; + +@op_expr = @assign_expr | @un_op | @bin_op | @ternary_op; + +@ternary_op = @ternary_log_op_expr; +@bin_op = @bin_arith_op_expr | @bin_log_op_expr | @bin_bit_op_expr | @comp_expr; +@un_op = @un_arith_op_expr | @un_log_op_expr | @un_bit_op_expr | @sizeof_expr + | @pointer_indirection_expr | @address_of_expr; + +@anonymous_function_expr = @lambda_expr | @anonymous_method_expr; + +@call = @method_invocation_expr | @constructor_init_expr | @operator_invocation_expr + | @delegate_invocation_expr | @object_creation_expr | @call_access_expr + | @local_function_invocation_expr | @function_pointer_invocation_expr; + +@call_access_expr = @property_access_expr | @event_access_expr | @indexer_access_expr; + +@late_bindable_expr = @dynamic_element_access_expr | @dynamic_member_access_expr + | @object_creation_expr | @method_invocation_expr | @operator_invocation_expr; + +@throw_element = @throw_expr | @throw_stmt; + +@implicitly_typeable_object_creation_expr = @object_creation_expr | @explicit_delegate_creation_expr; + +implicitly_typed_array_creation( + unique int id: @array_creation_expr ref); + +explicitly_sized_array_creation( + unique int id: @array_creation_expr ref); + +stackalloc_array_creation( + unique int id: @array_creation_expr ref); + +implicitly_typed_object_creation( + unique int id: @implicitly_typeable_object_creation_expr ref); + +mutator_invocation_mode( + unique int id: @operator_invocation_expr ref, + int mode: int ref /* prefix = 1, postfix = 2*/); + +expr_compiler_generated( + unique int id: @expr ref); + +expr_value( + unique int id: @expr ref, + string value: string ref); + +expr_call( + unique int caller_id: @expr ref, + int target_id: @callable ref); + +expr_access( + unique int accesser_id: @access_expr ref, + int target_id: @accessible ref); + +@accessible = @method | @assignable | @local_function | @namespace; + +expr_location( + unique int id: @expr ref, + int loc: @location ref); + +dynamic_member_name( + unique int id: @late_bindable_expr ref, + string name: string ref); + +@qualifiable_expr = @member_access_expr + | @method_invocation_expr + | @element_access_expr; + +conditional_access( + unique int id: @qualifiable_expr ref); + +expr_argument( + unique int id: @expr ref, + int mode: int ref); + /* mode is the same as params: value = 0, ref = 1, out = 2 */ + +expr_argument_name( + unique int id: @expr ref, + string name: string ref); + +/** CONTROL/DATA FLOW **/ + +@control_flow_element = @stmt | @expr; + +/* XML Files */ + +xmlEncoding ( + unique int id: @file ref, + string encoding: string ref); + +xmlDTDs( + unique int id: @xmldtd, + string root: string ref, + string publicId: string ref, + string systemId: string ref, + int fileid: @file ref); + +xmlElements( + unique int id: @xmlelement, + string name: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int fileid: @file ref); + +xmlAttrs( + unique int id: @xmlattribute, + int elementid: @xmlelement ref, + string name: string ref, + string value: string ref, + int idx: int ref, + int fileid: @file ref); + +xmlNs( + int id: @xmlnamespace, + string prefixName: string ref, + string URI: string ref, + int fileid: @file ref); + +xmlHasNs( + int elementId: @xmlnamespaceable ref, + int nsId: @xmlnamespace ref, + int fileid: @file ref); + +xmlComments( + unique int id: @xmlcomment, + string text: string ref, + int parentid: @xmlparent ref, + int fileid: @file ref); + +xmlChars( + unique int id: @xmlcharacters, + string text: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int isCDATA: int ref, + int fileid: @file ref); + +@xmlparent = @file | @xmlelement; +@xmlnamespaceable = @xmlelement | @xmlattribute; + +xmllocations( + int xmlElement: @xmllocatable ref, + int location: @location_default ref); + +@xmllocatable = @xmlcharacters | @xmlelement | @xmlcomment | @xmlattribute | @xmldtd | @file | @xmlnamespace; + +/* Comments */ + +commentline( + unique int id: @commentline, + int kind: int ref, + string text: string ref, + string rawtext: string ref); + +case @commentline.kind of + 0 = @singlelinecomment +| 1 = @xmldoccomment +| 2 = @multilinecomment; + +commentline_location( + unique int id: @commentline ref, + int loc: @location ref); + +commentblock( + unique int id : @commentblock); + +commentblock_location( + unique int id: @commentblock ref, + int loc: @location ref); + +commentblock_binding( + int id: @commentblock ref, + int entity: @element ref, + int bindtype: int ref); /* 0: Parent, 1: Best, 2: Before, 3: After */ + +commentblock_child( + int id: @commentblock ref, + int commentline: @commentline ref, + int index: int ref); + +/* ASP.NET */ + +case @asp_element.kind of + 0=@asp_close_tag +| 1=@asp_code +| 2=@asp_comment +| 3=@asp_data_binding +| 4=@asp_directive +| 5=@asp_open_tag +| 6=@asp_quoted_string +| 7=@asp_text +| 8=@asp_xml_directive; + +@asp_attribute = @asp_code | @asp_data_binding | @asp_quoted_string; + +asp_elements( + unique int id: @asp_element, + int kind: int ref, + int loc: @location ref); + +asp_comment_server(unique int comment: @asp_comment ref); +asp_code_inline(unique int code: @asp_code ref); +asp_directive_attribute( + int directive: @asp_directive ref, + int index: int ref, + string name: string ref, + int value: @asp_quoted_string ref); +asp_directive_name( + unique int directive: @asp_directive ref, + string name: string ref); +asp_element_body( + unique int element: @asp_element ref, + string body: string ref); +asp_tag_attribute( + int tag: @asp_open_tag ref, + int index: int ref, + string name: string ref, + int attribute: @asp_attribute ref); +asp_tag_name( + unique int tag: @asp_open_tag ref, + string name: string ref); +asp_tag_isempty(int tag: @asp_open_tag ref); + +/* Common Intermediate Language - CIL */ + +case @cil_instruction.opcode of + 0 = @cil_nop +| 1 = @cil_break +| 2 = @cil_ldarg_0 +| 3 = @cil_ldarg_1 +| 4 = @cil_ldarg_2 +| 5 = @cil_ldarg_3 +| 6 = @cil_ldloc_0 +| 7 = @cil_ldloc_1 +| 8 = @cil_ldloc_2 +| 9 = @cil_ldloc_3 +| 10 = @cil_stloc_0 +| 11 = @cil_stloc_1 +| 12 = @cil_stloc_2 +| 13 = @cil_stloc_3 +| 14 = @cil_ldarg_s +| 15 = @cil_ldarga_s +| 16 = @cil_starg_s +| 17 = @cil_ldloc_s +| 18 = @cil_ldloca_s +| 19 = @cil_stloc_s +| 20 = @cil_ldnull +| 21 = @cil_ldc_i4_m1 +| 22 = @cil_ldc_i4_0 +| 23 = @cil_ldc_i4_1 +| 24 = @cil_ldc_i4_2 +| 25 = @cil_ldc_i4_3 +| 26 = @cil_ldc_i4_4 +| 27 = @cil_ldc_i4_5 +| 28 = @cil_ldc_i4_6 +| 29 = @cil_ldc_i4_7 +| 30 = @cil_ldc_i4_8 +| 31 = @cil_ldc_i4_s +| 32 = @cil_ldc_i4 +| 33 = @cil_ldc_i8 +| 34 = @cil_ldc_r4 +| 35 = @cil_ldc_r8 +| 37 = @cil_dup +| 38 = @cil_pop +| 39 = @cil_jmp +| 40 = @cil_call +| 41 = @cil_calli +| 42 = @cil_ret +| 43 = @cil_br_s +| 44 = @cil_brfalse_s +| 45 = @cil_brtrue_s +| 46 = @cil_beq_s +| 47 = @cil_bge_s +| 48 = @cil_bgt_s +| 49 = @cil_ble_s +| 50 = @cil_blt_s +| 51 = @cil_bne_un_s +| 52 = @cil_bge_un_s +| 53 = @cil_bgt_un_s +| 54 = @cil_ble_un_s +| 55 = @cil_blt_un_s +| 56 = @cil_br +| 57 = @cil_brfalse +| 58 = @cil_brtrue +| 59 = @cil_beq +| 60 = @cil_bge +| 61 = @cil_bgt +| 62 = @cil_ble +| 63 = @cil_blt +| 64 = @cil_bne_un +| 65 = @cil_bge_un +| 66 = @cil_bgt_un +| 67 = @cil_ble_un +| 68 = @cil_blt_un +| 69 = @cil_switch +| 70 = @cil_ldind_i1 +| 71 = @cil_ldind_u1 +| 72 = @cil_ldind_i2 +| 73 = @cil_ldind_u2 +| 74 = @cil_ldind_i4 +| 75 = @cil_ldind_u4 +| 76 = @cil_ldind_i8 +| 77 = @cil_ldind_i +| 78 = @cil_ldind_r4 +| 79 = @cil_ldind_r8 +| 80 = @cil_ldind_ref +| 81 = @cil_stind_ref +| 82 = @cil_stind_i1 +| 83 = @cil_stind_i2 +| 84 = @cil_stind_i4 +| 85 = @cil_stind_i8 +| 86 = @cil_stind_r4 +| 87 = @cil_stind_r8 +| 88 = @cil_add +| 89 = @cil_sub +| 90 = @cil_mul +| 91 = @cil_div +| 92 = @cil_div_un +| 93 = @cil_rem +| 94 = @cil_rem_un +| 95 = @cil_and +| 96 = @cil_or +| 97 = @cil_xor +| 98 = @cil_shl +| 99 = @cil_shr +| 100 = @cil_shr_un +| 101 = @cil_neg +| 102 = @cil_not +| 103 = @cil_conv_i1 +| 104 = @cil_conv_i2 +| 105 = @cil_conv_i4 +| 106 = @cil_conv_i8 +| 107 = @cil_conv_r4 +| 108 = @cil_conv_r8 +| 109 = @cil_conv_u4 +| 110 = @cil_conv_u8 +| 111 = @cil_callvirt +| 112 = @cil_cpobj +| 113 = @cil_ldobj +| 114 = @cil_ldstr +| 115 = @cil_newobj +| 116 = @cil_castclass +| 117 = @cil_isinst +| 118 = @cil_conv_r_un +| 121 = @cil_unbox +| 122 = @cil_throw +| 123 = @cil_ldfld +| 124 = @cil_ldflda +| 125 = @cil_stfld +| 126 = @cil_ldsfld +| 127 = @cil_ldsflda +| 128 = @cil_stsfld +| 129 = @cil_stobj +| 130 = @cil_conv_ovf_i1_un +| 131 = @cil_conv_ovf_i2_un +| 132 = @cil_conv_ovf_i4_un +| 133 = @cil_conv_ovf_i8_un +| 134 = @cil_conv_ovf_u1_un +| 135 = @cil_conv_ovf_u2_un +| 136 = @cil_conv_ovf_u4_un +| 137 = @cil_conv_ovf_u8_un +| 138 = @cil_conv_ovf_i_un +| 139 = @cil_conv_ovf_u_un +| 140 = @cil_box +| 141 = @cil_newarr +| 142 = @cil_ldlen +| 143 = @cil_ldelema +| 144 = @cil_ldelem_i1 +| 145 = @cil_ldelem_u1 +| 146 = @cil_ldelem_i2 +| 147 = @cil_ldelem_u2 +| 148 = @cil_ldelem_i4 +| 149 = @cil_ldelem_u4 +| 150 = @cil_ldelem_i8 +| 151 = @cil_ldelem_i +| 152 = @cil_ldelem_r4 +| 153 = @cil_ldelem_r8 +| 154 = @cil_ldelem_ref +| 155 = @cil_stelem_i +| 156 = @cil_stelem_i1 +| 157 = @cil_stelem_i2 +| 158 = @cil_stelem_i4 +| 159 = @cil_stelem_i8 +| 160 = @cil_stelem_r4 +| 161 = @cil_stelem_r8 +| 162 = @cil_stelem_ref +| 163 = @cil_ldelem +| 164 = @cil_stelem +| 165 = @cil_unbox_any +| 179 = @cil_conv_ovf_i1 +| 180 = @cil_conv_ovf_u1 +| 181 = @cil_conv_ovf_i2 +| 182 = @cil_conv_ovf_u2 +| 183 = @cil_conv_ovf_i4 +| 184 = @cil_conv_ovf_u4 +| 185 = @cil_conv_ovf_i8 +| 186 = @cil_conv_ovf_u8 +| 194 = @cil_refanyval +| 195 = @cil_ckinfinite +| 198 = @cil_mkrefany +| 208 = @cil_ldtoken +| 209 = @cil_conv_u2 +| 210 = @cil_conv_u1 +| 211 = @cil_conv_i +| 212 = @cil_conv_ovf_i +| 213 = @cil_conv_ovf_u +| 214 = @cil_add_ovf +| 215 = @cil_add_ovf_un +| 216 = @cil_mul_ovf +| 217 = @cil_mul_ovf_un +| 218 = @cil_sub_ovf +| 219 = @cil_sub_ovf_un +| 220 = @cil_endfinally +| 221 = @cil_leave +| 222 = @cil_leave_s +| 223 = @cil_stind_i +| 224 = @cil_conv_u +| 65024 = @cil_arglist +| 65025 = @cil_ceq +| 65026 = @cil_cgt +| 65027 = @cil_cgt_un +| 65028 = @cil_clt +| 65029 = @cil_clt_un +| 65030 = @cil_ldftn +| 65031 = @cil_ldvirtftn +| 65033 = @cil_ldarg +| 65034 = @cil_ldarga +| 65035 = @cil_starg +| 65036 = @cil_ldloc +| 65037 = @cil_ldloca +| 65038 = @cil_stloc +| 65039 = @cil_localloc +| 65041 = @cil_endfilter +| 65042 = @cil_unaligned +| 65043 = @cil_volatile +| 65044 = @cil_tail +| 65045 = @cil_initobj +| 65046 = @cil_constrained +| 65047 = @cil_cpblk +| 65048 = @cil_initblk +| 65050 = @cil_rethrow +| 65052 = @cil_sizeof +| 65053 = @cil_refanytype +| 65054 = @cil_readonly +; + +// CIL ignored instructions + +@cil_ignore = @cil_nop | @cil_break | @cil_volatile | @cil_unaligned; + +// CIL local/parameter/field access + +@cil_ldarg_any = @cil_ldarg_0 | @cil_ldarg_1 | @cil_ldarg_2 | @cil_ldarg_3 | @cil_ldarg_s | @cil_ldarga_s | @cil_ldarg | @cil_ldarga; +@cil_starg_any = @cil_starg | @cil_starg_s; + +@cil_ldloc_any = @cil_ldloc_0 | @cil_ldloc_1 | @cil_ldloc_2 | @cil_ldloc_3 | @cil_ldloc_s | @cil_ldloca_s | @cil_ldloc | @cil_ldloca; +@cil_stloc_any = @cil_stloc_0 | @cil_stloc_1 | @cil_stloc_2 | @cil_stloc_3 | @cil_stloc_s | @cil_stloc; + +@cil_ldfld_any = @cil_ldfld | @cil_ldsfld | @cil_ldsflda | @cil_ldflda; +@cil_stfld_any = @cil_stfld | @cil_stsfld; + +@cil_local_access = @cil_stloc_any | @cil_ldloc_any; +@cil_arg_access = @cil_starg_any | @cil_ldarg_any; +@cil_read_access = @cil_ldloc_any | @cil_ldarg_any | @cil_ldfld_any; +@cil_write_access = @cil_stloc_any | @cil_starg_any | @cil_stfld_any; + +@cil_stack_access = @cil_local_access | @cil_arg_access; +@cil_field_access = @cil_ldfld_any | @cil_stfld_any; + +@cil_access = @cil_read_access | @cil_write_access; + +// CIL constant/literal instructions + +@cil_ldc_i = @cil_ldc_i4_any | @cil_ldc_i8; + +@cil_ldc_i4_any = @cil_ldc_i4_m1 | @cil_ldc_i4_0 | @cil_ldc_i4_1 | @cil_ldc_i4_2 | @cil_ldc_i4_3 | + @cil_ldc_i4_4 | @cil_ldc_i4_5 | @cil_ldc_i4_6 | @cil_ldc_i4_7 | @cil_ldc_i4_8 | @cil_ldc_i4_s | @cil_ldc_i4; + +@cil_ldc_r = @cil_ldc_r4 | @cil_ldc_r8; + +@cil_literal = @cil_ldnull | @cil_ldc_i | @cil_ldc_r | @cil_ldstr; + +// Control flow + +@cil_conditional_jump = @cil_binary_jump | @cil_unary_jump; +@cil_binary_jump = @cil_beq_s | @cil_bge_s | @cil_bgt_s | @cil_ble_s | @cil_blt_s | + @cil_bne_un_s | @cil_bge_un_s | @cil_bgt_un_s | @cil_ble_un_s | @cil_blt_un_s | + @cil_beq | @cil_bge | @cil_bgt | @cil_ble | @cil_blt | + @cil_bne_un | @cil_bge_un | @cil_bgt_un | @cil_ble_un | @cil_blt_un; +@cil_unary_jump = @cil_brfalse_s | @cil_brtrue_s | @cil_brfalse | @cil_brtrue | @cil_switch; +@cil_unconditional_jump = @cil_br | @cil_br_s | @cil_leave_any; +@cil_leave_any = @cil_leave | @cil_leave_s; +@cil_jump = @cil_unconditional_jump | @cil_conditional_jump; + +// CIL call instructions + +@cil_call_any = @cil_jmp | @cil_call | @cil_calli | @cil_tail | @cil_callvirt | @cil_newobj; + +// CIL expression instructions + +@cil_expr = @cil_literal | @cil_binary_expr | @cil_unary_expr | @cil_call_any | @cil_read_access | + @cil_newarr | @cil_ldtoken | @cil_sizeof | + @cil_ldftn | @cil_ldvirtftn | @cil_localloc | @cil_mkrefany | @cil_refanytype | @cil_arglist | @cil_dup; + +@cil_unary_expr = + @cil_conversion_operation | @cil_unary_arithmetic_operation | @cil_unary_bitwise_operation| + @cil_ldlen | @cil_isinst | @cil_box | @cil_ldobj | @cil_castclass | @cil_unbox_any | + @cil_ldind | @cil_unbox; + +@cil_conversion_operation = + @cil_conv_i1 | @cil_conv_i2 | @cil_conv_i4 | @cil_conv_i8 | + @cil_conv_u1 | @cil_conv_u2 | @cil_conv_u4 | @cil_conv_u8 | + @cil_conv_ovf_i | @cil_conv_ovf_i_un | @cil_conv_ovf_i1 | @cil_conv_ovf_i1_un | + @cil_conv_ovf_i2 | @cil_conv_ovf_i2_un | @cil_conv_ovf_i4 | @cil_conv_ovf_i4_un | + @cil_conv_ovf_i8 | @cil_conv_ovf_i8_un | @cil_conv_ovf_u | @cil_conv_ovf_u_un | + @cil_conv_ovf_u1 | @cil_conv_ovf_u1_un | @cil_conv_ovf_u2 | @cil_conv_ovf_u2_un | + @cil_conv_ovf_u4 | @cil_conv_ovf_u4_un | @cil_conv_ovf_u8 | @cil_conv_ovf_u8_un | + @cil_conv_r4 | @cil_conv_r8 | @cil_conv_ovf_u2 | @cil_conv_ovf_u2_un | + @cil_conv_i | @cil_conv_u | @cil_conv_r_un; + +@cil_ldind = @cil_ldind_i | @cil_ldind_i1 | @cil_ldind_i2 | @cil_ldind_i4 | @cil_ldind_i8 | + @cil_ldind_r4 | @cil_ldind_r8 | @cil_ldind_ref | @cil_ldind_u1 | @cil_ldind_u2 | @cil_ldind_u4; + +@cil_stind = @cil_stind_i | @cil_stind_i1 | @cil_stind_i2 | @cil_stind_i4 | @cil_stind_i8 | + @cil_stind_r4 | @cil_stind_r8 | @cil_stind_ref; + +@cil_bitwise_operation = @cil_binary_bitwise_operation | @cil_unary_bitwise_operation; + +@cil_binary_bitwise_operation = @cil_and | @cil_or | @cil_xor | @cil_shr | @cil_shr | @cil_shr_un | @cil_shl; + +@cil_binary_arithmetic_operation = @cil_add | @cil_sub | @cil_mul | @cil_div | @cil_div_un | + @cil_rem | @cil_rem_un | @cil_add_ovf | @cil_add_ovf_un | @cil_mul_ovf | @cil_mul_ovf_un | + @cil_sub_ovf | @cil_sub_ovf_un; + +@cil_unary_bitwise_operation = @cil_not; + +@cil_binary_expr = @cil_binary_arithmetic_operation | @cil_binary_bitwise_operation | @cil_read_array | @cil_comparison_operation; + +@cil_unary_arithmetic_operation = @cil_neg; + +@cil_comparison_operation = @cil_cgt_un | @cil_ceq | @cil_cgt | @cil_clt | @cil_clt_un; + +// Elements that retrieve an address of something +@cil_read_ref = @cil_ldloca_s | @cil_ldarga_s | @cil_ldflda | @cil_ldsflda | @cil_ldelema; + +// CIL array instructions + +@cil_read_array = + @cil_ldelem | @cil_ldelema | @cil_ldelem_i1 | @cil_ldelem_ref | @cil_ldelem_i | + @cil_ldelem_i1 | @cil_ldelem_i2 | @cil_ldelem_i4 | @cil_ldelem_i8 | @cil_ldelem_r4 | + @cil_ldelem_r8 | @cil_ldelem_u1 | @cil_ldelem_u2 | @cil_ldelem_u4; + +@cil_write_array = @cil_stelem | @cil_stelem_ref | + @cil_stelem_i | @cil_stelem_i1 | @cil_stelem_i2 | @cil_stelem_i4 | @cil_stelem_i8 | + @cil_stelem_r4 | @cil_stelem_r8; + +@cil_throw_any = @cil_throw | @cil_rethrow; + +#keyset[impl, index] +cil_instruction( + unique int id: @cil_instruction, + int opcode: int ref, + int index: int ref, + int impl: @cil_method_implementation ref); + +cil_jump( + unique int instruction: @cil_jump ref, + int target: @cil_instruction ref); + +cil_access( + unique int instruction: @cil_instruction ref, + int target: @cil_accessible ref); + +cil_value( + unique int instruction: @cil_literal ref, + string value: string ref); + +#keyset[instruction, index] +cil_switch( + int instruction: @cil_switch ref, + int index: int ref, + int target: @cil_instruction ref); + +cil_instruction_location( + unique int id: @cil_instruction ref, + int loc: @location ref); + +cil_type_location( + int id: @cil_type ref, + int loc: @location ref); + +cil_method_location( + int id: @cil_method ref, + int loc: @location ref); + +@cil_namespace = @namespace; + +@cil_type_container = @cil_type | @cil_namespace | @cil_method; + +case @cil_type.kind of + 0 = @cil_valueorreftype +| 1 = @cil_typeparameter +| 2 = @cil_array_type +| 3 = @cil_pointer_type +| 4 = @cil_function_pointer_type +; + +cil_type( + unique int id: @cil_type, + string name: string ref, + int kind: int ref, + int parent: @cil_type_container ref, + int sourceDecl: @cil_type ref); + +cil_pointer_type( + unique int id: @cil_pointer_type ref, + int pointee: @cil_type ref); + +cil_array_type( + unique int id: @cil_array_type ref, + int element_type: @cil_type ref, + int rank: int ref); + +cil_function_pointer_return_type( + unique int id: @cil_function_pointer_type ref, + int return_type: @cil_type ref); + +cil_method( + unique int id: @cil_method, + string name: string ref, + int parent: @cil_type ref, + int return_type: @cil_type ref); + +cil_method_source_declaration( + unique int method: @cil_method ref, + int source: @cil_method ref); + +cil_method_implementation( + unique int id: @cil_method_implementation, + int method: @cil_method ref, + int location: @assembly ref); + +cil_implements( + int id: @cil_method ref, + int decl: @cil_method ref); + +#keyset[parent, name] +cil_field( + unique int id: @cil_field, + int parent: @cil_type ref, + string name: string ref, + int field_type: @cil_type ref); + +@cil_element = @cil_instruction | @cil_declaration | @cil_handler | @cil_attribute | @cil_namespace; +@cil_named_element = @cil_declaration | @cil_namespace; +@cil_declaration = @cil_variable | @cil_method | @cil_type | @cil_member; +@cil_accessible = @cil_declaration; +@cil_variable = @cil_field | @cil_stack_variable; +@cil_stack_variable = @cil_local_variable | @cil_parameter; +@cil_member = @cil_method | @cil_type | @cil_field | @cil_property | @cil_event; +@cil_custom_modifier_receiver = @cil_method | @cil_property | @cil_parameter | @cil_field | @cil_function_pointer_type; +@cil_parameterizable = @cil_method | @cil_function_pointer_type; +@cil_has_type_annotation = @cil_stack_variable | @cil_property | @cil_method | @cil_function_pointer_type; + +#keyset[parameterizable, index] +cil_parameter( + unique int id: @cil_parameter, + int parameterizable: @cil_parameterizable ref, + int index: int ref, + int param_type: @cil_type ref); + +cil_parameter_in(unique int id: @cil_parameter ref); +cil_parameter_out(unique int id: @cil_parameter ref); + +cil_setter(unique int prop: @cil_property ref, + int method: @cil_method ref); + +#keyset[id, modifier] +cil_custom_modifiers( + int id: @cil_custom_modifier_receiver ref, + int modifier: @cil_type ref, + int kind: int ref); // modreq: 1, modopt: 0 + +cil_type_annotation( + int id: @cil_has_type_annotation ref, + int annotation: int ref); + +cil_getter(unique int prop: @cil_property ref, + int method: @cil_method ref); + +cil_adder(unique int event: @cil_event ref, + int method: @cil_method ref); + +cil_remover(unique int event: @cil_event ref, int method: @cil_method ref); + +cil_raiser(unique int event: @cil_event ref, int method: @cil_method ref); + +cil_property( + unique int id: @cil_property, + int parent: @cil_type ref, + string name: string ref, + int property_type: @cil_type ref); + +#keyset[parent, name] +cil_event(unique int id: @cil_event, + int parent: @cil_type ref, + string name: string ref, + int event_type: @cil_type ref); + +#keyset[impl, index] +cil_local_variable( + unique int id: @cil_local_variable, + int impl: @cil_method_implementation ref, + int index: int ref, + int var_type: @cil_type ref); + +cil_function_pointer_calling_conventions( + int id: @cil_function_pointer_type ref, + int kind: int ref); + +// CIL handlers (exception handlers etc). + +case @cil_handler.kind of + 0 = @cil_catch_handler +| 1 = @cil_filter_handler +| 2 = @cil_finally_handler +| 4 = @cil_fault_handler +; + +#keyset[impl, index] +cil_handler( + unique int id: @cil_handler, + int impl: @cil_method_implementation ref, + int index: int ref, + int kind: int ref, + int try_start: @cil_instruction ref, + int try_end: @cil_instruction ref, + int handler_start: @cil_instruction ref); + +cil_handler_filter( + unique int id: @cil_handler ref, + int filter_start: @cil_instruction ref); + +cil_handler_type( + unique int id: @cil_handler ref, + int catch_type: @cil_type ref); + +@cil_controlflow_node = @cil_entry_point | @cil_instruction; + +@cil_entry_point = @cil_method_implementation | @cil_handler; + +@cil_dataflow_node = @cil_instruction | @cil_variable | @cil_method; + +cil_method_stack_size( + unique int method: @cil_method_implementation ref, + int size: int ref); + +// CIL modifiers + +cil_public(int id: @cil_member ref); +cil_private(int id: @cil_member ref); +cil_protected(int id: @cil_member ref); +cil_internal(int id: @cil_member ref); +cil_static(int id: @cil_member ref); +cil_sealed(int id: @cil_member ref); +cil_virtual(int id: @cil_method ref); +cil_abstract(int id: @cil_member ref); +cil_class(int id: @cil_type ref); +cil_interface(int id: @cil_type ref); +cil_security(int id: @cil_member ref); +cil_requiresecobject(int id: @cil_method ref); +cil_specialname(int id: @cil_method ref); +cil_newslot(int id: @cil_method ref); + +cil_base_class(unique int id: @cil_type ref, int base: @cil_type ref); +cil_base_interface(int id: @cil_type ref, int base: @cil_type ref); +cil_enum_underlying_type(unique int id: @cil_type ref, int underlying: @cil_type ref); + +#keyset[unbound, index] +cil_type_parameter( + int unbound: @cil_member ref, + int index: int ref, + int param: @cil_typeparameter ref); + +#keyset[bound, index] +cil_type_argument( + int bound: @cil_member ref, + int index: int ref, + int t: @cil_type ref); + +// CIL type parameter constraints + +cil_typeparam_covariant(int tp: @cil_typeparameter ref); +cil_typeparam_contravariant(int tp: @cil_typeparameter ref); +cil_typeparam_class(int tp: @cil_typeparameter ref); +cil_typeparam_struct(int tp: @cil_typeparameter ref); +cil_typeparam_new(int tp: @cil_typeparameter ref); +cil_typeparam_constraint(int tp: @cil_typeparameter ref, int supertype: @cil_type ref); + +// CIL attributes + +cil_attribute( + unique int attributeid: @cil_attribute, + int element: @cil_declaration ref, + int constructor: @cil_method ref); + +#keyset[attribute_id, param] +cil_attribute_named_argument( + int attribute_id: @cil_attribute ref, + string param: string ref, + string value: string ref); + +#keyset[attribute_id, index] +cil_attribute_positional_argument( + int attribute_id: @cil_attribute ref, + int index: int ref, + string value: string ref); + + +// Common .Net data model covering both C# and CIL + +// Common elements +@dotnet_element = @element | @cil_element; +@dotnet_named_element = @named_element | @cil_named_element; +@dotnet_callable = @callable | @cil_method; +@dotnet_variable = @variable | @cil_variable; +@dotnet_field = @field | @cil_field; +@dotnet_parameter = @parameter | @cil_parameter; +@dotnet_declaration = @declaration | @cil_declaration; +@dotnet_member = @member | @cil_member; +@dotnet_event = @event | @cil_event; +@dotnet_property = @property | @cil_property | @indexer; +@dotnet_parameterizable = @parameterizable | @cil_parameterizable; + +// Common types +@dotnet_type = @type | @cil_type; +@dotnet_call = @call | @cil_call_any; +@dotnet_throw = @throw_element | @cil_throw_any; +@dotnet_valueorreftype = @cil_valueorreftype | @value_or_ref_type | @cil_array_type | @void_type; +@dotnet_typeparameter = @type_parameter | @cil_typeparameter; +@dotnet_array_type = @array_type | @cil_array_type; +@dotnet_pointer_type = @pointer_type | @cil_pointer_type; +@dotnet_type_parameter = @type_parameter | @cil_typeparameter; +@dotnet_generic = @dotnet_valueorreftype | @dotnet_callable; + +// Attributes +@dotnet_attribute = @attribute | @cil_attribute; + +// Expressions +@dotnet_expr = @expr | @cil_expr; + +// Literals +@dotnet_literal = @literal_expr | @cil_literal; +@dotnet_string_literal = @string_literal_expr | @cil_ldstr; +@dotnet_int_literal = @integer_literal_expr | @cil_ldc_i; +@dotnet_float_literal = @float_literal_expr | @cil_ldc_r; +@dotnet_null_literal = @null_literal_expr | @cil_ldnull; + +@metadata_entity = @cil_method | @cil_type | @cil_field | @cil_property | @field | @property | + @callable | @value_or_ref_type | @void_type; + +#keyset[entity, location] +metadata_handle(int entity : @metadata_entity ref, int location: @assembly ref, int handle: int ref) diff --git a/csharp/upgrades/efcd69e086a26dd33395f2ddb3113b2849399040/semmlecode.csharp.dbscheme b/csharp/upgrades/efcd69e086a26dd33395f2ddb3113b2849399040/semmlecode.csharp.dbscheme new file mode 100644 index 00000000000..68db341c2ed --- /dev/null +++ b/csharp/upgrades/efcd69e086a26dd33395f2ddb3113b2849399040/semmlecode.csharp.dbscheme @@ -0,0 +1,2070 @@ + +/** + * An invocation of the compiler. Note that more than one file may be + * compiled per invocation. For example, this command compiles three + * source files: + * + * csc f1.cs f2.cs f3.cs + * + * The `id` simply identifies the invocation, while `cwd` is the working + * directory from which the compiler was invoked. + */ +compilations( + unique int id : @compilation, + string cwd : string ref +); + +/** + * The arguments that were passed to the extractor for a compiler + * invocation. If `id` is for the compiler invocation + * + * csc f1.cs f2.cs f3.cs + * + * then typically there will be rows for + * + * num | arg + * --- | --- + * 0 | --compiler + * 1 | *path to compiler* + * 2 | --cil + * 3 | f1.cs + * 4 | f2.cs + * 5 | f3.cs + */ +#keyset[id, num] +compilation_args( + int id : @compilation ref, + int num : int ref, + string arg : string ref +); + +/** + * The source files that are compiled by a compiler invocation. + * If `id` is for the compiler invocation + * + * csc f1.cs f2.cs f3.cs + * + * then there will be rows for + * + * num | arg + * --- | --- + * 0 | f1.cs + * 1 | f2.cs + * 2 | f3.cs + */ +#keyset[id, num] +compilation_compiling_files( + int id : @compilation ref, + int num : int ref, + int file : @file ref +); + +/** + * The references used by a compiler invocation. + * If `id` is for the compiler invocation + * + * csc f1.cs f2.cs f3.cs /r:ref1.dll /r:ref2.dll /r:ref3.dll + * + * then there will be rows for + * + * num | arg + * --- | --- + * 0 | ref1.dll + * 1 | ref2.dll + * 2 | ref3.dll + */ +#keyset[id, num] +compilation_referencing_files( + int id : @compilation ref, + int num : int ref, + int file : @file ref +); + +/** + * The time taken by the extractor for a compiler invocation. + * + * For each file `num`, there will be rows for + * + * kind | seconds + * ---- | --- + * 1 | CPU seconds used by the extractor frontend + * 2 | Elapsed seconds during the extractor frontend + * 3 | CPU seconds used by the extractor backend + * 4 | Elapsed seconds during the extractor backend + */ +#keyset[id, num, kind] +compilation_time( + int id : @compilation ref, + int num : int ref, + /* kind: + 1 = frontend_cpu_seconds + 2 = frontend_elapsed_seconds + 3 = extractor_cpu_seconds + 4 = extractor_elapsed_seconds + */ + int kind : int ref, + float seconds : float ref +); + +/** + * An error or warning generated by the extractor. + * The diagnostic message `diagnostic` was generated during compiler + * invocation `compilation`, and is the `file_number_diagnostic_number`th + * message generated while extracting the `file_number`th file of that + * invocation. + */ +#keyset[compilation, file_number, file_number_diagnostic_number] +diagnostic_for( + unique int diagnostic : @diagnostic ref, + int compilation : @compilation ref, + int file_number : int ref, + int file_number_diagnostic_number : int ref +); + +diagnostics( + unique int id: @diagnostic, + int severity: int ref, + string error_tag: string ref, + string error_message: string ref, + string full_error_message: string ref, + int location: @location_default ref +); + +extractor_messages( + unique int id: @extractor_message, + int severity: int ref, + string origin : string ref, + string text : string ref, + string entity : string ref, + int location: @location_default ref, + string stack_trace : string ref +); + +/** + * If extraction was successful, then `cpu_seconds` and + * `elapsed_seconds` are the CPU time and elapsed time (respectively) + * that extraction took for compiler invocation `id`. + */ +compilation_finished( + unique int id : @compilation ref, + float cpu_seconds : float ref, + float elapsed_seconds : float ref +); + +compilation_assembly( + unique int id : @compilation ref, + int assembly: @assembly ref +) + +/* + * External artifacts + */ + +externalDefects( + unique int id: @externalDefect, + string queryPath: string ref, + int location: @location ref, + string message: string ref, + float severity: float ref); + +externalMetrics( + unique int id: @externalMetric, + string queryPath: string ref, + int location: @location ref, + float value: float ref); + +externalData( + int id: @externalDataElement, + string path: string ref, + int column: int ref, + string value: string ref); + +snapshotDate( + unique date snapshotDate: date ref); + +sourceLocationPrefix( + string prefix: string ref); + +/* + * Duplicate code + */ + +duplicateCode( + unique int id: @duplication, + string relativePath: string ref, + int equivClass: int ref); + +similarCode( + unique int id: @similarity, + string relativePath: string ref, + int equivClass: int ref); + +@duplication_or_similarity = @duplication | @similarity + +tokens( + int id: @duplication_or_similarity ref, + int offset: int ref, + int beginLine: int ref, + int beginColumn: int ref, + int endLine: int ref, + int endColumn: int ref); + +/* + * C# dbscheme + */ + +/** ELEMENTS **/ + +@element = @declaration | @stmt | @expr | @modifier | @attribute | @namespace_declaration + | @using_directive | @type_parameter_constraints | @external_element + | @xmllocatable | @asp_element | @namespace | @preprocessor_directive; + +@declaration = @callable | @generic | @assignable | @namespace; + +@named_element = @namespace | @declaration; + +@declaration_with_accessors = @property | @indexer | @event; + +@assignable = @variable | @assignable_with_accessors | @event; + +@assignable_with_accessors = @property | @indexer; + +@external_element = @externalMetric | @externalDefect | @externalDataElement; + +@attributable = @assembly | @field | @parameter | @operator | @method | @constructor + | @destructor | @callable_accessor | @value_or_ref_type | @declaration_with_accessors + | @local_function; + +/** LOCATIONS, ASEMMBLIES, MODULES, FILES and FOLDERS **/ + +@location = @location_default | @assembly; + +locations_default( + unique int id: @location_default, + int file: @file ref, + int beginLine: int ref, + int beginColumn: int ref, + int endLine: int ref, + int endColumn: int ref); + +locations_mapped( + unique int id: @location_default ref, + int mapped_to: @location_default ref); + +@sourceline = @file | @callable | @xmllocatable; + +numlines( + int element_id: @sourceline ref, + int num_lines: int ref, + int num_code: int ref, + int num_comment: int ref); + +assemblies( + unique int id: @assembly, + int file: @file ref, + string fullname: string ref, + string name: string ref, + string version: string ref); + +/* + fromSource(0) = unknown, + fromSource(1) = from source, + fromSource(2) = from library +*/ +files( + unique int id: @file, + string name: string ref, + string simple: string ref, + string ext: string ref, + int fromSource: int ref); + +folders( + unique int id: @folder, + string name: string ref, + string simple: string ref); + +@container = @folder | @file ; + +containerparent( + int parent: @container ref, + unique int child: @container ref); + +file_extraction_mode( + unique int file: @file ref, + int mode: int ref + /* 0 = normal, 1 = standalone extractor */ + ); + +/** NAMESPACES **/ + +@type_container = @namespace | @type; + +namespaces( + unique int id: @namespace, + string name: string ref); + +namespace_declarations( + unique int id: @namespace_declaration, + int namespace_id: @namespace ref); + +namespace_declaration_location( + unique int id: @namespace_declaration ref, + int loc: @location ref); + +parent_namespace( + unique int child_id: @type_container ref, + int namespace_id: @namespace ref); + +@declaration_or_directive = @namespace_declaration | @type | @using_directive; + +parent_namespace_declaration( + int child_id: @declaration_or_directive ref, // cannot be unique because of partial classes + int namespace_id: @namespace_declaration ref); + +@using_directive = @using_namespace_directive | @using_static_directive; + +using_namespace_directives( + unique int id: @using_namespace_directive, + int namespace_id: @namespace ref); + +using_static_directives( + unique int id: @using_static_directive, + int type_id: @type_or_ref ref); + +using_directive_location( + unique int id: @using_directive ref, + int loc: @location ref); + +@preprocessor_directive = @pragma_warning | @pragma_checksum | @directive_define | @directive_undefine | @directive_warning + | @directive_error | @directive_nullable | @directive_line | @directive_region | @directive_endregion | @directive_if + | @directive_elif | @directive_else | @directive_endif; + +@conditional_directive = @directive_if | @directive_elif; +@branch_directive = @directive_if | @directive_elif | @directive_else; + +directive_ifs( + unique int id: @directive_if, + int branchTaken: int ref, /* 0: false, 1: true */ + int conditionValue: int ref); /* 0: false, 1: true */ + +directive_elifs( + unique int id: @directive_elif, + int branchTaken: int ref, /* 0: false, 1: true */ + int conditionValue: int ref, /* 0: false, 1: true */ + int parent: @directive_if ref, + int index: int ref); + +directive_elses( + unique int id: @directive_else, + int branchTaken: int ref, /* 0: false, 1: true */ + int parent: @directive_if ref, + int index: int ref); + +#keyset[id, start] +directive_endifs( + unique int id: @directive_endif, + unique int start: @directive_if ref); + +directive_define_symbols( + unique int id: @define_symbol_expr ref, + string name: string ref); + +directive_regions( + unique int id: @directive_region, + string name: string ref); + +#keyset[id, start] +directive_endregions( + unique int id: @directive_endregion, + unique int start: @directive_region ref); + +directive_lines( + unique int id: @directive_line, + int kind: int ref); /* 0: default, 1: hidden, 2: numeric */ + +directive_line_value( + unique int id: @directive_line ref, + int line: int ref); + +directive_line_file( + unique int id: @directive_line ref, + int file: @file ref +) + +directive_nullables( + unique int id: @directive_nullable, + int setting: int ref, /* 0: disable, 1: enable, 2: restore */ + int target: int ref); /* 0: none, 1: annotations, 2: warnings */ + +directive_warnings( + unique int id: @directive_warning, + string message: string ref); + +directive_errors( + unique int id: @directive_error, + string message: string ref); + +directive_undefines( + unique int id: @directive_undefine, + string name: string ref); + +directive_defines( + unique int id: @directive_define, + string name: string ref); + +pragma_checksums( + unique int id: @pragma_checksum, + int file: @file ref, + string guid: string ref, + string bytes: string ref); + +pragma_warnings( + unique int id: @pragma_warning, + int kind: int ref /* 0 = disable, 1 = restore */); + +#keyset[id, index] +pragma_warning_error_codes( + int id: @pragma_warning ref, + string errorCode: string ref, + int index: int ref); + +preprocessor_directive_location( + unique int id: @preprocessor_directive ref, + int loc: @location ref); + +preprocessor_directive_compilation( + unique int id: @preprocessor_directive ref, + int compilation: @compilation ref); + +preprocessor_directive_active( + unique int id: @preprocessor_directive ref, + int active: int ref); /* 0: false, 1: true */ + +/** TYPES **/ + +types( + unique int id: @type, + int kind: int ref, + string name: string ref); + +case @type.kind of + 1 = @bool_type +| 2 = @char_type +| 3 = @decimal_type +| 4 = @sbyte_type +| 5 = @short_type +| 6 = @int_type +| 7 = @long_type +| 8 = @byte_type +| 9 = @ushort_type +| 10 = @uint_type +| 11 = @ulong_type +| 12 = @float_type +| 13 = @double_type +| 14 = @enum_type +| 15 = @struct_type +| 17 = @class_type +| 19 = @interface_type +| 20 = @delegate_type +| 21 = @null_type +| 22 = @type_parameter +| 23 = @pointer_type +| 24 = @nullable_type +| 25 = @array_type +| 26 = @void_type +| 27 = @int_ptr_type +| 28 = @uint_ptr_type +| 29 = @dynamic_type +| 30 = @arglist_type +| 31 = @unknown_type +| 32 = @tuple_type +| 33 = @function_pointer_type + ; + +@simple_type = @bool_type | @char_type | @integral_type | @floating_point_type | @decimal_type; +@integral_type = @signed_integral_type | @unsigned_integral_type; +@signed_integral_type = @sbyte_type | @short_type | @int_type | @long_type; +@unsigned_integral_type = @byte_type | @ushort_type | @uint_type | @ulong_type; +@floating_point_type = @float_type | @double_type; +@value_type = @simple_type | @enum_type | @struct_type | @nullable_type | @int_ptr_type + | @uint_ptr_type | @tuple_type; +@ref_type = @class_type | @interface_type | @array_type | @delegate_type | @null_type + | @dynamic_type; +@value_or_ref_type = @value_type | @ref_type; + +typerefs( + unique int id: @typeref, + string name: string ref); + +typeref_type( + int id: @typeref ref, + unique int typeId: @type ref); + +@type_or_ref = @type | @typeref; + +array_element_type( + unique int array: @array_type ref, + int dimension: int ref, + int rank: int ref, + int element: @type_or_ref ref); + +nullable_underlying_type( + unique int nullable: @nullable_type ref, + int underlying: @type_or_ref ref); + +pointer_referent_type( + unique int pointer: @pointer_type ref, + int referent: @type_or_ref ref); + +enum_underlying_type( + unique int enum_id: @enum_type ref, + int underlying_type_id: @type_or_ref ref); + +delegate_return_type( + unique int delegate_id: @delegate_type ref, + int return_type_id: @type_or_ref ref); + +function_pointer_return_type( + unique int function_pointer_id: @function_pointer_type ref, + int return_type_id: @type_or_ref ref); + +extend( + unique int sub: @type ref, + int super: @type_or_ref ref); + +anonymous_types( + unique int id: @type ref); + +@interface_or_ref = @interface_type | @typeref; + +implement( + int sub: @type ref, + int super: @type_or_ref ref); + +type_location( + int id: @type ref, + int loc: @location ref); + +tuple_underlying_type( + unique int tuple: @tuple_type ref, + int struct: @type_or_ref ref); + +#keyset[tuple, index] +tuple_element( + int tuple: @tuple_type ref, + int index: int ref, + unique int field: @field ref); + +attributes( + unique int id: @attribute, + int type_id: @type_or_ref ref, + int target: @attributable ref); + +attribute_location( + int id: @attribute ref, + int loc: @location ref); + +@type_mention_parent = @element | @type_mention; + +type_mention( + unique int id: @type_mention, + int type_id: @type_or_ref ref, + int parent: @type_mention_parent ref); + +type_mention_location( + unique int id: @type_mention ref, + int loc: @location ref); + +@has_type_annotation = @assignable | @type_parameter | @callable | @expr | @delegate_type | @generic | @function_pointer_type; + +/** + * A direct annotation on an entity, for example `string? x;`. + * + * Annotations: + * 2 = reftype is not annotated "!" + * 3 = reftype is annotated "?" + * 4 = readonly ref type / in parameter + * 5 = ref type parameter, return or local variable + * 6 = out parameter + * + * Note that the annotation depends on the element it annotates. + * @assignable: The annotation is on the type of the assignable, for example the variable type. + * @type_parameter: The annotation is on the reftype constraint + * @callable: The annotation is on the return type + * @array_type: The annotation is on the element type + */ +type_annotation(int id: @has_type_annotation ref, int annotation: int ref); + +nullability(unique int nullability: @nullability, int kind: int ref); + +case @nullability.kind of + 0 = @oblivious +| 1 = @not_annotated +| 2 = @annotated +; + +#keyset[parent, index] +nullability_parent(int nullability: @nullability ref, int index: int ref, int parent: @nullability ref) + +type_nullability(int id: @has_type_annotation ref, int nullability: @nullability ref); + +/** + * The nullable flow state of an expression, as determined by Roslyn. + * 0 = none (default, not populated) + * 1 = not null + * 2 = maybe null + */ +expr_flowstate(unique int id: @expr ref, int state: int ref); + +/** GENERICS **/ + +@generic = @type | @method | @local_function; + +type_parameters( + unique int id: @type_parameter ref, + int index: int ref, + int generic_id: @generic ref, + int variance: int ref /* none = 0, out = 1, in = 2 */); + +#keyset[constructed_id, index] +type_arguments( + int id: @type_or_ref ref, + int index: int ref, + int constructed_id: @generic_or_ref ref); + +@generic_or_ref = @generic | @typeref; + +constructed_generic( + unique int constructed: @generic ref, + int generic: @generic_or_ref ref); + +type_parameter_constraints( + unique int id: @type_parameter_constraints, + int param_id: @type_parameter ref); + +type_parameter_constraints_location( + int id: @type_parameter_constraints ref, + int loc: @location ref); + +general_type_parameter_constraints( + int id: @type_parameter_constraints ref, + int kind: int ref /* class = 1, struct = 2, new = 3 */); + +specific_type_parameter_constraints( + int id: @type_parameter_constraints ref, + int base_id: @type_or_ref ref); + +specific_type_parameter_nullability( + int id: @type_parameter_constraints ref, + int base_id: @type_or_ref ref, + int nullability: @nullability ref); + +/** FUNCTION POINTERS */ + +function_pointer_calling_conventions( + int id: @function_pointer_type ref, + int kind: int ref); + +#keyset[id, index] +has_unmanaged_calling_conventions( + int id: @function_pointer_type ref, + int index: int ref, + int conv_id: @type_or_ref ref); + +/** MODIFIERS */ + +@modifiable = @modifiable_direct | @event_accessor; + +@modifiable_direct = @member | @accessor | @local_function | @anonymous_function_expr; + +modifiers( + unique int id: @modifier, + string name: string ref); + +has_modifiers( + int id: @modifiable_direct ref, + int mod_id: @modifier ref); + +compiler_generated(unique int id: @modifiable_direct ref); + +/** MEMBERS **/ + +@member = @method | @constructor | @destructor | @field | @property | @event | @operator | @indexer | @type; + +@named_exprorstmt = @goto_stmt | @labeled_stmt | @expr; + +@virtualizable = @method | @property | @indexer | @event; + +exprorstmt_name( + unique int parent_id: @named_exprorstmt ref, + string name: string ref); + +nested_types( + unique int id: @type ref, + int declaring_type_id: @type ref, + int unbound_id: @type ref); + +properties( + unique int id: @property, + string name: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @property ref); + +property_location( + int id: @property ref, + int loc: @location ref); + +indexers( + unique int id: @indexer, + string name: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @indexer ref); + +indexer_location( + int id: @indexer ref, + int loc: @location ref); + +accessors( + unique int id: @accessor, + int kind: int ref, + string name: string ref, + int declaring_member_id: @member ref, + int unbound_id: @accessor ref); + +case @accessor.kind of + 1 = @getter +| 2 = @setter + ; + +init_only_accessors( + unique int id: @accessor ref); + +accessor_location( + int id: @accessor ref, + int loc: @location ref); + +events( + unique int id: @event, + string name: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @event ref); + +event_location( + int id: @event ref, + int loc: @location ref); + +event_accessors( + unique int id: @event_accessor, + int kind: int ref, + string name: string ref, + int declaring_event_id: @event ref, + int unbound_id: @event_accessor ref); + +case @event_accessor.kind of + 1 = @add_event_accessor +| 2 = @remove_event_accessor + ; + +event_accessor_location( + int id: @event_accessor ref, + int loc: @location ref); + +operators( + unique int id: @operator, + string name: string ref, + string symbol: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @operator ref); + +operator_location( + int id: @operator ref, + int loc: @location ref); + +constant_value( + int id: @variable ref, + string value: string ref); + +/** CALLABLES **/ + +@callable = @method | @constructor | @destructor | @operator | @callable_accessor | @anonymous_function_expr | @local_function; + +@callable_accessor = @accessor | @event_accessor; + +methods( + unique int id: @method, + string name: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @method ref); + +method_location( + int id: @method ref, + int loc: @location ref); + +constructors( + unique int id: @constructor, + string name: string ref, + int declaring_type_id: @type ref, + int unbound_id: @constructor ref); + +constructor_location( + int id: @constructor ref, + int loc: @location ref); + +destructors( + unique int id: @destructor, + string name: string ref, + int declaring_type_id: @type ref, + int unbound_id: @destructor ref); + +destructor_location( + int id: @destructor ref, + int loc: @location ref); + +overrides( + int id: @callable ref, + int base_id: @callable ref); + +explicitly_implements( + int id: @member ref, + int interface_id: @interface_or_ref ref); + +local_functions( + unique int id: @local_function, + string name: string ref, + int return_type: @type ref, + int unbound_id: @local_function ref); + +local_function_stmts( + unique int fn: @local_function_stmt ref, + int stmt: @local_function ref); + +/** VARIABLES **/ + +@variable = @local_scope_variable | @field; + +@local_scope_variable = @local_variable | @parameter; + +fields( + unique int id: @field, + int kind: int ref, + string name: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @field ref); + +case @field.kind of + 1 = @addressable_field +| 2 = @constant + ; + +field_location( + int id: @field ref, + int loc: @location ref); + +localvars( + unique int id: @local_variable, + int kind: int ref, + string name: string ref, + int implicitly_typed: int ref /* 0 = no, 1 = yes */, + int type_id: @type_or_ref ref, + int parent_id: @local_var_decl_expr ref); + +case @local_variable.kind of + 1 = @addressable_local_variable +| 2 = @local_constant +| 3 = @local_variable_ref + ; + +localvar_location( + unique int id: @local_variable ref, + int loc: @location ref); + +@parameterizable = @callable | @delegate_type | @indexer | @function_pointer_type; + +#keyset[name, parent_id] +#keyset[index, parent_id] +params( + unique int id: @parameter, + string name: string ref, + int type_id: @type_or_ref ref, + int index: int ref, + int mode: int ref, /* value = 0, ref = 1, out = 2, array = 3, this = 4 */ + int parent_id: @parameterizable ref, + int unbound_id: @parameter ref); + +param_location( + int id: @parameter ref, + int loc: @location ref); + +/** STATEMENTS **/ + +@exprorstmt_parent = @control_flow_element | @top_level_exprorstmt_parent; + +statements( + unique int id: @stmt, + int kind: int ref); + +#keyset[index, parent] +stmt_parent( + unique int stmt: @stmt ref, + int index: int ref, + int parent: @control_flow_element ref); + +@top_level_stmt_parent = @callable; + +// [index, parent] is not a keyset because the same parent may be compiled multiple times +stmt_parent_top_level( + unique int stmt: @stmt ref, + int index: int ref, + int parent: @top_level_stmt_parent ref); + +case @stmt.kind of + 1 = @block_stmt +| 2 = @expr_stmt +| 3 = @if_stmt +| 4 = @switch_stmt +| 5 = @while_stmt +| 6 = @do_stmt +| 7 = @for_stmt +| 8 = @foreach_stmt +| 9 = @break_stmt +| 10 = @continue_stmt +| 11 = @goto_stmt +| 12 = @goto_case_stmt +| 13 = @goto_default_stmt +| 14 = @throw_stmt +| 15 = @return_stmt +| 16 = @yield_stmt +| 17 = @try_stmt +| 18 = @checked_stmt +| 19 = @unchecked_stmt +| 20 = @lock_stmt +| 21 = @using_block_stmt +| 22 = @var_decl_stmt +| 23 = @const_decl_stmt +| 24 = @empty_stmt +| 25 = @unsafe_stmt +| 26 = @fixed_stmt +| 27 = @label_stmt +| 28 = @catch +| 29 = @case_stmt +| 30 = @local_function_stmt +| 31 = @using_decl_stmt + ; + +@using_stmt = @using_block_stmt | @using_decl_stmt; + +@labeled_stmt = @label_stmt | @case; + +@decl_stmt = @var_decl_stmt | @const_decl_stmt | @using_decl_stmt; + +@cond_stmt = @if_stmt | @switch_stmt; + +@loop_stmt = @while_stmt | @do_stmt | @for_stmt | @foreach_stmt; + +@jump_stmt = @break_stmt | @goto_any_stmt | @continue_stmt | @throw_stmt | @return_stmt + | @yield_stmt; + +@goto_any_stmt = @goto_default_stmt | @goto_case_stmt | @goto_stmt; + + +stmt_location( + unique int id: @stmt ref, + int loc: @location ref); + +catch_type( + unique int catch_id: @catch ref, + int type_id: @type_or_ref ref, + int kind: int ref /* explicit = 1, implicit = 2 */); + +/** EXPRESSIONS **/ + +expressions( + unique int id: @expr, + int kind: int ref, + int type_id: @type_or_ref ref); + +#keyset[index, parent] +expr_parent( + unique int expr: @expr ref, + int index: int ref, + int parent: @control_flow_element ref); + +@top_level_expr_parent = @attribute | @field | @property | @indexer | @parameter | @directive_if | @directive_elif; + +@top_level_exprorstmt_parent = @top_level_expr_parent | @top_level_stmt_parent; + +// [index, parent] is not a keyset because the same parent may be compiled multiple times +expr_parent_top_level( + unique int expr: @expr ref, + int index: int ref, + int parent: @top_level_exprorstmt_parent ref); + +case @expr.kind of +/* literal */ + 1 = @bool_literal_expr +| 2 = @char_literal_expr +| 3 = @decimal_literal_expr +| 4 = @int_literal_expr +| 5 = @long_literal_expr +| 6 = @uint_literal_expr +| 7 = @ulong_literal_expr +| 8 = @float_literal_expr +| 9 = @double_literal_expr +| 10 = @string_literal_expr +| 11 = @null_literal_expr +/* primary & unary */ +| 12 = @this_access_expr +| 13 = @base_access_expr +| 14 = @local_variable_access_expr +| 15 = @parameter_access_expr +| 16 = @field_access_expr +| 17 = @property_access_expr +| 18 = @method_access_expr +| 19 = @event_access_expr +| 20 = @indexer_access_expr +| 21 = @array_access_expr +| 22 = @type_access_expr +| 23 = @typeof_expr +| 24 = @method_invocation_expr +| 25 = @delegate_invocation_expr +| 26 = @operator_invocation_expr +| 27 = @cast_expr +| 28 = @object_creation_expr +| 29 = @explicit_delegate_creation_expr +| 30 = @implicit_delegate_creation_expr +| 31 = @array_creation_expr +| 32 = @default_expr +| 33 = @plus_expr +| 34 = @minus_expr +| 35 = @bit_not_expr +| 36 = @log_not_expr +| 37 = @post_incr_expr +| 38 = @post_decr_expr +| 39 = @pre_incr_expr +| 40 = @pre_decr_expr +/* multiplicative */ +| 41 = @mul_expr +| 42 = @div_expr +| 43 = @rem_expr +/* additive */ +| 44 = @add_expr +| 45 = @sub_expr +/* shift */ +| 46 = @lshift_expr +| 47 = @rshift_expr +/* relational */ +| 48 = @lt_expr +| 49 = @gt_expr +| 50 = @le_expr +| 51 = @ge_expr +/* equality */ +| 52 = @eq_expr +| 53 = @ne_expr +/* logical */ +| 54 = @bit_and_expr +| 55 = @bit_xor_expr +| 56 = @bit_or_expr +| 57 = @log_and_expr +| 58 = @log_or_expr +/* type testing */ +| 59 = @is_expr +| 60 = @as_expr +/* null coalescing */ +| 61 = @null_coalescing_expr +/* conditional */ +| 62 = @conditional_expr +/* assignment */ +| 63 = @simple_assign_expr +| 64 = @assign_add_expr +| 65 = @assign_sub_expr +| 66 = @assign_mul_expr +| 67 = @assign_div_expr +| 68 = @assign_rem_expr +| 69 = @assign_and_expr +| 70 = @assign_xor_expr +| 71 = @assign_or_expr +| 72 = @assign_lshift_expr +| 73 = @assign_rshift_expr +/* more */ +| 74 = @object_init_expr +| 75 = @collection_init_expr +| 76 = @array_init_expr +| 77 = @checked_expr +| 78 = @unchecked_expr +| 79 = @constructor_init_expr +| 80 = @add_event_expr +| 81 = @remove_event_expr +| 82 = @par_expr +| 83 = @local_var_decl_expr +| 84 = @lambda_expr +| 85 = @anonymous_method_expr +| 86 = @namespace_expr +/* dynamic */ +| 92 = @dynamic_element_access_expr +| 93 = @dynamic_member_access_expr +/* unsafe */ +| 100 = @pointer_indirection_expr +| 101 = @address_of_expr +| 102 = @sizeof_expr +/* async */ +| 103 = @await_expr +/* C# 6.0 */ +| 104 = @nameof_expr +| 105 = @interpolated_string_expr +| 106 = @unknown_expr +/* C# 7.0 */ +| 107 = @throw_expr +| 108 = @tuple_expr +| 109 = @local_function_invocation_expr +| 110 = @ref_expr +| 111 = @discard_expr +/* C# 8.0 */ +| 112 = @range_expr +| 113 = @index_expr +| 114 = @switch_expr +| 115 = @recursive_pattern_expr +| 116 = @property_pattern_expr +| 117 = @positional_pattern_expr +| 118 = @switch_case_expr +| 119 = @assign_coalesce_expr +| 120 = @suppress_nullable_warning_expr +| 121 = @namespace_access_expr +/* C# 9.0 */ +| 122 = @lt_pattern_expr +| 123 = @gt_pattern_expr +| 124 = @le_pattern_expr +| 125 = @ge_pattern_expr +| 126 = @not_pattern_expr +| 127 = @and_pattern_expr +| 128 = @or_pattern_expr +| 129 = @function_pointer_invocation_expr +/* Preprocessor */ +| 999 = @define_symbol_expr +; + +@switch = @switch_stmt | @switch_expr; +@case = @case_stmt | @switch_case_expr; +@pattern_match = @case | @is_expr; +@unary_pattern_expr = @not_pattern_expr; +@relational_pattern_expr = @gt_pattern_expr | @lt_pattern_expr | @ge_pattern_expr | @le_pattern_expr; +@binary_pattern_expr = @and_pattern_expr | @or_pattern_expr; + +@integer_literal_expr = @int_literal_expr | @long_literal_expr | @uint_literal_expr | @ulong_literal_expr; +@real_literal_expr = @float_literal_expr | @double_literal_expr | @decimal_literal_expr; +@literal_expr = @bool_literal_expr | @char_literal_expr | @integer_literal_expr | @real_literal_expr + | @string_literal_expr | @null_literal_expr; + +@assign_expr = @simple_assign_expr | @assign_op_expr | @local_var_decl_expr; +@assign_op_expr = @assign_arith_expr | @assign_bitwise_expr | @assign_event_expr | @assign_coalesce_expr; +@assign_event_expr = @add_event_expr | @remove_event_expr; + +@assign_arith_expr = @assign_add_expr | @assign_sub_expr | @assign_mul_expr | @assign_div_expr + | @assign_rem_expr +@assign_bitwise_expr = @assign_and_expr | @assign_or_expr | @assign_xor_expr + | @assign_lshift_expr | @assign_rshift_expr; + +@member_access_expr = @field_access_expr | @property_access_expr | @indexer_access_expr | @event_access_expr + | @method_access_expr | @type_access_expr | @dynamic_member_access_expr; +@access_expr = @member_access_expr | @this_access_expr | @base_access_expr | @assignable_access_expr | @namespace_access_expr; +@element_access_expr = @indexer_access_expr | @array_access_expr | @dynamic_element_access_expr; + +@local_variable_access = @local_variable_access_expr | @local_var_decl_expr; +@local_scope_variable_access_expr = @parameter_access_expr | @local_variable_access; +@variable_access_expr = @local_scope_variable_access_expr | @field_access_expr; + +@assignable_access_expr = @variable_access_expr | @property_access_expr | @element_access_expr + | @event_access_expr | @dynamic_member_access_expr; + +@objectorcollection_init_expr = @object_init_expr | @collection_init_expr; + +@delegate_creation_expr = @explicit_delegate_creation_expr | @implicit_delegate_creation_expr; + +@bin_arith_op_expr = @mul_expr | @div_expr | @rem_expr | @add_expr | @sub_expr; +@incr_op_expr = @pre_incr_expr | @post_incr_expr; +@decr_op_expr = @pre_decr_expr | @post_decr_expr; +@mut_op_expr = @incr_op_expr | @decr_op_expr; +@un_arith_op_expr = @plus_expr | @minus_expr | @mut_op_expr; +@arith_op_expr = @bin_arith_op_expr | @un_arith_op_expr; + +@ternary_log_op_expr = @conditional_expr; +@bin_log_op_expr = @log_and_expr | @log_or_expr | @null_coalescing_expr; +@un_log_op_expr = @log_not_expr; +@log_expr = @un_log_op_expr | @bin_log_op_expr | @ternary_log_op_expr; + +@bin_bit_op_expr = @bit_and_expr | @bit_or_expr | @bit_xor_expr | @lshift_expr + | @rshift_expr; +@un_bit_op_expr = @bit_not_expr; +@bit_expr = @un_bit_op_expr | @bin_bit_op_expr; + +@equality_op_expr = @eq_expr | @ne_expr; +@rel_op_expr = @gt_expr | @lt_expr| @ge_expr | @le_expr; +@comp_expr = @equality_op_expr | @rel_op_expr; + +@op_expr = @assign_expr | @un_op | @bin_op | @ternary_op; + +@ternary_op = @ternary_log_op_expr; +@bin_op = @bin_arith_op_expr | @bin_log_op_expr | @bin_bit_op_expr | @comp_expr; +@un_op = @un_arith_op_expr | @un_log_op_expr | @un_bit_op_expr | @sizeof_expr + | @pointer_indirection_expr | @address_of_expr; + +@anonymous_function_expr = @lambda_expr | @anonymous_method_expr; + +@call = @method_invocation_expr | @constructor_init_expr | @operator_invocation_expr + | @delegate_invocation_expr | @object_creation_expr | @call_access_expr + | @local_function_invocation_expr | @function_pointer_invocation_expr; + +@call_access_expr = @property_access_expr | @event_access_expr | @indexer_access_expr; + +@late_bindable_expr = @dynamic_element_access_expr | @dynamic_member_access_expr + | @object_creation_expr | @method_invocation_expr | @operator_invocation_expr; + +@throw_element = @throw_expr | @throw_stmt; + +@implicitly_typeable_object_creation_expr = @object_creation_expr | @explicit_delegate_creation_expr; + +implicitly_typed_array_creation( + unique int id: @array_creation_expr ref); + +explicitly_sized_array_creation( + unique int id: @array_creation_expr ref); + +stackalloc_array_creation( + unique int id: @array_creation_expr ref); + +implicitly_typed_object_creation( + unique int id: @implicitly_typeable_object_creation_expr ref); + +mutator_invocation_mode( + unique int id: @operator_invocation_expr ref, + int mode: int ref /* prefix = 1, postfix = 2*/); + +expr_compiler_generated( + unique int id: @expr ref); + +expr_value( + unique int id: @expr ref, + string value: string ref); + +expr_call( + unique int caller_id: @expr ref, + int target_id: @callable ref); + +expr_access( + unique int accesser_id: @access_expr ref, + int target_id: @accessible ref); + +@accessible = @method | @assignable | @local_function | @namespace; + +expr_location( + unique int id: @expr ref, + int loc: @location ref); + +dynamic_member_name( + unique int id: @late_bindable_expr ref, + string name: string ref); + +@qualifiable_expr = @member_access_expr + | @method_invocation_expr + | @element_access_expr; + +conditional_access( + unique int id: @qualifiable_expr ref); + +expr_argument( + unique int id: @expr ref, + int mode: int ref); + /* mode is the same as params: value = 0, ref = 1, out = 2 */ + +expr_argument_name( + unique int id: @expr ref, + string name: string ref); + +/** CONTROL/DATA FLOW **/ + +@control_flow_element = @stmt | @expr; + +/* XML Files */ + +xmlEncoding ( + unique int id: @file ref, + string encoding: string ref); + +xmlDTDs( + unique int id: @xmldtd, + string root: string ref, + string publicId: string ref, + string systemId: string ref, + int fileid: @file ref); + +xmlElements( + unique int id: @xmlelement, + string name: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int fileid: @file ref); + +xmlAttrs( + unique int id: @xmlattribute, + int elementid: @xmlelement ref, + string name: string ref, + string value: string ref, + int idx: int ref, + int fileid: @file ref); + +xmlNs( + int id: @xmlnamespace, + string prefixName: string ref, + string URI: string ref, + int fileid: @file ref); + +xmlHasNs( + int elementId: @xmlnamespaceable ref, + int nsId: @xmlnamespace ref, + int fileid: @file ref); + +xmlComments( + unique int id: @xmlcomment, + string text: string ref, + int parentid: @xmlparent ref, + int fileid: @file ref); + +xmlChars( + unique int id: @xmlcharacters, + string text: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int isCDATA: int ref, + int fileid: @file ref); + +@xmlparent = @file | @xmlelement; +@xmlnamespaceable = @xmlelement | @xmlattribute; + +xmllocations( + int xmlElement: @xmllocatable ref, + int location: @location_default ref); + +@xmllocatable = @xmlcharacters | @xmlelement | @xmlcomment | @xmlattribute | @xmldtd | @file | @xmlnamespace; + +/* Comments */ + +commentline( + unique int id: @commentline, + int kind: int ref, + string text: string ref, + string rawtext: string ref); + +case @commentline.kind of + 0 = @singlelinecomment +| 1 = @xmldoccomment +| 2 = @multilinecomment; + +commentline_location( + unique int id: @commentline ref, + int loc: @location ref); + +commentblock( + unique int id : @commentblock); + +commentblock_location( + unique int id: @commentblock ref, + int loc: @location ref); + +commentblock_binding( + int id: @commentblock ref, + int entity: @element ref, + int bindtype: int ref); /* 0: Parent, 1: Best, 2: Before, 3: After */ + +commentblock_child( + int id: @commentblock ref, + int commentline: @commentline ref, + int index: int ref); + +/* ASP.NET */ + +case @asp_element.kind of + 0=@asp_close_tag +| 1=@asp_code +| 2=@asp_comment +| 3=@asp_data_binding +| 4=@asp_directive +| 5=@asp_open_tag +| 6=@asp_quoted_string +| 7=@asp_text +| 8=@asp_xml_directive; + +@asp_attribute = @asp_code | @asp_data_binding | @asp_quoted_string; + +asp_elements( + unique int id: @asp_element, + int kind: int ref, + int loc: @location ref); + +asp_comment_server(unique int comment: @asp_comment ref); +asp_code_inline(unique int code: @asp_code ref); +asp_directive_attribute( + int directive: @asp_directive ref, + int index: int ref, + string name: string ref, + int value: @asp_quoted_string ref); +asp_directive_name( + unique int directive: @asp_directive ref, + string name: string ref); +asp_element_body( + unique int element: @asp_element ref, + string body: string ref); +asp_tag_attribute( + int tag: @asp_open_tag ref, + int index: int ref, + string name: string ref, + int attribute: @asp_attribute ref); +asp_tag_name( + unique int tag: @asp_open_tag ref, + string name: string ref); +asp_tag_isempty(int tag: @asp_open_tag ref); + +/* Common Intermediate Language - CIL */ + +case @cil_instruction.opcode of + 0 = @cil_nop +| 1 = @cil_break +| 2 = @cil_ldarg_0 +| 3 = @cil_ldarg_1 +| 4 = @cil_ldarg_2 +| 5 = @cil_ldarg_3 +| 6 = @cil_ldloc_0 +| 7 = @cil_ldloc_1 +| 8 = @cil_ldloc_2 +| 9 = @cil_ldloc_3 +| 10 = @cil_stloc_0 +| 11 = @cil_stloc_1 +| 12 = @cil_stloc_2 +| 13 = @cil_stloc_3 +| 14 = @cil_ldarg_s +| 15 = @cil_ldarga_s +| 16 = @cil_starg_s +| 17 = @cil_ldloc_s +| 18 = @cil_ldloca_s +| 19 = @cil_stloc_s +| 20 = @cil_ldnull +| 21 = @cil_ldc_i4_m1 +| 22 = @cil_ldc_i4_0 +| 23 = @cil_ldc_i4_1 +| 24 = @cil_ldc_i4_2 +| 25 = @cil_ldc_i4_3 +| 26 = @cil_ldc_i4_4 +| 27 = @cil_ldc_i4_5 +| 28 = @cil_ldc_i4_6 +| 29 = @cil_ldc_i4_7 +| 30 = @cil_ldc_i4_8 +| 31 = @cil_ldc_i4_s +| 32 = @cil_ldc_i4 +| 33 = @cil_ldc_i8 +| 34 = @cil_ldc_r4 +| 35 = @cil_ldc_r8 +| 37 = @cil_dup +| 38 = @cil_pop +| 39 = @cil_jmp +| 40 = @cil_call +| 41 = @cil_calli +| 42 = @cil_ret +| 43 = @cil_br_s +| 44 = @cil_brfalse_s +| 45 = @cil_brtrue_s +| 46 = @cil_beq_s +| 47 = @cil_bge_s +| 48 = @cil_bgt_s +| 49 = @cil_ble_s +| 50 = @cil_blt_s +| 51 = @cil_bne_un_s +| 52 = @cil_bge_un_s +| 53 = @cil_bgt_un_s +| 54 = @cil_ble_un_s +| 55 = @cil_blt_un_s +| 56 = @cil_br +| 57 = @cil_brfalse +| 58 = @cil_brtrue +| 59 = @cil_beq +| 60 = @cil_bge +| 61 = @cil_bgt +| 62 = @cil_ble +| 63 = @cil_blt +| 64 = @cil_bne_un +| 65 = @cil_bge_un +| 66 = @cil_bgt_un +| 67 = @cil_ble_un +| 68 = @cil_blt_un +| 69 = @cil_switch +| 70 = @cil_ldind_i1 +| 71 = @cil_ldind_u1 +| 72 = @cil_ldind_i2 +| 73 = @cil_ldind_u2 +| 74 = @cil_ldind_i4 +| 75 = @cil_ldind_u4 +| 76 = @cil_ldind_i8 +| 77 = @cil_ldind_i +| 78 = @cil_ldind_r4 +| 79 = @cil_ldind_r8 +| 80 = @cil_ldind_ref +| 81 = @cil_stind_ref +| 82 = @cil_stind_i1 +| 83 = @cil_stind_i2 +| 84 = @cil_stind_i4 +| 85 = @cil_stind_i8 +| 86 = @cil_stind_r4 +| 87 = @cil_stind_r8 +| 88 = @cil_add +| 89 = @cil_sub +| 90 = @cil_mul +| 91 = @cil_div +| 92 = @cil_div_un +| 93 = @cil_rem +| 94 = @cil_rem_un +| 95 = @cil_and +| 96 = @cil_or +| 97 = @cil_xor +| 98 = @cil_shl +| 99 = @cil_shr +| 100 = @cil_shr_un +| 101 = @cil_neg +| 102 = @cil_not +| 103 = @cil_conv_i1 +| 104 = @cil_conv_i2 +| 105 = @cil_conv_i4 +| 106 = @cil_conv_i8 +| 107 = @cil_conv_r4 +| 108 = @cil_conv_r8 +| 109 = @cil_conv_u4 +| 110 = @cil_conv_u8 +| 111 = @cil_callvirt +| 112 = @cil_cpobj +| 113 = @cil_ldobj +| 114 = @cil_ldstr +| 115 = @cil_newobj +| 116 = @cil_castclass +| 117 = @cil_isinst +| 118 = @cil_conv_r_un +| 121 = @cil_unbox +| 122 = @cil_throw +| 123 = @cil_ldfld +| 124 = @cil_ldflda +| 125 = @cil_stfld +| 126 = @cil_ldsfld +| 127 = @cil_ldsflda +| 128 = @cil_stsfld +| 129 = @cil_stobj +| 130 = @cil_conv_ovf_i1_un +| 131 = @cil_conv_ovf_i2_un +| 132 = @cil_conv_ovf_i4_un +| 133 = @cil_conv_ovf_i8_un +| 134 = @cil_conv_ovf_u1_un +| 135 = @cil_conv_ovf_u2_un +| 136 = @cil_conv_ovf_u4_un +| 137 = @cil_conv_ovf_u8_un +| 138 = @cil_conv_ovf_i_un +| 139 = @cil_conv_ovf_u_un +| 140 = @cil_box +| 141 = @cil_newarr +| 142 = @cil_ldlen +| 143 = @cil_ldelema +| 144 = @cil_ldelem_i1 +| 145 = @cil_ldelem_u1 +| 146 = @cil_ldelem_i2 +| 147 = @cil_ldelem_u2 +| 148 = @cil_ldelem_i4 +| 149 = @cil_ldelem_u4 +| 150 = @cil_ldelem_i8 +| 151 = @cil_ldelem_i +| 152 = @cil_ldelem_r4 +| 153 = @cil_ldelem_r8 +| 154 = @cil_ldelem_ref +| 155 = @cil_stelem_i +| 156 = @cil_stelem_i1 +| 157 = @cil_stelem_i2 +| 158 = @cil_stelem_i4 +| 159 = @cil_stelem_i8 +| 160 = @cil_stelem_r4 +| 161 = @cil_stelem_r8 +| 162 = @cil_stelem_ref +| 163 = @cil_ldelem +| 164 = @cil_stelem +| 165 = @cil_unbox_any +| 179 = @cil_conv_ovf_i1 +| 180 = @cil_conv_ovf_u1 +| 181 = @cil_conv_ovf_i2 +| 182 = @cil_conv_ovf_u2 +| 183 = @cil_conv_ovf_i4 +| 184 = @cil_conv_ovf_u4 +| 185 = @cil_conv_ovf_i8 +| 186 = @cil_conv_ovf_u8 +| 194 = @cil_refanyval +| 195 = @cil_ckinfinite +| 198 = @cil_mkrefany +| 208 = @cil_ldtoken +| 209 = @cil_conv_u2 +| 210 = @cil_conv_u1 +| 211 = @cil_conv_i +| 212 = @cil_conv_ovf_i +| 213 = @cil_conv_ovf_u +| 214 = @cil_add_ovf +| 215 = @cil_add_ovf_un +| 216 = @cil_mul_ovf +| 217 = @cil_mul_ovf_un +| 218 = @cil_sub_ovf +| 219 = @cil_sub_ovf_un +| 220 = @cil_endfinally +| 221 = @cil_leave +| 222 = @cil_leave_s +| 223 = @cil_stind_i +| 224 = @cil_conv_u +| 65024 = @cil_arglist +| 65025 = @cil_ceq +| 65026 = @cil_cgt +| 65027 = @cil_cgt_un +| 65028 = @cil_clt +| 65029 = @cil_clt_un +| 65030 = @cil_ldftn +| 65031 = @cil_ldvirtftn +| 65033 = @cil_ldarg +| 65034 = @cil_ldarga +| 65035 = @cil_starg +| 65036 = @cil_ldloc +| 65037 = @cil_ldloca +| 65038 = @cil_stloc +| 65039 = @cil_localloc +| 65041 = @cil_endfilter +| 65042 = @cil_unaligned +| 65043 = @cil_volatile +| 65044 = @cil_tail +| 65045 = @cil_initobj +| 65046 = @cil_constrained +| 65047 = @cil_cpblk +| 65048 = @cil_initblk +| 65050 = @cil_rethrow +| 65052 = @cil_sizeof +| 65053 = @cil_refanytype +| 65054 = @cil_readonly +; + +// CIL ignored instructions + +@cil_ignore = @cil_nop | @cil_break | @cil_volatile | @cil_unaligned; + +// CIL local/parameter/field access + +@cil_ldarg_any = @cil_ldarg_0 | @cil_ldarg_1 | @cil_ldarg_2 | @cil_ldarg_3 | @cil_ldarg_s | @cil_ldarga_s | @cil_ldarg | @cil_ldarga; +@cil_starg_any = @cil_starg | @cil_starg_s; + +@cil_ldloc_any = @cil_ldloc_0 | @cil_ldloc_1 | @cil_ldloc_2 | @cil_ldloc_3 | @cil_ldloc_s | @cil_ldloca_s | @cil_ldloc | @cil_ldloca; +@cil_stloc_any = @cil_stloc_0 | @cil_stloc_1 | @cil_stloc_2 | @cil_stloc_3 | @cil_stloc_s | @cil_stloc; + +@cil_ldfld_any = @cil_ldfld | @cil_ldsfld | @cil_ldsflda | @cil_ldflda; +@cil_stfld_any = @cil_stfld | @cil_stsfld; + +@cil_local_access = @cil_stloc_any | @cil_ldloc_any; +@cil_arg_access = @cil_starg_any | @cil_ldarg_any; +@cil_read_access = @cil_ldloc_any | @cil_ldarg_any | @cil_ldfld_any; +@cil_write_access = @cil_stloc_any | @cil_starg_any | @cil_stfld_any; + +@cil_stack_access = @cil_local_access | @cil_arg_access; +@cil_field_access = @cil_ldfld_any | @cil_stfld_any; + +@cil_access = @cil_read_access | @cil_write_access; + +// CIL constant/literal instructions + +@cil_ldc_i = @cil_ldc_i4_any | @cil_ldc_i8; + +@cil_ldc_i4_any = @cil_ldc_i4_m1 | @cil_ldc_i4_0 | @cil_ldc_i4_1 | @cil_ldc_i4_2 | @cil_ldc_i4_3 | + @cil_ldc_i4_4 | @cil_ldc_i4_5 | @cil_ldc_i4_6 | @cil_ldc_i4_7 | @cil_ldc_i4_8 | @cil_ldc_i4_s | @cil_ldc_i4; + +@cil_ldc_r = @cil_ldc_r4 | @cil_ldc_r8; + +@cil_literal = @cil_ldnull | @cil_ldc_i | @cil_ldc_r | @cil_ldstr; + +// Control flow + +@cil_conditional_jump = @cil_binary_jump | @cil_unary_jump; +@cil_binary_jump = @cil_beq_s | @cil_bge_s | @cil_bgt_s | @cil_ble_s | @cil_blt_s | + @cil_bne_un_s | @cil_bge_un_s | @cil_bgt_un_s | @cil_ble_un_s | @cil_blt_un_s | + @cil_beq | @cil_bge | @cil_bgt | @cil_ble | @cil_blt | + @cil_bne_un | @cil_bge_un | @cil_bgt_un | @cil_ble_un | @cil_blt_un; +@cil_unary_jump = @cil_brfalse_s | @cil_brtrue_s | @cil_brfalse | @cil_brtrue | @cil_switch; +@cil_unconditional_jump = @cil_br | @cil_br_s | @cil_leave_any; +@cil_leave_any = @cil_leave | @cil_leave_s; +@cil_jump = @cil_unconditional_jump | @cil_conditional_jump; + +// CIL call instructions + +@cil_call_any = @cil_jmp | @cil_call | @cil_calli | @cil_tail | @cil_callvirt | @cil_newobj; + +// CIL expression instructions + +@cil_expr = @cil_literal | @cil_binary_expr | @cil_unary_expr | @cil_call_any | @cil_read_access | + @cil_newarr | @cil_ldtoken | @cil_sizeof | + @cil_ldftn | @cil_ldvirtftn | @cil_localloc | @cil_mkrefany | @cil_refanytype | @cil_arglist | @cil_dup; + +@cil_unary_expr = + @cil_conversion_operation | @cil_unary_arithmetic_operation | @cil_unary_bitwise_operation| + @cil_ldlen | @cil_isinst | @cil_box | @cil_ldobj | @cil_castclass | @cil_unbox_any | + @cil_ldind | @cil_unbox; + +@cil_conversion_operation = + @cil_conv_i1 | @cil_conv_i2 | @cil_conv_i4 | @cil_conv_i8 | + @cil_conv_u1 | @cil_conv_u2 | @cil_conv_u4 | @cil_conv_u8 | + @cil_conv_ovf_i | @cil_conv_ovf_i_un | @cil_conv_ovf_i1 | @cil_conv_ovf_i1_un | + @cil_conv_ovf_i2 | @cil_conv_ovf_i2_un | @cil_conv_ovf_i4 | @cil_conv_ovf_i4_un | + @cil_conv_ovf_i8 | @cil_conv_ovf_i8_un | @cil_conv_ovf_u | @cil_conv_ovf_u_un | + @cil_conv_ovf_u1 | @cil_conv_ovf_u1_un | @cil_conv_ovf_u2 | @cil_conv_ovf_u2_un | + @cil_conv_ovf_u4 | @cil_conv_ovf_u4_un | @cil_conv_ovf_u8 | @cil_conv_ovf_u8_un | + @cil_conv_r4 | @cil_conv_r8 | @cil_conv_ovf_u2 | @cil_conv_ovf_u2_un | + @cil_conv_i | @cil_conv_u | @cil_conv_r_un; + +@cil_ldind = @cil_ldind_i | @cil_ldind_i1 | @cil_ldind_i2 | @cil_ldind_i4 | @cil_ldind_i8 | + @cil_ldind_r4 | @cil_ldind_r8 | @cil_ldind_ref | @cil_ldind_u1 | @cil_ldind_u2 | @cil_ldind_u4; + +@cil_stind = @cil_stind_i | @cil_stind_i1 | @cil_stind_i2 | @cil_stind_i4 | @cil_stind_i8 | + @cil_stind_r4 | @cil_stind_r8 | @cil_stind_ref; + +@cil_bitwise_operation = @cil_binary_bitwise_operation | @cil_unary_bitwise_operation; + +@cil_binary_bitwise_operation = @cil_and | @cil_or | @cil_xor | @cil_shr | @cil_shr | @cil_shr_un | @cil_shl; + +@cil_binary_arithmetic_operation = @cil_add | @cil_sub | @cil_mul | @cil_div | @cil_div_un | + @cil_rem | @cil_rem_un | @cil_add_ovf | @cil_add_ovf_un | @cil_mul_ovf | @cil_mul_ovf_un | + @cil_sub_ovf | @cil_sub_ovf_un; + +@cil_unary_bitwise_operation = @cil_not; + +@cil_binary_expr = @cil_binary_arithmetic_operation | @cil_binary_bitwise_operation | @cil_read_array | @cil_comparison_operation; + +@cil_unary_arithmetic_operation = @cil_neg; + +@cil_comparison_operation = @cil_cgt_un | @cil_ceq | @cil_cgt | @cil_clt | @cil_clt_un; + +// Elements that retrieve an address of something +@cil_read_ref = @cil_ldloca_s | @cil_ldarga_s | @cil_ldflda | @cil_ldsflda | @cil_ldelema; + +// CIL array instructions + +@cil_read_array = + @cil_ldelem | @cil_ldelema | @cil_ldelem_i1 | @cil_ldelem_ref | @cil_ldelem_i | + @cil_ldelem_i1 | @cil_ldelem_i2 | @cil_ldelem_i4 | @cil_ldelem_i8 | @cil_ldelem_r4 | + @cil_ldelem_r8 | @cil_ldelem_u1 | @cil_ldelem_u2 | @cil_ldelem_u4; + +@cil_write_array = @cil_stelem | @cil_stelem_ref | + @cil_stelem_i | @cil_stelem_i1 | @cil_stelem_i2 | @cil_stelem_i4 | @cil_stelem_i8 | + @cil_stelem_r4 | @cil_stelem_r8; + +@cil_throw_any = @cil_throw | @cil_rethrow; + +#keyset[impl, index] +cil_instruction( + unique int id: @cil_instruction, + int opcode: int ref, + int index: int ref, + int impl: @cil_method_implementation ref); + +cil_jump( + unique int instruction: @cil_jump ref, + int target: @cil_instruction ref); + +cil_access( + unique int instruction: @cil_instruction ref, + int target: @cil_accessible ref); + +cil_value( + unique int instruction: @cil_literal ref, + string value: string ref); + +#keyset[instruction, index] +cil_switch( + int instruction: @cil_switch ref, + int index: int ref, + int target: @cil_instruction ref); + +cil_instruction_location( + unique int id: @cil_instruction ref, + int loc: @location ref); + +cil_type_location( + int id: @cil_type ref, + int loc: @location ref); + +cil_method_location( + int id: @cil_method ref, + int loc: @location ref); + +@cil_namespace = @namespace; + +@cil_type_container = @cil_type | @cil_namespace | @cil_method; + +case @cil_type.kind of + 0 = @cil_valueorreftype +| 1 = @cil_typeparameter +| 2 = @cil_array_type +| 3 = @cil_pointer_type +| 4 = @cil_function_pointer_type +; + +cil_type( + unique int id: @cil_type, + string name: string ref, + int kind: int ref, + int parent: @cil_type_container ref, + int sourceDecl: @cil_type ref); + +cil_pointer_type( + unique int id: @cil_pointer_type ref, + int pointee: @cil_type ref); + +cil_array_type( + unique int id: @cil_array_type ref, + int element_type: @cil_type ref, + int rank: int ref); + +cil_function_pointer_return_type( + unique int id: @cil_function_pointer_type ref, + int return_type: @cil_type ref); + +cil_method( + unique int id: @cil_method, + string name: string ref, + int parent: @cil_type ref, + int return_type: @cil_type ref); + +cil_method_source_declaration( + unique int method: @cil_method ref, + int source: @cil_method ref); + +cil_method_implementation( + unique int id: @cil_method_implementation, + int method: @cil_method ref, + int location: @assembly ref); + +cil_implements( + int id: @cil_method ref, + int decl: @cil_method ref); + +#keyset[parent, name] +cil_field( + unique int id: @cil_field, + int parent: @cil_type ref, + string name: string ref, + int field_type: @cil_type ref); + +@cil_element = @cil_instruction | @cil_declaration | @cil_handler | @cil_attribute | @cil_namespace; +@cil_named_element = @cil_declaration | @cil_namespace; +@cil_declaration = @cil_variable | @cil_method | @cil_type | @cil_member; +@cil_accessible = @cil_declaration; +@cil_variable = @cil_field | @cil_stack_variable; +@cil_stack_variable = @cil_local_variable | @cil_parameter; +@cil_member = @cil_method | @cil_type | @cil_field | @cil_property | @cil_event; +@cil_custom_modifier_receiver = @cil_method | @cil_property | @cil_parameter | @cil_field | @cil_function_pointer_type; +@cil_parameterizable = @cil_method | @cil_function_pointer_type; +@cil_has_type_annotation = @cil_stack_variable | @cil_property | @cil_method | @cil_function_pointer_type; + +#keyset[parameterizable, index] +cil_parameter( + unique int id: @cil_parameter, + int parameterizable: @cil_parameterizable ref, + int index: int ref, + int param_type: @cil_type ref); + +cil_parameter_in(unique int id: @cil_parameter ref); +cil_parameter_out(unique int id: @cil_parameter ref); + +cil_setter(unique int prop: @cil_property ref, + int method: @cil_method ref); + +#keyset[id, modifier] +cil_custom_modifiers( + int id: @cil_custom_modifier_receiver ref, + int modifier: @cil_type ref, + int kind: int ref); // modreq: 1, modopt: 0 + +cil_type_annotation( + int id: @cil_has_type_annotation ref, + int annotation: int ref); + +cil_getter(unique int prop: @cil_property ref, + int method: @cil_method ref); + +cil_adder(unique int event: @cil_event ref, + int method: @cil_method ref); + +cil_remover(unique int event: @cil_event ref, int method: @cil_method ref); + +cil_raiser(unique int event: @cil_event ref, int method: @cil_method ref); + +cil_property( + unique int id: @cil_property, + int parent: @cil_type ref, + string name: string ref, + int property_type: @cil_type ref); + +#keyset[parent, name] +cil_event(unique int id: @cil_event, + int parent: @cil_type ref, + string name: string ref, + int event_type: @cil_type ref); + +#keyset[impl, index] +cil_local_variable( + unique int id: @cil_local_variable, + int impl: @cil_method_implementation ref, + int index: int ref, + int var_type: @cil_type ref); + +cil_function_pointer_calling_conventions( + int id: @cil_function_pointer_type ref, + int kind: int ref); + +// CIL handlers (exception handlers etc). + +case @cil_handler.kind of + 0 = @cil_catch_handler +| 1 = @cil_filter_handler +| 2 = @cil_finally_handler +| 4 = @cil_fault_handler +; + +#keyset[impl, index] +cil_handler( + unique int id: @cil_handler, + int impl: @cil_method_implementation ref, + int index: int ref, + int kind: int ref, + int try_start: @cil_instruction ref, + int try_end: @cil_instruction ref, + int handler_start: @cil_instruction ref); + +cil_handler_filter( + unique int id: @cil_handler ref, + int filter_start: @cil_instruction ref); + +cil_handler_type( + unique int id: @cil_handler ref, + int catch_type: @cil_type ref); + +@cil_controlflow_node = @cil_entry_point | @cil_instruction; + +@cil_entry_point = @cil_method_implementation | @cil_handler; + +@cil_dataflow_node = @cil_instruction | @cil_variable | @cil_method; + +cil_method_stack_size( + unique int method: @cil_method_implementation ref, + int size: int ref); + +// CIL modifiers + +cil_public(int id: @cil_member ref); +cil_private(int id: @cil_member ref); +cil_protected(int id: @cil_member ref); +cil_internal(int id: @cil_member ref); +cil_static(int id: @cil_member ref); +cil_sealed(int id: @cil_member ref); +cil_virtual(int id: @cil_method ref); +cil_abstract(int id: @cil_member ref); +cil_class(int id: @cil_type ref); +cil_interface(int id: @cil_type ref); +cil_security(int id: @cil_member ref); +cil_requiresecobject(int id: @cil_method ref); +cil_specialname(int id: @cil_method ref); +cil_newslot(int id: @cil_method ref); + +cil_base_class(unique int id: @cil_type ref, int base: @cil_type ref); +cil_base_interface(int id: @cil_type ref, int base: @cil_type ref); +cil_enum_underlying_type(unique int id: @cil_type ref, int underlying: @cil_type ref); + +#keyset[unbound, index] +cil_type_parameter( + int unbound: @cil_member ref, + int index: int ref, + int param: @cil_typeparameter ref); + +#keyset[bound, index] +cil_type_argument( + int bound: @cil_member ref, + int index: int ref, + int t: @cil_type ref); + +// CIL type parameter constraints + +cil_typeparam_covariant(int tp: @cil_typeparameter ref); +cil_typeparam_contravariant(int tp: @cil_typeparameter ref); +cil_typeparam_class(int tp: @cil_typeparameter ref); +cil_typeparam_struct(int tp: @cil_typeparameter ref); +cil_typeparam_new(int tp: @cil_typeparameter ref); +cil_typeparam_constraint(int tp: @cil_typeparameter ref, int supertype: @cil_type ref); + +// CIL attributes + +cil_attribute( + unique int attributeid: @cil_attribute, + int element: @cil_declaration ref, + int constructor: @cil_method ref); + +#keyset[attribute_id, param] +cil_attribute_named_argument( + int attribute_id: @cil_attribute ref, + string param: string ref, + string value: string ref); + +#keyset[attribute_id, index] +cil_attribute_positional_argument( + int attribute_id: @cil_attribute ref, + int index: int ref, + string value: string ref); + + +// Common .Net data model covering both C# and CIL + +// Common elements +@dotnet_element = @element | @cil_element; +@dotnet_named_element = @named_element | @cil_named_element; +@dotnet_callable = @callable | @cil_method; +@dotnet_variable = @variable | @cil_variable; +@dotnet_field = @field | @cil_field; +@dotnet_parameter = @parameter | @cil_parameter; +@dotnet_declaration = @declaration | @cil_declaration; +@dotnet_member = @member | @cil_member; +@dotnet_event = @event | @cil_event; +@dotnet_property = @property | @cil_property | @indexer; +@dotnet_parameterizable = @parameterizable | @cil_parameterizable; + +// Common types +@dotnet_type = @type | @cil_type; +@dotnet_call = @call | @cil_call_any; +@dotnet_throw = @throw_element | @cil_throw_any; +@dotnet_valueorreftype = @cil_valueorreftype | @value_or_ref_type | @cil_array_type | @void_type; +@dotnet_typeparameter = @type_parameter | @cil_typeparameter; +@dotnet_array_type = @array_type | @cil_array_type; +@dotnet_pointer_type = @pointer_type | @cil_pointer_type; +@dotnet_type_parameter = @type_parameter | @cil_typeparameter; +@dotnet_generic = @dotnet_valueorreftype | @dotnet_callable; + +// Attributes +@dotnet_attribute = @attribute | @cil_attribute; + +// Expressions +@dotnet_expr = @expr | @cil_expr; + +// Literals +@dotnet_literal = @literal_expr | @cil_literal; +@dotnet_string_literal = @string_literal_expr | @cil_ldstr; +@dotnet_int_literal = @integer_literal_expr | @cil_ldc_i; +@dotnet_float_literal = @float_literal_expr | @cil_ldc_r; +@dotnet_null_literal = @null_literal_expr | @cil_ldnull; + +@metadata_entity = @cil_method | @cil_type | @cil_field | @cil_property | @field | @property | + @callable | @value_or_ref_type | @void_type; + +#keyset[entity, location] +metadata_handle(int entity : @metadata_entity ref, int location: @assembly ref, int handle: int ref) diff --git a/csharp/upgrades/efcd69e086a26dd33395f2ddb3113b2849399040/upgrade.properties b/csharp/upgrades/efcd69e086a26dd33395f2ddb3113b2849399040/upgrade.properties new file mode 100644 index 00000000000..14ab5d3a87c --- /dev/null +++ b/csharp/upgrades/efcd69e086a26dd33395f2ddb3113b2849399040/upgrade.properties @@ -0,0 +1,5 @@ +description: Add '@preprocessor_directive' to store preprocessor directives. Add +'locations_mapped' relation to store location that take into account '#line' +directives. Finally, the '@define_symbol_expr' expression was added to represent +symbols inside conditions of '#if' and '#elif' directives. +compatibility: backwards diff --git a/csharp/upgrades/f5903552e3099dba41375ca19af7caca5c2e4966/old.dbscheme b/csharp/upgrades/f5903552e3099dba41375ca19af7caca5c2e4966/old.dbscheme new file mode 100644 index 00000000000..f5903552e30 --- /dev/null +++ b/csharp/upgrades/f5903552e3099dba41375ca19af7caca5c2e4966/old.dbscheme @@ -0,0 +1,1899 @@ + +/** + * An invocation of the compiler. Note that more than one file may be + * compiled per invocation. For example, this command compiles three + * source files: + * + * csc f1.cs f2.cs f3.cs + * + * The `id` simply identifies the invocation, while `cwd` is the working + * directory from which the compiler was invoked. + */ +compilations( + unique int id : @compilation, + string cwd : string ref +); + +/** + * The arguments that were passed to the extractor for a compiler + * invocation. If `id` is for the compiler invocation + * + * csc f1.cs f2.cs f3.cs + * + * then typically there will be rows for + * + * num | arg + * --- | --- + * 0 | --compiler + * 1 | *path to compiler* + * 2 | --cil + * 3 | f1.cs + * 4 | f2.cs + * 5 | f3.cs + */ +#keyset[id, num] +compilation_args( + int id : @compilation ref, + int num : int ref, + string arg : string ref +); + +/** + * The source files that are compiled by a compiler invocation. + * If `id` is for the compiler invocation + * + * csc f1.cs f2.cs f3.cs + * + * then there will be rows for + * + * num | arg + * --- | --- + * 0 | f1.cs + * 1 | f2.cs + * 2 | f3.cs + */ +#keyset[id, num] +compilation_compiling_files( + int id : @compilation ref, + int num : int ref, + int file : @file ref +); + +/** + * The references used by a compiler invocation. + * If `id` is for the compiler invocation + * + * csc f1.cs f2.cs f3.cs /r:ref1.dll /r:ref2.dll /r:ref3.dll + * + * then there will be rows for + * + * num | arg + * --- | --- + * 0 | ref1.dll + * 1 | ref2.dll + * 2 | ref3.dll + */ +#keyset[id, num] +compilation_referencing_files( + int id : @compilation ref, + int num : int ref, + int file : @file ref +); + +/** + * The time taken by the extractor for a compiler invocation. + * + * For each file `num`, there will be rows for + * + * kind | seconds + * ---- | --- + * 1 | CPU seconds used by the extractor frontend + * 2 | Elapsed seconds during the extractor frontend + * 3 | CPU seconds used by the extractor backend + * 4 | Elapsed seconds during the extractor backend + */ +#keyset[id, num, kind] +compilation_time( + int id : @compilation ref, + int num : int ref, + /* kind: + 1 = frontend_cpu_seconds + 2 = frontend_elapsed_seconds + 3 = extractor_cpu_seconds + 4 = extractor_elapsed_seconds + */ + int kind : int ref, + float seconds : float ref +); + +/** + * An error or warning generated by the extractor. + * The diagnostic message `diagnostic` was generated during compiler + * invocation `compilation`, and is the `file_number_diagnostic_number`th + * message generated while extracting the `file_number`th file of that + * invocation. + */ +#keyset[compilation, file_number, file_number_diagnostic_number] +diagnostic_for( + unique int diagnostic : @diagnostic ref, + int compilation : @compilation ref, + int file_number : int ref, + int file_number_diagnostic_number : int ref +); + +diagnostics( + unique int id: @diagnostic, + int severity: int ref, + string error_tag: string ref, + string error_message: string ref, + string full_error_message: string ref, + int location: @location_default ref +); + +extractor_messages( + unique int id: @extractor_message, + int severity: int ref, + string origin : string ref, + string text : string ref, + string entity : string ref, + int location: @location_default ref, + string stack_trace : string ref +); + +/** + * If extraction was successful, then `cpu_seconds` and + * `elapsed_seconds` are the CPU time and elapsed time (respectively) + * that extraction took for compiler invocation `id`. + */ +compilation_finished( + unique int id : @compilation ref, + float cpu_seconds : float ref, + float elapsed_seconds : float ref +); + +/* + * External artifacts + */ + +externalDefects( + unique int id: @externalDefect, + string queryPath: string ref, + int location: @location ref, + string message: string ref, + float severity: float ref); + +externalMetrics( + unique int id: @externalMetric, + string queryPath: string ref, + int location: @location ref, + float value: float ref); + +externalData( + int id: @externalDataElement, + string path: string ref, + int column: int ref, + string value: string ref); + +snapshotDate( + unique date snapshotDate: date ref); + +sourceLocationPrefix( + string prefix: string ref); + +/* + * Duplicate code + */ + +duplicateCode( + unique int id: @duplication, + string relativePath: string ref, + int equivClass: int ref); + +similarCode( + unique int id: @similarity, + string relativePath: string ref, + int equivClass: int ref); + +@duplication_or_similarity = @duplication | @similarity + +tokens( + int id: @duplication_or_similarity ref, + int offset: int ref, + int beginLine: int ref, + int beginColumn: int ref, + int endLine: int ref, + int endColumn: int ref); + +/* + * C# dbscheme + */ + +/** ELEMENTS **/ + +@element = @declaration | @stmt | @expr | @modifier | @attribute | @namespace_declaration + | @using_directive | @type_parameter_constraints | @external_element + | @xmllocatable | @asp_element | @namespace; + +@declaration = @callable | @generic | @assignable | @namespace; + +@named_element = @namespace | @declaration; + +@declaration_with_accessors = @property | @indexer | @event; + +@assignable = @variable | @assignable_with_accessors | @event; + +@assignable_with_accessors = @property | @indexer; + +@external_element = @externalMetric | @externalDefect | @externalDataElement; + +@attributable = @assembly | @field | @parameter | @operator | @method | @constructor + | @destructor | @callable_accessor | @value_or_ref_type | @declaration_with_accessors + | @local_function; + +/** LOCATIONS, ASEMMBLIES, MODULES, FILES and FOLDERS **/ + +@location = @location_default | @assembly; + +locations_default( + unique int id: @location_default, + int file: @file ref, + int beginLine: int ref, + int beginColumn: int ref, + int endLine: int ref, + int endColumn: int ref); + +@sourceline = @file | @callable | @xmllocatable; + +numlines( + int element_id: @sourceline ref, + int num_lines: int ref, + int num_code: int ref, + int num_comment: int ref); + +assemblies( + unique int id: @assembly, + int file: @file ref, + string fullname: string ref, + string name: string ref, + string version: string ref); + +/* + fromSource(0) = unknown, + fromSource(1) = from source, + fromSource(2) = from library +*/ +files( + unique int id: @file, + string name: string ref, + string simple: string ref, + string ext: string ref, + int fromSource: int ref); + +folders( + unique int id: @folder, + string name: string ref, + string simple: string ref); + +@container = @folder | @file ; + +containerparent( + int parent: @container ref, + unique int child: @container ref); + +file_extraction_mode( + unique int file: @file ref, + int mode: int ref + /* 0 = normal, 1 = standalone extractor */ + ); + +/** NAMESPACES **/ + +@type_container = @namespace | @type; + +namespaces( + unique int id: @namespace, + string name: string ref); + +namespace_declarations( + unique int id: @namespace_declaration, + int namespace_id: @namespace ref); + +namespace_declaration_location( + unique int id: @namespace_declaration ref, + int loc: @location ref); + +parent_namespace( + unique int child_id: @type_container ref, + int namespace_id: @namespace ref); + +@declaration_or_directive = @namespace_declaration | @type | @using_directive; + +parent_namespace_declaration( + int child_id: @declaration_or_directive ref, // cannot be unique because of partial classes + int namespace_id: @namespace_declaration ref); + +@using_directive = @using_namespace_directive | @using_static_directive; + +using_namespace_directives( + unique int id: @using_namespace_directive, + int namespace_id: @namespace ref); + +using_static_directives( + unique int id: @using_static_directive, + int type_id: @type_or_ref ref); + +using_directive_location( + unique int id: @using_directive ref, + int loc: @location ref); + +/** TYPES **/ + +types( + unique int id: @type, + int kind: int ref, + string name: string ref); + +case @type.kind of + 1 = @bool_type +| 2 = @char_type +| 3 = @decimal_type +| 4 = @sbyte_type +| 5 = @short_type +| 6 = @int_type +| 7 = @long_type +| 8 = @byte_type +| 9 = @ushort_type +| 10 = @uint_type +| 11 = @ulong_type +| 12 = @float_type +| 13 = @double_type +| 14 = @enum_type +| 15 = @struct_type +| 17 = @class_type +| 19 = @interface_type +| 20 = @delegate_type +| 21 = @null_type +| 22 = @type_parameter +| 23 = @pointer_type +| 24 = @nullable_type +| 25 = @array_type +| 26 = @void_type +| 27 = @int_ptr_type +| 28 = @uint_ptr_type +| 29 = @dynamic_type +| 30 = @arglist_type +| 31 = @unknown_type +| 32 = @tuple_type + ; + +@simple_type = @bool_type | @char_type | @integral_type | @floating_point_type | @decimal_type; +@integral_type = @signed_integral_type | @unsigned_integral_type; +@signed_integral_type = @sbyte_type | @short_type | @int_type | @long_type; +@unsigned_integral_type = @byte_type | @ushort_type | @uint_type | @ulong_type; +@floating_point_type = @float_type | @double_type; +@value_type = @simple_type | @enum_type | @struct_type | @nullable_type | @int_ptr_type + | @uint_ptr_type | @tuple_type; +@ref_type = @class_type | @interface_type | @array_type | @delegate_type | @null_type + | @dynamic_type; +@value_or_ref_type = @value_type | @ref_type; + +typerefs( + unique int id: @typeref, + string name: string ref); + +typeref_type( + int id: @typeref ref, + unique int typeId: @type ref); + +@type_or_ref = @type | @typeref; + +array_element_type( + unique int array: @array_type ref, + int dimension: int ref, + int rank: int ref, + int element: @type_or_ref ref); + +nullable_underlying_type( + unique int nullable: @nullable_type ref, + int underlying: @type_or_ref ref); + +pointer_referent_type( + unique int pointer: @pointer_type ref, + int referent: @type_or_ref ref); + +enum_underlying_type( + unique int enum_id: @enum_type ref, + int underlying_type_id: @type_or_ref ref); + +delegate_return_type( + unique int delegate_id: @delegate_type ref, + int return_type_id: @type_or_ref ref); + +extend( + unique int sub: @type ref, + int super: @type_or_ref ref); + +@interface_or_ref = @interface_type | @typeref; + +implement( + int sub: @type ref, + int super: @type_or_ref ref); + +type_location( + int id: @type ref, + int loc: @location ref); + +tuple_underlying_type( + unique int tuple: @tuple_type ref, + int struct: @type_or_ref ref); + +#keyset[tuple, index] +tuple_element( + int tuple: @tuple_type ref, + int index: int ref, + unique int field: @field ref); + +attributes( + unique int id: @attribute, + int type_id: @type_or_ref ref, + int target: @attributable ref); + +attribute_location( + int id: @attribute ref, + int loc: @location ref); + +@type_mention_parent = @element | @type_mention; + +type_mention( + unique int id: @type_mention, + int type_id: @type_or_ref ref, + int parent: @type_mention_parent ref); + +type_mention_location( + unique int id: @type_mention ref, + int loc: @location ref); + +@has_type_annotation = @assignable | @type_parameter | @callable | @expr | @delegate_type | @generic; + +/** + * A direct annotation on an entity, for example `string? x;`. + * + * Annotations: + * 2 = reftype is not annotated "!" + * 3 = reftype is annotated "?" + * 4 = readonly ref type / in parameter + * 5 = ref type parameter, return or local variable + * 6 = out parameter + * + * Note that the annotation depends on the element it annotates. + * @assignable: The annotation is on the type of the assignable, for example the variable type. + * @type_parameter: The annotation is on the reftype constraint + * @callable: The annotation is on the return type + * @array_type: The annotation is on the element type + */ +type_annotation(int id: @has_type_annotation ref, int annotation: int ref); + +nullability(unique int nullability: @nullability, int kind: int ref); + +case @nullability.kind of + 0 = @oblivious +| 1 = @not_annotated +| 2 = @annotated +; + +#keyset[parent, index] +nullability_parent(int nullability: @nullability ref, int index: int ref, int parent: @nullability ref) + +type_nullability(int id: @has_type_annotation ref, int nullability: @nullability ref); + +/** + * The nullable flow state of an expression, as determined by Roslyn. + * 0 = none (default, not populated) + * 1 = not null + * 2 = maybe null + */ +expr_flowstate(unique int id: @expr ref, int state: int ref); + +/** GENERICS **/ + +@generic = @type | @method | @local_function; + +type_parameters( + unique int id: @type_parameter ref, + int index: int ref, + int generic_id: @generic ref, + int variance: int ref /* none = 0, out = 1, in = 2 */); + +#keyset[constructed_id, index] +type_arguments( + int id: @type_or_ref ref, + int index: int ref, + int constructed_id: @generic_or_ref ref); + +@generic_or_ref = @generic | @typeref; + +constructed_generic( + unique int constructed: @generic ref, + int generic: @generic_or_ref ref); + +type_parameter_constraints( + unique int id: @type_parameter_constraints, + int param_id: @type_parameter ref); + +type_parameter_constraints_location( + int id: @type_parameter_constraints ref, + int loc: @location ref); + +general_type_parameter_constraints( + int id: @type_parameter_constraints ref, + int kind: int ref /* class = 1, struct = 2, new = 3 */); + +specific_type_parameter_constraints( + int id: @type_parameter_constraints ref, + int base_id: @type_or_ref ref); + +specific_type_parameter_nullability( + int id: @type_parameter_constraints ref, + int base_id: @type_or_ref ref, + int nullability: @nullability ref); + +/** MODIFIERS */ + +@modifiable = @modifiable_direct | @event_accessor; + +@modifiable_direct = @member | @accessor | @local_function | @anonymous_function_expr; + +modifiers( + unique int id: @modifier, + string name: string ref); + +has_modifiers( + int id: @modifiable_direct ref, + int mod_id: @modifier ref); + +compiler_generated(unique int id: @modifiable_direct ref); + +/** MEMBERS **/ + +@member = @method | @constructor | @destructor | @field | @property | @event | @operator | @indexer | @type; + +@named_exprorstmt = @goto_stmt | @labeled_stmt | @expr; + +@virtualizable = @method | @property | @indexer | @event; + +exprorstmt_name( + unique int parent_id: @named_exprorstmt ref, + string name: string ref); + +nested_types( + unique int id: @type ref, + int declaring_type_id: @type ref, + int unbound_id: @type ref); + +properties( + unique int id: @property, + string name: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @property ref); + +property_location( + int id: @property ref, + int loc: @location ref); + +indexers( + unique int id: @indexer, + string name: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @indexer ref); + +indexer_location( + int id: @indexer ref, + int loc: @location ref); + +accessors( + unique int id: @accessor, + int kind: int ref, + string name: string ref, + int declaring_member_id: @member ref, + int unbound_id: @accessor ref); + +case @accessor.kind of + 1 = @getter +| 2 = @setter + ; + +init_only_accessors( + unique int id: @accessor ref); + +accessor_location( + int id: @accessor ref, + int loc: @location ref); + +events( + unique int id: @event, + string name: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @event ref); + +event_location( + int id: @event ref, + int loc: @location ref); + +event_accessors( + unique int id: @event_accessor, + int kind: int ref, + string name: string ref, + int declaring_event_id: @event ref, + int unbound_id: @event_accessor ref); + +case @event_accessor.kind of + 1 = @add_event_accessor +| 2 = @remove_event_accessor + ; + +event_accessor_location( + int id: @event_accessor ref, + int loc: @location ref); + +operators( + unique int id: @operator, + string name: string ref, + string symbol: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @operator ref); + +operator_location( + int id: @operator ref, + int loc: @location ref); + +constant_value( + int id: @variable ref, + string value: string ref); + +/** CALLABLES **/ + +@callable = @method | @constructor | @destructor | @operator | @callable_accessor | @anonymous_function_expr | @local_function; + +@callable_accessor = @accessor | @event_accessor; + +methods( + unique int id: @method, + string name: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @method ref); + +method_location( + int id: @method ref, + int loc: @location ref); + +constructors( + unique int id: @constructor, + string name: string ref, + int declaring_type_id: @type ref, + int unbound_id: @constructor ref); + +constructor_location( + int id: @constructor ref, + int loc: @location ref); + +destructors( + unique int id: @destructor, + string name: string ref, + int declaring_type_id: @type ref, + int unbound_id: @destructor ref); + +destructor_location( + int id: @destructor ref, + int loc: @location ref); + +overrides( + int id: @callable ref, + int base_id: @callable ref); + +explicitly_implements( + int id: @member ref, + int interface_id: @interface_or_ref ref); + +local_functions( + unique int id: @local_function, + string name: string ref, + int return_type: @type ref, + int unbound_id: @local_function ref); + +local_function_stmts( + unique int fn: @local_function_stmt ref, + int stmt: @local_function ref); + +/** VARIABLES **/ + +@variable = @local_scope_variable | @field; + +@local_scope_variable = @local_variable | @parameter; + +fields( + unique int id: @field, + int kind: int ref, + string name: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @field ref); + +case @field.kind of + 1 = @addressable_field +| 2 = @constant + ; + +field_location( + int id: @field ref, + int loc: @location ref); + +localvars( + unique int id: @local_variable, + int kind: int ref, + string name: string ref, + int implicitly_typed: int ref /* 0 = no, 1 = yes */, + int type_id: @type_or_ref ref, + int parent_id: @local_var_decl_expr ref); + +case @local_variable.kind of + 1 = @addressable_local_variable +| 2 = @local_constant +| 3 = @local_variable_ref + ; + +localvar_location( + unique int id: @local_variable ref, + int loc: @location ref); + +@parameterizable = @callable | @delegate_type | @indexer; + +#keyset[name, parent_id] +#keyset[index, parent_id] +params( + unique int id: @parameter, + string name: string ref, + int type_id: @type_or_ref ref, + int index: int ref, + int mode: int ref, /* value = 0, ref = 1, out = 2, array = 3, this = 4 */ + int parent_id: @parameterizable ref, + int unbound_id: @parameter ref); + +param_location( + int id: @parameter ref, + int loc: @location ref); + +/** STATEMENTS **/ + +@exprorstmt_parent = @control_flow_element | @top_level_exprorstmt_parent; + +statements( + unique int id: @stmt, + int kind: int ref); + +#keyset[index, parent] +stmt_parent( + unique int stmt: @stmt ref, + int index: int ref, + int parent: @control_flow_element ref); + +@top_level_stmt_parent = @callable; + +// [index, parent] is not a keyset because the same parent may be compiled multiple times +stmt_parent_top_level( + unique int stmt: @stmt ref, + int index: int ref, + int parent: @top_level_stmt_parent ref); + +case @stmt.kind of + 1 = @block_stmt +| 2 = @expr_stmt +| 3 = @if_stmt +| 4 = @switch_stmt +| 5 = @while_stmt +| 6 = @do_stmt +| 7 = @for_stmt +| 8 = @foreach_stmt +| 9 = @break_stmt +| 10 = @continue_stmt +| 11 = @goto_stmt +| 12 = @goto_case_stmt +| 13 = @goto_default_stmt +| 14 = @throw_stmt +| 15 = @return_stmt +| 16 = @yield_stmt +| 17 = @try_stmt +| 18 = @checked_stmt +| 19 = @unchecked_stmt +| 20 = @lock_stmt +| 21 = @using_block_stmt +| 22 = @var_decl_stmt +| 23 = @const_decl_stmt +| 24 = @empty_stmt +| 25 = @unsafe_stmt +| 26 = @fixed_stmt +| 27 = @label_stmt +| 28 = @catch +| 29 = @case_stmt +| 30 = @local_function_stmt +| 31 = @using_decl_stmt + ; + +@using_stmt = @using_block_stmt | @using_decl_stmt; + +@labeled_stmt = @label_stmt | @case; + +@decl_stmt = @var_decl_stmt | @const_decl_stmt | @using_decl_stmt; + +@cond_stmt = @if_stmt | @switch_stmt; + +@loop_stmt = @while_stmt | @do_stmt | @for_stmt | @foreach_stmt; + +@jump_stmt = @break_stmt | @goto_any_stmt | @continue_stmt | @throw_stmt | @return_stmt + | @yield_stmt; + +@goto_any_stmt = @goto_default_stmt | @goto_case_stmt | @goto_stmt; + + +stmt_location( + unique int id: @stmt ref, + int loc: @location ref); + +catch_type( + unique int catch_id: @catch ref, + int type_id: @type_or_ref ref, + int kind: int ref /* explicit = 1, implicit = 2 */); + +/** EXPRESSIONS **/ + +expressions( + unique int id: @expr, + int kind: int ref, + int type_id: @type_or_ref ref); + +#keyset[index, parent] +expr_parent( + unique int expr: @expr ref, + int index: int ref, + int parent: @control_flow_element ref); + +@top_level_expr_parent = @attribute | @field | @property | @indexer | @parameter; + +@top_level_exprorstmt_parent = @top_level_expr_parent | @top_level_stmt_parent; + +// [index, parent] is not a keyset because the same parent may be compiled multiple times +expr_parent_top_level( + unique int expr: @expr ref, + int index: int ref, + int parent: @top_level_exprorstmt_parent ref); + +case @expr.kind of +/* literal */ + 1 = @bool_literal_expr +| 2 = @char_literal_expr +| 3 = @decimal_literal_expr +| 4 = @int_literal_expr +| 5 = @long_literal_expr +| 6 = @uint_literal_expr +| 7 = @ulong_literal_expr +| 8 = @float_literal_expr +| 9 = @double_literal_expr +| 10 = @string_literal_expr +| 11 = @null_literal_expr +/* primary & unary */ +| 12 = @this_access_expr +| 13 = @base_access_expr +| 14 = @local_variable_access_expr +| 15 = @parameter_access_expr +| 16 = @field_access_expr +| 17 = @property_access_expr +| 18 = @method_access_expr +| 19 = @event_access_expr +| 20 = @indexer_access_expr +| 21 = @array_access_expr +| 22 = @type_access_expr +| 23 = @typeof_expr +| 24 = @method_invocation_expr +| 25 = @delegate_invocation_expr +| 26 = @operator_invocation_expr +| 27 = @cast_expr +| 28 = @object_creation_expr +| 29 = @explicit_delegate_creation_expr +| 30 = @implicit_delegate_creation_expr +| 31 = @array_creation_expr +| 32 = @default_expr +| 33 = @plus_expr +| 34 = @minus_expr +| 35 = @bit_not_expr +| 36 = @log_not_expr +| 37 = @post_incr_expr +| 38 = @post_decr_expr +| 39 = @pre_incr_expr +| 40 = @pre_decr_expr +/* multiplicative */ +| 41 = @mul_expr +| 42 = @div_expr +| 43 = @rem_expr +/* additive */ +| 44 = @add_expr +| 45 = @sub_expr +/* shift */ +| 46 = @lshift_expr +| 47 = @rshift_expr +/* relational */ +| 48 = @lt_expr +| 49 = @gt_expr +| 50 = @le_expr +| 51 = @ge_expr +/* equality */ +| 52 = @eq_expr +| 53 = @ne_expr +/* logical */ +| 54 = @bit_and_expr +| 55 = @bit_xor_expr +| 56 = @bit_or_expr +| 57 = @log_and_expr +| 58 = @log_or_expr +/* type testing */ +| 59 = @is_expr +| 60 = @as_expr +/* null coalescing */ +| 61 = @null_coalescing_expr +/* conditional */ +| 62 = @conditional_expr +/* assignment */ +| 63 = @simple_assign_expr +| 64 = @assign_add_expr +| 65 = @assign_sub_expr +| 66 = @assign_mul_expr +| 67 = @assign_div_expr +| 68 = @assign_rem_expr +| 69 = @assign_and_expr +| 70 = @assign_xor_expr +| 71 = @assign_or_expr +| 72 = @assign_lshift_expr +| 73 = @assign_rshift_expr +/* more */ +| 74 = @object_init_expr +| 75 = @collection_init_expr +| 76 = @array_init_expr +| 77 = @checked_expr +| 78 = @unchecked_expr +| 79 = @constructor_init_expr +| 80 = @add_event_expr +| 81 = @remove_event_expr +| 82 = @par_expr +| 83 = @local_var_decl_expr +| 84 = @lambda_expr +| 85 = @anonymous_method_expr +| 86 = @namespace_expr +/* dynamic */ +| 92 = @dynamic_element_access_expr +| 93 = @dynamic_member_access_expr +/* unsafe */ +| 100 = @pointer_indirection_expr +| 101 = @address_of_expr +| 102 = @sizeof_expr +/* async */ +| 103 = @await_expr +/* C# 6.0 */ +| 104 = @nameof_expr +| 105 = @interpolated_string_expr +| 106 = @unknown_expr +/* C# 7.0 */ +| 107 = @throw_expr +| 108 = @tuple_expr +| 109 = @local_function_invocation_expr +| 110 = @ref_expr +| 111 = @discard_expr +/* C# 8.0 */ +| 112 = @range_expr +| 113 = @index_expr +| 114 = @switch_expr +| 115 = @recursive_pattern_expr +| 116 = @property_pattern_expr +| 117 = @positional_pattern_expr +| 118 = @switch_case_expr +| 119 = @assign_coalesce_expr +| 120 = @suppress_nullable_warning_expr +| 121 = @namespace_access_expr +; + +@switch = @switch_stmt | @switch_expr; +@case = @case_stmt | @switch_case_expr; +@pattern_match = @case | @is_expr; + +@integer_literal_expr = @int_literal_expr | @long_literal_expr | @uint_literal_expr | @ulong_literal_expr; +@real_literal_expr = @float_literal_expr | @double_literal_expr | @decimal_literal_expr; +@literal_expr = @bool_literal_expr | @char_literal_expr | @integer_literal_expr | @real_literal_expr + | @string_literal_expr | @null_literal_expr; + +@assign_expr = @simple_assign_expr | @assign_op_expr | @local_var_decl_expr; +@assign_op_expr = @assign_arith_expr | @assign_bitwise_expr | @assign_event_expr | @assign_coalesce_expr; +@assign_event_expr = @add_event_expr | @remove_event_expr; + +@assign_arith_expr = @assign_add_expr | @assign_sub_expr | @assign_mul_expr | @assign_div_expr + | @assign_rem_expr +@assign_bitwise_expr = @assign_and_expr | @assign_or_expr | @assign_xor_expr + | @assign_lshift_expr | @assign_rshift_expr; + +@member_access_expr = @field_access_expr | @property_access_expr | @indexer_access_expr | @event_access_expr + | @method_access_expr | @type_access_expr | @dynamic_member_access_expr; +@access_expr = @member_access_expr | @this_access_expr | @base_access_expr | @assignable_access_expr | @namespace_access_expr; +@element_access_expr = @indexer_access_expr | @array_access_expr | @dynamic_element_access_expr; + +@local_variable_access = @local_variable_access_expr | @local_var_decl_expr; +@local_scope_variable_access_expr = @parameter_access_expr | @local_variable_access; +@variable_access_expr = @local_scope_variable_access_expr | @field_access_expr; + +@assignable_access_expr = @variable_access_expr | @property_access_expr | @element_access_expr + | @event_access_expr | @dynamic_member_access_expr; + +@objectorcollection_init_expr = @object_init_expr | @collection_init_expr; + +@delegate_creation_expr = @explicit_delegate_creation_expr | @implicit_delegate_creation_expr; + +@bin_arith_op_expr = @mul_expr | @div_expr | @rem_expr | @add_expr | @sub_expr; +@incr_op_expr = @pre_incr_expr | @post_incr_expr; +@decr_op_expr = @pre_decr_expr | @post_decr_expr; +@mut_op_expr = @incr_op_expr | @decr_op_expr; +@un_arith_op_expr = @plus_expr | @minus_expr | @mut_op_expr; +@arith_op_expr = @bin_arith_op_expr | @un_arith_op_expr; + +@ternary_log_op_expr = @conditional_expr; +@bin_log_op_expr = @log_and_expr | @log_or_expr | @null_coalescing_expr; +@un_log_op_expr = @log_not_expr; +@log_expr = @un_log_op_expr | @bin_log_op_expr | @ternary_log_op_expr; + +@bin_bit_op_expr = @bit_and_expr | @bit_or_expr | @bit_xor_expr | @lshift_expr + | @rshift_expr; +@un_bit_op_expr = @bit_not_expr; +@bit_expr = @un_bit_op_expr | @bin_bit_op_expr; + +@equality_op_expr = @eq_expr | @ne_expr; +@rel_op_expr = @gt_expr | @lt_expr| @ge_expr | @le_expr; +@comp_expr = @equality_op_expr | @rel_op_expr; + +@op_expr = @assign_expr | @un_op | @bin_op | @ternary_op; + +@ternary_op = @ternary_log_op_expr; +@bin_op = @bin_arith_op_expr | @bin_log_op_expr | @bin_bit_op_expr | @comp_expr; +@un_op = @un_arith_op_expr | @un_log_op_expr | @un_bit_op_expr | @sizeof_expr + | @pointer_indirection_expr | @address_of_expr; + +@anonymous_function_expr = @lambda_expr | @anonymous_method_expr; + +@call = @method_invocation_expr | @constructor_init_expr | @operator_invocation_expr + | @delegate_invocation_expr | @object_creation_expr | @call_access_expr + | @local_function_invocation_expr; + +@call_access_expr = @property_access_expr | @event_access_expr | @indexer_access_expr; + +@late_bindable_expr = @dynamic_element_access_expr | @dynamic_member_access_expr + | @object_creation_expr | @method_invocation_expr | @operator_invocation_expr; + +@throw_element = @throw_expr | @throw_stmt; + +@implicitly_typeable_object_creation_expr = @object_creation_expr | @explicit_delegate_creation_expr; + +implicitly_typed_array_creation( + unique int id: @array_creation_expr ref); + +explicitly_sized_array_creation( + unique int id: @array_creation_expr ref); + +stackalloc_array_creation( + unique int id: @array_creation_expr ref); + +implicitly_typed_object_creation( + unique int id: @implicitly_typeable_object_creation_expr ref); + +mutator_invocation_mode( + unique int id: @operator_invocation_expr ref, + int mode: int ref /* prefix = 1, postfix = 2*/); + +expr_compiler_generated( + unique int id: @expr ref); + +expr_value( + unique int id: @expr ref, + string value: string ref); + +expr_call( + unique int caller_id: @expr ref, + int target_id: @callable ref); + +expr_access( + unique int accesser_id: @access_expr ref, + int target_id: @accessible ref); + +@accessible = @method | @assignable | @local_function | @namespace; + +expr_location( + unique int id: @expr ref, + int loc: @location ref); + +dynamic_member_name( + unique int id: @late_bindable_expr ref, + string name: string ref); + +@qualifiable_expr = @member_access_expr + | @method_invocation_expr + | @element_access_expr; + +conditional_access( + unique int id: @qualifiable_expr ref); + +expr_argument( + unique int id: @expr ref, + int mode: int ref); + /* mode is the same as params: value = 0, ref = 1, out = 2 */ + +expr_argument_name( + unique int id: @expr ref, + string name: string ref); + +/** CONTROL/DATA FLOW **/ + +@control_flow_element = @stmt | @expr; + +/* XML Files */ + +xmlEncoding ( + unique int id: @file ref, + string encoding: string ref); + +xmlDTDs( + unique int id: @xmldtd, + string root: string ref, + string publicId: string ref, + string systemId: string ref, + int fileid: @file ref); + +xmlElements( + unique int id: @xmlelement, + string name: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int fileid: @file ref); + +xmlAttrs( + unique int id: @xmlattribute, + int elementid: @xmlelement ref, + string name: string ref, + string value: string ref, + int idx: int ref, + int fileid: @file ref); + +xmlNs( + int id: @xmlnamespace, + string prefixName: string ref, + string URI: string ref, + int fileid: @file ref); + +xmlHasNs( + int elementId: @xmlnamespaceable ref, + int nsId: @xmlnamespace ref, + int fileid: @file ref); + +xmlComments( + unique int id: @xmlcomment, + string text: string ref, + int parentid: @xmlparent ref, + int fileid: @file ref); + +xmlChars( + unique int id: @xmlcharacters, + string text: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int isCDATA: int ref, + int fileid: @file ref); + +@xmlparent = @file | @xmlelement; +@xmlnamespaceable = @xmlelement | @xmlattribute; + +xmllocations( + int xmlElement: @xmllocatable ref, + int location: @location_default ref); + +@xmllocatable = @xmlcharacters | @xmlelement | @xmlcomment | @xmlattribute | @xmldtd | @file | @xmlnamespace; + +/* Comments */ + +commentline( + unique int id: @commentline, + int kind: int ref, + string text: string ref, + string rawtext: string ref); + +case @commentline.kind of + 0 = @singlelinecomment +| 1 = @xmldoccomment +| 2 = @multilinecomment; + +commentline_location( + unique int id: @commentline ref, + int loc: @location ref); + +commentblock( + unique int id : @commentblock); + +commentblock_location( + unique int id: @commentblock ref, + int loc: @location ref); + +commentblock_binding( + int id: @commentblock ref, + int entity: @element ref, + int bindtype: int ref); /* 0: Parent, 1: Best, 2: Before, 3: After */ + +commentblock_child( + int id: @commentblock ref, + int commentline: @commentline ref, + int index: int ref); + +/* ASP.NET */ + +case @asp_element.kind of + 0=@asp_close_tag +| 1=@asp_code +| 2=@asp_comment +| 3=@asp_data_binding +| 4=@asp_directive +| 5=@asp_open_tag +| 6=@asp_quoted_string +| 7=@asp_text +| 8=@asp_xml_directive; + +@asp_attribute = @asp_code | @asp_data_binding | @asp_quoted_string; + +asp_elements( + unique int id: @asp_element, + int kind: int ref, + int loc: @location ref); + +asp_comment_server(unique int comment: @asp_comment ref); +asp_code_inline(unique int code: @asp_code ref); +asp_directive_attribute( + int directive: @asp_directive ref, + int index: int ref, + string name: string ref, + int value: @asp_quoted_string ref); +asp_directive_name( + unique int directive: @asp_directive ref, + string name: string ref); +asp_element_body( + unique int element: @asp_element ref, + string body: string ref); +asp_tag_attribute( + int tag: @asp_open_tag ref, + int index: int ref, + string name: string ref, + int attribute: @asp_attribute ref); +asp_tag_name( + unique int tag: @asp_open_tag ref, + string name: string ref); +asp_tag_isempty(int tag: @asp_open_tag ref); + +/* Common Intermediate Language - CIL */ + +case @cil_instruction.opcode of + 0 = @cil_nop +| 1 = @cil_break +| 2 = @cil_ldarg_0 +| 3 = @cil_ldarg_1 +| 4 = @cil_ldarg_2 +| 5 = @cil_ldarg_3 +| 6 = @cil_ldloc_0 +| 7 = @cil_ldloc_1 +| 8 = @cil_ldloc_2 +| 9 = @cil_ldloc_3 +| 10 = @cil_stloc_0 +| 11 = @cil_stloc_1 +| 12 = @cil_stloc_2 +| 13 = @cil_stloc_3 +| 14 = @cil_ldarg_s +| 15 = @cil_ldarga_s +| 16 = @cil_starg_s +| 17 = @cil_ldloc_s +| 18 = @cil_ldloca_s +| 19 = @cil_stloc_s +| 20 = @cil_ldnull +| 21 = @cil_ldc_i4_m1 +| 22 = @cil_ldc_i4_0 +| 23 = @cil_ldc_i4_1 +| 24 = @cil_ldc_i4_2 +| 25 = @cil_ldc_i4_3 +| 26 = @cil_ldc_i4_4 +| 27 = @cil_ldc_i4_5 +| 28 = @cil_ldc_i4_6 +| 29 = @cil_ldc_i4_7 +| 30 = @cil_ldc_i4_8 +| 31 = @cil_ldc_i4_s +| 32 = @cil_ldc_i4 +| 33 = @cil_ldc_i8 +| 34 = @cil_ldc_r4 +| 35 = @cil_ldc_r8 +| 37 = @cil_dup +| 38 = @cil_pop +| 39 = @cil_jmp +| 40 = @cil_call +| 41 = @cil_calli +| 42 = @cil_ret +| 43 = @cil_br_s +| 44 = @cil_brfalse_s +| 45 = @cil_brtrue_s +| 46 = @cil_beq_s +| 47 = @cil_bge_s +| 48 = @cil_bgt_s +| 49 = @cil_ble_s +| 50 = @cil_blt_s +| 51 = @cil_bne_un_s +| 52 = @cil_bge_un_s +| 53 = @cil_bgt_un_s +| 54 = @cil_ble_un_s +| 55 = @cil_blt_un_s +| 56 = @cil_br +| 57 = @cil_brfalse +| 58 = @cil_brtrue +| 59 = @cil_beq +| 60 = @cil_bge +| 61 = @cil_bgt +| 62 = @cil_ble +| 63 = @cil_blt +| 64 = @cil_bne_un +| 65 = @cil_bge_un +| 66 = @cil_bgt_un +| 67 = @cil_ble_un +| 68 = @cil_blt_un +| 69 = @cil_switch +| 70 = @cil_ldind_i1 +| 71 = @cil_ldind_u1 +| 72 = @cil_ldind_i2 +| 73 = @cil_ldind_u2 +| 74 = @cil_ldind_i4 +| 75 = @cil_ldind_u4 +| 76 = @cil_ldind_i8 +| 77 = @cil_ldind_i +| 78 = @cil_ldind_r4 +| 79 = @cil_ldind_r8 +| 80 = @cil_ldind_ref +| 81 = @cil_stind_ref +| 82 = @cil_stind_i1 +| 83 = @cil_stind_i2 +| 84 = @cil_stind_i4 +| 85 = @cil_stind_i8 +| 86 = @cil_stind_r4 +| 87 = @cil_stind_r8 +| 88 = @cil_add +| 89 = @cil_sub +| 90 = @cil_mul +| 91 = @cil_div +| 92 = @cil_div_un +| 93 = @cil_rem +| 94 = @cil_rem_un +| 95 = @cil_and +| 96 = @cil_or +| 97 = @cil_xor +| 98 = @cil_shl +| 99 = @cil_shr +| 100 = @cil_shr_un +| 101 = @cil_neg +| 102 = @cil_not +| 103 = @cil_conv_i1 +| 104 = @cil_conv_i2 +| 105 = @cil_conv_i4 +| 106 = @cil_conv_i8 +| 107 = @cil_conv_r4 +| 108 = @cil_conv_r8 +| 109 = @cil_conv_u4 +| 110 = @cil_conv_u8 +| 111 = @cil_callvirt +| 112 = @cil_cpobj +| 113 = @cil_ldobj +| 114 = @cil_ldstr +| 115 = @cil_newobj +| 116 = @cil_castclass +| 117 = @cil_isinst +| 118 = @cil_conv_r_un +| 121 = @cil_unbox +| 122 = @cil_throw +| 123 = @cil_ldfld +| 124 = @cil_ldflda +| 125 = @cil_stfld +| 126 = @cil_ldsfld +| 127 = @cil_ldsflda +| 128 = @cil_stsfld +| 129 = @cil_stobj +| 130 = @cil_conv_ovf_i1_un +| 131 = @cil_conv_ovf_i2_un +| 132 = @cil_conv_ovf_i4_un +| 133 = @cil_conv_ovf_i8_un +| 134 = @cil_conv_ovf_u1_un +| 135 = @cil_conv_ovf_u2_un +| 136 = @cil_conv_ovf_u4_un +| 137 = @cil_conv_ovf_u8_un +| 138 = @cil_conv_ovf_i_un +| 139 = @cil_conv_ovf_u_un +| 140 = @cil_box +| 141 = @cil_newarr +| 142 = @cil_ldlen +| 143 = @cil_ldelema +| 144 = @cil_ldelem_i1 +| 145 = @cil_ldelem_u1 +| 146 = @cil_ldelem_i2 +| 147 = @cil_ldelem_u2 +| 148 = @cil_ldelem_i4 +| 149 = @cil_ldelem_u4 +| 150 = @cil_ldelem_i8 +| 151 = @cil_ldelem_i +| 152 = @cil_ldelem_r4 +| 153 = @cil_ldelem_r8 +| 154 = @cil_ldelem_ref +| 155 = @cil_stelem_i +| 156 = @cil_stelem_i1 +| 157 = @cil_stelem_i2 +| 158 = @cil_stelem_i4 +| 159 = @cil_stelem_i8 +| 160 = @cil_stelem_r4 +| 161 = @cil_stelem_r8 +| 162 = @cil_stelem_ref +| 163 = @cil_ldelem +| 164 = @cil_stelem +| 165 = @cil_unbox_any +| 179 = @cil_conv_ovf_i1 +| 180 = @cil_conv_ovf_u1 +| 181 = @cil_conv_ovf_i2 +| 182 = @cil_conv_ovf_u2 +| 183 = @cil_conv_ovf_i4 +| 184 = @cil_conv_ovf_u4 +| 185 = @cil_conv_ovf_i8 +| 186 = @cil_conv_ovf_u8 +| 194 = @cil_refanyval +| 195 = @cil_ckinfinite +| 198 = @cil_mkrefany +| 208 = @cil_ldtoken +| 209 = @cil_conv_u2 +| 210 = @cil_conv_u1 +| 211 = @cil_conv_i +| 212 = @cil_conv_ovf_i +| 213 = @cil_conv_ovf_u +| 214 = @cil_add_ovf +| 215 = @cil_add_ovf_un +| 216 = @cil_mul_ovf +| 217 = @cil_mul_ovf_un +| 218 = @cil_sub_ovf +| 219 = @cil_sub_ovf_un +| 220 = @cil_endfinally +| 221 = @cil_leave +| 222 = @cil_leave_s +| 223 = @cil_stind_i +| 224 = @cil_conv_u +| 65024 = @cil_arglist +| 65025 = @cil_ceq +| 65026 = @cil_cgt +| 65027 = @cil_cgt_un +| 65028 = @cil_clt +| 65029 = @cil_clt_un +| 65030 = @cil_ldftn +| 65031 = @cil_ldvirtftn +| 65033 = @cil_ldarg +| 65034 = @cil_ldarga +| 65035 = @cil_starg +| 65036 = @cil_ldloc +| 65037 = @cil_ldloca +| 65038 = @cil_stloc +| 65039 = @cil_localloc +| 65041 = @cil_endfilter +| 65042 = @cil_unaligned +| 65043 = @cil_volatile +| 65044 = @cil_tail +| 65045 = @cil_initobj +| 65046 = @cil_constrained +| 65047 = @cil_cpblk +| 65048 = @cil_initblk +| 65050 = @cil_rethrow +| 65052 = @cil_sizeof +| 65053 = @cil_refanytype +| 65054 = @cil_readonly +; + +// CIL ignored instructions + +@cil_ignore = @cil_nop | @cil_break | @cil_volatile | @cil_unaligned; + +// CIL local/parameter/field access + +@cil_ldarg_any = @cil_ldarg_0 | @cil_ldarg_1 | @cil_ldarg_2 | @cil_ldarg_3 | @cil_ldarg_s | @cil_ldarga_s | @cil_ldarg | @cil_ldarga; +@cil_starg_any = @cil_starg | @cil_starg_s; + +@cil_ldloc_any = @cil_ldloc_0 | @cil_ldloc_1 | @cil_ldloc_2 | @cil_ldloc_3 | @cil_ldloc_s | @cil_ldloca_s | @cil_ldloc | @cil_ldloca; +@cil_stloc_any = @cil_stloc_0 | @cil_stloc_1 | @cil_stloc_2 | @cil_stloc_3 | @cil_stloc_s | @cil_stloc; + +@cil_ldfld_any = @cil_ldfld | @cil_ldsfld | @cil_ldsflda | @cil_ldflda; +@cil_stfld_any = @cil_stfld | @cil_stsfld; + +@cil_local_access = @cil_stloc_any | @cil_ldloc_any; +@cil_arg_access = @cil_starg_any | @cil_ldarg_any; +@cil_read_access = @cil_ldloc_any | @cil_ldarg_any | @cil_ldfld_any; +@cil_write_access = @cil_stloc_any | @cil_starg_any | @cil_stfld_any; + +@cil_stack_access = @cil_local_access | @cil_arg_access; +@cil_field_access = @cil_ldfld_any | @cil_stfld_any; + +@cil_access = @cil_read_access | @cil_write_access; + +// CIL constant/literal instructions + +@cil_ldc_i = @cil_ldc_i4_any | @cil_ldc_i8; + +@cil_ldc_i4_any = @cil_ldc_i4_m1 | @cil_ldc_i4_0 | @cil_ldc_i4_1 | @cil_ldc_i4_2 | @cil_ldc_i4_3 | + @cil_ldc_i4_4 | @cil_ldc_i4_5 | @cil_ldc_i4_6 | @cil_ldc_i4_7 | @cil_ldc_i4_8 | @cil_ldc_i4_s | @cil_ldc_i4; + +@cil_ldc_r = @cil_ldc_r4 | @cil_ldc_r8; + +@cil_literal = @cil_ldnull | @cil_ldc_i | @cil_ldc_r | @cil_ldstr; + +// Control flow + +@cil_conditional_jump = @cil_binary_jump | @cil_unary_jump; +@cil_binary_jump = @cil_beq_s | @cil_bge_s | @cil_bgt_s | @cil_ble_s | @cil_blt_s | + @cil_bne_un_s | @cil_bge_un_s | @cil_bgt_un_s | @cil_ble_un_s | @cil_blt_un_s | + @cil_beq | @cil_bge | @cil_bgt | @cil_ble | @cil_blt | + @cil_bne_un | @cil_bge_un | @cil_bgt_un | @cil_ble_un | @cil_blt_un; +@cil_unary_jump = @cil_brfalse_s | @cil_brtrue_s | @cil_brfalse | @cil_brtrue | @cil_switch; +@cil_unconditional_jump = @cil_br | @cil_br_s | @cil_leave_any; +@cil_leave_any = @cil_leave | @cil_leave_s; +@cil_jump = @cil_unconditional_jump | @cil_conditional_jump; + +// CIL call instructions + +@cil_call_any = @cil_jmp | @cil_call | @cil_calli | @cil_tail | @cil_callvirt | @cil_newobj; + +// CIL expression instructions + +@cil_expr = @cil_literal | @cil_binary_expr | @cil_unary_expr | @cil_call_any | @cil_read_access | + @cil_newarr | @cil_ldtoken | @cil_sizeof | + @cil_ldftn | @cil_ldvirtftn | @cil_localloc | @cil_mkrefany | @cil_refanytype | @cil_arglist | @cil_dup; + +@cil_unary_expr = + @cil_conversion_operation | @cil_unary_arithmetic_operation | @cil_unary_bitwise_operation| + @cil_ldlen | @cil_isinst | @cil_box | @cil_ldobj | @cil_castclass | @cil_unbox_any | + @cil_ldind | @cil_unbox; + +@cil_conversion_operation = + @cil_conv_i1 | @cil_conv_i2 | @cil_conv_i4 | @cil_conv_i8 | + @cil_conv_u1 | @cil_conv_u2 | @cil_conv_u4 | @cil_conv_u8 | + @cil_conv_ovf_i | @cil_conv_ovf_i_un | @cil_conv_ovf_i1 | @cil_conv_ovf_i1_un | + @cil_conv_ovf_i2 | @cil_conv_ovf_i2_un | @cil_conv_ovf_i4 | @cil_conv_ovf_i4_un | + @cil_conv_ovf_i8 | @cil_conv_ovf_i8_un | @cil_conv_ovf_u | @cil_conv_ovf_u_un | + @cil_conv_ovf_u1 | @cil_conv_ovf_u1_un | @cil_conv_ovf_u2 | @cil_conv_ovf_u2_un | + @cil_conv_ovf_u4 | @cil_conv_ovf_u4_un | @cil_conv_ovf_u8 | @cil_conv_ovf_u8_un | + @cil_conv_r4 | @cil_conv_r8 | @cil_conv_ovf_u2 | @cil_conv_ovf_u2_un | + @cil_conv_i | @cil_conv_u | @cil_conv_r_un; + +@cil_ldind = @cil_ldind_i | @cil_ldind_i1 | @cil_ldind_i2 | @cil_ldind_i4 | @cil_ldind_i8 | + @cil_ldind_r4 | @cil_ldind_r8 | @cil_ldind_ref | @cil_ldind_u1 | @cil_ldind_u2 | @cil_ldind_u4; + +@cil_stind = @cil_stind_i | @cil_stind_i1 | @cil_stind_i2 | @cil_stind_i4 | @cil_stind_i8 | + @cil_stind_r4 | @cil_stind_r8 | @cil_stind_ref; + +@cil_bitwise_operation = @cil_binary_bitwise_operation | @cil_unary_bitwise_operation; + +@cil_binary_bitwise_operation = @cil_and | @cil_or | @cil_xor | @cil_shr | @cil_shr | @cil_shr_un | @cil_shl; + +@cil_binary_arithmetic_operation = @cil_add | @cil_sub | @cil_mul | @cil_div | @cil_div_un | + @cil_rem | @cil_rem_un | @cil_add_ovf | @cil_add_ovf_un | @cil_mul_ovf | @cil_mul_ovf_un | + @cil_sub_ovf | @cil_sub_ovf_un; + +@cil_unary_bitwise_operation = @cil_not; + +@cil_binary_expr = @cil_binary_arithmetic_operation | @cil_binary_bitwise_operation | @cil_read_array | @cil_comparison_operation; + +@cil_unary_arithmetic_operation = @cil_neg; + +@cil_comparison_operation = @cil_cgt_un | @cil_ceq | @cil_cgt | @cil_clt | @cil_clt_un; + +// Elements that retrieve an address of something +@cil_read_ref = @cil_ldloca_s | @cil_ldarga_s | @cil_ldflda | @cil_ldsflda | @cil_ldelema; + +// CIL array instructions + +@cil_read_array = + @cil_ldelem | @cil_ldelema | @cil_ldelem_i1 | @cil_ldelem_ref | @cil_ldelem_i | + @cil_ldelem_i1 | @cil_ldelem_i2 | @cil_ldelem_i4 | @cil_ldelem_i8 | @cil_ldelem_r4 | + @cil_ldelem_r8 | @cil_ldelem_u1 | @cil_ldelem_u2 | @cil_ldelem_u4; + +@cil_write_array = @cil_stelem | @cil_stelem_ref | + @cil_stelem_i | @cil_stelem_i1 | @cil_stelem_i2 | @cil_stelem_i4 | @cil_stelem_i8 | + @cil_stelem_r4 | @cil_stelem_r8; + +@cil_throw_any = @cil_throw | @cil_rethrow; + +#keyset[impl, index] +cil_instruction( + unique int id: @cil_instruction, + int opcode: int ref, + int index: int ref, + int impl: @cil_method_implementation ref); + +cil_jump( + unique int instruction: @cil_jump ref, + int target: @cil_instruction ref); + +cil_access( + unique int instruction: @cil_instruction ref, + int target: @cil_accessible ref); + +cil_value( + unique int instruction: @cil_literal ref, + string value: string ref); + +#keyset[instruction, index] +cil_switch( + int instruction: @cil_switch ref, + int index: int ref, + int target: @cil_instruction ref); + +cil_instruction_location( + unique int id: @cil_instruction ref, + int loc: @location ref); + +cil_type_location( + int id: @cil_type ref, + int loc: @location ref); + +cil_method_location( + int id: @cil_method ref, + int loc: @location ref); + +@cil_namespace = @namespace; + +@cil_type_container = @cil_type | @cil_namespace | @cil_method; + +case @cil_type.kind of + 0 = @cil_valueorreftype +| 1 = @cil_typeparameter +| 2 = @cil_array_type +| 3 = @cil_pointer_type +; + +cil_type( + unique int id: @cil_type, + string name: string ref, + int kind: int ref, + int parent: @cil_type_container ref, + int sourceDecl: @cil_type ref); + +cil_pointer_type( + unique int id: @cil_pointer_type ref, + int pointee: @cil_type ref); + +cil_array_type( + unique int id: @cil_array_type ref, + int element_type: @cil_type ref, + int rank: int ref); + +cil_method( + unique int id: @cil_method, + string name: string ref, + int parent: @cil_type ref, + int return_type: @cil_type ref); + +cil_method_source_declaration( + unique int method: @cil_method ref, + int source: @cil_method ref); + +cil_method_implementation( + unique int id: @cil_method_implementation, + int method: @cil_method ref, + int location: @assembly ref); + +cil_implements( + int id: @cil_method ref, + int decl: @cil_method ref); + +#keyset[parent, name] +cil_field( + unique int id: @cil_field, + int parent: @cil_type ref, + string name: string ref, + int field_type: @cil_type ref); + +@cil_element = @cil_instruction | @cil_declaration | @cil_handler | @cil_attribute | @cil_namespace; +@cil_named_element = @cil_declaration | @cil_namespace; +@cil_declaration = @cil_variable | @cil_method | @cil_type | @cil_member; +@cil_accessible = @cil_declaration; +@cil_variable = @cil_field | @cil_stack_variable; +@cil_stack_variable = @cil_local_variable | @cil_parameter; +@cil_member = @cil_method | @cil_type | @cil_field | @cil_property | @cil_event; + +#keyset[method, index] +cil_parameter( + unique int id: @cil_parameter, + int method: @cil_method ref, + int index: int ref, + int param_type: @cil_type ref); + +cil_parameter_in(unique int id: @cil_parameter ref); +cil_parameter_out(unique int id: @cil_parameter ref); + +cil_setter(unique int prop: @cil_property ref, + int method: @cil_method ref); + +cil_getter(unique int prop: @cil_property ref, + int method: @cil_method ref); + +cil_adder(unique int event: @cil_event ref, + int method: @cil_method ref); + +cil_remover(unique int event: @cil_event ref, int method: @cil_method ref); + +cil_raiser(unique int event: @cil_event ref, int method: @cil_method ref); + +cil_property( + unique int id: @cil_property, + int parent: @cil_type ref, + string name: string ref, + int property_type: @cil_type ref); + +#keyset[parent, name] +cil_event(unique int id: @cil_event, + int parent: @cil_type ref, + string name: string ref, + int event_type: @cil_type ref); + +#keyset[impl, index] +cil_local_variable( + unique int id: @cil_local_variable, + int impl: @cil_method_implementation ref, + int index: int ref, + int var_type: @cil_type ref); + +// CIL handlers (exception handlers etc). + +case @cil_handler.kind of + 0 = @cil_catch_handler +| 1 = @cil_filter_handler +| 2 = @cil_finally_handler +| 4 = @cil_fault_handler +; + +#keyset[impl, index] +cil_handler( + unique int id: @cil_handler, + int impl: @cil_method_implementation ref, + int index: int ref, + int kind: int ref, + int try_start: @cil_instruction ref, + int try_end: @cil_instruction ref, + int handler_start: @cil_instruction ref); + +cil_handler_filter( + unique int id: @cil_handler ref, + int filter_start: @cil_instruction ref); + +cil_handler_type( + unique int id: @cil_handler ref, + int catch_type: @cil_type ref); + +@cil_controlflow_node = @cil_entry_point | @cil_instruction; + +@cil_entry_point = @cil_method_implementation | @cil_handler; + +@cil_dataflow_node = @cil_instruction | @cil_variable | @cil_method; + +cil_method_stack_size( + unique int method: @cil_method_implementation ref, + int size: int ref); + +// CIL modifiers + +cil_public(int id: @cil_member ref); +cil_private(int id: @cil_member ref); +cil_protected(int id: @cil_member ref); +cil_internal(int id: @cil_member ref); +cil_static(int id: @cil_member ref); +cil_sealed(int id: @cil_member ref); +cil_virtual(int id: @cil_method ref); +cil_abstract(int id: @cil_member ref); +cil_class(int id: @cil_type ref); +cil_interface(int id: @cil_type ref); +cil_security(int id: @cil_member ref); +cil_requiresecobject(int id: @cil_method ref); +cil_specialname(int id: @cil_method ref); +cil_newslot(int id: @cil_method ref); + +cil_base_class(unique int id: @cil_type ref, int base: @cil_type ref); +cil_base_interface(int id: @cil_type ref, int base: @cil_type ref); +cil_enum_underlying_type(unique int id: @cil_type ref, int underlying: @cil_type ref); + +#keyset[unbound, index] +cil_type_parameter( + int unbound: @cil_member ref, + int index: int ref, + int param: @cil_typeparameter ref); + +#keyset[bound, index] +cil_type_argument( + int bound: @cil_member ref, + int index: int ref, + int t: @cil_type ref); + +// CIL type parameter constraints + +cil_typeparam_covariant(int tp: @cil_typeparameter ref); +cil_typeparam_contravariant(int tp: @cil_typeparameter ref); +cil_typeparam_class(int tp: @cil_typeparameter ref); +cil_typeparam_struct(int tp: @cil_typeparameter ref); +cil_typeparam_new(int tp: @cil_typeparameter ref); +cil_typeparam_constraint(int tp: @cil_typeparameter ref, int supertype: @cil_type ref); + +// CIL attributes + +cil_attribute( + unique int attributeid: @cil_attribute, + int element: @cil_declaration ref, + int constructor: @cil_method ref); + +#keyset[attribute_id, param] +cil_attribute_named_argument( + int attribute_id: @cil_attribute ref, + string param: string ref, + string value: string ref); + +#keyset[attribute_id, index] +cil_attribute_positional_argument( + int attribute_id: @cil_attribute ref, + int index: int ref, + string value: string ref); + + +// Common .Net data model covering both C# and CIL + +// Common elements +@dotnet_element = @element | @cil_element; +@dotnet_named_element = @named_element | @cil_named_element; +@dotnet_callable = @callable | @cil_method; +@dotnet_variable = @variable | @cil_variable; +@dotnet_field = @field | @cil_field; +@dotnet_parameter = @parameter | @cil_parameter; +@dotnet_declaration = @declaration | @cil_declaration; +@dotnet_member = @member | @cil_member; +@dotnet_event = @event | @cil_event; +@dotnet_property = @property | @cil_property | @indexer; + +// Common types +@dotnet_type = @type | @cil_type; +@dotnet_call = @call | @cil_call_any; +@dotnet_throw = @throw_element | @cil_throw_any; +@dotnet_valueorreftype = @cil_valueorreftype | @value_or_ref_type | @cil_array_type | @void_type; +@dotnet_typeparameter = @type_parameter | @cil_typeparameter; +@dotnet_array_type = @array_type | @cil_array_type; +@dotnet_pointer_type = @pointer_type | @cil_pointer_type; +@dotnet_type_parameter = @type_parameter | @cil_typeparameter; +@dotnet_generic = @dotnet_valueorreftype | @dotnet_callable; + +// Attributes +@dotnet_attribute = @attribute | @cil_attribute; + +// Expressions +@dotnet_expr = @expr | @cil_expr; + +// Literals +@dotnet_literal = @literal_expr | @cil_literal; +@dotnet_string_literal = @string_literal_expr | @cil_ldstr; +@dotnet_int_literal = @integer_literal_expr | @cil_ldc_i; +@dotnet_float_literal = @float_literal_expr | @cil_ldc_r; +@dotnet_null_literal = @null_literal_expr | @cil_ldnull; + +@metadata_entity = @cil_method | @cil_type | @cil_field | @cil_property | @field | @property | + @callable | @value_or_ref_type | @void_type; + +#keyset[entity, location] +metadata_handle(int entity : @metadata_entity ref, int location: @assembly ref, int handle: int ref) diff --git a/csharp/upgrades/f5903552e3099dba41375ca19af7caca5c2e4966/semmlecode.csharp.dbscheme b/csharp/upgrades/f5903552e3099dba41375ca19af7caca5c2e4966/semmlecode.csharp.dbscheme new file mode 100644 index 00000000000..094972aab8c --- /dev/null +++ b/csharp/upgrades/f5903552e3099dba41375ca19af7caca5c2e4966/semmlecode.csharp.dbscheme @@ -0,0 +1,1906 @@ + +/** + * An invocation of the compiler. Note that more than one file may be + * compiled per invocation. For example, this command compiles three + * source files: + * + * csc f1.cs f2.cs f3.cs + * + * The `id` simply identifies the invocation, while `cwd` is the working + * directory from which the compiler was invoked. + */ +compilations( + unique int id : @compilation, + string cwd : string ref +); + +/** + * The arguments that were passed to the extractor for a compiler + * invocation. If `id` is for the compiler invocation + * + * csc f1.cs f2.cs f3.cs + * + * then typically there will be rows for + * + * num | arg + * --- | --- + * 0 | --compiler + * 1 | *path to compiler* + * 2 | --cil + * 3 | f1.cs + * 4 | f2.cs + * 5 | f3.cs + */ +#keyset[id, num] +compilation_args( + int id : @compilation ref, + int num : int ref, + string arg : string ref +); + +/** + * The source files that are compiled by a compiler invocation. + * If `id` is for the compiler invocation + * + * csc f1.cs f2.cs f3.cs + * + * then there will be rows for + * + * num | arg + * --- | --- + * 0 | f1.cs + * 1 | f2.cs + * 2 | f3.cs + */ +#keyset[id, num] +compilation_compiling_files( + int id : @compilation ref, + int num : int ref, + int file : @file ref +); + +/** + * The references used by a compiler invocation. + * If `id` is for the compiler invocation + * + * csc f1.cs f2.cs f3.cs /r:ref1.dll /r:ref2.dll /r:ref3.dll + * + * then there will be rows for + * + * num | arg + * --- | --- + * 0 | ref1.dll + * 1 | ref2.dll + * 2 | ref3.dll + */ +#keyset[id, num] +compilation_referencing_files( + int id : @compilation ref, + int num : int ref, + int file : @file ref +); + +/** + * The time taken by the extractor for a compiler invocation. + * + * For each file `num`, there will be rows for + * + * kind | seconds + * ---- | --- + * 1 | CPU seconds used by the extractor frontend + * 2 | Elapsed seconds during the extractor frontend + * 3 | CPU seconds used by the extractor backend + * 4 | Elapsed seconds during the extractor backend + */ +#keyset[id, num, kind] +compilation_time( + int id : @compilation ref, + int num : int ref, + /* kind: + 1 = frontend_cpu_seconds + 2 = frontend_elapsed_seconds + 3 = extractor_cpu_seconds + 4 = extractor_elapsed_seconds + */ + int kind : int ref, + float seconds : float ref +); + +/** + * An error or warning generated by the extractor. + * The diagnostic message `diagnostic` was generated during compiler + * invocation `compilation`, and is the `file_number_diagnostic_number`th + * message generated while extracting the `file_number`th file of that + * invocation. + */ +#keyset[compilation, file_number, file_number_diagnostic_number] +diagnostic_for( + unique int diagnostic : @diagnostic ref, + int compilation : @compilation ref, + int file_number : int ref, + int file_number_diagnostic_number : int ref +); + +diagnostics( + unique int id: @diagnostic, + int severity: int ref, + string error_tag: string ref, + string error_message: string ref, + string full_error_message: string ref, + int location: @location_default ref +); + +extractor_messages( + unique int id: @extractor_message, + int severity: int ref, + string origin : string ref, + string text : string ref, + string entity : string ref, + int location: @location_default ref, + string stack_trace : string ref +); + +/** + * If extraction was successful, then `cpu_seconds` and + * `elapsed_seconds` are the CPU time and elapsed time (respectively) + * that extraction took for compiler invocation `id`. + */ +compilation_finished( + unique int id : @compilation ref, + float cpu_seconds : float ref, + float elapsed_seconds : float ref +); + +/* + * External artifacts + */ + +externalDefects( + unique int id: @externalDefect, + string queryPath: string ref, + int location: @location ref, + string message: string ref, + float severity: float ref); + +externalMetrics( + unique int id: @externalMetric, + string queryPath: string ref, + int location: @location ref, + float value: float ref); + +externalData( + int id: @externalDataElement, + string path: string ref, + int column: int ref, + string value: string ref); + +snapshotDate( + unique date snapshotDate: date ref); + +sourceLocationPrefix( + string prefix: string ref); + +/* + * Duplicate code + */ + +duplicateCode( + unique int id: @duplication, + string relativePath: string ref, + int equivClass: int ref); + +similarCode( + unique int id: @similarity, + string relativePath: string ref, + int equivClass: int ref); + +@duplication_or_similarity = @duplication | @similarity + +tokens( + int id: @duplication_or_similarity ref, + int offset: int ref, + int beginLine: int ref, + int beginColumn: int ref, + int endLine: int ref, + int endColumn: int ref); + +/* + * C# dbscheme + */ + +/** ELEMENTS **/ + +@element = @declaration | @stmt | @expr | @modifier | @attribute | @namespace_declaration + | @using_directive | @type_parameter_constraints | @external_element + | @xmllocatable | @asp_element | @namespace; + +@declaration = @callable | @generic | @assignable | @namespace; + +@named_element = @namespace | @declaration; + +@declaration_with_accessors = @property | @indexer | @event; + +@assignable = @variable | @assignable_with_accessors | @event; + +@assignable_with_accessors = @property | @indexer; + +@external_element = @externalMetric | @externalDefect | @externalDataElement; + +@attributable = @assembly | @field | @parameter | @operator | @method | @constructor + | @destructor | @callable_accessor | @value_or_ref_type | @declaration_with_accessors + | @local_function; + +/** LOCATIONS, ASEMMBLIES, MODULES, FILES and FOLDERS **/ + +@location = @location_default | @assembly; + +locations_default( + unique int id: @location_default, + int file: @file ref, + int beginLine: int ref, + int beginColumn: int ref, + int endLine: int ref, + int endColumn: int ref); + +@sourceline = @file | @callable | @xmllocatable; + +numlines( + int element_id: @sourceline ref, + int num_lines: int ref, + int num_code: int ref, + int num_comment: int ref); + +assemblies( + unique int id: @assembly, + int file: @file ref, + string fullname: string ref, + string name: string ref, + string version: string ref); + +/* + fromSource(0) = unknown, + fromSource(1) = from source, + fromSource(2) = from library +*/ +files( + unique int id: @file, + string name: string ref, + string simple: string ref, + string ext: string ref, + int fromSource: int ref); + +folders( + unique int id: @folder, + string name: string ref, + string simple: string ref); + +@container = @folder | @file ; + +containerparent( + int parent: @container ref, + unique int child: @container ref); + +file_extraction_mode( + unique int file: @file ref, + int mode: int ref + /* 0 = normal, 1 = standalone extractor */ + ); + +/** NAMESPACES **/ + +@type_container = @namespace | @type; + +namespaces( + unique int id: @namespace, + string name: string ref); + +namespace_declarations( + unique int id: @namespace_declaration, + int namespace_id: @namespace ref); + +namespace_declaration_location( + unique int id: @namespace_declaration ref, + int loc: @location ref); + +parent_namespace( + unique int child_id: @type_container ref, + int namespace_id: @namespace ref); + +@declaration_or_directive = @namespace_declaration | @type | @using_directive; + +parent_namespace_declaration( + int child_id: @declaration_or_directive ref, // cannot be unique because of partial classes + int namespace_id: @namespace_declaration ref); + +@using_directive = @using_namespace_directive | @using_static_directive; + +using_namespace_directives( + unique int id: @using_namespace_directive, + int namespace_id: @namespace ref); + +using_static_directives( + unique int id: @using_static_directive, + int type_id: @type_or_ref ref); + +using_directive_location( + unique int id: @using_directive ref, + int loc: @location ref); + +/** TYPES **/ + +types( + unique int id: @type, + int kind: int ref, + string name: string ref); + +case @type.kind of + 1 = @bool_type +| 2 = @char_type +| 3 = @decimal_type +| 4 = @sbyte_type +| 5 = @short_type +| 6 = @int_type +| 7 = @long_type +| 8 = @byte_type +| 9 = @ushort_type +| 10 = @uint_type +| 11 = @ulong_type +| 12 = @float_type +| 13 = @double_type +| 14 = @enum_type +| 15 = @struct_type +| 17 = @class_type +| 19 = @interface_type +| 20 = @delegate_type +| 21 = @null_type +| 22 = @type_parameter +| 23 = @pointer_type +| 24 = @nullable_type +| 25 = @array_type +| 26 = @void_type +| 27 = @int_ptr_type +| 28 = @uint_ptr_type +| 29 = @dynamic_type +| 30 = @arglist_type +| 31 = @unknown_type +| 32 = @tuple_type + ; + +@simple_type = @bool_type | @char_type | @integral_type | @floating_point_type | @decimal_type; +@integral_type = @signed_integral_type | @unsigned_integral_type; +@signed_integral_type = @sbyte_type | @short_type | @int_type | @long_type; +@unsigned_integral_type = @byte_type | @ushort_type | @uint_type | @ulong_type; +@floating_point_type = @float_type | @double_type; +@value_type = @simple_type | @enum_type | @struct_type | @nullable_type | @int_ptr_type + | @uint_ptr_type | @tuple_type; +@ref_type = @class_type | @interface_type | @array_type | @delegate_type | @null_type + | @dynamic_type; +@value_or_ref_type = @value_type | @ref_type; + +typerefs( + unique int id: @typeref, + string name: string ref); + +typeref_type( + int id: @typeref ref, + unique int typeId: @type ref); + +@type_or_ref = @type | @typeref; + +array_element_type( + unique int array: @array_type ref, + int dimension: int ref, + int rank: int ref, + int element: @type_or_ref ref); + +nullable_underlying_type( + unique int nullable: @nullable_type ref, + int underlying: @type_or_ref ref); + +pointer_referent_type( + unique int pointer: @pointer_type ref, + int referent: @type_or_ref ref); + +enum_underlying_type( + unique int enum_id: @enum_type ref, + int underlying_type_id: @type_or_ref ref); + +delegate_return_type( + unique int delegate_id: @delegate_type ref, + int return_type_id: @type_or_ref ref); + +extend( + unique int sub: @type ref, + int super: @type_or_ref ref); + +@interface_or_ref = @interface_type | @typeref; + +implement( + int sub: @type ref, + int super: @type_or_ref ref); + +type_location( + int id: @type ref, + int loc: @location ref); + +tuple_underlying_type( + unique int tuple: @tuple_type ref, + int struct: @type_or_ref ref); + +#keyset[tuple, index] +tuple_element( + int tuple: @tuple_type ref, + int index: int ref, + unique int field: @field ref); + +attributes( + unique int id: @attribute, + int type_id: @type_or_ref ref, + int target: @attributable ref); + +attribute_location( + int id: @attribute ref, + int loc: @location ref); + +@type_mention_parent = @element | @type_mention; + +type_mention( + unique int id: @type_mention, + int type_id: @type_or_ref ref, + int parent: @type_mention_parent ref); + +type_mention_location( + unique int id: @type_mention ref, + int loc: @location ref); + +@has_type_annotation = @assignable | @type_parameter | @callable | @expr | @delegate_type | @generic; + +/** + * A direct annotation on an entity, for example `string? x;`. + * + * Annotations: + * 2 = reftype is not annotated "!" + * 3 = reftype is annotated "?" + * 4 = readonly ref type / in parameter + * 5 = ref type parameter, return or local variable + * 6 = out parameter + * + * Note that the annotation depends on the element it annotates. + * @assignable: The annotation is on the type of the assignable, for example the variable type. + * @type_parameter: The annotation is on the reftype constraint + * @callable: The annotation is on the return type + * @array_type: The annotation is on the element type + */ +type_annotation(int id: @has_type_annotation ref, int annotation: int ref); + +nullability(unique int nullability: @nullability, int kind: int ref); + +case @nullability.kind of + 0 = @oblivious +| 1 = @not_annotated +| 2 = @annotated +; + +#keyset[parent, index] +nullability_parent(int nullability: @nullability ref, int index: int ref, int parent: @nullability ref) + +type_nullability(int id: @has_type_annotation ref, int nullability: @nullability ref); + +/** + * The nullable flow state of an expression, as determined by Roslyn. + * 0 = none (default, not populated) + * 1 = not null + * 2 = maybe null + */ +expr_flowstate(unique int id: @expr ref, int state: int ref); + +/** GENERICS **/ + +@generic = @type | @method | @local_function; + +type_parameters( + unique int id: @type_parameter ref, + int index: int ref, + int generic_id: @generic ref, + int variance: int ref /* none = 0, out = 1, in = 2 */); + +#keyset[constructed_id, index] +type_arguments( + int id: @type_or_ref ref, + int index: int ref, + int constructed_id: @generic_or_ref ref); + +@generic_or_ref = @generic | @typeref; + +constructed_generic( + unique int constructed: @generic ref, + int generic: @generic_or_ref ref); + +type_parameter_constraints( + unique int id: @type_parameter_constraints, + int param_id: @type_parameter ref); + +type_parameter_constraints_location( + int id: @type_parameter_constraints ref, + int loc: @location ref); + +general_type_parameter_constraints( + int id: @type_parameter_constraints ref, + int kind: int ref /* class = 1, struct = 2, new = 3 */); + +specific_type_parameter_constraints( + int id: @type_parameter_constraints ref, + int base_id: @type_or_ref ref); + +specific_type_parameter_nullability( + int id: @type_parameter_constraints ref, + int base_id: @type_or_ref ref, + int nullability: @nullability ref); + +/** MODIFIERS */ + +@modifiable = @modifiable_direct | @event_accessor; + +@modifiable_direct = @member | @accessor | @local_function | @anonymous_function_expr; + +modifiers( + unique int id: @modifier, + string name: string ref); + +has_modifiers( + int id: @modifiable_direct ref, + int mod_id: @modifier ref); + +compiler_generated(unique int id: @modifiable_direct ref); + +/** MEMBERS **/ + +@member = @method | @constructor | @destructor | @field | @property | @event | @operator | @indexer | @type; + +@named_exprorstmt = @goto_stmt | @labeled_stmt | @expr; + +@virtualizable = @method | @property | @indexer | @event; + +exprorstmt_name( + unique int parent_id: @named_exprorstmt ref, + string name: string ref); + +nested_types( + unique int id: @type ref, + int declaring_type_id: @type ref, + int unbound_id: @type ref); + +properties( + unique int id: @property, + string name: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @property ref); + +property_location( + int id: @property ref, + int loc: @location ref); + +indexers( + unique int id: @indexer, + string name: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @indexer ref); + +indexer_location( + int id: @indexer ref, + int loc: @location ref); + +accessors( + unique int id: @accessor, + int kind: int ref, + string name: string ref, + int declaring_member_id: @member ref, + int unbound_id: @accessor ref); + +case @accessor.kind of + 1 = @getter +| 2 = @setter + ; + +init_only_accessors( + unique int id: @accessor ref); + +accessor_location( + int id: @accessor ref, + int loc: @location ref); + +events( + unique int id: @event, + string name: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @event ref); + +event_location( + int id: @event ref, + int loc: @location ref); + +event_accessors( + unique int id: @event_accessor, + int kind: int ref, + string name: string ref, + int declaring_event_id: @event ref, + int unbound_id: @event_accessor ref); + +case @event_accessor.kind of + 1 = @add_event_accessor +| 2 = @remove_event_accessor + ; + +event_accessor_location( + int id: @event_accessor ref, + int loc: @location ref); + +operators( + unique int id: @operator, + string name: string ref, + string symbol: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @operator ref); + +operator_location( + int id: @operator ref, + int loc: @location ref); + +constant_value( + int id: @variable ref, + string value: string ref); + +/** CALLABLES **/ + +@callable = @method | @constructor | @destructor | @operator | @callable_accessor | @anonymous_function_expr | @local_function; + +@callable_accessor = @accessor | @event_accessor; + +methods( + unique int id: @method, + string name: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @method ref); + +method_location( + int id: @method ref, + int loc: @location ref); + +constructors( + unique int id: @constructor, + string name: string ref, + int declaring_type_id: @type ref, + int unbound_id: @constructor ref); + +constructor_location( + int id: @constructor ref, + int loc: @location ref); + +destructors( + unique int id: @destructor, + string name: string ref, + int declaring_type_id: @type ref, + int unbound_id: @destructor ref); + +destructor_location( + int id: @destructor ref, + int loc: @location ref); + +overrides( + int id: @callable ref, + int base_id: @callable ref); + +explicitly_implements( + int id: @member ref, + int interface_id: @interface_or_ref ref); + +local_functions( + unique int id: @local_function, + string name: string ref, + int return_type: @type ref, + int unbound_id: @local_function ref); + +local_function_stmts( + unique int fn: @local_function_stmt ref, + int stmt: @local_function ref); + +/** VARIABLES **/ + +@variable = @local_scope_variable | @field; + +@local_scope_variable = @local_variable | @parameter; + +fields( + unique int id: @field, + int kind: int ref, + string name: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @field ref); + +case @field.kind of + 1 = @addressable_field +| 2 = @constant + ; + +field_location( + int id: @field ref, + int loc: @location ref); + +localvars( + unique int id: @local_variable, + int kind: int ref, + string name: string ref, + int implicitly_typed: int ref /* 0 = no, 1 = yes */, + int type_id: @type_or_ref ref, + int parent_id: @local_var_decl_expr ref); + +case @local_variable.kind of + 1 = @addressable_local_variable +| 2 = @local_constant +| 3 = @local_variable_ref + ; + +localvar_location( + unique int id: @local_variable ref, + int loc: @location ref); + +@parameterizable = @callable | @delegate_type | @indexer; + +#keyset[name, parent_id] +#keyset[index, parent_id] +params( + unique int id: @parameter, + string name: string ref, + int type_id: @type_or_ref ref, + int index: int ref, + int mode: int ref, /* value = 0, ref = 1, out = 2, array = 3, this = 4 */ + int parent_id: @parameterizable ref, + int unbound_id: @parameter ref); + +param_location( + int id: @parameter ref, + int loc: @location ref); + +/** STATEMENTS **/ + +@exprorstmt_parent = @control_flow_element | @top_level_exprorstmt_parent; + +statements( + unique int id: @stmt, + int kind: int ref); + +#keyset[index, parent] +stmt_parent( + unique int stmt: @stmt ref, + int index: int ref, + int parent: @control_flow_element ref); + +@top_level_stmt_parent = @callable; + +// [index, parent] is not a keyset because the same parent may be compiled multiple times +stmt_parent_top_level( + unique int stmt: @stmt ref, + int index: int ref, + int parent: @top_level_stmt_parent ref); + +case @stmt.kind of + 1 = @block_stmt +| 2 = @expr_stmt +| 3 = @if_stmt +| 4 = @switch_stmt +| 5 = @while_stmt +| 6 = @do_stmt +| 7 = @for_stmt +| 8 = @foreach_stmt +| 9 = @break_stmt +| 10 = @continue_stmt +| 11 = @goto_stmt +| 12 = @goto_case_stmt +| 13 = @goto_default_stmt +| 14 = @throw_stmt +| 15 = @return_stmt +| 16 = @yield_stmt +| 17 = @try_stmt +| 18 = @checked_stmt +| 19 = @unchecked_stmt +| 20 = @lock_stmt +| 21 = @using_block_stmt +| 22 = @var_decl_stmt +| 23 = @const_decl_stmt +| 24 = @empty_stmt +| 25 = @unsafe_stmt +| 26 = @fixed_stmt +| 27 = @label_stmt +| 28 = @catch +| 29 = @case_stmt +| 30 = @local_function_stmt +| 31 = @using_decl_stmt + ; + +@using_stmt = @using_block_stmt | @using_decl_stmt; + +@labeled_stmt = @label_stmt | @case; + +@decl_stmt = @var_decl_stmt | @const_decl_stmt | @using_decl_stmt; + +@cond_stmt = @if_stmt | @switch_stmt; + +@loop_stmt = @while_stmt | @do_stmt | @for_stmt | @foreach_stmt; + +@jump_stmt = @break_stmt | @goto_any_stmt | @continue_stmt | @throw_stmt | @return_stmt + | @yield_stmt; + +@goto_any_stmt = @goto_default_stmt | @goto_case_stmt | @goto_stmt; + + +stmt_location( + unique int id: @stmt ref, + int loc: @location ref); + +catch_type( + unique int catch_id: @catch ref, + int type_id: @type_or_ref ref, + int kind: int ref /* explicit = 1, implicit = 2 */); + +/** EXPRESSIONS **/ + +expressions( + unique int id: @expr, + int kind: int ref, + int type_id: @type_or_ref ref); + +#keyset[index, parent] +expr_parent( + unique int expr: @expr ref, + int index: int ref, + int parent: @control_flow_element ref); + +@top_level_expr_parent = @attribute | @field | @property | @indexer | @parameter; + +@top_level_exprorstmt_parent = @top_level_expr_parent | @top_level_stmt_parent; + +// [index, parent] is not a keyset because the same parent may be compiled multiple times +expr_parent_top_level( + unique int expr: @expr ref, + int index: int ref, + int parent: @top_level_exprorstmt_parent ref); + +case @expr.kind of +/* literal */ + 1 = @bool_literal_expr +| 2 = @char_literal_expr +| 3 = @decimal_literal_expr +| 4 = @int_literal_expr +| 5 = @long_literal_expr +| 6 = @uint_literal_expr +| 7 = @ulong_literal_expr +| 8 = @float_literal_expr +| 9 = @double_literal_expr +| 10 = @string_literal_expr +| 11 = @null_literal_expr +/* primary & unary */ +| 12 = @this_access_expr +| 13 = @base_access_expr +| 14 = @local_variable_access_expr +| 15 = @parameter_access_expr +| 16 = @field_access_expr +| 17 = @property_access_expr +| 18 = @method_access_expr +| 19 = @event_access_expr +| 20 = @indexer_access_expr +| 21 = @array_access_expr +| 22 = @type_access_expr +| 23 = @typeof_expr +| 24 = @method_invocation_expr +| 25 = @delegate_invocation_expr +| 26 = @operator_invocation_expr +| 27 = @cast_expr +| 28 = @object_creation_expr +| 29 = @explicit_delegate_creation_expr +| 30 = @implicit_delegate_creation_expr +| 31 = @array_creation_expr +| 32 = @default_expr +| 33 = @plus_expr +| 34 = @minus_expr +| 35 = @bit_not_expr +| 36 = @log_not_expr +| 37 = @post_incr_expr +| 38 = @post_decr_expr +| 39 = @pre_incr_expr +| 40 = @pre_decr_expr +/* multiplicative */ +| 41 = @mul_expr +| 42 = @div_expr +| 43 = @rem_expr +/* additive */ +| 44 = @add_expr +| 45 = @sub_expr +/* shift */ +| 46 = @lshift_expr +| 47 = @rshift_expr +/* relational */ +| 48 = @lt_expr +| 49 = @gt_expr +| 50 = @le_expr +| 51 = @ge_expr +/* equality */ +| 52 = @eq_expr +| 53 = @ne_expr +/* logical */ +| 54 = @bit_and_expr +| 55 = @bit_xor_expr +| 56 = @bit_or_expr +| 57 = @log_and_expr +| 58 = @log_or_expr +/* type testing */ +| 59 = @is_expr +| 60 = @as_expr +/* null coalescing */ +| 61 = @null_coalescing_expr +/* conditional */ +| 62 = @conditional_expr +/* assignment */ +| 63 = @simple_assign_expr +| 64 = @assign_add_expr +| 65 = @assign_sub_expr +| 66 = @assign_mul_expr +| 67 = @assign_div_expr +| 68 = @assign_rem_expr +| 69 = @assign_and_expr +| 70 = @assign_xor_expr +| 71 = @assign_or_expr +| 72 = @assign_lshift_expr +| 73 = @assign_rshift_expr +/* more */ +| 74 = @object_init_expr +| 75 = @collection_init_expr +| 76 = @array_init_expr +| 77 = @checked_expr +| 78 = @unchecked_expr +| 79 = @constructor_init_expr +| 80 = @add_event_expr +| 81 = @remove_event_expr +| 82 = @par_expr +| 83 = @local_var_decl_expr +| 84 = @lambda_expr +| 85 = @anonymous_method_expr +| 86 = @namespace_expr +/* dynamic */ +| 92 = @dynamic_element_access_expr +| 93 = @dynamic_member_access_expr +/* unsafe */ +| 100 = @pointer_indirection_expr +| 101 = @address_of_expr +| 102 = @sizeof_expr +/* async */ +| 103 = @await_expr +/* C# 6.0 */ +| 104 = @nameof_expr +| 105 = @interpolated_string_expr +| 106 = @unknown_expr +/* C# 7.0 */ +| 107 = @throw_expr +| 108 = @tuple_expr +| 109 = @local_function_invocation_expr +| 110 = @ref_expr +| 111 = @discard_expr +/* C# 8.0 */ +| 112 = @range_expr +| 113 = @index_expr +| 114 = @switch_expr +| 115 = @recursive_pattern_expr +| 116 = @property_pattern_expr +| 117 = @positional_pattern_expr +| 118 = @switch_case_expr +| 119 = @assign_coalesce_expr +| 120 = @suppress_nullable_warning_expr +| 121 = @namespace_access_expr +; + +@switch = @switch_stmt | @switch_expr; +@case = @case_stmt | @switch_case_expr; +@pattern_match = @case | @is_expr; + +@integer_literal_expr = @int_literal_expr | @long_literal_expr | @uint_literal_expr | @ulong_literal_expr; +@real_literal_expr = @float_literal_expr | @double_literal_expr | @decimal_literal_expr; +@literal_expr = @bool_literal_expr | @char_literal_expr | @integer_literal_expr | @real_literal_expr + | @string_literal_expr | @null_literal_expr; + +@assign_expr = @simple_assign_expr | @assign_op_expr | @local_var_decl_expr; +@assign_op_expr = @assign_arith_expr | @assign_bitwise_expr | @assign_event_expr | @assign_coalesce_expr; +@assign_event_expr = @add_event_expr | @remove_event_expr; + +@assign_arith_expr = @assign_add_expr | @assign_sub_expr | @assign_mul_expr | @assign_div_expr + | @assign_rem_expr +@assign_bitwise_expr = @assign_and_expr | @assign_or_expr | @assign_xor_expr + | @assign_lshift_expr | @assign_rshift_expr; + +@member_access_expr = @field_access_expr | @property_access_expr | @indexer_access_expr | @event_access_expr + | @method_access_expr | @type_access_expr | @dynamic_member_access_expr; +@access_expr = @member_access_expr | @this_access_expr | @base_access_expr | @assignable_access_expr | @namespace_access_expr; +@element_access_expr = @indexer_access_expr | @array_access_expr | @dynamic_element_access_expr; + +@local_variable_access = @local_variable_access_expr | @local_var_decl_expr; +@local_scope_variable_access_expr = @parameter_access_expr | @local_variable_access; +@variable_access_expr = @local_scope_variable_access_expr | @field_access_expr; + +@assignable_access_expr = @variable_access_expr | @property_access_expr | @element_access_expr + | @event_access_expr | @dynamic_member_access_expr; + +@objectorcollection_init_expr = @object_init_expr | @collection_init_expr; + +@delegate_creation_expr = @explicit_delegate_creation_expr | @implicit_delegate_creation_expr; + +@bin_arith_op_expr = @mul_expr | @div_expr | @rem_expr | @add_expr | @sub_expr; +@incr_op_expr = @pre_incr_expr | @post_incr_expr; +@decr_op_expr = @pre_decr_expr | @post_decr_expr; +@mut_op_expr = @incr_op_expr | @decr_op_expr; +@un_arith_op_expr = @plus_expr | @minus_expr | @mut_op_expr; +@arith_op_expr = @bin_arith_op_expr | @un_arith_op_expr; + +@ternary_log_op_expr = @conditional_expr; +@bin_log_op_expr = @log_and_expr | @log_or_expr | @null_coalescing_expr; +@un_log_op_expr = @log_not_expr; +@log_expr = @un_log_op_expr | @bin_log_op_expr | @ternary_log_op_expr; + +@bin_bit_op_expr = @bit_and_expr | @bit_or_expr | @bit_xor_expr | @lshift_expr + | @rshift_expr; +@un_bit_op_expr = @bit_not_expr; +@bit_expr = @un_bit_op_expr | @bin_bit_op_expr; + +@equality_op_expr = @eq_expr | @ne_expr; +@rel_op_expr = @gt_expr | @lt_expr| @ge_expr | @le_expr; +@comp_expr = @equality_op_expr | @rel_op_expr; + +@op_expr = @assign_expr | @un_op | @bin_op | @ternary_op; + +@ternary_op = @ternary_log_op_expr; +@bin_op = @bin_arith_op_expr | @bin_log_op_expr | @bin_bit_op_expr | @comp_expr; +@un_op = @un_arith_op_expr | @un_log_op_expr | @un_bit_op_expr | @sizeof_expr + | @pointer_indirection_expr | @address_of_expr; + +@anonymous_function_expr = @lambda_expr | @anonymous_method_expr; + +@call = @method_invocation_expr | @constructor_init_expr | @operator_invocation_expr + | @delegate_invocation_expr | @object_creation_expr | @call_access_expr + | @local_function_invocation_expr; + +@call_access_expr = @property_access_expr | @event_access_expr | @indexer_access_expr; + +@late_bindable_expr = @dynamic_element_access_expr | @dynamic_member_access_expr + | @object_creation_expr | @method_invocation_expr | @operator_invocation_expr; + +@throw_element = @throw_expr | @throw_stmt; + +@implicitly_typeable_object_creation_expr = @object_creation_expr | @explicit_delegate_creation_expr; + +implicitly_typed_array_creation( + unique int id: @array_creation_expr ref); + +explicitly_sized_array_creation( + unique int id: @array_creation_expr ref); + +stackalloc_array_creation( + unique int id: @array_creation_expr ref); + +implicitly_typed_object_creation( + unique int id: @implicitly_typeable_object_creation_expr ref); + +mutator_invocation_mode( + unique int id: @operator_invocation_expr ref, + int mode: int ref /* prefix = 1, postfix = 2*/); + +expr_compiler_generated( + unique int id: @expr ref); + +expr_value( + unique int id: @expr ref, + string value: string ref); + +expr_call( + unique int caller_id: @expr ref, + int target_id: @callable ref); + +expr_access( + unique int accesser_id: @access_expr ref, + int target_id: @accessible ref); + +@accessible = @method | @assignable | @local_function | @namespace; + +expr_location( + unique int id: @expr ref, + int loc: @location ref); + +dynamic_member_name( + unique int id: @late_bindable_expr ref, + string name: string ref); + +@qualifiable_expr = @member_access_expr + | @method_invocation_expr + | @element_access_expr; + +conditional_access( + unique int id: @qualifiable_expr ref); + +expr_argument( + unique int id: @expr ref, + int mode: int ref); + /* mode is the same as params: value = 0, ref = 1, out = 2 */ + +expr_argument_name( + unique int id: @expr ref, + string name: string ref); + +/** CONTROL/DATA FLOW **/ + +@control_flow_element = @stmt | @expr; + +/* XML Files */ + +xmlEncoding ( + unique int id: @file ref, + string encoding: string ref); + +xmlDTDs( + unique int id: @xmldtd, + string root: string ref, + string publicId: string ref, + string systemId: string ref, + int fileid: @file ref); + +xmlElements( + unique int id: @xmlelement, + string name: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int fileid: @file ref); + +xmlAttrs( + unique int id: @xmlattribute, + int elementid: @xmlelement ref, + string name: string ref, + string value: string ref, + int idx: int ref, + int fileid: @file ref); + +xmlNs( + int id: @xmlnamespace, + string prefixName: string ref, + string URI: string ref, + int fileid: @file ref); + +xmlHasNs( + int elementId: @xmlnamespaceable ref, + int nsId: @xmlnamespace ref, + int fileid: @file ref); + +xmlComments( + unique int id: @xmlcomment, + string text: string ref, + int parentid: @xmlparent ref, + int fileid: @file ref); + +xmlChars( + unique int id: @xmlcharacters, + string text: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int isCDATA: int ref, + int fileid: @file ref); + +@xmlparent = @file | @xmlelement; +@xmlnamespaceable = @xmlelement | @xmlattribute; + +xmllocations( + int xmlElement: @xmllocatable ref, + int location: @location_default ref); + +@xmllocatable = @xmlcharacters | @xmlelement | @xmlcomment | @xmlattribute | @xmldtd | @file | @xmlnamespace; + +/* Comments */ + +commentline( + unique int id: @commentline, + int kind: int ref, + string text: string ref, + string rawtext: string ref); + +case @commentline.kind of + 0 = @singlelinecomment +| 1 = @xmldoccomment +| 2 = @multilinecomment; + +commentline_location( + unique int id: @commentline ref, + int loc: @location ref); + +commentblock( + unique int id : @commentblock); + +commentblock_location( + unique int id: @commentblock ref, + int loc: @location ref); + +commentblock_binding( + int id: @commentblock ref, + int entity: @element ref, + int bindtype: int ref); /* 0: Parent, 1: Best, 2: Before, 3: After */ + +commentblock_child( + int id: @commentblock ref, + int commentline: @commentline ref, + int index: int ref); + +/* ASP.NET */ + +case @asp_element.kind of + 0=@asp_close_tag +| 1=@asp_code +| 2=@asp_comment +| 3=@asp_data_binding +| 4=@asp_directive +| 5=@asp_open_tag +| 6=@asp_quoted_string +| 7=@asp_text +| 8=@asp_xml_directive; + +@asp_attribute = @asp_code | @asp_data_binding | @asp_quoted_string; + +asp_elements( + unique int id: @asp_element, + int kind: int ref, + int loc: @location ref); + +asp_comment_server(unique int comment: @asp_comment ref); +asp_code_inline(unique int code: @asp_code ref); +asp_directive_attribute( + int directive: @asp_directive ref, + int index: int ref, + string name: string ref, + int value: @asp_quoted_string ref); +asp_directive_name( + unique int directive: @asp_directive ref, + string name: string ref); +asp_element_body( + unique int element: @asp_element ref, + string body: string ref); +asp_tag_attribute( + int tag: @asp_open_tag ref, + int index: int ref, + string name: string ref, + int attribute: @asp_attribute ref); +asp_tag_name( + unique int tag: @asp_open_tag ref, + string name: string ref); +asp_tag_isempty(int tag: @asp_open_tag ref); + +/* Common Intermediate Language - CIL */ + +case @cil_instruction.opcode of + 0 = @cil_nop +| 1 = @cil_break +| 2 = @cil_ldarg_0 +| 3 = @cil_ldarg_1 +| 4 = @cil_ldarg_2 +| 5 = @cil_ldarg_3 +| 6 = @cil_ldloc_0 +| 7 = @cil_ldloc_1 +| 8 = @cil_ldloc_2 +| 9 = @cil_ldloc_3 +| 10 = @cil_stloc_0 +| 11 = @cil_stloc_1 +| 12 = @cil_stloc_2 +| 13 = @cil_stloc_3 +| 14 = @cil_ldarg_s +| 15 = @cil_ldarga_s +| 16 = @cil_starg_s +| 17 = @cil_ldloc_s +| 18 = @cil_ldloca_s +| 19 = @cil_stloc_s +| 20 = @cil_ldnull +| 21 = @cil_ldc_i4_m1 +| 22 = @cil_ldc_i4_0 +| 23 = @cil_ldc_i4_1 +| 24 = @cil_ldc_i4_2 +| 25 = @cil_ldc_i4_3 +| 26 = @cil_ldc_i4_4 +| 27 = @cil_ldc_i4_5 +| 28 = @cil_ldc_i4_6 +| 29 = @cil_ldc_i4_7 +| 30 = @cil_ldc_i4_8 +| 31 = @cil_ldc_i4_s +| 32 = @cil_ldc_i4 +| 33 = @cil_ldc_i8 +| 34 = @cil_ldc_r4 +| 35 = @cil_ldc_r8 +| 37 = @cil_dup +| 38 = @cil_pop +| 39 = @cil_jmp +| 40 = @cil_call +| 41 = @cil_calli +| 42 = @cil_ret +| 43 = @cil_br_s +| 44 = @cil_brfalse_s +| 45 = @cil_brtrue_s +| 46 = @cil_beq_s +| 47 = @cil_bge_s +| 48 = @cil_bgt_s +| 49 = @cil_ble_s +| 50 = @cil_blt_s +| 51 = @cil_bne_un_s +| 52 = @cil_bge_un_s +| 53 = @cil_bgt_un_s +| 54 = @cil_ble_un_s +| 55 = @cil_blt_un_s +| 56 = @cil_br +| 57 = @cil_brfalse +| 58 = @cil_brtrue +| 59 = @cil_beq +| 60 = @cil_bge +| 61 = @cil_bgt +| 62 = @cil_ble +| 63 = @cil_blt +| 64 = @cil_bne_un +| 65 = @cil_bge_un +| 66 = @cil_bgt_un +| 67 = @cil_ble_un +| 68 = @cil_blt_un +| 69 = @cil_switch +| 70 = @cil_ldind_i1 +| 71 = @cil_ldind_u1 +| 72 = @cil_ldind_i2 +| 73 = @cil_ldind_u2 +| 74 = @cil_ldind_i4 +| 75 = @cil_ldind_u4 +| 76 = @cil_ldind_i8 +| 77 = @cil_ldind_i +| 78 = @cil_ldind_r4 +| 79 = @cil_ldind_r8 +| 80 = @cil_ldind_ref +| 81 = @cil_stind_ref +| 82 = @cil_stind_i1 +| 83 = @cil_stind_i2 +| 84 = @cil_stind_i4 +| 85 = @cil_stind_i8 +| 86 = @cil_stind_r4 +| 87 = @cil_stind_r8 +| 88 = @cil_add +| 89 = @cil_sub +| 90 = @cil_mul +| 91 = @cil_div +| 92 = @cil_div_un +| 93 = @cil_rem +| 94 = @cil_rem_un +| 95 = @cil_and +| 96 = @cil_or +| 97 = @cil_xor +| 98 = @cil_shl +| 99 = @cil_shr +| 100 = @cil_shr_un +| 101 = @cil_neg +| 102 = @cil_not +| 103 = @cil_conv_i1 +| 104 = @cil_conv_i2 +| 105 = @cil_conv_i4 +| 106 = @cil_conv_i8 +| 107 = @cil_conv_r4 +| 108 = @cil_conv_r8 +| 109 = @cil_conv_u4 +| 110 = @cil_conv_u8 +| 111 = @cil_callvirt +| 112 = @cil_cpobj +| 113 = @cil_ldobj +| 114 = @cil_ldstr +| 115 = @cil_newobj +| 116 = @cil_castclass +| 117 = @cil_isinst +| 118 = @cil_conv_r_un +| 121 = @cil_unbox +| 122 = @cil_throw +| 123 = @cil_ldfld +| 124 = @cil_ldflda +| 125 = @cil_stfld +| 126 = @cil_ldsfld +| 127 = @cil_ldsflda +| 128 = @cil_stsfld +| 129 = @cil_stobj +| 130 = @cil_conv_ovf_i1_un +| 131 = @cil_conv_ovf_i2_un +| 132 = @cil_conv_ovf_i4_un +| 133 = @cil_conv_ovf_i8_un +| 134 = @cil_conv_ovf_u1_un +| 135 = @cil_conv_ovf_u2_un +| 136 = @cil_conv_ovf_u4_un +| 137 = @cil_conv_ovf_u8_un +| 138 = @cil_conv_ovf_i_un +| 139 = @cil_conv_ovf_u_un +| 140 = @cil_box +| 141 = @cil_newarr +| 142 = @cil_ldlen +| 143 = @cil_ldelema +| 144 = @cil_ldelem_i1 +| 145 = @cil_ldelem_u1 +| 146 = @cil_ldelem_i2 +| 147 = @cil_ldelem_u2 +| 148 = @cil_ldelem_i4 +| 149 = @cil_ldelem_u4 +| 150 = @cil_ldelem_i8 +| 151 = @cil_ldelem_i +| 152 = @cil_ldelem_r4 +| 153 = @cil_ldelem_r8 +| 154 = @cil_ldelem_ref +| 155 = @cil_stelem_i +| 156 = @cil_stelem_i1 +| 157 = @cil_stelem_i2 +| 158 = @cil_stelem_i4 +| 159 = @cil_stelem_i8 +| 160 = @cil_stelem_r4 +| 161 = @cil_stelem_r8 +| 162 = @cil_stelem_ref +| 163 = @cil_ldelem +| 164 = @cil_stelem +| 165 = @cil_unbox_any +| 179 = @cil_conv_ovf_i1 +| 180 = @cil_conv_ovf_u1 +| 181 = @cil_conv_ovf_i2 +| 182 = @cil_conv_ovf_u2 +| 183 = @cil_conv_ovf_i4 +| 184 = @cil_conv_ovf_u4 +| 185 = @cil_conv_ovf_i8 +| 186 = @cil_conv_ovf_u8 +| 194 = @cil_refanyval +| 195 = @cil_ckinfinite +| 198 = @cil_mkrefany +| 208 = @cil_ldtoken +| 209 = @cil_conv_u2 +| 210 = @cil_conv_u1 +| 211 = @cil_conv_i +| 212 = @cil_conv_ovf_i +| 213 = @cil_conv_ovf_u +| 214 = @cil_add_ovf +| 215 = @cil_add_ovf_un +| 216 = @cil_mul_ovf +| 217 = @cil_mul_ovf_un +| 218 = @cil_sub_ovf +| 219 = @cil_sub_ovf_un +| 220 = @cil_endfinally +| 221 = @cil_leave +| 222 = @cil_leave_s +| 223 = @cil_stind_i +| 224 = @cil_conv_u +| 65024 = @cil_arglist +| 65025 = @cil_ceq +| 65026 = @cil_cgt +| 65027 = @cil_cgt_un +| 65028 = @cil_clt +| 65029 = @cil_clt_un +| 65030 = @cil_ldftn +| 65031 = @cil_ldvirtftn +| 65033 = @cil_ldarg +| 65034 = @cil_ldarga +| 65035 = @cil_starg +| 65036 = @cil_ldloc +| 65037 = @cil_ldloca +| 65038 = @cil_stloc +| 65039 = @cil_localloc +| 65041 = @cil_endfilter +| 65042 = @cil_unaligned +| 65043 = @cil_volatile +| 65044 = @cil_tail +| 65045 = @cil_initobj +| 65046 = @cil_constrained +| 65047 = @cil_cpblk +| 65048 = @cil_initblk +| 65050 = @cil_rethrow +| 65052 = @cil_sizeof +| 65053 = @cil_refanytype +| 65054 = @cil_readonly +; + +// CIL ignored instructions + +@cil_ignore = @cil_nop | @cil_break | @cil_volatile | @cil_unaligned; + +// CIL local/parameter/field access + +@cil_ldarg_any = @cil_ldarg_0 | @cil_ldarg_1 | @cil_ldarg_2 | @cil_ldarg_3 | @cil_ldarg_s | @cil_ldarga_s | @cil_ldarg | @cil_ldarga; +@cil_starg_any = @cil_starg | @cil_starg_s; + +@cil_ldloc_any = @cil_ldloc_0 | @cil_ldloc_1 | @cil_ldloc_2 | @cil_ldloc_3 | @cil_ldloc_s | @cil_ldloca_s | @cil_ldloc | @cil_ldloca; +@cil_stloc_any = @cil_stloc_0 | @cil_stloc_1 | @cil_stloc_2 | @cil_stloc_3 | @cil_stloc_s | @cil_stloc; + +@cil_ldfld_any = @cil_ldfld | @cil_ldsfld | @cil_ldsflda | @cil_ldflda; +@cil_stfld_any = @cil_stfld | @cil_stsfld; + +@cil_local_access = @cil_stloc_any | @cil_ldloc_any; +@cil_arg_access = @cil_starg_any | @cil_ldarg_any; +@cil_read_access = @cil_ldloc_any | @cil_ldarg_any | @cil_ldfld_any; +@cil_write_access = @cil_stloc_any | @cil_starg_any | @cil_stfld_any; + +@cil_stack_access = @cil_local_access | @cil_arg_access; +@cil_field_access = @cil_ldfld_any | @cil_stfld_any; + +@cil_access = @cil_read_access | @cil_write_access; + +// CIL constant/literal instructions + +@cil_ldc_i = @cil_ldc_i4_any | @cil_ldc_i8; + +@cil_ldc_i4_any = @cil_ldc_i4_m1 | @cil_ldc_i4_0 | @cil_ldc_i4_1 | @cil_ldc_i4_2 | @cil_ldc_i4_3 | + @cil_ldc_i4_4 | @cil_ldc_i4_5 | @cil_ldc_i4_6 | @cil_ldc_i4_7 | @cil_ldc_i4_8 | @cil_ldc_i4_s | @cil_ldc_i4; + +@cil_ldc_r = @cil_ldc_r4 | @cil_ldc_r8; + +@cil_literal = @cil_ldnull | @cil_ldc_i | @cil_ldc_r | @cil_ldstr; + +// Control flow + +@cil_conditional_jump = @cil_binary_jump | @cil_unary_jump; +@cil_binary_jump = @cil_beq_s | @cil_bge_s | @cil_bgt_s | @cil_ble_s | @cil_blt_s | + @cil_bne_un_s | @cil_bge_un_s | @cil_bgt_un_s | @cil_ble_un_s | @cil_blt_un_s | + @cil_beq | @cil_bge | @cil_bgt | @cil_ble | @cil_blt | + @cil_bne_un | @cil_bge_un | @cil_bgt_un | @cil_ble_un | @cil_blt_un; +@cil_unary_jump = @cil_brfalse_s | @cil_brtrue_s | @cil_brfalse | @cil_brtrue | @cil_switch; +@cil_unconditional_jump = @cil_br | @cil_br_s | @cil_leave_any; +@cil_leave_any = @cil_leave | @cil_leave_s; +@cil_jump = @cil_unconditional_jump | @cil_conditional_jump; + +// CIL call instructions + +@cil_call_any = @cil_jmp | @cil_call | @cil_calli | @cil_tail | @cil_callvirt | @cil_newobj; + +// CIL expression instructions + +@cil_expr = @cil_literal | @cil_binary_expr | @cil_unary_expr | @cil_call_any | @cil_read_access | + @cil_newarr | @cil_ldtoken | @cil_sizeof | + @cil_ldftn | @cil_ldvirtftn | @cil_localloc | @cil_mkrefany | @cil_refanytype | @cil_arglist | @cil_dup; + +@cil_unary_expr = + @cil_conversion_operation | @cil_unary_arithmetic_operation | @cil_unary_bitwise_operation| + @cil_ldlen | @cil_isinst | @cil_box | @cil_ldobj | @cil_castclass | @cil_unbox_any | + @cil_ldind | @cil_unbox; + +@cil_conversion_operation = + @cil_conv_i1 | @cil_conv_i2 | @cil_conv_i4 | @cil_conv_i8 | + @cil_conv_u1 | @cil_conv_u2 | @cil_conv_u4 | @cil_conv_u8 | + @cil_conv_ovf_i | @cil_conv_ovf_i_un | @cil_conv_ovf_i1 | @cil_conv_ovf_i1_un | + @cil_conv_ovf_i2 | @cil_conv_ovf_i2_un | @cil_conv_ovf_i4 | @cil_conv_ovf_i4_un | + @cil_conv_ovf_i8 | @cil_conv_ovf_i8_un | @cil_conv_ovf_u | @cil_conv_ovf_u_un | + @cil_conv_ovf_u1 | @cil_conv_ovf_u1_un | @cil_conv_ovf_u2 | @cil_conv_ovf_u2_un | + @cil_conv_ovf_u4 | @cil_conv_ovf_u4_un | @cil_conv_ovf_u8 | @cil_conv_ovf_u8_un | + @cil_conv_r4 | @cil_conv_r8 | @cil_conv_ovf_u2 | @cil_conv_ovf_u2_un | + @cil_conv_i | @cil_conv_u | @cil_conv_r_un; + +@cil_ldind = @cil_ldind_i | @cil_ldind_i1 | @cil_ldind_i2 | @cil_ldind_i4 | @cil_ldind_i8 | + @cil_ldind_r4 | @cil_ldind_r8 | @cil_ldind_ref | @cil_ldind_u1 | @cil_ldind_u2 | @cil_ldind_u4; + +@cil_stind = @cil_stind_i | @cil_stind_i1 | @cil_stind_i2 | @cil_stind_i4 | @cil_stind_i8 | + @cil_stind_r4 | @cil_stind_r8 | @cil_stind_ref; + +@cil_bitwise_operation = @cil_binary_bitwise_operation | @cil_unary_bitwise_operation; + +@cil_binary_bitwise_operation = @cil_and | @cil_or | @cil_xor | @cil_shr | @cil_shr | @cil_shr_un | @cil_shl; + +@cil_binary_arithmetic_operation = @cil_add | @cil_sub | @cil_mul | @cil_div | @cil_div_un | + @cil_rem | @cil_rem_un | @cil_add_ovf | @cil_add_ovf_un | @cil_mul_ovf | @cil_mul_ovf_un | + @cil_sub_ovf | @cil_sub_ovf_un; + +@cil_unary_bitwise_operation = @cil_not; + +@cil_binary_expr = @cil_binary_arithmetic_operation | @cil_binary_bitwise_operation | @cil_read_array | @cil_comparison_operation; + +@cil_unary_arithmetic_operation = @cil_neg; + +@cil_comparison_operation = @cil_cgt_un | @cil_ceq | @cil_cgt | @cil_clt | @cil_clt_un; + +// Elements that retrieve an address of something +@cil_read_ref = @cil_ldloca_s | @cil_ldarga_s | @cil_ldflda | @cil_ldsflda | @cil_ldelema; + +// CIL array instructions + +@cil_read_array = + @cil_ldelem | @cil_ldelema | @cil_ldelem_i1 | @cil_ldelem_ref | @cil_ldelem_i | + @cil_ldelem_i1 | @cil_ldelem_i2 | @cil_ldelem_i4 | @cil_ldelem_i8 | @cil_ldelem_r4 | + @cil_ldelem_r8 | @cil_ldelem_u1 | @cil_ldelem_u2 | @cil_ldelem_u4; + +@cil_write_array = @cil_stelem | @cil_stelem_ref | + @cil_stelem_i | @cil_stelem_i1 | @cil_stelem_i2 | @cil_stelem_i4 | @cil_stelem_i8 | + @cil_stelem_r4 | @cil_stelem_r8; + +@cil_throw_any = @cil_throw | @cil_rethrow; + +#keyset[impl, index] +cil_instruction( + unique int id: @cil_instruction, + int opcode: int ref, + int index: int ref, + int impl: @cil_method_implementation ref); + +cil_jump( + unique int instruction: @cil_jump ref, + int target: @cil_instruction ref); + +cil_access( + unique int instruction: @cil_instruction ref, + int target: @cil_accessible ref); + +cil_value( + unique int instruction: @cil_literal ref, + string value: string ref); + +#keyset[instruction, index] +cil_switch( + int instruction: @cil_switch ref, + int index: int ref, + int target: @cil_instruction ref); + +cil_instruction_location( + unique int id: @cil_instruction ref, + int loc: @location ref); + +cil_type_location( + int id: @cil_type ref, + int loc: @location ref); + +cil_method_location( + int id: @cil_method ref, + int loc: @location ref); + +@cil_namespace = @namespace; + +@cil_type_container = @cil_type | @cil_namespace | @cil_method; + +case @cil_type.kind of + 0 = @cil_valueorreftype +| 1 = @cil_typeparameter +| 2 = @cil_array_type +| 3 = @cil_pointer_type +; + +cil_type( + unique int id: @cil_type, + string name: string ref, + int kind: int ref, + int parent: @cil_type_container ref, + int sourceDecl: @cil_type ref); + +cil_pointer_type( + unique int id: @cil_pointer_type ref, + int pointee: @cil_type ref); + +cil_array_type( + unique int id: @cil_array_type ref, + int element_type: @cil_type ref, + int rank: int ref); + +cil_method( + unique int id: @cil_method, + string name: string ref, + int parent: @cil_type ref, + int return_type: @cil_type ref); + +cil_method_source_declaration( + unique int method: @cil_method ref, + int source: @cil_method ref); + +cil_method_implementation( + unique int id: @cil_method_implementation, + int method: @cil_method ref, + int location: @assembly ref); + +cil_implements( + int id: @cil_method ref, + int decl: @cil_method ref); + +#keyset[parent, name] +cil_field( + unique int id: @cil_field, + int parent: @cil_type ref, + string name: string ref, + int field_type: @cil_type ref); + +@cil_element = @cil_instruction | @cil_declaration | @cil_handler | @cil_attribute | @cil_namespace; +@cil_named_element = @cil_declaration | @cil_namespace; +@cil_declaration = @cil_variable | @cil_method | @cil_type | @cil_member; +@cil_accessible = @cil_declaration; +@cil_variable = @cil_field | @cil_stack_variable; +@cil_stack_variable = @cil_local_variable | @cil_parameter; +@cil_member = @cil_method | @cil_type | @cil_field | @cil_property | @cil_event; +@cil_custom_modifier_receiver = @cil_method | @cil_property | @cil_parameter | @cil_field; // todo: add function pointer type + +#keyset[method, index] +cil_parameter( + unique int id: @cil_parameter, + int method: @cil_method ref, + int index: int ref, + int param_type: @cil_type ref); + +cil_parameter_in(unique int id: @cil_parameter ref); +cil_parameter_out(unique int id: @cil_parameter ref); + +cil_setter(unique int prop: @cil_property ref, + int method: @cil_method ref); + +#keyset[id, modifier] +cil_custom_modifiers( + int id: @cil_custom_modifier_receiver ref, + int modifier: @cil_type ref, + int kind: int ref); // modreq: 1, modopt: 0 + +cil_getter(unique int prop: @cil_property ref, + int method: @cil_method ref); + +cil_adder(unique int event: @cil_event ref, + int method: @cil_method ref); + +cil_remover(unique int event: @cil_event ref, int method: @cil_method ref); + +cil_raiser(unique int event: @cil_event ref, int method: @cil_method ref); + +cil_property( + unique int id: @cil_property, + int parent: @cil_type ref, + string name: string ref, + int property_type: @cil_type ref); + +#keyset[parent, name] +cil_event(unique int id: @cil_event, + int parent: @cil_type ref, + string name: string ref, + int event_type: @cil_type ref); + +#keyset[impl, index] +cil_local_variable( + unique int id: @cil_local_variable, + int impl: @cil_method_implementation ref, + int index: int ref, + int var_type: @cil_type ref); + +// CIL handlers (exception handlers etc). + +case @cil_handler.kind of + 0 = @cil_catch_handler +| 1 = @cil_filter_handler +| 2 = @cil_finally_handler +| 4 = @cil_fault_handler +; + +#keyset[impl, index] +cil_handler( + unique int id: @cil_handler, + int impl: @cil_method_implementation ref, + int index: int ref, + int kind: int ref, + int try_start: @cil_instruction ref, + int try_end: @cil_instruction ref, + int handler_start: @cil_instruction ref); + +cil_handler_filter( + unique int id: @cil_handler ref, + int filter_start: @cil_instruction ref); + +cil_handler_type( + unique int id: @cil_handler ref, + int catch_type: @cil_type ref); + +@cil_controlflow_node = @cil_entry_point | @cil_instruction; + +@cil_entry_point = @cil_method_implementation | @cil_handler; + +@cil_dataflow_node = @cil_instruction | @cil_variable | @cil_method; + +cil_method_stack_size( + unique int method: @cil_method_implementation ref, + int size: int ref); + +// CIL modifiers + +cil_public(int id: @cil_member ref); +cil_private(int id: @cil_member ref); +cil_protected(int id: @cil_member ref); +cil_internal(int id: @cil_member ref); +cil_static(int id: @cil_member ref); +cil_sealed(int id: @cil_member ref); +cil_virtual(int id: @cil_method ref); +cil_abstract(int id: @cil_member ref); +cil_class(int id: @cil_type ref); +cil_interface(int id: @cil_type ref); +cil_security(int id: @cil_member ref); +cil_requiresecobject(int id: @cil_method ref); +cil_specialname(int id: @cil_method ref); +cil_newslot(int id: @cil_method ref); + +cil_base_class(unique int id: @cil_type ref, int base: @cil_type ref); +cil_base_interface(int id: @cil_type ref, int base: @cil_type ref); +cil_enum_underlying_type(unique int id: @cil_type ref, int underlying: @cil_type ref); + +#keyset[unbound, index] +cil_type_parameter( + int unbound: @cil_member ref, + int index: int ref, + int param: @cil_typeparameter ref); + +#keyset[bound, index] +cil_type_argument( + int bound: @cil_member ref, + int index: int ref, + int t: @cil_type ref); + +// CIL type parameter constraints + +cil_typeparam_covariant(int tp: @cil_typeparameter ref); +cil_typeparam_contravariant(int tp: @cil_typeparameter ref); +cil_typeparam_class(int tp: @cil_typeparameter ref); +cil_typeparam_struct(int tp: @cil_typeparameter ref); +cil_typeparam_new(int tp: @cil_typeparameter ref); +cil_typeparam_constraint(int tp: @cil_typeparameter ref, int supertype: @cil_type ref); + +// CIL attributes + +cil_attribute( + unique int attributeid: @cil_attribute, + int element: @cil_declaration ref, + int constructor: @cil_method ref); + +#keyset[attribute_id, param] +cil_attribute_named_argument( + int attribute_id: @cil_attribute ref, + string param: string ref, + string value: string ref); + +#keyset[attribute_id, index] +cil_attribute_positional_argument( + int attribute_id: @cil_attribute ref, + int index: int ref, + string value: string ref); + + +// Common .Net data model covering both C# and CIL + +// Common elements +@dotnet_element = @element | @cil_element; +@dotnet_named_element = @named_element | @cil_named_element; +@dotnet_callable = @callable | @cil_method; +@dotnet_variable = @variable | @cil_variable; +@dotnet_field = @field | @cil_field; +@dotnet_parameter = @parameter | @cil_parameter; +@dotnet_declaration = @declaration | @cil_declaration; +@dotnet_member = @member | @cil_member; +@dotnet_event = @event | @cil_event; +@dotnet_property = @property | @cil_property | @indexer; + +// Common types +@dotnet_type = @type | @cil_type; +@dotnet_call = @call | @cil_call_any; +@dotnet_throw = @throw_element | @cil_throw_any; +@dotnet_valueorreftype = @cil_valueorreftype | @value_or_ref_type | @cil_array_type | @void_type; +@dotnet_typeparameter = @type_parameter | @cil_typeparameter; +@dotnet_array_type = @array_type | @cil_array_type; +@dotnet_pointer_type = @pointer_type | @cil_pointer_type; +@dotnet_type_parameter = @type_parameter | @cil_typeparameter; +@dotnet_generic = @dotnet_valueorreftype | @dotnet_callable; + +// Attributes +@dotnet_attribute = @attribute | @cil_attribute; + +// Expressions +@dotnet_expr = @expr | @cil_expr; + +// Literals +@dotnet_literal = @literal_expr | @cil_literal; +@dotnet_string_literal = @string_literal_expr | @cil_ldstr; +@dotnet_int_literal = @integer_literal_expr | @cil_ldc_i; +@dotnet_float_literal = @float_literal_expr | @cil_ldc_r; +@dotnet_null_literal = @null_literal_expr | @cil_ldnull; + +@metadata_entity = @cil_method | @cil_type | @cil_field | @cil_property | @field | @property | + @callable | @value_or_ref_type | @void_type; + +#keyset[entity, location] +metadata_handle(int entity : @metadata_entity ref, int location: @assembly ref, int handle: int ref) diff --git a/csharp/upgrades/f5903552e3099dba41375ca19af7caca5c2e4966/upgrade.properties b/csharp/upgrades/f5903552e3099dba41375ca19af7caca5c2e4966/upgrade.properties new file mode 100644 index 00000000000..15e0fbf4c00 --- /dev/null +++ b/csharp/upgrades/f5903552e3099dba41375ca19af7caca5c2e4966/upgrade.properties @@ -0,0 +1,2 @@ +description: Added 'cil_custom_modifiers' to store custom modifiers ('modreq', 'modopt'). +compatibility: backwards diff --git a/csharp/upgrades/initial/semmlecode.csharp.dbscheme b/csharp/upgrades/initial/semmlecode.csharp.dbscheme new file mode 100644 index 00000000000..34565707dfb --- /dev/null +++ b/csharp/upgrades/initial/semmlecode.csharp.dbscheme @@ -0,0 +1,1707 @@ +/* + * External artifacts + */ + +externalDefects( + unique int id: @externalDefect, + varchar(900) queryPath: string ref, + int location: @location ref, + varchar(900) message: string ref, + float severity: float ref); + +externalMetrics( + unique int id: @externalMetric, + varchar(900) queryPath: string ref, + int location: @location ref, + float value: float ref); + +externalData( + int id: @externalDataElement, + varchar(900) path: string ref, + int column: int ref, + varchar(900) value: string ref); + +snapshotDate( + unique date snapshotDate: date ref); + +sourceLocationPrefix( + varchar(900) prefix: string ref); + +/* + * Duplicate code + */ + +duplicateCode( + unique int id: @duplication, + varchar(900) relativePath: string ref, + int equivClass: int ref); + +similarCode( + unique int id: @similarity, + varchar(900) relativePath: string ref, + int equivClass: int ref); + +@duplication_or_similarity = @duplication | @similarity + +tokens( + int id: @duplication_or_similarity ref, + int offset: int ref, + int beginLine: int ref, + int beginColumn: int ref, + int endLine: int ref, + int endColumn: int ref); + +/* + * Version history + */ + +svnentries( + int id: @svnentry, + varchar(500) revision: string ref, + varchar(500) author: string ref, + date revisionDate: date ref, + int changeSize: int ref); + +svnaffectedfiles( + int id: @svnentry ref, + int file: @file ref, + varchar(500) action: string ref); + +svnentrymsg( + int id: @svnentry ref, + varchar(500) message: string ref +) + +svnchurn( + int commit: @svnentry ref, + int file: @file ref, + int addedLines: int ref, + int deletedLines: int ref); + +/* + * C# dbscheme + */ + +/** ELEMENTS **/ + +@element = @declaration | @stmt | @expr | @modifier | @attribute | @namespace_declaration + | @using_directive | @type_parameter_constraints | @external_element + | @xmllocatable | @asp_element | @namespace; + +@declaration = @callable | @generic | @assignable; + +@named_element = @namespace | @declaration; + +@declaration_with_accessors = @property | @indexer | @event; + +@assignable = @variable | @assignable_with_accessors | @event; + +@assignable_with_accessors = @property | @indexer; + +@external_element = @externalMetric | @externalDefect | @externalDataElement; + +@attributable = @assembly | @field | @parameter | @operator | @method | @constructor + | @destructor | @callable_accessor | @value_or_ref_type | @declaration_with_accessors; + +/** LOCATIONS, ASEMMBLIES, MODULES, FILES and FOLDERS **/ + +@location = @location_default | @assembly; + +locations_default( + unique int id: @location_default, + int file: @file ref, + int beginLine: int ref, + int beginColumn: int ref, + int endLine: int ref, + int endColumn: int ref); + +@sourceline = @file | @callable | @xmllocatable; + +numlines( + unique int element_id: @sourceline ref, + int num_lines: int ref, + int num_code: int ref, + int num_comment: int ref); + +assemblies( + unique int id: @assembly, + int file: @file ref, + varchar(900) fullname: string ref, + varchar(900) name: string ref, + varchar(900) version: string ref); + +/* + fromSource(0) = unknown, + fromSource(1) = from source, + fromSource(2) = from library +*/ +files( + unique int id: @file, + varchar(900) name: string ref, + varchar(900) simple: string ref, + varchar(900) ext: string ref, + int fromSource: int ref); + +folders( + unique int id: @folder, + varchar(900) name: string ref, + varchar(900) simple: string ref); + +@container = @folder | @file ; + +containerparent( + int parent: @container ref, + unique int child: @container ref); + +file_extraction_mode( + unique int file: @file ref, + int mode: int ref + /* 0 = normal, 1 = standalone extractor */ + ); + +/** NAMESPACES **/ + +@type_container = @namespace | @type; + +namespaces( + unique int id: @namespace, + varchar(900) name: string ref); + +namespace_declarations( + unique int id: @namespace_declaration, + int namespace_id: @namespace ref); + +namespace_declaration_location( + unique int id: @namespace_declaration ref, + int loc: @location ref); + +parent_namespace( + unique int child_id: @type_container ref, + int namespace_id: @namespace ref); + +@declaration_or_directive = @namespace_declaration | @type | @using_directive; + +parent_namespace_declaration( + int child_id: @declaration_or_directive ref, // cannot be unique because of partial classes + int namespace_id: @namespace_declaration ref); + +@using_directive = @using_namespace_directive | @using_static_directive; + +using_namespace_directives( + unique int id: @using_namespace_directive, + int namespace_id: @namespace ref); + +using_static_directives( + unique int id: @using_static_directive, + int type_id: @type_or_ref ref); + +using_directive_location( + unique int id: @using_directive ref, + int loc: @location ref); + +/** TYPES **/ + +types( + unique int id: @type, + int kind: int ref, + varchar(900) name: string ref); + +case @type.kind of + 1 = @bool_type +| 2 = @char_type +| 3 = @decimal_type +| 4 = @sbyte_type +| 5 = @short_type +| 6 = @int_type +| 7 = @long_type +| 8 = @byte_type +| 9 = @ushort_type +| 10 = @uint_type +| 11 = @ulong_type +| 12 = @float_type +| 13 = @double_type +| 14 = @enum_type +| 15 = @struct_type +| 17 = @class_type +| 19 = @interface_type +| 20 = @delegate_type +| 21 = @null_type +| 22 = @type_parameter +| 23 = @pointer_type +| 24 = @nullable_type +| 25 = @array_type +| 26 = @void_type +| 27 = @int_ptr_type +| 28 = @uint_ptr_type +| 29 = @dynamic_type +| 30 = @arglist_type +| 31 = @unknown_type +| 32 = @tuple_type + ; + +@simple_type = @bool_type | @char_type | @integral_type | @floating_point_type | @decimal_type; +@integral_type = @signed_integral_type | @unsigned_integral_type; +@signed_integral_type = @sbyte_type | @short_type | @int_type | @long_type; +@unsigned_integral_type = @byte_type | @ushort_type | @uint_type | @ulong_type; +@floating_point_type = @float_type | @double_type; +@value_type = @simple_type | @enum_type | @struct_type | @nullable_type | @int_ptr_type + | @uint_ptr_type | @tuple_type; +@ref_type = @class_type | @interface_type | @array_type | @delegate_type | @null_type + | @dynamic_type; +@value_or_ref_type = @value_type | @ref_type; + +typerefs( + unique int id: @typeref, + varchar(900) name: string ref); + +typeref_type( + unique int id: @typeref ref, + unique int typeId: @type ref); + +@type_or_ref = @type | @typeref; + +array_element_type( + unique int array: @array_type ref, + int dimension: int ref, + int rank: int ref, + int element: @type_or_ref ref); + +nullable_underlying_type( + unique int nullable: @nullable_type ref, + int underlying: @type_or_ref ref); + +pointer_referent_type( + unique int pointer: @pointer_type ref, + int referent: @type_or_ref ref); + +enum_underlying_type( + unique int enum_id: @enum_type ref, + int underlying_type_id: @type_or_ref ref); + +delegate_return_type( + unique int delegate_id: @delegate_type ref, + int return_type_id: @type_or_ref ref); + +extend( + unique int sub: @type ref, + int super: @type_or_ref ref); + +@interface_or_ref = @interface_type | @typeref; + +implement( + int sub: @type ref, + int super: @type_or_ref ref); + +type_location( + int id: @type ref, + int loc: @location ref); + +tuple_underlying_type( + unique int tuple: @tuple_type ref, + int struct: @struct_type ref); + +#keyset[tuple, index] +tuple_element( + int tuple: @tuple_type ref, + int index: int ref, + unique int field: @field ref); + +attributes( + unique int id: @attribute, + int type_id: @type_or_ref ref, + int target: @attributable ref); + +attribute_location( + int id: @attribute ref, + int loc: @location ref); + +@type_mention_parent = @element | @type_mention; + +type_mention( + unique int id: @type_mention, + int type_id: @type_or_ref ref, + int parent: @type_mention_parent ref); + +type_mention_location( + unique int id: @type_mention ref, + int loc: @location ref); + +/** GENERICS **/ + +@generic = @type | @method | @local_function; + +is_generic(unique int id: @generic ref); + +is_constructed(unique int id: @generic ref); + +type_parameters( + unique int id: @type_parameter ref, + int index: int ref, + int generic_id: @generic ref, + int variance: int ref /* none = 0, out = 1, in = 2 */); + +#keyset[constructed_id, index] +type_arguments( + int id: @type_or_ref ref, + int index: int ref, + int constructed_id: @generic_or_ref ref); + +@generic_or_ref = @generic | @typeref; + +constructed_generic( + unique int constructed: @generic ref, + int generic: @generic_or_ref ref); + +type_parameter_constraints( + unique int id: @type_parameter_constraints, + int param_id: @type_parameter ref); + +type_parameter_constraints_location( + int id: @type_parameter_constraints ref, + int loc: @location ref); + +general_type_parameter_constraints( + int id: @type_parameter_constraints ref, + int kind: int ref /* class = 1, struct = 2, new = 3 */); + +specific_type_parameter_constraints( + int id: @type_parameter_constraints ref, + int base_id: @type_or_ref ref); + + +/** MODIFIERS */ + +@modifiable = @modifiable_direct | @event_accessor; + +@modifiable_direct = @member | @accessor; + +modifiers( + unique int id: @modifier, + varchar(900) name: string ref); + +has_modifiers( + int id: @modifiable_direct ref, + int mod_id: @modifier ref); + +compiler_generated(unique int id: @modifiable_direct ref); + +/** MEMBERS **/ + +@member = @method | @constructor | @destructor | @field | @property | @event | @operator | @indexer | @type; + +@named_exprorstmt = @goto_stmt | @labeled_stmt | @literal_expr; + +@virtualizable = @method | @property | @indexer | @event; + +exprorstmt_name( + unique int parent_id: @named_exprorstmt ref, + varchar(900) name: string ref); + +nested_types( + unique int id: @type ref, + int declaring_type_id: @type ref, + int unbound_id: @type ref); + +properties( + unique int id: @property, + varchar(900) name: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @property ref); + +property_location( + int id: @property ref, + int loc: @location ref); + +indexers( + unique int id: @indexer, + varchar(900) name: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @indexer ref); + +indexer_location( + int id: @indexer ref, + int loc: @location ref); + +accessors( + unique int id: @accessor, + int kind: int ref, + varchar(900) name: string ref, + int declaring_member_id: @member ref, + int unbound_id: @accessor ref); + +case @accessor.kind of + 1 = @getter +| 2 = @setter + ; + +accessor_location( + int id: @accessor ref, + int loc: @location ref); + +events( + unique int id: @event, + varchar(900) name: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @event ref); + +event_location( + int id: @event ref, + int loc: @location ref); + +event_accessors( + unique int id: @event_accessor, + int kind: int ref, + varchar(900) name: string ref, + int declaring_event_id: @event ref, + int unbound_id: @event_accessor ref); + +case @event_accessor.kind of + 1 = @add_event_accessor +| 2 = @remove_event_accessor + ; + +event_accessor_location( + int id: @event_accessor ref, + int loc: @location ref); + +operators( + unique int id: @operator, + varchar(900) name: string ref, + varchar(900) symbol: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @operator ref); + +operator_location( + int id: @operator ref, + int loc: @location ref); + +constant_value( + unique int id: @variable ref, + varchar(900) value: string ref); + +/** CALLABLES **/ + +@callable = @method | @constructor | @destructor | @operator | @callable_accessor | @anonymous_function_expr | @local_function; + +@callable_accessor = @accessor | @event_accessor; + +methods( + unique int id: @method, + varchar(900) name: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @method ref); + +method_location( + int id: @method ref, + int loc: @location ref); + +constructors( + unique int id: @constructor, + varchar(900) name: string ref, + int declaring_type_id: @type ref, + int unbound_id: @constructor ref); + +constructor_location( + int id: @constructor ref, + int loc: @location ref); + +destructors( + unique int id: @destructor, + varchar(900) name: string ref, + int declaring_type_id: @type ref, + int unbound_id: @destructor ref); + +destructor_location( + int id: @destructor ref, + int loc: @location ref); + +overrides( + unique int id: @callable ref, + int base_id: @callable ref); + +explicitly_implements( + unique int id: @member ref, + int interface_id: @interface_or_ref ref); + +local_functions( + unique int id: @local_function, + varchar(900) name: string ref, + int return_type: @type ref, + int unbound_id: @local_function ref); + +local_function_stmts( + unique int fn: @local_function_stmt ref, + int stmt: @local_function ref); + +@ref_callable = @local_function | @method | @delegate_type; + +ref_returns(int fn: @ref_callable ref); + +ref_readonly_returns(int fn: @ref_callable ref); + +/** VARIABLES **/ + +@variable = @local_scope_variable | @field; + +@local_scope_variable = @local_variable | @parameter; + +fields( + unique int id: @field, + int kind: int ref, + varchar(900) name: string ref, + int declaring_type_id: @type ref, + int type_id: @type_or_ref ref, + int unbound_id: @field ref); + +case @field.kind of + 1 = @addressable_field +| 2 = @constant + ; + +field_location( + int id: @field ref, + int loc: @location ref); + +localvars( + unique int id: @local_variable, + int kind: int ref, + varchar(900) name: string ref, + int implicitly_typed: int ref /* 0 = no, 1 = yes */, + int type_id: @type_or_ref ref, + int parent_id: @local_var_decl_expr ref); + +case @local_variable.kind of + 1 = @addressable_local_variable +| 2 = @local_constant +| 3 = @local_variable_ref + ; + +localvar_location( + unique int id: @local_variable ref, + int loc: @location ref); + +@parameterizable = @callable | @delegate_type | @indexer; + +#keyset[name, parent_id] +#keyset[index, parent_id] +params( + unique int id: @parameter, + varchar(900) name: string ref, + int type_id: @type_or_ref ref, + int index: int ref, + int mode: int ref, /* value = 0, ref = 1, out = 2, array = 3, this = 4 */ + int parent_id: @parameterizable ref, + int unbound_id: @parameter ref); + +param_location( + int id: @parameter ref, + int loc: @location ref); + +/** STATEMENTS **/ + +@exprorstmt_parent = @control_flow_element | @top_level_exprorstmt_parent; + +statements( + unique int id: @stmt, + int kind: int ref); + +#keyset[index, parent] +stmt_parent( + unique int stmt: @stmt ref, + int index: int ref, + int parent: @control_flow_element ref); + +@top_level_stmt_parent = @callable; + +// [index, parent] is not a keyset because the same parent may be compiled multiple times +stmt_parent_top_level( + unique int stmt: @stmt ref, + int index: int ref, + int parent: @top_level_stmt_parent ref); + +case @stmt.kind of + 1 = @block_stmt +| 2 = @expr_stmt +| 3 = @if_stmt +| 4 = @switch_stmt +| 5 = @while_stmt +| 6 = @do_stmt +| 7 = @for_stmt +| 8 = @foreach_stmt +| 9 = @break_stmt +| 10 = @continue_stmt +| 11 = @goto_stmt +| 12 = @goto_case_stmt +| 13 = @goto_default_stmt +| 14 = @throw_stmt +| 15 = @return_stmt +| 16 = @yield_stmt +| 17 = @try_stmt +| 18 = @checked_stmt +| 19 = @unchecked_stmt +| 20 = @lock_stmt +| 21 = @using_stmt +| 22 = @var_decl_stmt +| 23 = @const_decl_stmt +| 24 = @empty_stmt +| 25 = @unsafe_stmt +| 26 = @fixed_stmt +| 27 = @label_stmt +| 28 = @catch +| 29 = @case +| 30 = @local_function_stmt + ; + +@labeled_stmt = @label_stmt | @case; + +@decl_stmt = @var_decl_stmt | @const_decl_stmt; + +@cond_stmt = @if_stmt | @switch_stmt; + +@loop_stmt = @while_stmt | @do_stmt | @for_stmt | @foreach_stmt; + +@jump_stmt = @break_stmt | @goto_any_stmt | @continue_stmt | @throw_stmt | @return_stmt + | @yield_stmt; + +@goto_any_stmt = @goto_default_stmt | @goto_case_stmt | @goto_stmt; + + +stmt_location( + unique int id: @stmt ref, + int loc: @location ref); + +catch_type( + unique int catch_id: @catch ref, + int type_id: @type_or_ref ref, + int kind: int ref /* explicit = 1, implicit = 2 */); + +/** EXPRESSIONS **/ + +expressions( + unique int id: @expr, + int kind: int ref, + int type_id: @type_or_ref ref); + +#keyset[index, parent] +expr_parent( + unique int expr: @expr ref, + int index: int ref, + int parent: @control_flow_element ref); + +@top_level_expr_parent = @attribute | @field | @property | @indexer | @parameter; + +@top_level_exprorstmt_parent = @top_level_expr_parent | @top_level_stmt_parent; + +// [index, parent] is not a keyset because the same parent may be compiled multiple times +expr_parent_top_level( + unique int expr: @expr ref, + int index: int ref, + int parent: @top_level_exprorstmt_parent ref); + +case @expr.kind of +/* literal */ + 1 = @bool_literal_expr +| 2 = @char_literal_expr +| 3 = @decimal_literal_expr +| 4 = @int_literal_expr +| 5 = @long_literal_expr +| 6 = @uint_literal_expr +| 7 = @ulong_literal_expr +| 8 = @float_literal_expr +| 9 = @double_literal_expr +| 10 = @string_literal_expr +| 11 = @null_literal_expr +/* primary & unary */ +| 12 = @this_access_expr +| 13 = @base_access_expr +| 14 = @local_variable_access_expr +| 15 = @parameter_access_expr +| 16 = @field_access_expr +| 17 = @property_access_expr +| 18 = @method_access_expr +| 19 = @event_access_expr +| 20 = @indexer_access_expr +| 21 = @array_access_expr +| 22 = @type_access_expr +| 23 = @typeof_expr +| 24 = @method_invocation_expr +| 25 = @delegate_invocation_expr +| 26 = @operator_invocation_expr +| 27 = @cast_expr +| 28 = @object_creation_expr +| 29 = @explicit_delegate_creation_expr +| 30 = @implicit_delegate_creation_expr +| 31 = @array_creation_expr +| 32 = @default_expr +| 33 = @plus_expr +| 34 = @minus_expr +| 35 = @bit_not_expr +| 36 = @log_not_expr +| 37 = @post_incr_expr +| 38 = @post_decr_expr +| 39 = @pre_incr_expr +| 40 = @pre_decr_expr +/* multiplicative */ +| 41 = @mul_expr +| 42 = @div_expr +| 43 = @rem_expr +/* additive */ +| 44 = @add_expr +| 45 = @sub_expr +/* shift */ +| 46 = @lshift_expr +| 47 = @rshift_expr +/* relational */ +| 48 = @lt_expr +| 49 = @gt_expr +| 50 = @le_expr +| 51 = @ge_expr +/* equality */ +| 52 = @eq_expr +| 53 = @ne_expr +/* logical */ +| 54 = @bit_and_expr +| 55 = @bit_xor_expr +| 56 = @bit_or_expr +| 57 = @log_and_expr +| 58 = @log_or_expr +/* type testing */ +| 59 = @is_expr +| 60 = @as_expr +/* null coalescing */ +| 61 = @null_coalescing_expr +/* conditional */ +| 62 = @conditional_expr +/* assignment */ +| 63 = @simple_assign_expr +| 64 = @assign_add_expr +| 65 = @assign_sub_expr +| 66 = @assign_mul_expr +| 67 = @assign_div_expr +| 68 = @assign_rem_expr +| 69 = @assign_and_expr +| 70 = @assign_xor_expr +| 71 = @assign_or_expr +| 72 = @assign_lshift_expr +| 73 = @assign_rshift_expr +/* more */ +| 74 = @object_init_expr +| 75 = @collection_init_expr +| 76 = @array_init_expr +| 77 = @checked_expr +| 78 = @unchecked_expr +| 79 = @constructor_init_expr +| 80 = @add_event_expr +| 81 = @remove_event_expr +| 82 = @par_expr +| 83 = @local_var_decl_expr +| 84 = @lambda_expr +| 85 = @anonymous_method_expr +| 86 = @namespace_expr +/* dynamic */ +| 92 = @dynamic_element_access_expr +| 93 = @dynamic_member_access_expr +/* unsafe */ +| 100 = @pointer_indirection_expr +| 101 = @address_of_expr +| 102 = @sizeof_expr +/* async */ +| 103 = @await_expr +/* C# 6.0 */ +| 104 = @nameof_expr +| 105 = @interpolated_string_expr +| 106 = @unknown_expr +/* C# 7.0 */ +| 107 = @throw_expr +| 108 = @tuple_expr +| 109 = @local_function_invocation_expr +| 110 = @ref_expr +| 111 = @discard_expr +; + +@integer_literal_expr = @int_literal_expr | @long_literal_expr | @uint_literal_expr | @ulong_literal_expr; +@real_literal_expr = @float_literal_expr | @double_literal_expr | @decimal_literal_expr; +@literal_expr = @bool_literal_expr | @char_literal_expr | @integer_literal_expr | @real_literal_expr + | @string_literal_expr | @null_literal_expr; + +@assign_expr = @simple_assign_expr | @assign_op_expr | @local_var_decl_expr; +@assign_op_expr = @assign_arith_expr | @assign_bitwise_expr | @assign_event_expr; +@assign_event_expr = @add_event_expr | @remove_event_expr; + +@assign_arith_expr = @assign_add_expr | @assign_sub_expr | @assign_mul_expr | @assign_div_expr + | @assign_rem_expr +@assign_bitwise_expr = @assign_and_expr | @assign_or_expr | @assign_xor_expr + | @assign_lshift_expr | @assign_rshift_expr; + +@member_access_expr = @field_access_expr | @property_access_expr | @indexer_access_expr | @event_access_expr + | @method_access_expr | @type_access_expr | @dynamic_member_access_expr; +@access_expr = @member_access_expr | @this_access_expr | @base_access_expr | @assignable_access_expr; +@element_access_expr = @indexer_access_expr | @array_access_expr | @dynamic_element_access_expr; + +@local_variable_access = @local_variable_access_expr | @local_var_decl_expr; +@local_scope_variable_access_expr = @parameter_access_expr | @local_variable_access; +@variable_access_expr = @local_scope_variable_access_expr | @field_access_expr; + +@assignable_access_expr = @variable_access_expr | @property_access_expr | @element_access_expr + | @event_access_expr | @dynamic_member_access_expr; + +@objectorcollection_init_expr = @object_init_expr | @collection_init_expr; + +@delegate_creation_expr = @explicit_delegate_creation_expr | @implicit_delegate_creation_expr; + +@bin_arith_op_expr = @mul_expr | @div_expr | @rem_expr | @add_expr | @sub_expr; +@incr_op_expr = @pre_incr_expr | @post_incr_expr; +@decr_op_expr = @pre_decr_expr | @post_decr_expr; +@mut_op_expr = @incr_op_expr | @decr_op_expr; +@un_arith_op_expr = @plus_expr | @minus_expr | @mut_op_expr; +@arith_op_expr = @bin_arith_op_expr | @un_arith_op_expr; + +@ternary_log_op_expr = @conditional_expr; +@bin_log_op_expr = @log_and_expr | @log_or_expr | @null_coalescing_expr; +@un_log_op_expr = @log_not_expr; +@log_expr = @un_log_op_expr | @bin_log_op_expr | @ternary_log_op_expr; + +@bin_bit_op_expr = @bit_and_expr | @bit_or_expr | @bit_xor_expr | @lshift_expr + | @rshift_expr; +@un_bit_op_expr = @bit_not_expr; +@bit_expr = @un_bit_op_expr | @bin_bit_op_expr; + +@equality_op_expr = @eq_expr | @ne_expr; +@rel_op_expr = @gt_expr | @lt_expr| @ge_expr | @le_expr; +@comp_expr = @equality_op_expr | @rel_op_expr; + +@op_expr = @assign_expr | @un_op | @bin_op | @ternary_op; + +@ternary_op = @ternary_log_op_expr; +@bin_op = @bin_arith_op_expr | @bin_log_op_expr | @bin_bit_op_expr | @comp_expr; +@un_op = @un_arith_op_expr | @un_log_op_expr | @un_bit_op_expr | @sizeof_expr + | @pointer_indirection_expr | @address_of_expr; + +@anonymous_function_expr = @lambda_expr | @anonymous_method_expr; + +@call = @method_invocation_expr | @constructor_init_expr | @operator_invocation_expr + | @delegate_invocation_expr | @object_creation_expr | @call_access_expr + | @local_function_invocation_expr; + +@call_access_expr = @property_access_expr | @event_access_expr | @indexer_access_expr; + +@late_bindable_expr = @dynamic_element_access_expr | @dynamic_member_access_expr + | @object_creation_expr | @method_invocation_expr | @operator_invocation_expr; + +@throw_element = @throw_expr | @throw_stmt; + +implicitly_typed_array_creation( + unique int id: @array_creation_expr ref); + +explicitly_sized_array_creation( + unique int id: @array_creation_expr ref); + +mutator_invocation_mode( + unique int id: @operator_invocation_expr ref, + int mode: int ref /* prefix = 1, postfix = 2*/); + +expr_compiler_generated( + unique int id: @expr ref); + +expr_value( + unique int id: @expr ref, + varchar(900) value: string ref); + +expr_call( + unique int caller_id: @expr ref, + int target_id: @callable ref); + +expr_access( + unique int accesser_id: @access_expr ref, + int target_id: @accessible ref); + +@accessible = @method | @assignable | @local_function; + +expr_location( + unique int id: @expr ref, + int loc: @location ref); + +dynamic_member_name( + unique int id: @late_bindable_expr ref, + varchar(900) name: string ref); + +@qualifiable_expr = @member_access_expr + | @method_invocation_expr + | @element_access_expr; + +conditional_access( + unique int id: @qualifiable_expr ref); + +expr_argument( + unique int id: @expr ref, + int mode: int ref); + /* mode is the same as params: value = 0, ref = 1, out = 2 */ + +expr_argument_name( + unique int id: @expr ref, + varchar(900) name: string ref); + +/** CONTROL/DATA FLOW **/ + +@control_flow_element = @stmt | @expr; + +/* XML Files */ + +xmlEncoding ( + unique int id: @file ref, + varchar(900) encoding: string ref); + +xmlDTDs( + unique int id: @xmldtd, + varchar(900) root: string ref, + varchar(900) publicId: string ref, + varchar(900) systemId: string ref, + int fileid: @file ref); + +xmlElements( + unique int id: @xmlelement, + varchar(900) name: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int fileid: @file ref); + +xmlAttrs( + unique int id: @xmlattribute, + int elementid: @xmlelement ref, + varchar(900) name: string ref, + varchar(3600) value: string ref, + int idx: int ref, + int fileid: @file ref); + +xmlNs( + int id: @xmlnamespace, + varchar(900) prefixName: string ref, + varchar(900) URI: string ref, + int fileid: @file ref); + +xmlHasNs( + int elementId: @xmlnamespaceable ref, + int nsId: @xmlnamespace ref, + int fileid: @file ref); + +xmlComments( + unique int id: @xmlcomment, + varchar(3600) text: string ref, + int parentid: @xmlparent ref, + int fileid: @file ref); + +xmlChars( + unique int id: @xmlcharacters, + varchar(3600) text: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int isCDATA: int ref, + int fileid: @file ref); + +@xmlparent = @file | @xmlelement; +@xmlnamespaceable = @xmlelement | @xmlattribute; + +xmllocations( + int xmlElement: @xmllocatable ref, + int location: @location_default ref); + +@xmllocatable = @xmlcharacters | @xmlelement | @xmlcomment | @xmlattribute | @xmldtd | @file | @xmlnamespace; + +/* Comments */ + +commentline( + unique int id: @commentline, + int kind: int ref, + varchar(800) text: string ref, + varchar(800) rawtext: string ref); + +case @commentline.kind of + 0 = @singlelinecomment +| 1 = @xmldoccomment +| 2 = @multilinecomment; + +commentline_location( + unique int id: @commentline ref, + int loc: @location ref); + +commentblock( + unique int id : @commentblock); + +commentblock_location( + unique int id: @commentblock ref, + int loc: @location ref); + +commentblock_binding( + int id: @commentblock ref, + int entity: @element ref, + int bindtype: int ref); /* 0: Parent, 1: Best, 2: Before, 3: After */ + +commentblock_child( + int id: @commentblock ref, + int commentline: @commentline ref, + int index: int ref); + +/* ASP.NET */ + +case @asp_element.kind of + 0=@asp_close_tag +| 1=@asp_code +| 2=@asp_comment +| 3=@asp_data_binding +| 4=@asp_directive +| 5=@asp_open_tag +| 6=@asp_quoted_string +| 7=@asp_text +| 8=@asp_xml_directive; + +@asp_attribute = @asp_code | @asp_data_binding | @asp_quoted_string; + +asp_elements( + unique int id: @asp_element, + int kind: int ref, + int loc: @location ref); + +asp_comment_server(unique int comment: @asp_comment ref); +asp_code_inline(unique int code: @asp_code ref); +asp_directive_attribute( + int directive: @asp_directive ref, + int index: int ref, + varchar(1000) name: string ref, + int value: @asp_quoted_string ref); +asp_directive_name( + unique int directive: @asp_directive ref, + varchar(1000) name: string ref); +asp_element_body( + unique int element: @asp_element ref, + varchar(1000) body: string ref); +asp_tag_attribute( + int tag: @asp_open_tag ref, + int index: int ref, + varchar(1000) name: string ref, + int attribute: @asp_attribute ref); +asp_tag_name( + unique int tag: @asp_open_tag ref, + varchar(1000) name: string ref); +asp_tag_isempty(int tag: @asp_open_tag ref); + +/* Common Intermediate Language - CIL */ + +case @cil_instruction.opcode of + 0 = @cil_nop +| 1 = @cil_break +| 2 = @cil_ldarg_0 +| 3 = @cil_ldarg_1 +| 4 = @cil_ldarg_2 +| 5 = @cil_ldarg_3 +| 6 = @cil_ldloc_0 +| 7 = @cil_ldloc_1 +| 8 = @cil_ldloc_2 +| 9 = @cil_ldloc_3 +| 10 = @cil_stloc_0 +| 11 = @cil_stloc_1 +| 12 = @cil_stloc_2 +| 13 = @cil_stloc_3 +| 14 = @cil_ldarg_s +| 15 = @cil_ldarga_s +| 16 = @cil_starg_s +| 17 = @cil_ldloc_s +| 18 = @cil_ldloca_s +| 19 = @cil_stloc_s +| 20 = @cil_ldnull +| 21 = @cil_ldc_i4_m1 +| 22 = @cil_ldc_i4_0 +| 23 = @cil_ldc_i4_1 +| 24 = @cil_ldc_i4_2 +| 25 = @cil_ldc_i4_3 +| 26 = @cil_ldc_i4_4 +| 27 = @cil_ldc_i4_5 +| 28 = @cil_ldc_i4_6 +| 29 = @cil_ldc_i4_7 +| 30 = @cil_ldc_i4_8 +| 31 = @cil_ldc_i4_s +| 32 = @cil_ldc_i4 +| 33 = @cil_ldc_i8 +| 34 = @cil_ldc_r4 +| 35 = @cil_ldc_r8 +| 37 = @cil_dup +| 38 = @cil_pop +| 39 = @cil_jmp +| 40 = @cil_call +| 41 = @cil_calli +| 42 = @cil_ret +| 43 = @cil_br_s +| 44 = @cil_brfalse_s +| 45 = @cil_brtrue_s +| 46 = @cil_beq_s +| 47 = @cil_bge_s +| 48 = @cil_bgt_s +| 49 = @cil_ble_s +| 50 = @cil_blt_s +| 51 = @cil_bne_un_s +| 52 = @cil_bge_un_s +| 53 = @cil_bgt_un_s +| 54 = @cil_ble_un_s +| 55 = @cil_blt_un_s +| 56 = @cil_br +| 57 = @cil_brfalse +| 58 = @cil_brtrue +| 59 = @cil_beq +| 60 = @cil_bge +| 61 = @cil_bgt +| 62 = @cil_ble +| 63 = @cil_blt +| 64 = @cil_bne_un +| 65 = @cil_bge_un +| 66 = @cil_bgt_un +| 67 = @cil_ble_un +| 68 = @cil_blt_un +| 69 = @cil_switch +| 70 = @cil_ldind_i1 +| 71 = @cil_ldind_u1 +| 72 = @cil_ldind_i2 +| 73 = @cil_ldind_u2 +| 74 = @cil_ldind_i4 +| 75 = @cil_ldind_u4 +| 76 = @cil_ldind_i8 +| 77 = @cil_ldind_i +| 78 = @cil_ldind_r4 +| 79 = @cil_ldind_r8 +| 80 = @cil_ldind_ref +| 81 = @cil_stind_ref +| 82 = @cil_stind_i1 +| 83 = @cil_stind_i2 +| 84 = @cil_stind_i4 +| 85 = @cil_stind_i8 +| 86 = @cil_stind_r4 +| 87 = @cil_stind_r8 +| 88 = @cil_add +| 89 = @cil_sub +| 90 = @cil_mul +| 91 = @cil_div +| 92 = @cil_div_un +| 93 = @cil_rem +| 94 = @cil_rem_un +| 95 = @cil_and +| 96 = @cil_or +| 97 = @cil_xor +| 98 = @cil_shl +| 99 = @cil_shr +| 100 = @cil_shr_un +| 101 = @cil_neg +| 102 = @cil_not +| 103 = @cil_conv_i1 +| 104 = @cil_conv_i2 +| 105 = @cil_conv_i4 +| 106 = @cil_conv_i8 +| 107 = @cil_conv_r4 +| 108 = @cil_conv_r8 +| 109 = @cil_conv_u4 +| 110 = @cil_conv_u8 +| 111 = @cil_callvirt +| 112 = @cil_cpobj +| 113 = @cil_ldobj +| 114 = @cil_ldstr +| 115 = @cil_newobj +| 116 = @cil_castclass +| 117 = @cil_isinst +| 118 = @cil_conv_r_un +| 121 = @cil_unbox +| 122 = @cil_throw +| 123 = @cil_ldfld +| 124 = @cil_ldflda +| 125 = @cil_stfld +| 126 = @cil_ldsfld +| 127 = @cil_ldsflda +| 128 = @cil_stsfld +| 129 = @cil_stobj +| 130 = @cil_conv_ovf_i1_un +| 131 = @cil_conv_ovf_i2_un +| 132 = @cil_conv_ovf_i4_un +| 133 = @cil_conv_ovf_i8_un +| 134 = @cil_conv_ovf_u1_un +| 135 = @cil_conv_ovf_u2_un +| 136 = @cil_conv_ovf_u4_un +| 137 = @cil_conv_ovf_u8_un +| 138 = @cil_conv_ovf_i_un +| 139 = @cil_conv_ovf_u_un +| 140 = @cil_box +| 141 = @cil_newarr +| 142 = @cil_ldlen +| 143 = @cil_ldelema +| 144 = @cil_ldelem_i1 +| 145 = @cil_ldelem_u1 +| 146 = @cil_ldelem_i2 +| 147 = @cil_ldelem_u2 +| 148 = @cil_ldelem_i4 +| 149 = @cil_ldelem_u4 +| 150 = @cil_ldelem_i8 +| 151 = @cil_ldelem_i +| 152 = @cil_ldelem_r4 +| 153 = @cil_ldelem_r8 +| 154 = @cil_ldelem_ref +| 155 = @cil_stelem_i +| 156 = @cil_stelem_i1 +| 157 = @cil_stelem_i2 +| 158 = @cil_stelem_i4 +| 159 = @cil_stelem_i8 +| 160 = @cil_stelem_r4 +| 161 = @cil_stelem_r8 +| 162 = @cil_stelem_ref +| 163 = @cil_ldelem +| 164 = @cil_stelem +| 165 = @cil_unbox_any +| 179 = @cil_conv_ovf_i1 +| 180 = @cil_conv_ovf_u1 +| 181 = @cil_conv_ovf_i2 +| 182 = @cil_conv_ovf_u2 +| 183 = @cil_conv_ovf_i4 +| 184 = @cil_conv_ovf_u4 +| 185 = @cil_conv_ovf_i8 +| 186 = @cil_conv_ovf_u8 +| 194 = @cil_refanyval +| 195 = @cil_ckinfinite +| 198 = @cil_mkrefany +| 208 = @cil_ldtoken +| 209 = @cil_conv_u2 +| 210 = @cil_conv_u1 +| 211 = @cil_conv_i +| 212 = @cil_conv_ovf_i +| 213 = @cil_conv_ovf_u +| 214 = @cil_add_ovf +| 215 = @cil_add_ovf_un +| 216 = @cil_mul_ovf +| 217 = @cil_mul_ovf_un +| 218 = @cil_sub_ovf +| 219 = @cil_sub_ovf_un +| 220 = @cil_endfinally +| 221 = @cil_leave +| 222 = @cil_leave_s +| 223 = @cil_stind_i +| 224 = @cil_conv_u +| 65024 = @cil_arglist +| 65025 = @cil_ceq +| 65026 = @cil_cgt +| 65027 = @cil_cgt_un +| 65028 = @cil_clt +| 65029 = @cil_clt_un +| 65030 = @cil_ldftn +| 65031 = @cil_ldvirtftn +| 65033 = @cil_ldarg +| 65034 = @cil_ldarga +| 65035 = @cil_starg +| 65036 = @cil_ldloc +| 65037 = @cil_ldloca +| 65038 = @cil_stloc +| 65039 = @cil_localloc +| 65041 = @cil_endfilter +| 65042 = @cil_unaligned +| 65043 = @cil_volatile +| 65044 = @cil_tail +| 65045 = @cil_initobj +| 65046 = @cil_constrained +| 65047 = @cil_cpblk +| 65048 = @cil_initblk +| 65050 = @cil_rethrow +| 65052 = @cil_sizeof +| 65053 = @cil_refanytype +| 65054 = @cil_readonly +; + +// CIL ignored instructions + +@cil_ignore = @cil_nop | @cil_break | @cil_volatile | @cil_unaligned; + +// CIL local/parameter/field access + +@cil_ldarg_any = @cil_ldarg_0 | @cil_ldarg_1 | @cil_ldarg_2 | @cil_ldarg_3 | @cil_ldarg_s | @cil_ldarga_s | @cil_ldarg | @cil_ldarga; +@cil_starg_any = @cil_starg | @cil_starg_s; + +@cil_ldloc_any = @cil_ldloc_0 | @cil_ldloc_1 | @cil_ldloc_2 | @cil_ldloc_3 | @cil_ldloc_s | @cil_ldloca_s | @cil_ldloc | @cil_ldloca; +@cil_stloc_any = @cil_stloc_0 | @cil_stloc_1 | @cil_stloc_2 | @cil_stloc_3 | @cil_stloc_s | @cil_stloc; + +@cil_ldfld_any = @cil_ldfld | @cil_ldsfld | @cil_ldsflda | @cil_ldflda; +@cil_stfld_any = @cil_stfld | @cil_stsfld; + +@cil_local_access = @cil_stloc_any | @cil_ldloc_any; +@cil_arg_access = @cil_starg_any | @cil_ldarg_any; +@cil_read_access = @cil_ldloc_any | @cil_ldarg_any | @cil_ldfld_any; +@cil_write_access = @cil_stloc_any | @cil_starg_any | @cil_stfld_any; + +@cil_stack_access = @cil_local_access | @cil_arg_access; +@cil_field_access = @cil_ldfld_any | @cil_stfld_any; + +@cil_access = @cil_read_access | @cil_write_access; + +// CIL constant/literal instructions + +@cil_ldc_i = @cil_ldc_i4_any | @cil_ldc_i8; + +@cil_ldc_i4_any = @cil_ldc_i4_m1 | @cil_ldc_i4_0 | @cil_ldc_i4_1 | @cil_ldc_i4_2 | @cil_ldc_i4_3 | + @cil_ldc_i4_4 | @cil_ldc_i4_5 | @cil_ldc_i4_6 | @cil_ldc_i4_7 | @cil_ldc_i4_8 | @cil_ldc_i4_s | @cil_ldc_i4; + +@cil_ldc_r = @cil_ldc_r4 | @cil_ldc_r8; + +@cil_literal = @cil_ldnull | @cil_ldc_i | @cil_ldc_r | @cil_ldstr; + +// Control flow + +@cil_conditional_jump = @cil_binary_jump | @cil_unary_jump; +@cil_binary_jump = @cil_beq_s | @cil_bge_s | @cil_bgt_s | @cil_ble_s | @cil_blt_s | + @cil_bne_un_s | @cil_bge_un_s | @cil_bgt_un_s | @cil_ble_un_s | @cil_blt_un_s | + @cil_beq | @cil_bge | @cil_bgt | @cil_ble | @cil_blt | + @cil_bne_un | @cil_bge_un | @cil_bgt_un | @cil_ble_un | @cil_blt_un; +@cil_unary_jump = @cil_brfalse_s | @cil_brtrue_s | @cil_brfalse | @cil_brtrue | @cil_switch; +@cil_unconditional_jump = @cil_br | @cil_br_s | @cil_leave_any; +@cil_leave_any = @cil_leave | @cil_leave_s; +@cil_jump = @cil_unconditional_jump | @cil_conditional_jump; + +// CIL call instructions + +@cil_call_any = @cil_jmp | @cil_call | @cil_calli | @cil_tail | @cil_callvirt | @cil_newobj; + +// CIL expression instructions + +@cil_expr = @cil_literal | @cil_binary_expr | @cil_unary_expr | @cil_call_any | @cil_read_access | + @cil_newarr | @cil_ldtoken | @cil_sizeof | + @cil_ldftn | @cil_ldvirtftn | @cil_localloc | @cil_mkrefany | @cil_refanytype | @cil_arglist | @cil_dup; + +@cil_unary_expr = + @cil_conversion_operation | @cil_unary_arithmetic_operation | @cil_unary_bitwise_operation| + @cil_ldlen | @cil_isinst | @cil_box | @cil_ldobj | @cil_castclass | @cil_unbox_any | + @cil_ldind | @cil_unbox; + +@cil_conversion_operation = + @cil_conv_i1 | @cil_conv_i2 | @cil_conv_i4 | @cil_conv_i8 | + @cil_conv_u1 | @cil_conv_u2 | @cil_conv_u4 | @cil_conv_u8 | + @cil_conv_ovf_i | @cil_conv_ovf_i_un | @cil_conv_ovf_i1 | @cil_conv_ovf_i1_un | + @cil_conv_ovf_i2 | @cil_conv_ovf_i2_un | @cil_conv_ovf_i4 | @cil_conv_ovf_i4_un | + @cil_conv_ovf_i8 | @cil_conv_ovf_i8_un | @cil_conv_ovf_u | @cil_conv_ovf_u_un | + @cil_conv_ovf_u1 | @cil_conv_ovf_u1_un | @cil_conv_ovf_u2 | @cil_conv_ovf_u2_un | + @cil_conv_ovf_u4 | @cil_conv_ovf_u4_un | @cil_conv_ovf_u8 | @cil_conv_ovf_u8_un | + @cil_conv_r4 | @cil_conv_r8 | @cil_conv_ovf_u2 | @cil_conv_ovf_u2_un | + @cil_conv_i | @cil_conv_u | @cil_conv_r_un; + +@cil_ldind = @cil_ldind_i | @cil_ldind_i1 | @cil_ldind_i2 | @cil_ldind_i4 | @cil_ldind_i8 | + @cil_ldind_r4 | @cil_ldind_r8 | @cil_ldind_ref | @cil_ldind_u1 | @cil_ldind_u2 | @cil_ldind_u4; + +@cil_stind = @cil_stind_i | @cil_stind_i1 | @cil_stind_i2 | @cil_stind_i4 | @cil_stind_i8 | + @cil_stind_r4 | @cil_stind_r8 | @cil_stind_ref; + +@cil_bitwise_operation = @cil_binary_bitwise_operation | @cil_unary_bitwise_operation; + +@cil_binary_bitwise_operation = @cil_and | @cil_or | @cil_xor | @cil_shr | @cil_shr | @cil_shr_un | @cil_shl; + +@cil_binary_arithmetic_operation = @cil_add | @cil_sub | @cil_mul | @cil_div | @cil_div_un | + @cil_rem | @cil_rem_un | @cil_add_ovf | @cil_add_ovf_un | @cil_mul_ovf | @cil_mul_ovf_un | + @cil_sub_ovf | @cil_sub_ovf_un; + +@cil_unary_bitwise_operation = @cil_not; + +@cil_binary_expr = @cil_binary_arithmetic_operation | @cil_binary_bitwise_operation | @cil_read_array | @cil_comparison_operation; + +@cil_unary_arithmetic_operation = @cil_neg; + +@cil_comparison_operation = @cil_cgt_un | @cil_ceq | @cil_cgt | @cil_clt | @cil_clt_un; + +// Elements that retrieve an address of something +@cil_read_ref = @cil_ldloca_s | @cil_ldarga_s | @cil_ldflda | @cil_ldsflda | @cil_ldelema; + +// CIL array instructions + +@cil_read_array = + @cil_ldelem | @cil_ldelema | @cil_ldelem_i1 | @cil_ldelem_ref | @cil_ldelem_i | + @cil_ldelem_i1 | @cil_ldelem_i2 | @cil_ldelem_i4 | @cil_ldelem_i8 | @cil_ldelem_r4 | + @cil_ldelem_r8 | @cil_ldelem_u1 | @cil_ldelem_u2 | @cil_ldelem_u4; + +@cil_write_array = @cil_stelem | @cil_stelem_ref | + @cil_stelem_i | @cil_stelem_i1 | @cil_stelem_i2 | @cil_stelem_i4 | @cil_stelem_i8 | + @cil_stelem_r4 | @cil_stelem_r8; + +@cil_throw_any = @cil_throw | @cil_rethrow; + +#keyset[impl, index] +cil_instruction( + unique int id: @cil_instruction, + int opcode: int ref, + int index: int ref, + int impl: @cil_method_implementation ref); + +cil_jump( + unique int instruction: @cil_jump ref, + int target: @cil_instruction ref); + +cil_access( + unique int instruction: @cil_instruction ref, + int target: @cil_accessible ref); + +cil_value( + unique int instruction: @cil_literal ref, + varchar(900) value: string ref); + +#keyset[instruction, index] +cil_switch( + int instruction: @cil_switch ref, + int index: int ref, + int target: @cil_instruction ref); + +cil_instruction_location( + unique int id: @cil_instruction ref, + int loc: @location ref); + +cil_type_location( + int id: @cil_type ref, + int loc: @location ref); + +cil_method_location( + int id: @cil_method ref, + int loc: @location ref); + +@cil_namespace = @namespace; + +@cil_type_container = @cil_type | @cil_namespace | @cil_method; + +case @cil_type.kind of + 0 = @cil_valueorreftype +| 1 = @cil_typeparameter +| 2 = @cil_array_type +| 3 = @cil_pointer_type +; + +cil_type( + unique int id: @cil_type, + varchar(900) name: string ref, + int kind: int ref, + int parent: @cil_type_container ref, + int sourceDecl: @cil_type ref); + +cil_pointer_type( + unique int id: @cil_pointer_type ref, + int pointee: @cil_type ref); + +cil_array_type( + unique int id: @cil_array_type ref, + int element_type: @cil_type ref, + int rank: int ref); + +cil_method( + unique int id: @cil_method, + varchar(900) name: string ref, + int parent: @cil_type ref, + int return_type: @cil_type ref); + +cil_method_source_declaration( + unique int method: @cil_method ref, + int source: @cil_method ref); + +cil_method_implementation( + unique int id: @cil_method_implementation, + int method: @cil_method ref, + int location: @assembly ref); + +cil_implements( + int id: @cil_method ref, + int decl: @cil_method ref); + +#keyset[parent, name] +cil_field( + unique int id: @cil_field, + int parent: @cil_type ref, + varchar(900) name: string ref, + int field_type: @cil_type ref); + +@cil_element = @cil_instruction | @cil_declaration | @cil_handler | @cil_attribute | @cil_namespace; +@cil_named_element = @cil_declaration | @cil_namespace; +@cil_declaration = @cil_variable | @cil_method | @cil_type | @cil_member; +@cil_accessible = @cil_declaration; +@cil_variable = @cil_field | @cil_stack_variable; +@cil_stack_variable = @cil_local_variable | @cil_parameter; +@cil_member = @cil_method | @cil_type | @cil_field | @cil_property | @cil_event; + +#keyset[method, index] +cil_parameter( + unique int id: @cil_parameter, + int method: @cil_method ref, + int index: int ref, + int param_type: @cil_type ref); + +cil_parameter_in(unique int id: @cil_parameter ref); +cil_parameter_out(unique int id: @cil_parameter ref); + +cil_setter(unique int prop: @cil_property ref, + int method: @cil_method ref); + +cil_getter(unique int prop: @cil_property ref, + int method: @cil_method ref); + +cil_adder(unique int event: @cil_event ref, + int method: @cil_method ref); + +cil_remover(unique int event: @cil_event ref, int method: @cil_method ref); + +cil_raiser(unique int event: @cil_event ref, int method: @cil_method ref); + +cil_property( + unique int id: @cil_property, + int parent: @cil_type ref, + varchar(900) name: string ref, + int property_type: @cil_type ref); + +#keyset[parent, name] +cil_event(unique int id: @cil_event, + int parent: @cil_type ref, + varchar(900) name: string ref, + int event_type: @cil_type ref); + +#keyset[impl, index] +cil_local_variable( + unique int id: @cil_local_variable, + int impl: @cil_method_implementation ref, + int index: int ref, + int var_type: @cil_type ref); + +// CIL handlers (exception handlers etc). + +case @cil_handler.kind of + 0 = @cil_catch_handler +| 1 = @cil_filter_handler +| 2 = @cil_finally_handler +| 4 = @cil_fault_handler +; + +#keyset[impl, index] +cil_handler( + unique int id: @cil_handler, + int impl: @cil_method_implementation ref, + int index: int ref, + int kind: int ref, + int try_start: @cil_instruction ref, + int try_end: @cil_instruction ref, + int handler_start: @cil_instruction ref); + +cil_handler_filter( + unique int id: @cil_handler ref, + int filter_start: @cil_instruction ref); + +cil_handler_type( + unique int id: @cil_handler ref, + int catch_type: @cil_type ref); + +@cil_controlflow_node = @cil_entry_point | @cil_instruction; + +@cil_entry_point = @cil_method_implementation | @cil_handler; + +@cil_dataflow_node = @cil_instruction | @cil_variable | @cil_method; + +cil_method_stack_size( + unique int method: @cil_method_implementation ref, + int size: int ref); + +// CIL modifiers + +cil_public(int id: @cil_member ref); +cil_private(int id: @cil_member ref); +cil_protected(int id: @cil_member ref); +cil_internal(int id: @cil_member ref); +cil_static(int id: @cil_member ref); +cil_sealed(int id: @cil_member ref); +cil_virtual(int id: @cil_method ref); +cil_abstract(int id: @cil_member ref); +cil_class(int id: @cil_type ref); +cil_interface(int id: @cil_type ref); +cil_security(int id: @cil_member ref); +cil_requiresecobject(int id: @cil_method ref); +cil_specialname(int id: @cil_method ref); +cil_newslot(int id: @cil_method ref); + +cil_base_class(unique int id: @cil_type ref, int base: @cil_type ref); +cil_base_interface(int id: @cil_type ref, int base: @cil_type ref); + +#keyset[unbound, index] +cil_type_parameter( + int unbound: @cil_member ref, + int index: int ref, + int param: @cil_typeparameter ref); + +#keyset[bound, index] +cil_type_argument( + int bound: @cil_member ref, + int index: int ref, + int t: @cil_type ref); + +// CIL type parameter constraints + +cil_typeparam_covariant(int tp: @cil_typeparameter ref); +cil_typeparam_contravariant(int tp: @cil_typeparameter ref); +cil_typeparam_class(int tp: @cil_typeparameter ref); +cil_typeparam_struct(int tp: @cil_typeparameter ref); +cil_typeparam_new(int tp: @cil_typeparameter ref); +cil_typeparam_constraint(int tp: @cil_typeparameter ref, int supertype: @cil_type ref); + +// CIL attributes + +cil_attribute( + unique int attributeid: @cil_attribute, + int element: @cil_declaration ref, + int constructor: @cil_method ref); + +#keyset[attribute_id, param] +cil_attribute_named_argument( + int attribute_id: @cil_attribute ref, + varchar(100) param: string ref, + varchar(900) value: string ref); + +#keyset[attribute_id, index] +cil_attribute_positional_argument( + int attribute_id: @cil_attribute ref, + int index: int ref, + varchar(900) value: string ref); + + +// Common .Net data model covering both C# and CIL + +// Common elements +@dotnet_element = @element | @cil_element; +@dotnet_named_element = @named_element | @cil_named_element; +@dotnet_callable = @callable | @cil_method; +@dotnet_variable = @variable | @cil_variable; +@dotnet_field = @field | @cil_field; +@dotnet_parameter = @parameter | @cil_parameter; +@dotnet_declaration = @declaration | @cil_declaration; +@dotnet_member = @member | @cil_member; +@dotnet_event = @event | @cil_event; +@dotnet_property = @property | @cil_property | @indexer; + +// Common types +@dotnet_type = @type | @cil_type; +@dotnet_call = @call | @cil_call_any; +@dotnet_throw = @throw_element | @cil_throw_any; +@dotnet_valueorreftype = @cil_valueorreftype | @value_or_ref_type | @cil_array_type | @void_type; +@dotnet_typeparameter = @type_parameter | @cil_typeparameter; +@dotnet_array_type = @array_type | @cil_array_type; +@dotnet_pointer_type = @pointer_type | @cil_pointer_type; +@dotnet_type_parameter = @type_parameter | @cil_typeparameter; +@dotnet_generic = @dotnet_valueorreftype | @dotnet_callable; + +// Attributes +@dotnet_attribute = @attribute | @cil_attribute; + +// Expressions +@dotnet_expr = @expr | @cil_expr; + +// Literals +@dotnet_literal = @literal_expr | @cil_literal; +@dotnet_string_literal = @string_literal_expr | @cil_ldstr; +@dotnet_int_literal = @integer_literal_expr | @cil_ldc_i; +@dotnet_float_literal = @float_literal_expr | @cil_ldc_r; +@dotnet_null_literal = @null_literal_expr | @cil_ldnull; + +@metadata_entity = @cil_method | @cil_type | @cil_field | @cil_property | @field | @property | + @callable | @value_or_ref_type | @void_type; + +#keyset[entity, location] +metadata_handle(int entity : @metadata_entity ref, int location: @assembly ref, int handle: int ref) diff --git a/docs/codeql/README.rst b/docs/codeql/README.rst index 39c4d18cd55..c7ea08519da 100644 --- a/docs/codeql/README.rst +++ b/docs/codeql/README.rst @@ -105,6 +105,6 @@ Viewing the current version of the CodeQL documentation ******************************************************* The documentation for the most recent release is -published to `help.semmle.com <https://help.semmle.com>`__. +published to `codeql.github.com <https://codeql.github.com>`__. There, you can find the documentation for the CodeQL queries, -the CodeQL standard libraries, and LGTM Enterprise. +the CodeQL standard libraries, and can learn about CodeQL. diff --git a/docs/codeql/_static/custom.css_t b/docs/codeql/_static/custom.css_t index 927660034fe..e8667ede93a 100644 --- a/docs/codeql/_static/custom.css_t +++ b/docs/codeql/_static/custom.css_t @@ -34,6 +34,10 @@ article { min-height: calc(100vh - 145px); /* Makes sure GitHub footer stays at bottom of viewport */ } +article ul, article ol { + margin-left: 18px; /* Aligns list items with other text */ +} + /* -- SIDEBAR ------------------------------------------------------------------------------- */ .SideNav { @@ -181,6 +185,11 @@ table.docutils.footnote { margin-left: 10px; } +table.footnote td.label { + padding-right: 10px; + display: table-cell; +} + /* -- STYLE PULL-QUOTE AS ADMONITION WHILE DOCS STILL PARSED FOR LGTM EMBEDDED HELP------------------------- */ blockquote.pull-quote { @@ -191,7 +200,7 @@ blockquote.pull-quote { border-radius: 5px; } -blockquote.pull-quote p:first-of-type { +blockquote.pull-quote:first-line { font-weight: bold; margin-top: 0px; } @@ -213,10 +222,12 @@ blockquote.pull-quote > :last-child { .toggle .name:after { content: " ▶"; + font-family: "monospace"; } .toggle .name.open:after { content: " ▼"; + font-family: "monospace"; } /* -- PRINT VIEW ----------------------------------------------------------------------------*/ @@ -252,4 +263,4 @@ blockquote.pull-quote > :last-child { div.footer { display: block; } -} \ No newline at end of file +} diff --git a/docs/codeql/_templates/layout.html b/docs/codeql/_templates/layout.html index 46ce61398f9..e5c6a5d67e6 100644 --- a/docs/codeql/_templates/layout.html +++ b/docs/codeql/_templates/layout.html @@ -38,7 +38,7 @@ {%- block content %} <header class="Header"> <div class="Header-item--full"> - <a href="{{ pathto(master_doc) }}" class="Header-link f2 d-flex flex-items-center"> + <a href="https://codeql.github.com/docs" class="Header-link f2 d-flex flex-items-center"> <!-- <%= octicon "mark-github", class: "mr-2", height: 32 %> --> <svg height="32" class="octicon octicon-mark-github mr-2" viewBox="0 0 16 16" version="1.1" width="32" aria-hidden="true"> @@ -46,19 +46,11 @@ d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.013 8.013 0 0 0 16 8c0-4.42-3.58-8-8-8z"> </path> </svg> - <span class="hide-sm">{{ project }}</span> + <span class="hide-sm">CodeQL documentation</span> </a> </div> <div class="Header-item hide-sm hide-md"> - <form class="search" action="{{ pathto('search') }}" method="get"> - <input class="form-control input-dark" type="text" name="q" placeholder="Search" /> - <input class="btn" type="submit" value="Search" /> - <input type="hidden" name="check_keywords" value="yes" /> - <input type="hidden" name="area" value="default" /> - </form> - <script type="text/javascript">$('#searchbox').show(0);</script> - - <div class="clearer"></div> + <script src="https://addsearch.com/js/?key=93b4d287e2fc079a4089412b669785d5&categories=!0xhelp.semmle.com,0xcodeql.github.com,1xdocs,1xcodeql-standard-libraries,1xcodeql-query-help"></script> </div> <div class="Header-item"> @@ -69,20 +61,30 @@ </summary> <ul class="dropdown-menu dropdown-menu-se dropdown-menu-dark"> + <li><a class="dropdown-item" href="https://codeql.github.com/docs/codeql-overview">CodeQL overview</a></li> + <li class="dropdown-divider" role="separator"></li> <div class="dropdown-header"> - Help docs + CodeQL tools </div> - <li><a class="dropdown-item" href="https://help.semmle.com/QL/learn-ql/">Learn CodeQL</a></li> - <li><a class="dropdown-item" href="https://help.semmle.com/codeql/codeql-tools.html">CodeQL tools</a> + <li><a class="dropdown-item" href="https://codeql.github.com/docs/codeql-for-visual-studio-code">CodeQL for VS Code</a> + <li><a class="dropdown-item" href="https://codeql.github.com/docs/codeql-cli">CodeQL CLI</a> </li> <li class="dropdown-divider" role="separator"></li> + <div class="dropdown-header"> + CodeQL guides + </div> + <li><a class="dropdown-item" href="https://codeql.github.com/docs/writing-codeql-queries">Writing CodeQL queries</a></li> + <li><a class="dropdown-item" href="https://codeql.github.com/docs/codeql-language-guides">CodeQL language guides</a> + <li class="dropdown-divider" role="separator"></li> <div class="dropdown-header"> Reference docs </div> - <li><a class="dropdown-item" href="https://help.semmle.com/QL/ql-handbook/">QL language reference</a> - <li><a class="dropdown-item" href="https://help.semmle.com/QL/ql-libraries.html">CodeQL libraries</a> - <li><a class="dropdown-item" href="https://help.semmle.com/QL/ql-built-in-queries.html">CodeQL - queries</a> + <li><a class="dropdown-item" href="https://codeql.github.com/docs/ql-language-reference/">QL language + reference</a> + <li><a class="dropdown-item" href="https://codeql.github.com/codeql-standard-libraries">CodeQL + standard-libraries</a> + <li><a class="dropdown-item" href="https://codeql.github.com/codeql-query-help">CodeQL + query help</a> <li class="dropdown-divider" role="separator"></li> <div class="dropdown-header"> Source files @@ -163,7 +165,7 @@ </li> </ul> <ul class="list-style-none d-flex text-gray"> - <li class="mr-3">© 2020 GitHub, Inc.</li> + <li class="mr-3">© 2021 GitHub, Inc.</li> <li class="mr-3"><a href="https://docs.github.com/github/site-policy/github-terms-of-service" class="link-gray">Terms </a></li> diff --git a/docs/codeql/codeql-cli/codeql-cli-reference/about-ql-packs.rst b/docs/codeql/codeql-cli/about-ql-packs.rst similarity index 94% rename from docs/codeql/codeql-cli/codeql-cli-reference/about-ql-packs.rst rename to docs/codeql/codeql-cli/about-ql-packs.rst index 39769f1f79c..200dadc173b 100644 --- a/docs/codeql/codeql-cli/codeql-cli-reference/about-ql-packs.rst +++ b/docs/codeql/codeql-cli/about-ql-packs.rst @@ -21,7 +21,7 @@ files and directories within the pack should be logically organized. For example - Queries are organized into directories for specific categories. - Queries for specific products, libraries, and frameworks are organized into their own top-level directories. -- There is a top-level directory named ``<owner>/<ql-language-specification>`` for query library +- There is a top-level directory named ``<owner>/<language>`` for query library (``.qll``) files. Within this directory, ``.qll`` files should be organized into subdirectories for specific categories. @@ -57,6 +57,8 @@ from any location in the pack by declaring ``import mycompany.java.CustomSinks`` For more information, see ":ref:`Importing modules <importing-modules>`" in the QL language reference. +.. _qlpack-yml-properties: + ``qlpack.yml`` properties ~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -85,11 +87,11 @@ The following properties are supported in ``qlpack.yml`` files. * - ``suites`` - ``suites`` - Optional - - The path to a directory that contains the "well-known" query suites in the pack, defined relative to the pack directory. You can run "well-known" suites stored in this directory by specifying the pack name, without providing their full path. To use query suites stored in other directories in the pack, you must provide their full path. For more information about query suites, see ":doc:`Creating CodeQL query suites <../using-the-codeql-cli/creating-codeql-query-suites>`." + - The path to a directory that contains the "well-known" query suites in the pack, defined relative to the pack directory. You can run "well-known" suites stored in this directory by specifying the pack name, without providing their full path. To use query suites stored in other directories in the pack, you must provide their full path. For more information about query suites, see ":doc:`Creating CodeQL query suites <creating-codeql-query-suites>`." * - ``extractor`` - ``javascript`` - All test packs - - The CodeQL language extractor to use when the CLI creates a database from test files in the pack. For more information about testing queries, see ":doc:`Testing custom queries <../using-the-codeql-cli/testing-custom-queries>`." + - The CodeQL language extractor to use when the CLI creates a database from test files in the pack. For more information about testing queries, see ":doc:`Testing custom queries <testing-custom-queries>`." * - ``tests`` - ``.`` - Optional for test packs @@ -101,7 +103,7 @@ The following properties are supported in ``qlpack.yml`` files. * - ``upgrades`` - ``.`` - Packs with upgrades - - The path to a directory within the pack that contains upgrade scripts, defined relative to the pack directory. The ``database upgrade`` action uses these scripts to update databases that were created by an older version of an extractor so they're compatible with the current extractor (see `Upgrade scripts for a language <upgrade-scripts-for-a-language>`__ below.) + - The path to a directory within the pack that contains upgrade scripts, defined relative to the pack directory. The ``database upgrade`` action uses these scripts to update databases that were created by an older version of an extractor so they're compatible with the current extractor (see `Upgrade scripts for a language <#upgrade-scripts-for-a-language>`__ below.) .. _custom-ql-packs: @@ -124,7 +126,7 @@ and ``libraryPathDependencies`` properties. If the pack contains query suites, y use the ``suites`` property to define their location. Query suites defined here are called "well-known" suites, and can be used on the command line by referring to their name only, rather than their full path. -For more information about query suites, see ":doc:`Creating CodeQL query suites <../using-the-codeql-cli/creating-codeql-query-suites>`." +For more information about query suites, see ":doc:`Creating CodeQL query suites <creating-codeql-query-suites>`." For example, a ``qlpack.yml`` file for a QL pack featuring custom C++ queries and libraries may contain: @@ -154,10 +156,10 @@ For custom QL packs containing test files, you also need to include an ``extractor`` property so that the ``test run`` command knows how to create test databases. You may also wish to specify the ``tests`` property. -.. include:: ../../reusables/test-qlpack.rst +.. include:: ../reusables/test-qlpack.rst For more information about running tests, see ":doc:`Testing custom queries -<../using-the-codeql-cli/testing-custom-queries>`." +<testing-custom-queries>`." .. _standard-ql-packs: diff --git a/docs/codeql/codeql-cli/using-the-codeql-cli/about-the-codeql-cli.rst b/docs/codeql/codeql-cli/about-the-codeql-cli.rst similarity index 94% rename from docs/codeql/codeql-cli/using-the-codeql-cli/about-the-codeql-cli.rst rename to docs/codeql/codeql-cli/about-the-codeql-cli.rst index 87f9f0f5d5a..4e278c47de6 100644 --- a/docs/codeql/codeql-cli/using-the-codeql-cli/about-the-codeql-cli.rst +++ b/docs/codeql/codeql-cli/about-the-codeql-cli.rst @@ -26,4 +26,4 @@ command line. To run a command, use:: codeql [command] [subcommand] To view the reference documentation for a command, add the ``--help`` flag, or visit the -"`CodeQL CLI manual <../../codeql-cli-manual>`__." +"`CodeQL CLI manual <../manual>`__." diff --git a/docs/codeql/codeql-cli/using-the-codeql-cli/analyzing-databases-with-the-codeql-cli.rst b/docs/codeql/codeql-cli/analyzing-databases-with-the-codeql-cli.rst similarity index 95% rename from docs/codeql/codeql-cli/using-the-codeql-cli/analyzing-databases-with-the-codeql-cli.rst rename to docs/codeql/codeql-cli/analyzing-databases-with-the-codeql-cli.rst index daf92ceb4bb..60126d12d0a 100644 --- a/docs/codeql/codeql-cli/using-the-codeql-cli/analyzing-databases-with-the-codeql-cli.rst +++ b/docs/codeql/codeql-cli/analyzing-databases-with-the-codeql-cli.rst @@ -11,7 +11,7 @@ CodeQL analyses produce :ref:`interpreted results For information about writing queries to run with ``database analyze``, see ":doc:`Using custom queries with the CodeQL CLI <using-custom-queries-with-the-codeql-cli>`." -.. include:: ../../reusables/advanced-query-execution.rst +.. include:: ../reusables/advanced-query-execution.rst Before starting an analysis you must: @@ -49,13 +49,13 @@ You must specify: <sarif-file>`, and graph formats. For more information about CSV and SARIF, see `Results <#results>`__. To find out which other results formats are supported, see the `database analyze reference - <../codeql-cli-manual/database-analyze.html>`__. + <../manual/database-analyze>`__. - ``--output``: the output path of the results file generated during analysis. You can also specify: -- .. include:: ../../reusables/threads-query-execution.rst +- .. include:: ../reusables/threads-query-execution.rst .. pull-quote:: @@ -70,7 +70,7 @@ You can also specify: <upgrading-codeql-databases>`." For full details of all the options you can use when analyzing databases, see -the `database analyze reference documentation <../codeql-cli-manual/database-analyze.html>`__. +the `database analyze reference documentation <../manual/database-analyze>`__. .. _database-analyze-examples: @@ -149,7 +149,7 @@ recursively, so any queries contained in subfolders will also be executed. Important You shouldn't specify the root of a :doc:`QL pack - <../codeql-cli-reference/about-ql-packs>` when executing ``database analyze`` + <about-ql-packs>` when executing ``database analyze`` as it contains some special queries that aren't designed to be used with the command. Rather, to run a wide range of useful queries, run one of the LGTM.com query suites. @@ -171,7 +171,7 @@ You can save analysis results in a number of different formats, including SARIF and CSV. The SARIF format is designed to represent the output of a broad range of static -analysis tools. For more information, see :doc:`SARIF output <../codeql-cli-reference/sarif-output>`. +analysis tools. For more information, see :doc:`SARIF output <sarif-output>`. If you choose to generate results in CSV format, then each line in the output file corresponds to an alert. Each line is a comma-separated list with the following information: diff --git a/docs/codeql/codeql-cli/codeql-cli-reference/index.rst b/docs/codeql/codeql-cli/codeql-cli-reference.rst similarity index 95% rename from docs/codeql/codeql-cli/codeql-cli-reference/index.rst rename to docs/codeql/codeql-cli/codeql-cli-reference.rst index fe19123893b..75513a06b54 100644 --- a/docs/codeql/codeql-cli/codeql-cli-reference/index.rst +++ b/docs/codeql/codeql-cli/codeql-cli-reference.rst @@ -28,4 +28,4 @@ CodeQL CLI manual ----------------- To view detailed information about each CodeQL CLI command, -including its usage and options, add the ``--help`` flag or visit the "`CodeQL CLI manual <../codeql-cli-manual>`__." +including its usage and options, add the ``--help`` flag or visit the "`CodeQL CLI manual <../manual>`__." diff --git a/docs/codeql/codeql-cli/using-the-codeql-cli/creating-codeql-databases.rst b/docs/codeql/codeql-cli/creating-codeql-databases.rst similarity index 97% rename from docs/codeql/codeql-cli/using-the-codeql-cli/creating-codeql-databases.rst rename to docs/codeql/codeql-cli/creating-codeql-databases.rst index e7248e5725f..73fa4fb4818 100644 --- a/docs/codeql/codeql-cli/using-the-codeql-cli/creating-codeql-databases.rst +++ b/docs/codeql/codeql-cli/creating-codeql-databases.rst @@ -35,7 +35,7 @@ You must specify: - ``--language``: the identifier for the language to create a database for. CodeQL supports creating databases for the following languages: - .. include:: ../../reusables/extractors.rst + .. include:: ../reusables/extractors.rst Other options may be specified depending on the location of your source file and the language you want to analyze: @@ -50,7 +50,7 @@ the language you want to analyze: detect the build system automatically, using a built-in autobuilder. For full details of all the options you can use when creating databases, -see the `database create reference documentation <../codeql-cli-manual/database-create.html>`__. +see the `database create reference documentation <../manual/database-create>`__. Progress and results -------------------- @@ -75,7 +75,7 @@ CodeQL. For each project on LGTM.com, you can download an archived CodeQL database corresponding to the most recently analyzed revision of the code. These databases can also be analyzed using the CodeQL CLI. -.. include:: ../../reusables/download-lgtm-database.rst +.. include:: ../reusables/download-lgtm-database.rst Before running an analysis, unzip the databases and try :doc:`upgrading <upgrading-codeql-databases>` the unzipped databases to ensure they are compatible with your local copy of the @@ -85,7 +85,7 @@ CodeQL queries and libraries. Note - .. include:: ../../reusables/index-files-note.rst + .. include:: ../reusables/index-files-note.rst Creating databases for non-compiled languages --------------------------------------------- diff --git a/docs/codeql/codeql-cli/using-the-codeql-cli/creating-codeql-query-suites.rst b/docs/codeql/codeql-cli/creating-codeql-query-suites.rst similarity index 97% rename from docs/codeql/codeql-cli/using-the-codeql-cli/creating-codeql-query-suites.rst rename to docs/codeql/codeql-cli/creating-codeql-query-suites.rst index 75c7113b4a9..04de07c5c33 100644 --- a/docs/codeql/codeql-cli/using-the-codeql-cli/creating-codeql-query-suites.rst +++ b/docs/codeql/codeql-cli/creating-codeql-query-suites.rst @@ -16,10 +16,10 @@ mapping with (usually) a single key. The instructions are executed in the order they appear in the query suite definition. After all the instructions in the suite definition have been executed, the result is a set of selected queries. -.. note:: +.. pull-quote:: Note Any custom queries that you want to add to a query suite must be in a :doc:`QL - pack <../codeql-cli-reference/about-ql-packs>` and contain the correct query metadata. + pack <about-ql-packs>` and contain the correct query metadata. For more information, see ":doc:`Using custom queries with the CodeQL CLI <using-custom-queries-with-the-codeql-cli>`." @@ -54,7 +54,7 @@ queries using: - qlpack: <qlpack-name> -.. note:: +.. pull-quote:: Note When pathnames appear in query suite definitions, they must always be given with a forward slash, ``/``, as a directory separator. @@ -234,7 +234,7 @@ instruction:: - description: <name-of-query-suite> This value is displayed when you run `codeql resolve queries -<../codeql-cli-manual/resolve-queries.html>`__, if the suite is added to a "well-known" +<../manual/resolve-queries>`__, if the suite is added to a "well-known" directory. For more information, see "`Specifying well-known query suites <#specifying-well-known-query-suites>`__." @@ -254,7 +254,7 @@ without providing their full path. This gives you a simple way of specifying a set of queries, without needing to search inside QL packs and distributions. To declare a directory that contains "well-known" query suites, add the directory to the ``suites`` property in the ``qlpack.yml`` file at the root of your QL pack. -For more information, see "`About QL packs <../codeql-cli-reference/qlpack-overview.html#qlpack-yml-properties>`__." +For more information, see ":ref:`About QL packs <qlpack-yml-properties>`." Using query suites with CodeQL ------------------------------ diff --git a/docs/codeql/codeql-cli/codeql-cli-reference/exit-codes.rst b/docs/codeql/codeql-cli/exit-codes.rst similarity index 82% rename from docs/codeql/codeql-cli/codeql-cli-reference/exit-codes.rst rename to docs/codeql/codeql-cli/exit-codes.rst index f313e4080d4..5d9a0d434b6 100644 --- a/docs/codeql/codeql-cli/codeql-cli-reference/exit-codes.rst +++ b/docs/codeql/codeql-cli/exit-codes.rst @@ -16,7 +16,7 @@ Success, normal termination. The command successfully determined that the answer to your question is "no". -This exit code is only used by a few commands, such as `codeql test run <../codeql-cli-manual/test-run.html>`__, `codeql database check <../codeql-cli-manual/dataset-check.html>`__, `codeql query format <../codeql-cli-manual/query-format.html>`__,and `codeql resolve extractor <../codeql-cli-manual/resolve-extractor.html>`__. +This exit code is only used by a few commands, such as `codeql test run <../manual/test-run>`__, `codeql database check <../manual/dataset-check>`__, `codeql query format <../manual/query-format>`__,and `codeql resolve extractor <../manual/resolve-extractor>`__. For more details, see the documentation for those commands. 2 @@ -37,7 +37,7 @@ In this case, the launcher can't start the Java code for the CodeQL CLI at all. 32 --- -The extractor didn't find any code to analyze when running `codeql database create <../codeql-cli-manual/database-create.html>`__ or `codeql database finalize <../codeql-cli-manual/database-finalize.html>`__. +The extractor didn't find any code to analyze when running `codeql database create <../manual/database-create>`__ or `codeql database finalize <../manual/database-finalize>`__. 33 --- diff --git a/docs/codeql/codeql-cli/using-the-codeql-cli/getting-started-with-the-codeql-cli.rst b/docs/codeql/codeql-cli/getting-started-with-the-codeql-cli.rst similarity index 98% rename from docs/codeql/codeql-cli/using-the-codeql-cli/getting-started-with-the-codeql-cli.rst rename to docs/codeql/codeql-cli/getting-started-with-the-codeql-cli.rst index 1cd0ce63eee..cb4cd413f25 100644 --- a/docs/codeql/codeql-cli/using-the-codeql-cli/getting-started-with-the-codeql-cli.rst +++ b/docs/codeql/codeql-cli/getting-started-with-the-codeql-cli.rst @@ -6,7 +6,7 @@ Getting started with the CodeQL CLI To run CodeQL commands, you need to set up the CLI so that it can access the tools, queries, and libraries required to create and analyze databases. -.. include:: ../../reusables/license-note.rst +.. include:: ../reusables/license-note.rst .. _setting-up-cli: @@ -115,7 +115,7 @@ repository should be ``$HOME/codeql-home/codeql-go``. Within these repositories, the queries and libraries are organized into QL packs. Along with the queries themselves, QL packs contain important metadata that tells the CodeQL CLI how to process the query files. For more information, -see ":doc:`About QL packs <../codeql-cli-reference/about-ql-packs>`." +see ":doc:`About QL packs <about-ql-packs>`." .. pull-quote:: Important @@ -184,7 +184,7 @@ executable in a couple of ways: can run the executable as just ``codeql``. At this point, you can execute CodeQL commands. For a full list of the CodeQL -CLI commands, see the "`CodeQL CLI manual <../../codeql-cli-manual>`__." +CLI commands, see the "`CodeQL CLI manual <../manual>`__." .. pull-quote:: Note diff --git a/docs/codeql/codeql-cli/index.rst b/docs/codeql/codeql-cli/index.rst index efa02e61e3c..07ec8431235 100644 --- a/docs/codeql/codeql-cli/index.rst +++ b/docs/codeql/codeql-cli/index.rst @@ -5,19 +5,17 @@ CodeQL CLI .. include:: ../reusables/codeql-cli-overview.rst -See the following links to learn how to get set up and run CodeQL commands: - - :ref:`Using the CodeQL CLI <using-the-codeql-cli>`: Software developers and security researchers can secure their code using the CodeQL CLI. - :ref:`CodeQL CLI reference <codeql-cli-reference>`: Learn more about the files you can use when running CodeQL processes and the results format and exit codes that CodeQL generates. -- `CodeQL CLI manual <codeql-cli-manual>`__: Detailed information about all the commands available with the CodeQL CLI. +- `CodeQL CLI manual <manual>`__: Detailed information about all the commands available with the CodeQL CLI. .. toctree:: :titlesonly: :hidden: - using-the-codeql-cli/index - codeql-cli-reference/index + using-the-codeql-cli + codeql-cli-reference diff --git a/docs/codeql/codeql-cli/codeql-cli-reference/query-reference-files.rst b/docs/codeql/codeql-cli/query-reference-files.rst similarity index 95% rename from docs/codeql/codeql-cli/codeql-cli-reference/query-reference-files.rst rename to docs/codeql/codeql-cli/query-reference-files.rst index e4bea0df72f..f19996aae29 100644 --- a/docs/codeql/codeql-cli/codeql-cli-reference/query-reference-files.rst +++ b/docs/codeql/codeql-cli/query-reference-files.rst @@ -44,4 +44,4 @@ to the ``codeql-javascript`` QL pack:: AngularJS/DeadAngularJSEventListener.ql -For another example, see `Testing custom queries <../using-the-codeql-cli/test-queries.html#example>`__. +For another example, see :doc:`Testing custom queries <testing-custom-queries>`. diff --git a/docs/codeql/codeql-cli/codeql-cli-reference/sarif-output.rst b/docs/codeql/codeql-cli/sarif-output.rst similarity index 99% rename from docs/codeql/codeql-cli/codeql-cli-reference/sarif-output.rst rename to docs/codeql/codeql-cli/sarif-output.rst index fca88ac8f2f..d9b10785851 100644 --- a/docs/codeql/codeql-cli/codeql-cli-reference/sarif-output.rst +++ b/docs/codeql/codeql-cli/sarif-output.rst @@ -11,7 +11,7 @@ considered "optional". This document details the output produced when using the format type ``sarifv2.1.0``, which corresponds to the SARIF v2.1.0.csd1 specification. For more information on selecting a file format for your analysis results, see -the `database analyze reference <../codeql-cli-manual/database-analyze.html>`__. +the `database analyze reference <../manual/database-analyze>`__. SARIF specification and schema ------------------------------ diff --git a/docs/codeql/codeql-cli/using-the-codeql-cli/specifying-command-options-in-a-codeql-configuration-file.rst b/docs/codeql/codeql-cli/specifying-command-options-in-a-codeql-configuration-file.rst similarity index 100% rename from docs/codeql/codeql-cli/using-the-codeql-cli/specifying-command-options-in-a-codeql-configuration-file.rst rename to docs/codeql/codeql-cli/specifying-command-options-in-a-codeql-configuration-file.rst diff --git a/docs/codeql/codeql-cli/using-the-codeql-cli/testing-custom-queries.rst b/docs/codeql/codeql-cli/testing-custom-queries.rst similarity index 96% rename from docs/codeql/codeql-cli/using-the-codeql-cli/testing-custom-queries.rst rename to docs/codeql/codeql-cli/testing-custom-queries.rst index 5746158e1de..3890703a83d 100644 --- a/docs/codeql/codeql-cli/using-the-codeql-cli/testing-custom-queries.rst +++ b/docs/codeql/codeql-cli/testing-custom-queries.rst @@ -44,7 +44,7 @@ file that defines: The ``libraryPathDependencies`` value specifies the CodeQL queries to test. The ``extractor`` defines which language the CLI will use to create test databases from the code files stored in this QL pack. -For more information, see ":doc:`About QL packs <../codeql-cli-reference/about-ql-packs>`." +For more information, see ":doc:`About QL packs <about-ql-packs>`." You may find it useful to look at the way query tests are organized in the `CodeQL repository <https://github.com/github/codeql>`__. @@ -70,7 +70,7 @@ Then add the following files to the subdirectory before you run the test command The location is defined relative to the root of the QL pack that contains the query. Usually, this is a QL pack specified by the ``libraryPathDependencies`` for the test pack. - For more information, see ":doc:`Query reference files <../codeql-cli-reference/query-reference-files>`." + For more information, see ":doc:`Query reference files <query-reference-files>`." You don't need to add a query reference file if the query you want to test is stored in the test directory, @@ -127,10 +127,10 @@ The ``<test|dir>`` argument can be one or more of the following: You can also specify: -- .. include:: ../../reusables/threads-query-execution.rst +- .. include:: ../reusables/threads-query-execution.rst For full details of all the options you can use when testing queries, -see the `test run reference documentation <../codeql-cli-manual/test-run.html>`__. +see the `test run reference documentation <../manual/test-run>`__. Example ------- @@ -172,13 +172,13 @@ Prepare a query and test files libraryPathDependencies: codeql-java For more information about QL packs, see ":doc:`About QL packs - <../codeql-cli-reference/about-ql-packs>`." + <about-ql-packs>`." #. Create a QL pack for your Java tests by adding a ``qlpack.yml`` file with the following contents to ``custom-queries/java/tests``, updating ``libraryPathDependencies`` to match the name of your QL pack of custom queries: - .. include:: ../../reusables/test-qlpack.rst + .. include:: ../reusables/test-qlpack.rst #. Within the Java test pack, create a directory to contain the test files associated with ``EmptyThen.ql``. diff --git a/docs/codeql/codeql-cli/using-the-codeql-cli/testing-query-help-files.rst b/docs/codeql/codeql-cli/testing-query-help-files.rst similarity index 96% rename from docs/codeql/codeql-cli/using-the-codeql-cli/testing-query-help-files.rst rename to docs/codeql/codeql-cli/testing-query-help-files.rst index 38e154f3f38..d8285eb57cc 100644 --- a/docs/codeql/codeql-cli/using-the-codeql-cli/testing-query-help-files.rst +++ b/docs/codeql/codeql-cli/testing-query-help-files.rst @@ -54,7 +54,7 @@ The ``--output`` option defines a file path where the rendered query help will b For full details of all the options you can use when testing query help files, see the `generate query-help reference documentation -<codeql-cli-manual:generate-query-help>`__. +<../manual/generate-query-help>`__. Results ------- @@ -73,7 +73,7 @@ By default, the CodeQL CLI will print a warning message if: as an accompanying ``.qhelp`` file You can tell the CodeQL CLI how to handle these warnings by including a ``--warnings`` option in your command. -For more information, see the `generate query-help reference documentation <../codeql-cli-manual/generate-query-help.html#cmdoption-codeql-generate-query-help-warnings>`__. +For more information, see the `generate query-help reference documentation <../manual/generate-query-help#cmdoption-codeql-generate-query-help-warnings>`__. Further reading --------------- diff --git a/docs/codeql/codeql-cli/using-the-codeql-cli/upgrading-codeql-databases.rst b/docs/codeql/codeql-cli/upgrading-codeql-databases.rst similarity index 95% rename from docs/codeql/codeql-cli/using-the-codeql-cli/upgrading-codeql-databases.rst rename to docs/codeql/codeql-cli/upgrading-codeql-databases.rst index 30636fbfa2c..d4f769bc538 100644 --- a/docs/codeql/codeql-cli/using-the-codeql-cli/upgrading-codeql-databases.rst +++ b/docs/codeql/codeql-cli/upgrading-codeql-databases.rst @@ -40,7 +40,7 @@ where ``<database>``, the path to the CodeQL database you want to upgrade, must be specified. For full details of all the options you can use when upgrading databases, -see the "`database upgrade <../codeql-cli-manual/database-upgrade.html>`__" reference documentation. +see the "`database upgrade <../manual/database-upgrade>`__" reference documentation. Progress and results -------------------- diff --git a/docs/codeql/codeql-cli/using-the-codeql-cli/using-custom-queries-with-the-codeql-cli.rst b/docs/codeql/codeql-cli/using-custom-queries-with-the-codeql-cli.rst similarity index 95% rename from docs/codeql/codeql-cli/using-the-codeql-cli/using-custom-queries-with-the-codeql-cli.rst rename to docs/codeql/codeql-cli/using-custom-queries-with-the-codeql-cli.rst index b3f2d02ca1b..aa9e45927f1 100644 --- a/docs/codeql/codeql-cli/using-the-codeql-cli/using-custom-queries-with-the-codeql-cli.rst +++ b/docs/codeql/codeql-cli/using-custom-queries-with-the-codeql-cli.rst @@ -7,10 +7,10 @@ You can customize your CodeQL analyses by writing your own queries to highlight specific vulnerabilities or errors. This topic is specifically about writing -queries to use with the `database analyze <../codeql-cli-manual/database-analyze.html>`__ +queries to use with the `database analyze <../manual/database-analyze>`__ command to produce :ref:`interpreted results <interpret-query-results>`. -.. include:: ../../reusables/advanced-query-execution.rst +.. include:: ../reusables/advanced-query-execution.rst Writing a valid query --------------------- diff --git a/docs/codeql/codeql-cli/using-the-codeql-cli/index.rst b/docs/codeql/codeql-cli/using-the-codeql-cli.rst similarity index 97% rename from docs/codeql/codeql-cli/using-the-codeql-cli/index.rst rename to docs/codeql/codeql-cli/using-the-codeql-cli.rst index 95a1f412fe2..064f6369eca 100644 --- a/docs/codeql/codeql-cli/using-the-codeql-cli/index.rst +++ b/docs/codeql/codeql-cli/using-the-codeql-cli.rst @@ -3,7 +3,7 @@ Using the CodeQL CLI ==================== -.. include:: ../../reusables/codeql-cli-overview.rst +.. include:: ../reusables/codeql-cli-overview.rst See the following links to learn how to get set up and run CodeQL commands: diff --git a/docs/codeql/codeql-for-visual-studio-code/about-codeql-for-visual-studio-code.rst b/docs/codeql/codeql-for-visual-studio-code/about-codeql-for-visual-studio-code.rst index 0525013f8a1..57a39cef5b4 100644 --- a/docs/codeql/codeql-for-visual-studio-code/about-codeql-for-visual-studio-code.rst +++ b/docs/codeql/codeql-for-visual-studio-code/about-codeql-for-visual-studio-code.rst @@ -1,3 +1,5 @@ +:tocdepth: 1 + .. _about-codeql-for-visual-studio-code: About CodeQL for Visual Studio Code diff --git a/docs/codeql/codeql-for-visual-studio-code/analyzing-your-projects.rst b/docs/codeql/codeql-for-visual-studio-code/analyzing-your-projects.rst index e2baaa9443d..02ece5284fa 100644 --- a/docs/codeql/codeql-for-visual-studio-code/analyzing-your-projects.rst +++ b/docs/codeql/codeql-for-visual-studio-code/analyzing-your-projects.rst @@ -1,3 +1,5 @@ +:tocdepth: 1 + .. _analyzing-your-projects: Analyzing your projects @@ -135,7 +137,7 @@ To use standard code navigation features in the source code, you can right-click If you're using an older database, code navigation commands such as **Go to Definition** and **Go to References** may not work. To use code navigation, try unzipping the database and running ``codeql database cleanup <database>`` on the unzipped database using the CodeQL CLI. Then, re-add the database to Visual Studio Code. - For more information, see the `database cleanup <../codeql-cli/codeql-cli-manual/database-cleanup.html>`__ reference documentation. + For more information, see the `database cleanup <../../codeql-cli/manual/database-cleanup>`__ reference documentation. Comparing query results ------------------------ diff --git a/docs/codeql/codeql-for-visual-studio-code/customizing-settings.rst b/docs/codeql/codeql-for-visual-studio-code/customizing-settings.rst index a2621c34b15..fd61771831a 100644 --- a/docs/codeql/codeql-for-visual-studio-code/customizing-settings.rst +++ b/docs/codeql/codeql-for-visual-studio-code/customizing-settings.rst @@ -1,3 +1,5 @@ +:tocdepth: 1 + .. _customizing-settings: Customizing settings diff --git a/docs/codeql/codeql-for-visual-studio-code/exploring-data-flow-with-path-queries.rst b/docs/codeql/codeql-for-visual-studio-code/exploring-data-flow-with-path-queries.rst index 2ca36badda3..34d68fbe223 100644 --- a/docs/codeql/codeql-for-visual-studio-code/exploring-data-flow-with-path-queries.rst +++ b/docs/codeql/codeql-for-visual-studio-code/exploring-data-flow-with-path-queries.rst @@ -1,3 +1,5 @@ +:tocdepth: 1 + .. _exploring-data-flow-with-path-queries: Exploring data flow with path queries diff --git a/docs/codeql/codeql-for-visual-studio-code/exploring-the-structure-of-your-source-code.rst b/docs/codeql/codeql-for-visual-studio-code/exploring-the-structure-of-your-source-code.rst index 5d314a1fb6e..f3338283ba7 100644 --- a/docs/codeql/codeql-for-visual-studio-code/exploring-the-structure-of-your-source-code.rst +++ b/docs/codeql/codeql-for-visual-studio-code/exploring-the-structure-of-your-source-code.rst @@ -1,3 +1,5 @@ +:tocdepth: 1 + .. _exploring-the-structure-of-your-source-code: Exploring the structure of your source code diff --git a/docs/codeql/codeql-for-visual-studio-code/index.rst b/docs/codeql/codeql-for-visual-studio-code/index.rst index bf7eee0fd7f..3163dd2d029 100644 --- a/docs/codeql/codeql-for-visual-studio-code/index.rst +++ b/docs/codeql/codeql-for-visual-studio-code/index.rst @@ -5,8 +5,6 @@ CodeQL for Visual Studio Code The CodeQL extension for Visual Studio Code adds rich language support for CodeQL and allows you to easily find problems in codebases. -See the following help topics for more information: - - :doc:`About CodeQL for Visual Studio Code <about-codeql-for-visual-studio-code>`: CodeQL for Visual Studio Code is an extension that lets you write, run, and test CodeQL queries in Visual diff --git a/docs/codeql/codeql-for-visual-studio-code/setting-up-codeql-in-visual-studio-code.rst b/docs/codeql/codeql-for-visual-studio-code/setting-up-codeql-in-visual-studio-code.rst index 8ba4e18de68..cfc85fa23bd 100644 --- a/docs/codeql/codeql-for-visual-studio-code/setting-up-codeql-in-visual-studio-code.rst +++ b/docs/codeql/codeql-for-visual-studio-code/setting-up-codeql-in-visual-studio-code.rst @@ -1,3 +1,5 @@ +:tocdepth: 1 + .. _setting-up-codeql-in-visual-studio-code: Setting up CodeQL in Visual Studio Code @@ -78,7 +80,7 @@ The starter workspace is a Git repository. It contains: * The `repository of CodeQL libraries and queries <https://github.com/github/codeql>`__ for C/C++, C#, Java, JavaScript, and Python. This is included as a submodule, so it can be updated without affecting your custom queries. * The `repository of CodeQL libraries and queries <https://github.com/github/codeql-go>`__ for Go. This is also included as a submodule. -* A series of folders named ``codeql-custom-queries-<ql-language-specification>``. These are ready for you to start developing your own custom queries for each language, using the standard libraries. There are some example queries to get you started. +* A series of folders named ``codeql-custom-queries-<language>``. These are ready for you to start developing your own custom queries for each language, using the standard libraries. There are some example queries to get you started. To use the starter workspace: diff --git a/docs/codeql/codeql-for-visual-studio-code/testing-codeql-queries-in-visual-studio-code.rst b/docs/codeql/codeql-for-visual-studio-code/testing-codeql-queries-in-visual-studio-code.rst index 0f5ae552c31..ceeab432ae0 100644 --- a/docs/codeql/codeql-for-visual-studio-code/testing-codeql-queries-in-visual-studio-code.rst +++ b/docs/codeql/codeql-for-visual-studio-code/testing-codeql-queries-in-visual-studio-code.rst @@ -1,3 +1,5 @@ +:tocdepth: 1 + .. _testing-codeql-queries-in-visual-studio-code: Testing CodeQL queries in Visual Studio Code diff --git a/docs/codeql/codeql-for-visual-studio-code/troubleshooting-codeql-for-visual-studio-code.rst b/docs/codeql/codeql-for-visual-studio-code/troubleshooting-codeql-for-visual-studio-code.rst index 3d07f3baf63..80fc5efea0f 100644 --- a/docs/codeql/codeql-for-visual-studio-code/troubleshooting-codeql-for-visual-studio-code.rst +++ b/docs/codeql/codeql-for-visual-studio-code/troubleshooting-codeql-for-visual-studio-code.rst @@ -1,3 +1,5 @@ +:tocdepth: 1 + .. _troubleshooting-codeql-for-visual-studio-code: Troubleshooting CodeQL for Visual Studio Code diff --git a/docs/codeql/codeql-language-guides/abstract-syntax-tree-classes-for-working-with-go-programs.rst b/docs/codeql/codeql-language-guides/abstract-syntax-tree-classes-for-working-with-go-programs.rst new file mode 100644 index 00000000000..c866db9b24e --- /dev/null +++ b/docs/codeql/codeql-language-guides/abstract-syntax-tree-classes-for-working-with-go-programs.rst @@ -0,0 +1,519 @@ +.. _abstract-syntax-tree-classes-for-working-with-go-programs: + +Abstract syntax tree classes for working with Go programs +========================================================= + +CodeQL has a large selection of classes for representing the abstract syntax tree of Go programs. + +.. include:: ../reusables/abstract-syntax-tree.rst + +Statement classes +----------------- + +This table lists all subclasses of Stmt_. + ++-------------------------------------------------------------------------------+-----------------------+----------------------------------+---------------------------------------------------+ +| Statement syntax | CodeQL class | Superclasses | Remarks | ++===============================================================================+=======================+==================================+===================================================+ +| ``;`` | EmptyStmt_ | | | +| | | | | ++-------------------------------------------------------------------------------+-----------------------+----------------------------------+---------------------------------------------------+ +| Expr_ | ExprStmt_ | | | +| | | | | ++-------------------------------------------------------------------------------+-----------------------+----------------------------------+---------------------------------------------------+ +| ``{`` Stmt_ ``...`` ``}`` | BlockStmt_ | | | +| | | | | ++-------------------------------------------------------------------------------+-----------------------+----------------------------------+---------------------------------------------------+ +| ``if`` Expr_ BlockStmt_ | IfStmt_ | | | +| | | | | ++-------------------------------------------------------------------------------+ | | | +| ``if`` Expr_ BlockStmt_ ``else`` Stmt_ | | | | +| | | | | ++-------------------------------------------------------------------------------+ | | | +| ``if`` Stmt_\ ``;`` Expr_ BlockStmt_ | | | | +| | | | | ++-------------------------------------------------------------------------------+-----------------------+----------------------------------+---------------------------------------------------+ +| ``for`` Expr_ BlockStmt_ | ForStmt_ | LoopStmt_ | | +| | | | | ++-------------------------------------------------------------------------------+ | | | +| ``for`` Stmt_\ ``;`` Expr_\ ``;`` Stmt_ BlockStmt_ | | | | +| | | | | ++-------------------------------------------------------------------------------+-----------------------+----------------------------------+---------------------------------------------------+ +| ``for`` Expr_ ``...`` ``=`` ``range`` Expr_ BlockStmt_ | RangeStmt_ | LoopStmt_ | | +| | | | | ++-------------------------------------------------------------------------------+-----------------------+----------------------------------+---------------------------------------------------+ +| ``switch`` Expr_ ``{`` CaseClause_ ``...`` ``}`` | ExpressionSwitchStmt_ | SwitchStmt_ | | +| | | | | ++-------------------------------------------------------------------------------+ | | | +| ``switch`` Stmt_\ ``;`` Expr_ ``{`` CaseClause_ ``...`` ``}`` | | | | +| | | | | ++-------------------------------------------------------------------------------+-----------------------+----------------------------------+---------------------------------------------------+ +| ``switch`` Expr_\ ``.(type)`` ``{`` CaseClause_ ``...`` ``}`` | TypeSwitchStmt_ | SwitchStmt_ | | +| | | | | ++-------------------------------------------------------------------------------+ | | | +| ``switch`` SimpleAssignStmt_\ ``.(type)`` ``{`` CaseClause_ ``...`` ``}`` | | | | +| | | | | ++-------------------------------------------------------------------------------+ | | | +| ``switch`` Stmt_\ ``;`` Expr_\ ``.(type)`` ``{`` CaseClause_ ``...`` ``}`` | | | | +| | | | | ++-------------------------------------------------------------------------------+-----------------------+----------------------------------+---------------------------------------------------+ +| ``select`` ``{`` CommClause_ ``...`` ``}`` | SelectStmt_ | | | +| | | | | ++-------------------------------------------------------------------------------+-----------------------+----------------------------------+---------------------------------------------------+ +| ``return`` | ReturnStmt_ | | | ++-------------------------------------------------------------------------------+ | | | +| | | | | ++-------------------------------------------------------------------------------+-----------------------+----------------------------------+---------------------------------------------------+ +| ``break`` | BreakStmt_ | BranchStmt_ | | ++-------------------------------------------------------------------------------+ | | | +| | | | | ++-------------------------------------------------------------------------------+-----------------------+----------------------------------+---------------------------------------------------+ +| ``continue`` | ContinueStmt_ | BranchStmt_ | | ++-------------------------------------------------------------------------------+ | | | +| | | | | ++-------------------------------------------------------------------------------+-----------------------+----------------------------------+---------------------------------------------------+ +| ``goto`` LabelName_ | GotoStmt_ | BranchStmt_ | | +| | | | | ++-------------------------------------------------------------------------------+-----------------------+----------------------------------+---------------------------------------------------+ +| ``fallthrough`` | FallthroughStmt_ | BranchStmt_ | can only occur as final non-empty child of | +| | | | a CaseClause_ in an ExpressionSwitchStmt_ | ++-------------------------------------------------------------------------------+-----------------------+----------------------------------+---------------------------------------------------+ +| LabelName_\ ``:`` Stmt_ | LabeledStmt_ | | | +| | | | | ++-------------------------------------------------------------------------------+-----------------------+----------------------------------+---------------------------------------------------+ +| ``var`` VariableName_ TypeName_ | DeclStmt_ | | | +| | | | | ++-------------------------------------------------------------------------------+ | | | +| ``const`` VariableName_ ``=`` Expr_ | | | | +| | | | | ++-------------------------------------------------------------------------------+ | | | +| ``type`` TypeName_ TypeExpr_ | | | | +| | | | | ++-------------------------------------------------------------------------------+ | | | +| ``type`` TypeName_ ``=`` TypeExpr_ | | | | +| | | | | ++-------------------------------------------------------------------------------+-----------------------+----------------------------------+---------------------------------------------------+ +| Expr_ ``...`` ``=`` Expr_ ``...`` | AssignStmt_ | SimpleAssignStmt_, Assignment_ | | +| | | | | ++-------------------------------------------------------------------------------+-----------------------+----------------------------------+---------------------------------------------------+ +| VariableName_ ``...`` ``:=`` Expr_ ``...`` | DefineStmt_ | SimpleAssignStmt_, Assignment_ | | +| | | | | ++-------------------------------------------------------------------------------+-----------------------+----------------------------------+---------------------------------------------------+ +| Expr_ ``+=`` Expr_ | AddAssignStmt_ | CompoundAssignStmt_, Assignment_ | | +| | | | | ++-------------------------------------------------------------------------------+-----------------------+----------------------------------+---------------------------------------------------+ +| Expr_ ``-=`` Expr_ | SubAssignStmt_ | CompoundAssignStmt_, Assignment_ | | +| | | | | ++-------------------------------------------------------------------------------+-----------------------+----------------------------------+---------------------------------------------------+ +| Expr_ ``*=`` Expr_ | MulAssignStmt_ | CompoundAssignStmt_, Assignment_ | | +| | | | | ++-------------------------------------------------------------------------------+-----------------------+----------------------------------+---------------------------------------------------+ +| Expr_ ``/=`` Expr_ | QuoAssignStmt_ | CompoundAssignStmt_, Assignment_ | | +| | | | | ++-------------------------------------------------------------------------------+-----------------------+----------------------------------+---------------------------------------------------+ +| Expr_ ``%=`` Expr_ | RemAssignStmt_ | CompoundAssignStmt_, Assignment_ | | +| | | | | ++-------------------------------------------------------------------------------+-----------------------+----------------------------------+---------------------------------------------------+ +| Expr_ ``*=`` Expr_ | MulAssignStmt_ | CompoundAssignStmt_, Assignment_ | | +| | | | | ++-------------------------------------------------------------------------------+-----------------------+----------------------------------+---------------------------------------------------+ +| Expr_ ``&=`` Expr_ | AndAssignStmt_ | CompoundAssignStmt_, Assignment_ | | +| | | | | ++-------------------------------------------------------------------------------+-----------------------+----------------------------------+---------------------------------------------------+ +| Expr_ ``|=`` Expr_ | OrAssignStmt_ | CompoundAssignStmt_, Assignment_ | | +| | | | | ++-------------------------------------------------------------------------------+-----------------------+----------------------------------+---------------------------------------------------+ +| Expr_ ``^=`` Expr_ | XorAssignStmt_ | CompoundAssignStmt_, Assignment_ | | +| | | | | ++-------------------------------------------------------------------------------+-----------------------+----------------------------------+---------------------------------------------------+ +| Expr_ ``<<=`` Expr_ | ShlAssignStmt_ | CompoundAssignStmt_, Assignment_ | | +| | | | | ++-------------------------------------------------------------------------------+-----------------------+----------------------------------+---------------------------------------------------+ +| Expr_ ``>>=`` Expr_ | ShrAssignStmt_ | CompoundAssignStmt_, Assignment_ | | +| | | | | ++-------------------------------------------------------------------------------+-----------------------+----------------------------------+---------------------------------------------------+ +| Expr_ ``&^=`` Expr_ | AndNotAssignStmt_ | CompoundAssignStmt_, Assignment_ | | +| | | | | ++-------------------------------------------------------------------------------+-----------------------+----------------------------------+---------------------------------------------------+ +| Expr_ ``++`` | IncStmt_ | IncDecStmt_ | | +| | | | | ++-------------------------------------------------------------------------------+-----------------------+----------------------------------+---------------------------------------------------+ +| Expr_ ``--`` | DecStmt_ | IncDecStmt_ | | +| | | | | ++-------------------------------------------------------------------------------+-----------------------+----------------------------------+---------------------------------------------------+ +| ``go`` CallExpr_ | GoStmt_ | | | +| | | | | ++-------------------------------------------------------------------------------+-----------------------+----------------------------------+---------------------------------------------------+ +| ``defer`` CallExpr_ | DeferStmt_ | | | +| | | | | ++-------------------------------------------------------------------------------+-----------------------+----------------------------------+---------------------------------------------------+ +| Expr_ ``<-`` Expr_ | SendStmt_ | | | +| | | | | ++-------------------------------------------------------------------------------+-----------------------+----------------------------------+---------------------------------------------------+ +| ``case`` Expr_ ``...``\ ``:`` Stmt_ ``...`` | CaseClause_ | | can only occur as child of a SwitchStmt_ | +| | | | | ++-------------------------------------------------------------------------------+ | | | +| ``case`` TypeExpr_ ``...``\ ``:`` Stmt_ ``...`` | | | | +| | | | | ++-------------------------------------------------------------------------------+ | | | +| ``default:`` Stmt_ ``...`` | | | | +| | | | | ++-------------------------------------------------------------------------------+-----------------------+----------------------------------+---------------------------------------------------+ +| ``case`` SendStmt_\ ``:`` Stmt_ ``...`` | CommClause_ | | can only occur as child of a SelectStmt_ | +| | | | | ++-------------------------------------------------------------------------------+ | | | +| ``case`` RecvStmt_\ ``:`` Stmt_ ``...`` | | | | +| | | | | ++-------------------------------------------------------------------------------+ | | | +| ``default:`` Stmt_ ``...`` | | | | +| | | | | ++-------------------------------------------------------------------------------+-----------------------+----------------------------------+---------------------------------------------------+ +| Expr_ ``...`` ``=`` RecvExpr_ | RecvStmt_ | | can only occur as child of a CommClause_ | +| | | | | ++-------------------------------------------------------------------------------+ | | | +| VariableName_ ``...`` ``:=`` RecvExpr_ | | | | +| | | | | ++-------------------------------------------------------------------------------+-----------------------+----------------------------------+---------------------------------------------------+ +| (anything unparseable) | BadStmt_ | | | +| | | | | ++-------------------------------------------------------------------------------+-----------------------+----------------------------------+---------------------------------------------------+ + +Expression classes +------------------ + +There are many expression classes, so we present them by category. +All classes in this section are subclasses of +Expr_. + +Literals +~~~~~~~~ + ++-----------------------------------------+--------------+---------------+ +| Expression syntax example | CodeQL class | Superclass | ++=========================================+==============+===============+ +| ``23`` | IntLit_ | BasicLit_ | ++-----------------------------------------+--------------+---------------+ +| ``4.2`` | FloatLit_ | BasicLit_ | ++-----------------------------------------+--------------+---------------+ +| ``4.2 + 2.7i`` | ImagLit_ | BasicLit_ | ++-----------------------------------------+--------------+---------------+ +| ``'a'`` | CharLit_ | BasicLit_ | ++-----------------------------------------+--------------+---------------+ +| ``"Hello"`` | StringLit_ | BasicLit_ | ++-----------------------------------------+--------------+---------------+ +| ``func(x, y int) int { return x + y }`` | FuncLit_ | FuncDef_ | ++-----------------------------------------+--------------+---------------+ +| ``map[string]int{"A": 1, "B": 2}`` | MapLit_ | CompositeLit_ | ++-----------------------------------------+--------------+---------------+ +| ``Point3D{0.5, -0.5, 0.5}`` | StructLit_ | CompositeLit_ | ++-----------------------------------------+--------------+---------------+ + +Unary expressions +~~~~~~~~~~~~~~~~~ + +All classes in this subsection are subclasses of +UnaryExpr_. + ++-------------------+-----------------+----------------------+ +| Expression syntax | CodeQL class | Superclasses | ++===================+=================+======================+ +| ``+``\ Expr_ | PlusExpr_ | ArithmeticUnaryExpr_ | ++-------------------+-----------------+----------------------+ +| ``-``\ Expr_ | MinusExpr_ | ArithmeticUnaryExpr_ | ++-------------------+-----------------+----------------------+ +| ``!``\ Expr_ | NotExpr_ | LogicalUnaryExpr_ | ++-------------------+-----------------+----------------------+ +| ``^``\ Expr_ | ComplementExpr_ | BitwiseUnaryExpr_ | ++-------------------+-----------------+----------------------+ +| ``&``\ Expr_ | AddressExpr_ | | ++-------------------+-----------------+----------------------+ +| ``<-``\ Expr_ | RecvExpr_ | | ++-------------------+-----------------+----------------------+ + +Binary expressions +~~~~~~~~~~~~~~~~~~ + +All classes in this subsection are subclasses of +BinaryExpr_. + ++--------------------+--------------+---------------------------+ +| Expression syntax | CodeQL class | Superclasses | ++====================+==============+===========================+ +| Expr_ ``*`` Expr_ | MulExpr_ | ArithmeticBinaryExpr_ | ++--------------------+--------------+---------------------------+ +| Expr_ ``/`` Expr_ | QuoExpr_ | ArithmeticBinaryExpr_ | ++--------------------+--------------+---------------------------+ +| Expr_ ``%`` Expr_ | RemExpr_ | ArithmeticBinaryExpr_ | ++--------------------+--------------+---------------------------+ +| Expr_ ``+`` Expr_ | AddExpr_ | ArithmeticBinaryExpr_ | ++--------------------+--------------+---------------------------+ +| Expr_ ``-`` Expr_ | SubExpr_ | ArithmeticBinaryExpr_ | ++--------------------+--------------+---------------------------+ +| Expr_ ``<<`` Expr_ | ShlExpr_ | ShiftExpr_ | ++--------------------+--------------+---------------------------+ +| Expr_ ``>>`` Expr_ | ShrExpr_ | ShiftExpr_ | ++--------------------+--------------+---------------------------+ +| Expr_ ``&&`` Expr_ | LandExpr_ | LogicalBinaryExpr_ | ++--------------------+--------------+---------------------------+ +| Expr_ ``||`` Expr_ | LorExpr_ | LogicalBinaryExpr_ | ++--------------------+--------------+---------------------------+ +| Expr_ ``<`` Expr_ | LssExpr_ | RelationalComparisonExpr_ | ++--------------------+--------------+---------------------------+ +| Expr_ ``>`` Expr_ | GtrExpr_ | RelationalComparisonExpr_ | ++--------------------+--------------+---------------------------+ +| Expr_ ``<=`` Expr_ | LeqExpr_ | RelationalComparisonExpr_ | ++--------------------+--------------+---------------------------+ +| Expr_ ``>=`` Expr_ | GeqExpr_ | RelationalComparisonExpr_ | ++--------------------+--------------+---------------------------+ +| Expr_ ``==`` Expr_ | EqlExpr_ | EqualityTestExpr_ | ++--------------------+--------------+---------------------------+ +| Expr_ ``!=`` Expr_ | NeqExpr_ | EqualityTestExpr_ | ++--------------------+--------------+---------------------------+ +| Expr_ ``&`` Expr_ | AndExpr_ | BitwiseBinaryExpr_ | ++--------------------+--------------+---------------------------+ +| Expr_ ``|`` Expr_ | OrExpr_ | BitwiseBinaryExpr_ | ++--------------------+--------------+---------------------------+ +| Expr_ ``^`` Expr_ | XorExpr_ | BitwiseBinaryExpr_ | ++--------------------+--------------+---------------------------+ +| Expr_ ``&^`` Expr_ | AndNotExpr_ | BitwiseBinaryExpr_ | ++--------------------+--------------+---------------------------+ + +Type expressions +~~~~~~~~~~~~~~~~ + +These classes represent different expressions for types. They do +not have a common superclass. + ++-----------------------------------------+-----------------------+---------------+ +| Expression syntax | CodeQL class | Superclasses | ++=========================================+=======================+===============+ +| ``[``\ Expr_\ ``]`` TypeExpr_ | ArrayTypeExpr_ | | ++-----------------------------------------+-----------------------+---------------+ +| ``struct { ... }`` | StructTypeExpr_ | | ++-----------------------------------------+-----------------------+---------------+ +| ``func`` FunctionName_\ ``(...) (...)`` | FuncTypeExpr_ | | ++-----------------------------------------+-----------------------+---------------+ +| ``interface { ... }`` | InterfaceTypeExpr_ | | ++-----------------------------------------+-----------------------+---------------+ +| ``map[``\ TypeExpr_\ ``]``\ TypeExpr_ | MapTypeExpr_ | | ++-----------------------------------------+-----------------------+---------------+ +| ``chan<-`` TypeExpr_ | SendChanTypeExpr_ | ChanTypeExpr_ | ++-----------------------------------------+-----------------------+---------------+ +| ``<-chan`` TypeExpr_ | RecvChanTypeExpr_ | ChanTypeExpr_ | ++-----------------------------------------+-----------------------+---------------+ +| ``chan`` TypeExpr_ | SendRecvChanTypeExpr_ | ChanTypeExpr_ | ++-----------------------------------------+-----------------------+---------------+ + +Name expressions +~~~~~~~~~~~~~~~~ + +All classes in this subsection are subclasses of +Name_. + +The following classes relate to the structure of the name. + ++-----------------------+----------------+---------------+ +| Expression syntax | CodeQL class | Superclasses | ++=======================+================+===============+ +| Ident_ | SimpleName_ | Ident_ | ++-----------------------+----------------+---------------+ +| Ident_\ ``.``\ Ident_ | QualifiedName_ | SelectorExpr_ | ++-----------------------+----------------+---------------+ + +The following classes relate to what sort of entity the name refers to. + + +- PackageName_ +- TypeName_ +- LabelName_ +- ValueName_ + + - ConstantName_ + - VariableName_ + - FunctionName_ + +Miscellaneous +~~~~~~~~~~~~~ + ++--------------------------------------------------------+-----------------+-----------------------+-------------------------------------------------------+ +| Expression syntax | CodeQL class | Superclasses | Remarks | ++========================================================+=================+=======================+=======================================================+ +| ``foo`` | Ident_ | | | ++--------------------------------------------------------+-----------------+-----------------------+-------------------------------------------------------+ +| ``_`` | BlankIdent_ | | | ++--------------------------------------------------------+-----------------+-----------------------+-------------------------------------------------------+ +| ``...`` | Ellipsis_ | | | ++--------------------------------------------------------+-----------------+-----------------------+-------------------------------------------------------+ +| ``(``\ Expr_\ ``)`` | ParenExpr_ | | | ++--------------------------------------------------------+-----------------+-----------------------+-------------------------------------------------------+ +| Ident_\ ``.``\ Ident_ | SelectorExpr_ | | | ++--------------------------------------------------------+-----------------+-----------------------+-------------------------------------------------------+ +| Expr_\ ``[``\ Expr_\ ``]`` | IndexExpr_ | | | ++--------------------------------------------------------+-----------------+-----------------------+-------------------------------------------------------+ +| Expr_\ ``[``\ Expr_\ ``:``\ Expr_\ ``:``\ Expr_\ ``]`` | SliceExpr_ | | | ++--------------------------------------------------------+-----------------+-----------------------+-------------------------------------------------------+ +| Expr_\ ``.(``\ TypeExpr_\ ``)`` | TypeAssertExpr_ | | | ++--------------------------------------------------------+-----------------+-----------------------+-------------------------------------------------------+ +| ``*``\ Expr_ | StarExpr_ | | can be a ValueExpr_ or TypeExpr_ depending on context | ++--------------------------------------------------------+-----------------+-----------------------+-------------------------------------------------------+ +| Expr_\ ``:`` Expr_ | KeyValueExpr_ | | | ++--------------------------------------------------------+-----------------+-----------------------+-------------------------------------------------------+ +| TypeExpr_\ ``(``\ Expr_\ ``)`` | ConversionExpr_ | CallOrConversionExpr_ | | ++--------------------------------------------------------+-----------------+-----------------------+-------------------------------------------------------+ +| Expr_\ ``(...)`` | CallExpr_ | CallOrConversionExpr_ | | ++--------------------------------------------------------+-----------------+-----------------------+-------------------------------------------------------+ +| (anything unparseable) | BadExpr_ | | | ++--------------------------------------------------------+-----------------+-----------------------+-------------------------------------------------------+ + +The following classes organize expressions by the kind of entity they refer to. + ++----------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| CodeQL class | Explanation | ++================+===================================================================================================================================================================+ +| TypeExpr_ | an expression that denotes a type | ++----------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| ReferenceExpr_ | an expression that refers to a variable, a constant, a function, a field, or an element of an array or a slice | ++----------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| ValueExpr_ | an expression that can be evaluated to a value (as opposed to expressions that refer to a package, a type, or a statement label). This generalizes ReferenceExpr_ | ++----------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------+ + + +Further reading +--------------- + +.. include:: ../reusables/go-further-reading.rst +.. include:: ../reusables/codeql-ref-tools-further-reading.rst + +.. Links used in tables. For information about using these links, see + https://www.sphinx-doc.org/en/master/usage/restructuredtext/basics.html#hyperlinks. + +.. _Stmt: https://codeql.github.com/codeql-standard-libraries/go/semmle/go/Stmt.qll/type.Stmt$Stmt.html +.. _Expr: https://codeql.github.com/codeql-standard-libraries/go/semmle/go/Expr.qll/type.Expr$Expr.html +.. _IntLit: https://codeql.github.com/codeql-standard-libraries/go/semmle/go/Expr.qll/type.Expr$IntLit.html +.. _BasicLit: https://codeql.github.com/codeql-standard-libraries/go/semmle/go/Expr.qll/type.Expr$BasicLit.html +.. _FloatLit: https://codeql.github.com/codeql-standard-libraries/go/semmle/go/Expr.qll/type.Expr$FloatLit.html +.. _ImagLit: https://codeql.github.com/codeql-standard-libraries/go/semmle/go/Expr.qll/type.Expr$ImagLit.html +.. _CharLit: https://codeql.github.com/codeql-standard-libraries/go/semmle/go/Expr.qll/type.Expr$CharLit.html +.. _StringLit: https://codeql.github.com/codeql-standard-libraries/go/semmle/go/Expr.qll/type.Expr$StringLit.html +.. _FuncLit: https://codeql.github.com/codeql-standard-libraries/go/semmle/go/Expr.qll/type.Expr$FuncLit.html +.. _FuncDef: https://codeql.github.com/codeql-standard-libraries/go/semmle/go/Decls.qll/type.Decls$FuncDef.html +.. _MapLit: https://codeql.github.com/codeql-standard-libraries/go/semmle/go/Expr.qll/type.Expr$MapLit.html +.. _CompositeLit: https://codeql.github.com/codeql-standard-libraries/go/semmle/go/Expr.qll/type.Expr$CompositeLit.html +.. _StructLit: https://codeql.github.com/codeql-standard-libraries/go/semmle/go/Expr.qll/type.Expr$StructLit.html +.. _UnaryExpr: https://codeql.github.com/codeql-standard-libraries/go/semmle/go/Expr.qll/type.Expr$UnaryExpr.html +.. _PlusExpr: https://codeql.github.com/codeql-standard-libraries/go/semmle/go/Expr.qll/type.Expr$PlusExpr.html +.. _ArithmeticUnaryExpr: https://codeql.github.com/codeql-standard-libraries/go/semmle/go/Expr.qll/type.Expr$ArithmeticUnaryExpr.html +.. _MinusExpr: https://codeql.github.com/codeql-standard-libraries/go/semmle/go/Expr.qll/type.Expr$MinusExpr.html +.. _NotExpr: https://codeql.github.com/codeql-standard-libraries/go/semmle/go/Expr.qll/type.Expr$NotExpr.html +.. _LogicalUnaryExpr: https://codeql.github.com/codeql-standard-libraries/go/semmle/go/Expr.qll/type.Expr$LogicalUnaryExpr.html +.. _ComplementExpr: https://codeql.github.com/codeql-standard-libraries/go/semmle/go/Expr.qll/type.Expr$ComplementExpr.html +.. _BitwiseUnaryExpr: https://codeql.github.com/codeql-standard-libraries/go/semmle/go/Expr.qll/type.Expr$BitwiseUnaryExpr.html +.. _AddressExpr: https://codeql.github.com/codeql-standard-libraries/go/semmle/go/Expr.qll/type.Expr$AddressExpr.html +.. _RecvExpr: https://codeql.github.com/codeql-standard-libraries/go/semmle/go/Expr.qll/type.Expr$RecvExpr.html +.. _BinaryExpr: https://codeql.github.com/codeql-standard-libraries/go/semmle/go/Expr.qll/type.Expr$BinaryExpr.html +.. _MulExpr: https://codeql.github.com/codeql-standard-libraries/go/semmle/go/Expr.qll/type.Expr$MulExpr.html +.. _ArithmeticBinaryExpr: https://codeql.github.com/codeql-standard-libraries/go/semmle/go/Expr.qll/type.Expr$ArithmeticBinaryExpr.html +.. _QuoExpr: https://codeql.github.com/codeql-standard-libraries/go/semmle/go/Expr.qll/type.Expr$QuoExpr.html +.. _RemExpr: https://codeql.github.com/codeql-standard-libraries/go/semmle/go/Expr.qll/type.Expr$RemExpr.html +.. _AddExpr: https://codeql.github.com/codeql-standard-libraries/go/semmle/go/Expr.qll/type.Expr$AddExpr.html +.. _SubExpr: https://codeql.github.com/codeql-standard-libraries/go/semmle/go/Expr.qll/type.Expr$SubExpr.html +.. _ShlExpr: https://codeql.github.com/codeql-standard-libraries/go/semmle/go/Expr.qll/type.Expr$ShlExpr.html +.. _ShiftExpr: https://codeql.github.com/codeql-standard-libraries/go/semmle/go/Expr.qll/type.Expr$ShiftExpr.html +.. _ShrExpr: https://codeql.github.com/codeql-standard-libraries/go/semmle/go/Expr.qll/type.Expr$ShrExpr.html +.. _LandExpr: https://codeql.github.com/codeql-standard-libraries/go/semmle/go/Expr.qll/type.Expr$LandExpr.html +.. _LogicalBinaryExpr: https://codeql.github.com/codeql-standard-libraries/go/semmle/go/Expr.qll/type.Expr$LogicalBinaryExpr.html +.. _LorExpr: https://codeql.github.com/codeql-standard-libraries/go/semmle/go/Expr.qll/type.Expr$LorExpr.html +.. _LssExpr: https://codeql.github.com/codeql-standard-libraries/go/semmle/go/Expr.qll/type.Expr$LssExpr.html +.. _RelationalComparisonExpr: https://codeql.github.com/codeql-standard-libraries/go/semmle/go/Expr.qll/type.Expr$RelationalComparisonExpr.html +.. _GtrExpr: https://codeql.github.com/codeql-standard-libraries/go/semmle/go/Expr.qll/type.Expr$GtrExpr.html +.. _LeqExpr: https://codeql.github.com/codeql-standard-libraries/go/semmle/go/Expr.qll/type.Expr$LeqExpr.html +.. _GeqExpr: https://codeql.github.com/codeql-standard-libraries/go/semmle/go/Expr.qll/type.Expr$GeqExpr.html +.. _EqlExpr: https://codeql.github.com/codeql-standard-libraries/go/semmle/go/Expr.qll/type.Expr$EqlExpr.html +.. _EqualityTestExpr: https://codeql.github.com/codeql-standard-libraries/go/semmle/go/Expr.qll/type.Expr$EqualityTestExpr.html +.. _NeqExpr: https://codeql.github.com/codeql-standard-libraries/go/semmle/go/Expr.qll/type.Expr$NeqExpr.html +.. _AndExpr: https://codeql.github.com/codeql-standard-libraries/go/semmle/go/Expr.qll/type.Expr$AndExpr.html +.. _BitwiseBinaryExpr: https://codeql.github.com/codeql-standard-libraries/go/semmle/go/Expr.qll/type.Expr$BitwiseBinaryExpr.html +.. _OrExpr: https://codeql.github.com/codeql-standard-libraries/go/semmle/go/Expr.qll/type.Expr$OrExpr.html +.. _XorExpr: https://codeql.github.com/codeql-standard-libraries/go/semmle/go/Expr.qll/type.Expr$XorExpr.html +.. _AndNotExpr: https://codeql.github.com/codeql-standard-libraries/go/semmle/go/Expr.qll/type.Expr$AndNotExpr.html +.. _TypeExpr: https://codeql.github.com/codeql-standard-libraries/go/semmle/go/Expr.qll/type.Expr$TypeExpr.html +.. _ArrayTypeExpr: https://codeql.github.com/codeql-standard-libraries/go/semmle/go/Expr.qll/type.Expr$ArrayTypeExpr.html +.. _StructTypeExpr: https://codeql.github.com/codeql-standard-libraries/go/semmle/go/Expr.qll/type.Expr$StructTypeExpr.html +.. _FunctionName: https://codeql.github.com/codeql-standard-libraries/go/semmle/go/Expr.qll/type.Expr$FunctionName.html +.. _FuncTypeExpr: https://codeql.github.com/codeql-standard-libraries/go/semmle/go/Expr.qll/type.Expr$FuncTypeExpr.html +.. _InterfaceTypeExpr: https://codeql.github.com/codeql-standard-libraries/go/semmle/go/Expr.qll/type.Expr$InterfaceTypeExpr.html +.. _MapTypeExpr: https://codeql.github.com/codeql-standard-libraries/go/semmle/go/Expr.qll/type.Expr$MapTypeExpr.html +.. _SendChanTypeExpr: https://codeql.github.com/codeql-standard-libraries/go/semmle/go/Expr.qll/type.Expr$SendChanTypeExpr.html +.. _ChanTypeExpr: https://codeql.github.com/codeql-standard-libraries/go/semmle/go/Expr.qll/type.Expr$ChanTypeExpr.html +.. _RecvChanTypeExpr: https://codeql.github.com/codeql-standard-libraries/go/semmle/go/Expr.qll/type.Expr$RecvChanTypeExpr.html +.. _SendRecvChanTypeExpr: https://codeql.github.com/codeql-standard-libraries/go/semmle/go/Expr.qll/type.Expr$SendRecvChanTypeExpr.html +.. _Name: https://codeql.github.com/codeql-standard-libraries/go/semmle/go/Expr.qll/type.Expr$Name.html +.. _Ident: https://codeql.github.com/codeql-standard-libraries/go/semmle/go/Expr.qll/type.Expr$Ident.html +.. _SimpleName: https://codeql.github.com/codeql-standard-libraries/go/semmle/go/Expr.qll/type.Expr$SimpleName.html +.. _QualifiedName: https://codeql.github.com/codeql-standard-libraries/go/semmle/go/Expr.qll/type.Expr$QualifiedName.html +.. _SelectorExpr: https://codeql.github.com/codeql-standard-libraries/go/semmle/go/Expr.qll/type.Expr$SelectorExpr.html +.. _PackageName: https://codeql.github.com/codeql-standard-libraries/go/semmle/go/Expr.qll/type.Expr$PackageName.html +.. _TypeName: https://codeql.github.com/codeql-standard-libraries/go/semmle/go/Expr.qll/type.Expr$TypeName.html +.. _LabelName: https://codeql.github.com/codeql-standard-libraries/go/semmle/go/Expr.qll/type.Expr$LabelName.html +.. _ValueName: https://codeql.github.com/codeql-standard-libraries/go/semmle/go/Expr.qll/type.Expr$ValueName.html +.. _ConstantName: https://codeql.github.com/codeql-standard-libraries/go/semmle/go/Expr.qll/type.Expr$ConstantName.html +.. _VariableName: https://codeql.github.com/codeql-standard-libraries/go/semmle/go/Expr.qll/type.Expr$VariableName.html +.. _BlankIdent: https://codeql.github.com/codeql-standard-libraries/go/semmle/go/Expr.qll/type.Expr$BlankIdent.html +.. _Ellipsis: https://codeql.github.com/codeql-standard-libraries/go/semmle/go/Expr.qll/type.Expr$Ellipsis.html +.. _ParenExpr: https://codeql.github.com/codeql-standard-libraries/go/semmle/go/Expr.qll/type.Expr$ParenExpr.html +.. _IndexExpr: https://codeql.github.com/codeql-standard-libraries/go/semmle/go/Expr.qll/type.Expr$IndexExpr.html +.. _SliceExpr: https://codeql.github.com/codeql-standard-libraries/go/semmle/go/Expr.qll/type.Expr$SliceExpr.html +.. _TypeAssertExpr: https://codeql.github.com/codeql-standard-libraries/go/semmle/go/Expr.qll/type.Expr$TypeAssertExpr.html +.. _StarExpr: https://codeql.github.com/codeql-standard-libraries/go/semmle/go/Expr.qll/type.Expr$StarExpr.html +.. _ValueExpr: https://codeql.github.com/codeql-standard-libraries/go/semmle/go/Expr.qll/type.Expr$ValueExpr.html +.. _KeyValueExpr: https://codeql.github.com/codeql-standard-libraries/go/semmle/go/Expr.qll/type.Expr$KeyValueExpr.html +.. _ConversionExpr: https://codeql.github.com/codeql-standard-libraries/go/semmle/go/Expr.qll/type.Expr$ConversionExpr.html +.. _CallOrConversionExpr: https://codeql.github.com/codeql-standard-libraries/go/semmle/go/Expr.qll/type.Expr$CallOrConversionExpr.html +.. _CallExpr: https://codeql.github.com/codeql-standard-libraries/go/semmle/go/Expr.qll/type.Expr$CallExpr.html +.. _BadExpr: https://codeql.github.com/codeql-standard-libraries/go/semmle/go/Expr.qll/type.Expr$BadExpr.html +.. _ReferenceExpr: https://codeql.github.com/codeql-standard-libraries/go/semmle/go/Expr.qll/type.Expr$ReferenceExpr.html +.. _EmptyStmt: https://codeql.github.com/codeql-standard-libraries/go/semmle/go/Stmt.qll/type.Stmt$EmptyStmt.html +.. _ExprStmt: https://codeql.github.com/codeql-standard-libraries/go/semmle/go/Stmt.qll/type.Stmt$ExprStmt.html +.. _BlockStmt: https://codeql.github.com/codeql-standard-libraries/go/semmle/go/Stmt.qll/type.Stmt$BlockStmt.html +.. _IfStmt: https://codeql.github.com/codeql-standard-libraries/go/semmle/go/Stmt.qll/type.Stmt$IfStmt.html +.. _ForStmt: https://codeql.github.com/codeql-standard-libraries/go/semmle/go/Stmt.qll/type.Stmt$ForStmt.html +.. _LoopStmt: https://codeql.github.com/codeql-standard-libraries/go/semmle/go/Stmt.qll/type.Stmt$LoopStmt.html +.. _RangeStmt: https://codeql.github.com/codeql-standard-libraries/go/semmle/go/Stmt.qll/type.Stmt$RangeStmt.html +.. _ExpressionSwitchStmt: https://codeql.github.com/codeql-standard-libraries/go/semmle/go/Stmt.qll/type.Stmt$ExpressionSwitchStmt.html +.. _SwitchStmt: https://codeql.github.com/codeql-standard-libraries/go/semmle/go/Stmt.qll/type.Stmt$SwitchStmt.html +.. _CaseClause: https://codeql.github.com/codeql-standard-libraries/go/semmle/go/Stmt.qll/type.Stmt$CaseClause.html +.. _TypeSwitchStmt: https://codeql.github.com/codeql-standard-libraries/go/semmle/go/Stmt.qll/type.Stmt$TypeSwitchStmt.html +.. _SimpleAssignStmt: https://codeql.github.com/codeql-standard-libraries/go/semmle/go/Stmt.qll/type.Stmt$SimpleAssignStmt.html +.. _CommClause: https://codeql.github.com/codeql-standard-libraries/go/semmle/go/Stmt.qll/type.Stmt$CommClause.html +.. _SelectStmt: https://codeql.github.com/codeql-standard-libraries/go/semmle/go/Stmt.qll/type.Stmt$SelectStmt.html +.. _ReturnStmt: https://codeql.github.com/codeql-standard-libraries/go/semmle/go/Stmt.qll/type.Stmt$ReturnStmt.html +.. _BreakStmt: https://codeql.github.com/codeql-standard-libraries/go/semmle/go/Stmt.qll/type.Stmt$BreakStmt.html +.. _BranchStmt: https://codeql.github.com/codeql-standard-libraries/go/semmle/go/Stmt.qll/type.Stmt$BranchStmt.html +.. _ContinueStmt: https://codeql.github.com/codeql-standard-libraries/go/semmle/go/Stmt.qll/type.Stmt$ContinueStmt.html +.. _GotoStmt: https://codeql.github.com/codeql-standard-libraries/go/semmle/go/Stmt.qll/type.Stmt$GotoStmt.html +.. _FallthroughStmt: https://codeql.github.com/codeql-standard-libraries/go/semmle/go/Stmt.qll/type.Stmt$FallthroughStmt.html +.. _LabeledStmt: https://codeql.github.com/codeql-standard-libraries/go/semmle/go/Stmt.qll/type.Stmt$LabeledStmt.html +.. _DeclStmt: https://codeql.github.com/codeql-standard-libraries/go/semmle/go/Stmt.qll/type.Stmt$DeclStmt.html +.. _AssignStmt: https://codeql.github.com/codeql-standard-libraries/go/semmle/go/Stmt.qll/type.Stmt$AssignStmt.html +.. _Assignment: https://codeql.github.com/codeql-standard-libraries/go/semmle/go/Stmt.qll/type.Stmt$Assignment.html +.. _DefineStmt: https://codeql.github.com/codeql-standard-libraries/go/semmle/go/Stmt.qll/type.Stmt$DefineStmt.html +.. _AddAssignStmt: https://codeql.github.com/codeql-standard-libraries/go/semmle/go/Stmt.qll/type.Stmt$AddAssignStmt.html +.. _CompoundAssignStmt: https://codeql.github.com/codeql-standard-libraries/go/semmle/go/Stmt.qll/type.Stmt$CompoundAssignStmt.html +.. _SubAssignStmt: https://codeql.github.com/codeql-standard-libraries/go/semmle/go/Stmt.qll/type.Stmt$SubAssignStmt.html +.. _MulAssignStmt: https://codeql.github.com/codeql-standard-libraries/go/semmle/go/Stmt.qll/type.Stmt$MulAssignStmt.html +.. _QuoAssignStmt: https://codeql.github.com/codeql-standard-libraries/go/semmle/go/Stmt.qll/type.Stmt$QuoAssignStmt.html +.. _RemAssignStmt: https://codeql.github.com/codeql-standard-libraries/go/semmle/go/Stmt.qll/type.Stmt$RemAssignStmt.html +.. _AndAssignStmt: https://codeql.github.com/codeql-standard-libraries/go/semmle/go/Stmt.qll/type.Stmt$AndAssignStmt.html +.. _OrAssignStmt: https://codeql.github.com/codeql-standard-libraries/go/semmle/go/Stmt.qll/type.Stmt$OrAssignStmt.html +.. _XorAssignStmt: https://codeql.github.com/codeql-standard-libraries/go/semmle/go/Stmt.qll/type.Stmt$XorAssignStmt.html +.. _ShlAssignStmt: https://codeql.github.com/codeql-standard-libraries/go/semmle/go/Stmt.qll/type.Stmt$ShlAssignStmt.html +.. _ShrAssignStmt: https://codeql.github.com/codeql-standard-libraries/go/semmle/go/Stmt.qll/type.Stmt$ShrAssignStmt.html +.. _AndNotAssignStmt: https://codeql.github.com/codeql-standard-libraries/go/semmle/go/Stmt.qll/type.Stmt$AndNotAssignStmt.html +.. _IncStmt: https://codeql.github.com/codeql-standard-libraries/go/semmle/go/Stmt.qll/type.Stmt$IncStmt.html +.. _IncDecStmt: https://codeql.github.com/codeql-standard-libraries/go/semmle/go/Stmt.qll/type.Stmt$IncDecStmt.html +.. _DecStmt: https://codeql.github.com/codeql-standard-libraries/go/semmle/go/Stmt.qll/type.Stmt$DecStmt.html +.. _GoStmt: https://codeql.github.com/codeql-standard-libraries/go/semmle/go/Stmt.qll/type.Stmt$GoStmt.html +.. _DeferStmt: https://codeql.github.com/codeql-standard-libraries/go/semmle/go/Stmt.qll/type.Stmt$DeferStmt.html +.. _SendStmt: https://codeql.github.com/codeql-standard-libraries/go/semmle/go/Stmt.qll/type.Stmt$SendStmt.html +.. _RecvStmt: https://codeql.github.com/codeql-standard-libraries/go/semmle/go/Stmt.qll/type.Stmt$RecvStmt.html +.. _BadStmt: https://codeql.github.com/codeql-standard-libraries/go/semmle/go/Stmt.qll/type.Stmt$BadStmt.html diff --git a/docs/codeql/codeql-language-guides/abstract-syntax-tree-classes-for-working-with-java-programs.rst b/docs/codeql/codeql-language-guides/abstract-syntax-tree-classes-for-working-with-java-programs.rst new file mode 100644 index 00000000000..1664b8407dc --- /dev/null +++ b/docs/codeql/codeql-language-guides/abstract-syntax-tree-classes-for-working-with-java-programs.rst @@ -0,0 +1,387 @@ +.. _abstract-syntax-tree-classes-for-working-with-java-programs: + +Abstract syntax tree classes for working with Java programs +=========================================================== + +CodeQL has a large selection of classes for representing the abstract syntax tree of Java programs. + +.. include:: ../reusables/abstract-syntax-tree.rst + +Statement classes +----------------- + +This table lists all subclasses of `Stmt`_. + ++------------------------------------------------------------------------------------+---------------------------------+---------------------------------+--------------------------------------------+ +| Statement syntax | CodeQL class | Superclasses | Remarks | ++====================================================================================+=================================+=================================+============================================+ +| ``;`` | EmptyStmt_ | | | ++------------------------------------------------------------------------------------+---------------------------------+---------------------------------+--------------------------------------------+ +| `Expr`_ ``;`` | ExprStmt_ | | | ++------------------------------------------------------------------------------------+---------------------------------+---------------------------------+--------------------------------------------+ +| ``{`` `Stmt`_ ``... }`` | BlockStmt_ | | | ++------------------------------------------------------------------------------------+---------------------------------+---------------------------------+--------------------------------------------+ +| ``if (`` `Expr`_ ``)`` `Stmt`_ ``else`` `Stmt`_ | IfStmt_ | `ConditionalStmt`_ | | ++------------------------------------------------------------------------------------+ | | | +| ``if (`` `Expr`_ ``)`` `Stmt`_ | | | | ++------------------------------------------------------------------------------------+---------------------------------+---------------------------------+--------------------------------------------+ +| ``while (`` `Expr`_ ``)`` `Stmt`_ | WhileStmt_ | `ConditionalStmt`_, `LoopStmt`_ | | ++------------------------------------------------------------------------------------+---------------------------------+---------------------------------+--------------------------------------------+ +| ``do`` `Stmt`_ ``while (`` `Expr`_ ``)`` | DoStmt_ | `ConditionalStmt`_, `LoopStmt`_ | | ++------------------------------------------------------------------------------------+---------------------------------+---------------------------------+--------------------------------------------+ +| ``for (`` `Expr`_ ``;`` `Expr`_ ``;`` `Expr`_ ``)`` `Stmt`_ | ForStmt_ | `ConditionalStmt`_, `LoopStmt`_ | | ++------------------------------------------------------------------------------------+---------------------------------+---------------------------------+--------------------------------------------+ +| ``for (`` `VarAccess`_ ``:`` `Expr`_ ``)`` `Stmt`_ | EnhancedForStmt_ | `LoopStmt`_ | | ++------------------------------------------------------------------------------------+---------------------------------+---------------------------------+--------------------------------------------+ +| ``switch (`` `Expr`_ ``) {`` `SwitchCase`_ ``... }`` | SwitchStmt_ | | | ++------------------------------------------------------------------------------------+---------------------------------+---------------------------------+--------------------------------------------+ +| ``try {`` `Stmt`_ ``... } finally {`` `Stmt`_ ``... }`` | TryStmt_ | | | ++------------------------------------------------------------------------------------+---------------------------------+---------------------------------+--------------------------------------------+ +| ``return`` `Expr`_ ``;`` | ReturnStmt_ | | | ++------------------------------------------------------------------------------------+ | | | +| ``return ;`` | | | | ++------------------------------------------------------------------------------------+---------------------------------+---------------------------------+--------------------------------------------+ +| ``throw`` `Expr`_ ``;`` | ThrowStmt_ | | | ++------------------------------------------------------------------------------------+---------------------------------+---------------------------------+--------------------------------------------+ +| ``break ;`` | BreakStmt_ | `JumpStmt`_ | | ++------------------------------------------------------------------------------------+ | | | +| ``break label ;`` | | | | ++------------------------------------------------------------------------------------+---------------------------------+---------------------------------+--------------------------------------------+ +| ``continue ;`` | ContinueStmt_ | `JumpStmt`_ | | ++------------------------------------------------------------------------------------+ | | | +| ``continue label ;`` | | | | ++------------------------------------------------------------------------------------+---------------------------------+---------------------------------+--------------------------------------------+ +| ``label :`` `Stmt`_ | LabeledStmt_ | | | ++------------------------------------------------------------------------------------+---------------------------------+---------------------------------+--------------------------------------------+ +| ``synchronized (`` `Expr`_ ``)`` `Stmt`_ | SynchronizedStmt_ | | | ++------------------------------------------------------------------------------------+---------------------------------+---------------------------------+--------------------------------------------+ +| ``assert`` `Expr`_ ``:`` `Expr`_ ``;`` | AssertStmt_ | | | ++------------------------------------------------------------------------------------+ | | | +| ``assert`` `Expr`_ ``;`` | | | | ++------------------------------------------------------------------------------------+---------------------------------+---------------------------------+--------------------------------------------+ +| `TypeAccess`_ ``name ;`` | LocalVariableDeclStmt_ | | | ++------------------------------------------------------------------------------------+---------------------------------+---------------------------------+--------------------------------------------+ +| ``class name {`` `Member`_ ``... } ;`` | LocalClassDeclStmt_ | | | ++------------------------------------------------------------------------------------+---------------------------------+---------------------------------+--------------------------------------------+ +| ``this (`` `Expr`_ ``, ... ) ;`` | ThisConstructorInvocationStmt_ | | | ++------------------------------------------------------------------------------------+---------------------------------+---------------------------------+--------------------------------------------+ +| ``super (`` `Expr`_ ``, ... ) ;`` | SuperConstructorInvocationStmt_ | | | ++------------------------------------------------------------------------------------+---------------------------------+---------------------------------+--------------------------------------------+ +| ``catch (`` `TypeAccess`_ ``name ) {`` `Stmt`_ ``... }`` | CatchClause_ | | can only occur as child of a `TryStmt`_ | ++------------------------------------------------------------------------------------+---------------------------------+---------------------------------+--------------------------------------------+ +| ``case`` `Literal`_ ``:`` `Stmt`_ ``...`` | ConstCase_ | | can only occur as child of a `SwitchStmt`_ | ++------------------------------------------------------------------------------------+---------------------------------+---------------------------------+--------------------------------------------+ +| ``default :`` `Stmt`_ ``...`` | DefaultCase_ | | can only occur as child of a `SwitchStmt`_ | ++------------------------------------------------------------------------------------+---------------------------------+---------------------------------+--------------------------------------------+ + +Expression classes +------------------ + +There are many expression classes, so we present them by category. All classes in this section are subclasses of Expr_. + +Literals +~~~~~~~~ + +All classes in this subsection are subclasses of Literal_. + ++---------------------------+-------------------------+ +| Expression syntax example | CodeQL class | ++===========================+=========================+ +| ``true`` | `BooleanLiteral`_ | ++---------------------------+-------------------------+ +| ``23`` | `IntegerLiteral`_ | ++---------------------------+-------------------------+ +| ``23l`` | `LongLiteral`_ | ++---------------------------+-------------------------+ +| ``4.2f`` | `FloatingPointLiteral`_ | ++---------------------------+-------------------------+ +| ``4.2`` | `DoubleLiteral`_ | ++---------------------------+-------------------------+ +| ``'a'`` | `CharacterLiteral`_ | ++---------------------------+-------------------------+ +| ``"Hello"`` | `StringLiteral`_ | ++---------------------------+-------------------------+ +| ``null`` | `NullLiteral`_ | ++---------------------------+-------------------------+ + +Unary expressions +~~~~~~~~~~~~~~~~~ + +All classes in this subsection are subclasses of UnaryExpr_. + ++-------------------+----------------+--------------------+--------------------------------------------------+ +| Expression syntax | CodeQL class | Superclasses | Remarks | ++===================+================+====================+==================================================+ +| `Expr`_\ ``++`` | `PostIncExpr`_ | `UnaryAssignExpr`_ | | ++-------------------+----------------+--------------------+--------------------------------------------------+ +| `Expr`_\ ``--`` | `PostDecExpr`_ | `UnaryAssignExpr`_ | | ++-------------------+----------------+--------------------+--------------------------------------------------+ +| ``++``\ `Expr`_ | `PreIncExpr`_ | `UnaryAssignExpr`_ | | ++-------------------+----------------+--------------------+--------------------------------------------------+ +| ``--``\ `Expr`_ | `PreDecExpr`_ | `UnaryAssignExpr`_ | | ++-------------------+----------------+--------------------+--------------------------------------------------+ +| ``~``\ `Expr`_ | `BitNotExpr`_ | `BitwiseExpr`_ | see below for other subclasses of `BitwiseExpr`_ | ++-------------------+----------------+--------------------+--------------------------------------------------+ +| ``-``\ `Expr`_ | `MinusExpr`_ | | | ++-------------------+----------------+--------------------+--------------------------------------------------+ +| ``+``\ `Expr`_ | `PlusExpr`_ | | | ++-------------------+----------------+--------------------+--------------------------------------------------+ +| ``!``\ `Expr`_ | `LogNotExpr`_ | `LogicExpr`_ | see below for other subclasses of `LogicExpr`_ | ++-------------------+----------------+--------------------+--------------------------------------------------+ + +Binary expressions +~~~~~~~~~~~~~~~~~~ + +All classes in this subsection are subclasses of BinaryExpr_. + ++-------------------------+-------------------+-------------------+ +| Expression syntax | CodeQL class | Superclasses | ++=========================+===================+===================+ +| `Expr`_ ``*`` `Expr`_ | `MulExpr`_ | | ++-------------------------+-------------------+-------------------+ +| `Expr`_ ``/`` `Expr`_ | `DivExpr`_ | | ++-------------------------+-------------------+-------------------+ +| `Expr`_ ``%`` `Expr`_ | `RemExpr`_ | | ++-------------------------+-------------------+-------------------+ +| `Expr`_ ``+`` `Expr`_ | `AddExpr`_ | | ++-------------------------+-------------------+-------------------+ +| `Expr`_ ``-`` `Expr`_ | `SubExpr`_ | | ++-------------------------+-------------------+-------------------+ +| `Expr`_ ``<<`` `Expr`_ | `LShiftExpr`_ | | ++-------------------------+-------------------+-------------------+ +| `Expr`_ ``>>`` `Expr`_ | `RShiftExpr`_ | | ++-------------------------+-------------------+-------------------+ +| `Expr`_ ``>>>`` `Expr`_ | `URShiftExpr`_ | | ++-------------------------+-------------------+-------------------+ +| `Expr`_ ``&&`` `Expr`_ | `AndLogicalExpr`_ | `LogicExpr`_ | ++-------------------------+-------------------+-------------------+ +| `Expr`_ ``||`` `Expr`_ | `OrLogicalExpr`_ | `LogicExpr`_ | ++-------------------------+-------------------+-------------------+ +| `Expr`_ ``<`` `Expr`_ | `LTExpr`_ | `ComparisonExpr`_ | ++-------------------------+-------------------+-------------------+ +| `Expr`_ ``>`` `Expr`_ | `GTExpr`_ | `ComparisonExpr`_ | ++-------------------------+-------------------+-------------------+ +| `Expr`_ ``<=`` `Expr`_ | `LEExpr`_ | `ComparisonExpr`_ | ++-------------------------+-------------------+-------------------+ +| `Expr`_ ``>=`` `Expr`_ | `GEExpr`_ | `ComparisonExpr`_ | ++-------------------------+-------------------+-------------------+ +| `Expr`_ ``==`` `Expr`_ | `EQExpr`_ | `EqualityTest`_ | ++-------------------------+-------------------+-------------------+ +| `Expr`_ ``!=`` `Expr`_ | `NEExpr`_ | `EqualityTest`_ | ++-------------------------+-------------------+-------------------+ +| `Expr`_ ``&`` `Expr`_ | `AndBitwiseExpr`_ | `BitwiseExpr`_ | ++-------------------------+-------------------+-------------------+ +| `Expr`_ ``|`` `Expr`_ | `OrBitwiseExpr`_ | `BitwiseExpr`_ | ++-------------------------+-------------------+-------------------+ +| `Expr`_ ``^`` `Expr`_ | `XorBitwiseExpr`_ | `BitwiseExpr`_ | ++-------------------------+-------------------+-------------------+ + +Assignment expressions +~~~~~~~~~~~~~~~~~~~~~~ + +All classes in this table are subclasses of Assignment_. + ++--------------------------+----------------------+-----------------+ +| Expression syntax | CodeQL class | Superclasses | ++==========================+======================+=================+ +| `Expr`_ ``=`` `Expr`_ | `AssignExpr`_ | | ++--------------------------+----------------------+-----------------+ +| `Expr`_ ``+=`` `Expr`_ | `AssignAddExpr`_ | `AssignOp`_ | ++--------------------------+----------------------+-----------------+ +| `Expr`_ ``-=`` `Expr`_ | `AssignSubExpr`_ | `AssignOp`_ | ++--------------------------+----------------------+-----------------+ +| `Expr`_ ``*=`` `Expr`_ | `AssignMulExpr`_ | `AssignOp`_ | ++--------------------------+----------------------+-----------------+ +| `Expr`_ ``/=`` `Expr`_ | `AssignDivExpr`_ | `AssignOp`_ | ++--------------------------+----------------------+-----------------+ +| `Expr`_ ``%=`` `Expr`_ | `AssignRemExpr`_ | `AssignOp`_ | ++--------------------------+----------------------+-----------------+ +| `Expr`_ ``&=`` `Expr`_ | `AssignAndExpr`_ | `AssignOp`_ | ++--------------------------+----------------------+-----------------+ +| `Expr`_ ``|=`` `Expr`_ | `AssignOrExpr`_ | `AssignOp`_ | ++--------------------------+----------------------+-----------------+ +| `Expr`_ ``^=`` `Expr`_ | `AssignXorExpr`_ | `AssignOp`_ | ++--------------------------+----------------------+-----------------+ +| `Expr`_ ``<<=`` `Expr`_ | `AssignLShiftExpr`_ | `AssignOp`_ | ++--------------------------+----------------------+-----------------+ +| `Expr`_ ``>>=`` `Expr`_ | `AssignRShiftExpr`_ | `AssignOp`_ | ++--------------------------+----------------------+-----------------+ +| `Expr`_ ``>>>=`` `Expr`_ | `AssignURShiftExpr`_ | `AssignOp`_ | ++--------------------------+----------------------+-----------------+ + +Accesses +~~~~~~~~ + ++--------------------------------+---------------------+ +| Expression syntax examples | CodeQL class | ++================================+=====================+ +| ``this`` | ThisAccess_ | ++--------------------------------+ | +| ``Outer.this`` | | ++--------------------------------+---------------------+ +| ``super`` | SuperAccess_ | ++--------------------------------+ | +| ``Outer.super`` | | ++--------------------------------+---------------------+ +| ``x`` | VarAccess_ | ++--------------------------------+ | +| ``e.f`` | | ++--------------------------------+---------------------+ +| ``a[i]`` | ArrayAccess_ | ++--------------------------------+---------------------+ +| ``f(...)`` | MethodAccess_ | ++--------------------------------+ | +| ``e.m(...)`` | | ++--------------------------------+---------------------+ +| ``String`` | TypeAccess_ | ++--------------------------------+ | +| ``java.lang.String`` | | ++--------------------------------+---------------------+ +| ``? extends Number`` | WildcardTypeAccess_ | ++--------------------------------+ | +| ``? super Double`` | | ++--------------------------------+---------------------+ + +A VarAccess_ that refers to a field is a FieldAccess_. + +Miscellaneous +~~~~~~~~~~~~~ + ++-------------------------------------+--------------------+----------------------------------------------------------------------------+ +| Expression syntax examples | CodeQL class | Remarks | ++=====================================+====================+============================================================================+ +| ``(int) f`` | CastExpr_ | | ++-------------------------------------+--------------------+----------------------------------------------------------------------------+ +| ``(23 + 42)`` | ParExpr_ | | ++-------------------------------------+--------------------+----------------------------------------------------------------------------+ +| ``o instanceof String`` | InstanceOfExpr_ | | ++-------------------------------------+--------------------+----------------------------------------------------------------------------+ +| `Expr`_ ``?`` `Expr`_ ``:`` `Expr`_ | ConditionalExpr_ | | ++-------------------------------------+--------------------+----------------------------------------------------------------------------+ +| ``String. class`` | TypeLiteral_ | | ++-------------------------------------+--------------------+----------------------------------------------------------------------------+ +| ``new A()`` | ClassInstanceExpr_ | | ++-------------------------------------+--------------------+----------------------------------------------------------------------------+ +| ``new String[3][2]`` | ArrayCreationExpr_ | | ++-------------------------------------+ | | +| ``new int[] { 23, 42 }`` | | | ++-------------------------------------+--------------------+----------------------------------------------------------------------------+ +| ``{ 23, 42 }`` | ArrayInit_ | can only appear as an initializer or as a child of an `ArrayCreationExpr`_ | ++-------------------------------------+--------------------+----------------------------------------------------------------------------+ +| ``@Annot(key=val)`` | Annotation_ | | ++-------------------------------------+--------------------+----------------------------------------------------------------------------+ + +Further reading +--------------- + +.. include:: ../reusables/java-further-reading.rst +.. include:: ../reusables/codeql-ref-tools-further-reading.rst + +.. Links used in tables. For information about using these links, see + https://www.sphinx-doc.org/en/master/usage/restructuredtext/basics.html#hyperlinks. + +.. _Expr: https://codeql.github.com/codeql-standard-libraries/java/semmle/code/java/Expr.qll/type.Expr$Expr.html +.. _Stmt: https://codeql.github.com/codeql-standard-libraries/java/semmle/code/java/Statement.qll/type.Statement$Stmt.html +.. _VarAccess: https://codeql.github.com/codeql-standard-libraries/java/semmle/code/java/Expr.qll/type.Expr$VarAccess.html +.. _SwitchCase: https://codeql.github.com/codeql-standard-libraries/java/semmle/code/java/Statement.qll/type.Statement$SwitchCase.html +.. _TypeAccess: https://codeql.github.com/codeql-standard-libraries/java/semmle/code/java/Expr.qll/type.Expr$TypeAccess.html +.. _Member: https://codeql.github.com/codeql-standard-libraries/java/semmle/code/java/Member.qll/type.Member$Member.html +.. _Literal: https://codeql.github.com/codeql-standard-libraries/java/semmle/code/java/Expr.qll/type.Expr$Literal.html +.. _ConditionalStmt: https://codeql.github.com/codeql-standard-libraries/java/semmle/code/java/Statement.qll/type.Statement$ConditionalStmt.html +.. _LoopStmt: https://codeql.github.com/codeql-standard-libraries/java/semmle/code/java/Statement.qll/type.Statement$LoopStmt.html +.. _JumpStmt: https://codeql.github.com/codeql-standard-libraries/java/semmle/code/java/Statement.qll/type.Statement$JumpStmt.html +.. _TryStmt: https://codeql.github.com/codeql-standard-libraries/java/semmle/code/java/Statement.qll/type.Statement$TryStmt.html +.. _SwitchStmt: https://codeql.github.com/codeql-standard-libraries/java/semmle/code/java/Statement.qll/type.Statement$SwitchStmt.html +.. _BooleanLiteral: https://codeql.github.com/codeql-standard-libraries/java/semmle/code/java/Expr.qll/type.Expr$BooleanLiteral.html +.. _IntegerLiteral: https://codeql.github.com/codeql-standard-libraries/java/semmle/code/java/Expr.qll/type.Expr$IntegerLiteral.html +.. _LongLiteral: https://codeql.github.com/codeql-standard-libraries/java/semmle/code/java/Expr.qll/type.Expr$LongLiteral.html +.. _FloatingPointLiteral: https://codeql.github.com/codeql-standard-libraries/java/semmle/code/java/Expr.qll/type.Expr$FloatingPointLiteral.html +.. _DoubleLiteral: https://codeql.github.com/codeql-standard-libraries/java/semmle/code/java/Expr.qll/type.Expr$DoubleLiteral.html +.. _CharacterLiteral: https://codeql.github.com/codeql-standard-libraries/java/semmle/code/java/Expr.qll/type.Expr$CharacterLiteral.html +.. _StringLiteral: https://codeql.github.com/codeql-standard-libraries/java/semmle/code/java/Expr.qll/type.Expr$StringLiteral.html +.. _NullLiteral: https://codeql.github.com/codeql-standard-libraries/java/semmle/code/java/Expr.qll/type.Expr$NullLiteral.html +.. _PostIncExpr: https://codeql.github.com/codeql-standard-libraries/java/semmle/code/java/Expr.qll/type.Expr$PostIncExpr.html +.. _PostDecExpr: https://codeql.github.com/codeql-standard-libraries/java/semmle/code/java/Expr.qll/type.Expr$PostDecExpr.html +.. _PreIncExpr: https://codeql.github.com/codeql-standard-libraries/java/semmle/code/java/Expr.qll/type.Expr$PreIncExpr.html +.. _PreDecExpr: https://codeql.github.com/codeql-standard-libraries/java/semmle/code/java/Expr.qll/type.Expr$PreDecExpr.html +.. _BitNotExpr: https://codeql.github.com/codeql-standard-libraries/java/semmle/code/java/Expr.qll/type.Expr$BitNotExpr.html +.. _MinusExpr: https://codeql.github.com/codeql-standard-libraries/java/semmle/code/java/Expr.qll/type.Expr$MinusExpr.html +.. _PlusExpr: https://codeql.github.com/codeql-standard-libraries/java/semmle/code/java/Expr.qll/type.Expr$PlusExpr.html +.. _LogNotExpr: https://codeql.github.com/codeql-standard-libraries/java/semmle/code/java/Expr.qll/type.Expr$LogNotExpr.html +.. _UnaryAssignExpr: https://codeql.github.com/codeql-standard-libraries/java/semmle/code/java/Expr.qll/type.Expr$UnaryAssignExpr.html +.. _BitwiseExpr: https://codeql.github.com/codeql-standard-libraries/java/semmle/code/java/Expr.qll/type.Expr$BitwiseExpr.html +.. _LogicExpr: https://codeql.github.com/codeql-standard-libraries/java/semmle/code/java/Expr.qll/type.Expr$LogicExpr.html +.. _MulExpr: https://codeql.github.com/codeql-standard-libraries/java/semmle/code/java/Expr.qll/type.Expr$MulExpr.html +.. _DivExpr: https://codeql.github.com/codeql-standard-libraries/java/semmle/code/java/Expr.qll/type.Expr$DivExpr.html +.. _RemExpr: https://codeql.github.com/codeql-standard-libraries/java/semmle/code/java/Expr.qll/type.Expr$RemExpr.html +.. _AddExpr: https://codeql.github.com/codeql-standard-libraries/java/semmle/code/java/Expr.qll/type.Expr$AddExpr.html +.. _SubExpr: https://codeql.github.com/codeql-standard-libraries/java/semmle/code/java/Expr.qll/type.Expr$SubExpr.html +.. _LShiftExpr: https://codeql.github.com/codeql-standard-libraries/java/semmle/code/java/Expr.qll/type.Expr$LShiftExpr.html +.. _RShiftExpr: https://codeql.github.com/codeql-standard-libraries/java/semmle/code/java/Expr.qll/type.Expr$RShiftExpr.html +.. _URShiftExpr: https://codeql.github.com/codeql-standard-libraries/java/semmle/code/java/Expr.qll/type.Expr$URShiftExpr.html +.. _AndLogicalExpr: https://codeql.github.com/codeql-standard-libraries/java/semmle/code/java/Expr.qll/type.Expr$AndLogicalExpr.html +.. _OrLogicalExpr: https://codeql.github.com/codeql-standard-libraries/java/semmle/code/java/Expr.qll/type.Expr$OrLogicalExpr.html +.. _LTExpr: https://codeql.github.com/codeql-standard-libraries/java/semmle/code/java/Expr.qll/type.Expr$LTExpr.html +.. _GTExpr: https://codeql.github.com/codeql-standard-libraries/java/semmle/code/java/Expr.qll/type.Expr$GTExpr.html +.. _LEExpr: https://codeql.github.com/codeql-standard-libraries/java/semmle/code/java/Expr.qll/type.Expr$LEExpr.html +.. _GEExpr: https://codeql.github.com/codeql-standard-libraries/java/semmle/code/java/Expr.qll/type.Expr$GEExpr.html +.. _EQExpr: https://codeql.github.com/codeql-standard-libraries/java/semmle/code/java/Expr.qll/type.Expr$EQExpr.html +.. _NEExpr: https://codeql.github.com/codeql-standard-libraries/java/semmle/code/java/Expr.qll/type.Expr$NEExpr.html +.. _AndBitwiseExpr: https://codeql.github.com/codeql-standard-libraries/java/semmle/code/java/Expr.qll/type.Expr$AndBitwiseExpr.html +.. _OrBitwiseExpr: https://codeql.github.com/codeql-standard-libraries/java/semmle/code/java/Expr.qll/type.Expr$OrBitwiseExpr.html +.. _XorBitwiseExpr: https://codeql.github.com/codeql-standard-libraries/java/semmle/code/java/Expr.qll/type.Expr$XorBitwiseExpr.html +.. _ComparisonExpr: https://codeql.github.com/codeql-standard-libraries/java/semmle/code/java/Expr.qll/type.Expr$ComparisonExpr.html +.. _EqualityTest: https://codeql.github.com/codeql-standard-libraries/java/semmle/code/java/Expr.qll/type.Expr$EqualityTest.html +.. _AssignExpr: https://codeql.github.com/codeql-standard-libraries/java/semmle/code/java/Expr.qll/type.Expr$AssignExpr.html +.. _AssignAddExpr: https://codeql.github.com/codeql-standard-libraries/java/semmle/code/java/Expr.qll/type.Expr$AssignAddExpr.html +.. _AssignSubExpr: https://codeql.github.com/codeql-standard-libraries/java/semmle/code/java/Expr.qll/type.Expr$AssignSubExpr.html +.. _AssignMulExpr: https://codeql.github.com/codeql-standard-libraries/java/semmle/code/java/Expr.qll/type.Expr$AssignMulExpr.html +.. _AssignDivExpr: https://codeql.github.com/codeql-standard-libraries/java/semmle/code/java/Expr.qll/type.Expr$AssignDivExpr.html +.. _AssignRemExpr: https://codeql.github.com/codeql-standard-libraries/java/semmle/code/java/Expr.qll/type.Expr$AssignRemExpr.html +.. _AssignAndExpr: https://codeql.github.com/codeql-standard-libraries/java/semmle/code/java/Expr.qll/type.Expr$AssignAndExpr.html +.. _AssignOrExpr: https://codeql.github.com/codeql-standard-libraries/java/semmle/code/java/Expr.qll/type.Expr$AssignOrExpr.html +.. _AssignXorExpr: https://codeql.github.com/codeql-standard-libraries/java/semmle/code/java/Expr.qll/type.Expr$AssignXorExpr.html +.. _AssignLShiftExpr: https://codeql.github.com/codeql-standard-libraries/java/semmle/code/java/Expr.qll/type.Expr$AssignLShiftExpr.html +.. _AssignRShiftExpr: https://codeql.github.com/codeql-standard-libraries/java/semmle/code/java/Expr.qll/type.Expr$AssignRShiftExpr.html +.. _AssignURShiftExpr: https://codeql.github.com/codeql-standard-libraries/java/semmle/code/java/Expr.qll/type.Expr$AssignURShiftExpr.html +.. _AssignOp: https://codeql.github.com/codeql-standard-libraries/java/semmle/code/java/Expr.qll/type.Expr$AssignOp.html +.. _ArrayCreationExpr: https://codeql.github.com/codeql-standard-libraries/java/semmle/code/java/Expr.qll/type.Expr$ArrayCreationExpr.html +.. _EmptyStmt: https://codeql.github.com/codeql-standard-libraries/java/semmle/code/java/Statement.qll/type.Statement$EmptyStmt.html +.. _ExprStmt: https://codeql.github.com/codeql-standard-libraries/java/semmle/code/java/Statement.qll/type.Statement$ExprStmt.html +.. _BlockStmt: https://codeql.github.com/codeql-standard-libraries/java/semmle/code/java/Statement.qll/type.Statement$BlockStmt.html +.. _IfStmt: https://codeql.github.com/codeql-standard-libraries/java/semmle/code/java/Statement.qll/type.Statement$IfStmt.html +.. _WhileStmt: https://codeql.github.com/codeql-standard-libraries/java/semmle/code/java/Statement.qll/type.Statement$WhileStmt.html +.. _DoStmt: https://codeql.github.com/codeql-standard-libraries/java/semmle/code/java/Statement.qll/type.Statement$DoStmt.html +.. _ForStmt: https://codeql.github.com/codeql-standard-libraries/java/semmle/code/java/Statement.qll/type.Statement$ForStmt.html +.. _EnhancedForStmt: https://codeql.github.com/codeql-standard-libraries/java/semmle/code/java/Statement.qll/type.Statement$EnhancedForStmt.html +.. _ReturnStmt: https://codeql.github.com/codeql-standard-libraries/java/semmle/code/java/Statement.qll/type.Statement$ReturnStmt.html +.. _ThrowStmt: https://codeql.github.com/codeql-standard-libraries/java/semmle/code/java/Statement.qll/type.Statement$ThrowStmt.html +.. _BreakStmt: https://codeql.github.com/codeql-standard-libraries/java/semmle/code/java/Statement.qll/type.Statement$BreakStmt.html +.. _ContinueStmt: https://codeql.github.com/codeql-standard-libraries/java/semmle/code/java/Statement.qll/type.Statement$ContinueStmt.html +.. _LabeledStmt: https://codeql.github.com/codeql-standard-libraries/java/semmle/code/java/Statement.qll/type.Statement$LabeledStmt.html +.. _SynchronizedStmt: https://codeql.github.com/codeql-standard-libraries/java/semmle/code/java/Statement.qll/type.Statement$SynchronizedStmt.html +.. _AssertStmt: https://codeql.github.com/codeql-standard-libraries/java/semmle/code/java/Statement.qll/type.Statement$AssertStmt.html +.. _LocalVariableDeclStmt: https://codeql.github.com/codeql-standard-libraries/java/semmle/code/java/Statement.qll/type.Statement$LocalVariableDeclStmt.html +.. _LocalClassDeclStmt: https://codeql.github.com/codeql-standard-libraries/java/semmle/code/java/Statement.qll/type.Statement$LocalClassDeclStmt.html +.. _ThisConstructorInvocationStmt: https://codeql.github.com/codeql-standard-libraries/java/semmle/code/java/Statement.qll/type.Statement$ThisConstructorInvocationStmt.html +.. _SuperConstructorInvocationStmt: https://codeql.github.com/codeql-standard-libraries/java/semmle/code/java/Statement.qll/type.Statement$SuperConstructorInvocationStmt.html +.. _CatchClause: https://codeql.github.com/codeql-standard-libraries/java/semmle/code/java/Statement.qll/type.Statement$CatchClause.html +.. _ConstCase: https://codeql.github.com/codeql-standard-libraries/java/semmle/code/java/Statement.qll/type.Statement$ConstCase.html +.. _DefaultCase: https://codeql.github.com/codeql-standard-libraries/java/semmle/code/java/Statement.qll/type.Statement$DefaultCase.html +.. _UnaryExpr: https://codeql.github.com/codeql-standard-libraries/java/semmle/code/java/Expr.qll/type.Expr$UnaryExpr.html +.. _BinaryExpr: https://codeql.github.com/codeql-standard-libraries/java/semmle/code/java/Expr.qll/type.Expr$BinaryExpr.html +.. _Assignment: https://codeql.github.com/codeql-standard-libraries/java/semmle/code/java/Expr.qll/type.Expr$Assignment.html +.. _ThisAccess: https://codeql.github.com/codeql-standard-libraries/java/semmle/code/java/Expr.qll/type.Expr$ThisAccess.html +.. _SuperAccess: https://codeql.github.com/codeql-standard-libraries/java/semmle/code/java/Expr.qll/type.Expr$SuperAccess.html +.. _ArrayAccess: https://codeql.github.com/codeql-standard-libraries/java/semmle/code/java/Expr.qll/type.Expr$ArrayAccess.html +.. _MethodAccess: https://codeql.github.com/codeql-standard-libraries/java/semmle/code/java/Expr.qll/type.Expr$MethodAccess.html +.. _WildcardTypeAccess: https://codeql.github.com/codeql-standard-libraries/java/semmle/code/java/Expr.qll/type.Expr$WildcardTypeAccess.html +.. _FieldAccess: https://codeql.github.com/codeql-standard-libraries/java/semmle/code/java/Expr.qll/type.Expr$FieldAccess.html +.. _CastExpr: https://codeql.github.com/codeql-standard-libraries/java/semmle/code/java/Expr.qll/type.Expr$CastExpr.html +.. _ParExpr: https://codeql.github.com/codeql-standard-libraries/java/semmle/code/java/Expr.qll/type.Expr$ParExpr.html +.. _InstanceOfExpr: https://codeql.github.com/codeql-standard-libraries/java/semmle/code/java/Expr.qll/type.Expr$InstanceOfExpr.html +.. _ConditionalExpr: https://codeql.github.com/codeql-standard-libraries/java/semmle/code/java/Expr.qll/type.Expr$ConditionalExpr.html +.. _TypeLiteral: https://codeql.github.com/codeql-standard-libraries/java/semmle/code/java/Expr.qll/type.Expr$TypeLiteral.html +.. _ClassInstanceExpr: https://codeql.github.com/codeql-standard-libraries/java/semmle/code/java/Expr.qll/type.Expr$ClassInstanceExpr.html +.. _ArrayInit: https://codeql.github.com/codeql-standard-libraries/java/semmle/code/java/Expr.qll/type.Expr$ArrayInit.html +.. _Annotation: https://codeql.github.com/codeql-standard-libraries/java/semmle/code/java/Annotation.qll/type.Annotation$Annotation.html \ No newline at end of file diff --git a/docs/codeql/codeql-language-guides/abstract-syntax-tree-classes-for-working-with-javascript-and-typescript-programs.rst b/docs/codeql/codeql-language-guides/abstract-syntax-tree-classes-for-working-with-javascript-and-typescript-programs.rst new file mode 100644 index 00000000000..cf26aeeafed --- /dev/null +++ b/docs/codeql/codeql-language-guides/abstract-syntax-tree-classes-for-working-with-javascript-and-typescript-programs.rst @@ -0,0 +1,526 @@ +.. _abstract-syntax-tree-classes-for-working-with-javascript-and-typescript-programs: + +Abstract syntax tree classes for working with JavaScript and TypeScript programs +================================================================================ + +CodeQL has a large selection of classes for representing the abstract syntax tree of JavaScript and TypeScript programs. + +.. include:: ../reusables/abstract-syntax-tree.rst + +Statement classes +----------------- + +This table lists subclasses of Stmt_ representing ECMAScript and TypeScript statements. + ++-------------------------------------------------------------------------------+--------------------------------+-------------------------------------------------------------+------------------------------------------------------------------------------------------------+ +| Statement syntax | CodeQL class | Superclasses | Remarks | ++===============================================================================+================================+=============================================================+================================================================================================+ +| Expr_ ``;`` | ExprStmt_ | | | ++-------------------------------------------------------------------------------+--------------------------------+-------------------------------------------------------------+------------------------------------------------------------------------------------------------+ +| Label_ ``:`` Stmt_ | LabeledStmt_ | | | ++-------------------------------------------------------------------------------+--------------------------------+-------------------------------------------------------------+------------------------------------------------------------------------------------------------+ +| ``;`` | EmptyStmt_ | | | ++-------------------------------------------------------------------------------+--------------------------------+-------------------------------------------------------------+------------------------------------------------------------------------------------------------+ +| ``break`` Label_ ``;`` | BreakStmt_ | JumpStmt_, BreakOrContinueStmt_ | | ++-------------------------------------------------------------------------------+--------------------------------+-------------------------------------------------------------+------------------------------------------------------------------------------------------------+ +| ``case`` Expr_ ``:`` Stmt_... | Case_ | | can only occur as child of a SwitchStmt_ | ++-------------------------------------------------------------------------------+--------------------------------+-------------------------------------------------------------+------------------------------------------------------------------------------------------------+ +| ``catch(`` Identifier_ ``)`` ``{`` Stmt_... ``}`` | CatchClause_ | ControlStmt_ | can only occur as child of a TryStmt_ | ++-------------------------------------------------------------------------------+--------------------------------+-------------------------------------------------------------+------------------------------------------------------------------------------------------------+ +| ``class`` Identifier_ ``extends`` Expr_ ``{`` MemberDeclaration_... ``}`` | ClassDeclStmt_ | ClassDefinition_, ClassOrInterface_, TypeParameterized_ | | ++-------------------------------------------------------------------------------+--------------------------------+-------------------------------------------------------------+------------------------------------------------------------------------------------------------+ +| ``const`` Identifier_ ``=`` Expr_ ``;`` | ConstDeclStmt_ | DeclStmt_ | | ++-------------------------------------------------------------------------------+--------------------------------+-------------------------------------------------------------+------------------------------------------------------------------------------------------------+ +| ``continue`` Label_ ``;`` | ContinueStmt_ | JumpStmt_, BreakOrContinueStmt_ | | ++-------------------------------------------------------------------------------+--------------------------------+-------------------------------------------------------------+------------------------------------------------------------------------------------------------+ +| ``debugger;`` | DebuggerStmt_ | | | ++-------------------------------------------------------------------------------+--------------------------------+-------------------------------------------------------------+------------------------------------------------------------------------------------------------+ +| ``declare`` ``global`` ``{`` Stmt_... ``}`` | GlobalAugmentationDeclaration_ | | | ++-------------------------------------------------------------------------------+--------------------------------+-------------------------------------------------------------+------------------------------------------------------------------------------------------------+ +| ``declare`` ``module`` StringLiteral_ ``{`` Stmt_... ``}`` | ExternalModuleDeclaration_ | | | ++-------------------------------------------------------------------------------+--------------------------------+-------------------------------------------------------------+------------------------------------------------------------------------------------------------+ +| ``default:`` Stmt_... | Case_ | | can only occur as child of a SwitchStmt_; use `isDefault` to distinguish `default` from `case` | ++-------------------------------------------------------------------------------+--------------------------------+-------------------------------------------------------------+------------------------------------------------------------------------------------------------+ +| ``do`` Stmt_ ``while`` ``(`` Expr_ ``)`` | DoWhileStmt_ | ControlStmt_, LoopStmt_ | | ++-------------------------------------------------------------------------------+--------------------------------+-------------------------------------------------------------+------------------------------------------------------------------------------------------------+ +| ``enum`` Identifier_ ``{`` MemberDeclaration_... ``}`` | EnumDeclaration_ | NamespaceDefinition_ | | ++-------------------------------------------------------------------------------+--------------------------------+-------------------------------------------------------------+------------------------------------------------------------------------------------------------+ +| ``export * from`` StringLiteral_ | BulkReExportDeclaration_ | ReExportDeclaration_, ExportDeclaration_ | | ++-------------------------------------------------------------------------------+--------------------------------+-------------------------------------------------------------+------------------------------------------------------------------------------------------------+ +| ``export default`` ClassDeclStmt_ | ExportDefaultDeclaration_ | ExportDeclaration_ | | ++-------------------------------------------------------------------------------+--------------------------------+-------------------------------------------------------------+------------------------------------------------------------------------------------------------+ +| ``export default`` Expr_ ``;`` | ExportDefaultDeclaration_ | ExportDeclaration_ | | ++-------------------------------------------------------------------------------+--------------------------------+-------------------------------------------------------------+------------------------------------------------------------------------------------------------+ +| ``export default`` FunctionDeclStmt_ | ExportDefaultDeclaration_ | ExportDeclaration_ | | ++-------------------------------------------------------------------------------+--------------------------------+-------------------------------------------------------------+------------------------------------------------------------------------------------------------+ +| ``export {`` ExportSpecifier_... ``};`` | ExportNamedDeclaration_ | ExportDeclaration_ | | ++-------------------------------------------------------------------------------+--------------------------------+-------------------------------------------------------------+------------------------------------------------------------------------------------------------+ +| ``export`` DeclStmt_ | ExportNamedDeclaration_ | ExportDeclaration_ | | ++-------------------------------------------------------------------------------+--------------------------------+-------------------------------------------------------------+------------------------------------------------------------------------------------------------+ +| ``export`` ``=`` Expr_ ``;`` | ExportAssignDeclaration_ | | | ++-------------------------------------------------------------------------------+--------------------------------+-------------------------------------------------------------+------------------------------------------------------------------------------------------------+ +| ``export`` ``as`` ``namespace`` Identifier_ ``;`` | ExportAsNamespaceDeclaration_ | | | ++-------------------------------------------------------------------------------+--------------------------------+-------------------------------------------------------------+------------------------------------------------------------------------------------------------+ +| ``for`` ``(`` Expr_ ``;`` Expr_ ``;`` Expr_ ``)`` Stmt_ | ForStmt_ | ControlStmt_, LoopStmt_ | | ++-------------------------------------------------------------------------------+--------------------------------+-------------------------------------------------------------+------------------------------------------------------------------------------------------------+ +| ``for`` ``(`` VarAccess_ ``in`` Expr_ ``)`` Stmt_ | ForInStmt_ | ControlStmt_, LoopStmt_, EnhancedForLoop_ | | ++-------------------------------------------------------------------------------+--------------------------------+-------------------------------------------------------------+------------------------------------------------------------------------------------------------+ +| ``for`` ``(`` VarAccess_ ``of`` Expr_ ``)`` Stmt_ | ForOfStmt_ | ControlStmt_, LoopStmt_, EnhancedForLoop_ | | ++-------------------------------------------------------------------------------+--------------------------------+-------------------------------------------------------------+------------------------------------------------------------------------------------------------+ +| ``function`` Identifier_ ``(`` Parameter_... ``)`` ``{`` Stmt_... ``}`` | FunctionDeclStmt_ | Function_ | | ++-------------------------------------------------------------------------------+--------------------------------+-------------------------------------------------------------+------------------------------------------------------------------------------------------------+ +| ``if`` ``(`` Expr_ ``)`` Stmt_ ``else`` Stmt_ | IfStmt_ | ControlStmt_ | | ++-------------------------------------------------------------------------------+--------------------------------+-------------------------------------------------------------+------------------------------------------------------------------------------------------------+ +| ``import {`` ImportSpecifier_... ``from`` StringLiteral_ | ImportDeclaration_ | Import_ | | ++-------------------------------------------------------------------------------+--------------------------------+-------------------------------------------------------------+------------------------------------------------------------------------------------------------+ +| ``import`` Identifier_ ``=`` Expr_ ``;`` | ImportEqualsDeclaration_ | | | ++-------------------------------------------------------------------------------+--------------------------------+-------------------------------------------------------------+------------------------------------------------------------------------------------------------+ +| ``interface`` Identifier_ ``{`` MemberDeclaration_... ``}`` | InterfaceDeclaration_ | InterfaceDefinition_, ClassOrInterface_, TypeParameterized_ | | ++-------------------------------------------------------------------------------+--------------------------------+-------------------------------------------------------------+------------------------------------------------------------------------------------------------+ +| ``let`` Identifier_ ``=`` Expr_ ``;`` | LetStmt_ | DeclStmt_ | | ++-------------------------------------------------------------------------------+--------------------------------+-------------------------------------------------------------+------------------------------------------------------------------------------------------------+ +| ``namespace`` Identifier_ ``{`` Stmt_... ``}`` | NamespaceDeclaration_ | NamespaceDefinition_ | | ++-------------------------------------------------------------------------------+--------------------------------+-------------------------------------------------------------+------------------------------------------------------------------------------------------------+ +| ``return`` Expr_ ``;`` | ReturnStmt_ | JumpStmt_ | | ++-------------------------------------------------------------------------------+--------------------------------+-------------------------------------------------------------+------------------------------------------------------------------------------------------------+ +| ``switch`` ``(`` Expr_ ``) {`` Case_... ``}`` | SwitchStmt_ | ControlStmt_ | | ++-------------------------------------------------------------------------------+--------------------------------+-------------------------------------------------------------+------------------------------------------------------------------------------------------------+ +| ``throw`` Expr_ ``;`` | ThrowStmt_ | JumpStmt_ | | ++-------------------------------------------------------------------------------+--------------------------------+-------------------------------------------------------------+------------------------------------------------------------------------------------------------+ +| ``try`` ``{`` Stmt_... ``}`` CatchClause_... ``finally`` ``{`` Stmt_... ``}`` | TryStmt_ | ControlStmt_ | | ++-------------------------------------------------------------------------------+--------------------------------+-------------------------------------------------------------+------------------------------------------------------------------------------------------------+ +| ``type`` Identifier_ ``=`` TypeExpr_ ``;`` | TypeAliasDeclaration_ | TypeParameterized_ | | ++-------------------------------------------------------------------------------+--------------------------------+-------------------------------------------------------------+------------------------------------------------------------------------------------------------+ +| ``var`` Identifier_ ``=`` Expr_ ``;`` | VarDeclStmt_ | DeclStmt_ | | ++-------------------------------------------------------------------------------+--------------------------------+-------------------------------------------------------------+------------------------------------------------------------------------------------------------+ +| ``while`` ``(`` Expr_ ``)`` Stmt_ | WhileStmt_ | ControlStmt_, LoopStmt_ | | ++-------------------------------------------------------------------------------+--------------------------------+-------------------------------------------------------------+------------------------------------------------------------------------------------------------+ +| ``with`` ``(`` Expr_ ``)`` Stmt_ | WithStmt_ | ControlStmt_ | | ++-------------------------------------------------------------------------------+--------------------------------+-------------------------------------------------------------+------------------------------------------------------------------------------------------------+ +| ``{`` Stmt_... ``}`` | BlockStmt_ | | | ++-------------------------------------------------------------------------------+--------------------------------+-------------------------------------------------------------+------------------------------------------------------------------------------------------------+ + +Expression classes +------------------ + +There is a large number of expression classes, so we present them by category. All classes in this section are subclasses of Expr_, except where noted otherwise. + +Literals +~~~~~~~~ + +All classes in this subsection are subclasses of Literal_. + ++-------------------+-----------------+ +| Expression syntax | CodeQL class | ++===================+=================+ +| ``true`` | BooleanLiteral_ | ++-------------------+-----------------+ +| ``23`` | NumberLiteral_ | ++-------------------+-----------------+ +| ``4.2`` | NumberLiteral_ | ++-------------------+-----------------+ +| ``"Hello"`` | StringLiteral_ | ++-------------------+-----------------+ +| ``/ab*c?/`` | RegExpLiteral_ | ++-------------------+-----------------+ +| ``null`` | NullLiteral_ | ++-------------------+-----------------+ + +Identifiers +~~~~~~~~~~~ + +All identifiers are represented by the class Identifier_, which has subclasses to represent specific kinds of identifiers: + +- VarAccess_: an identifier that refers to a variable +- VarDecl_: an identifier that declares a variable, for example ``x`` in ``var x = "hi"`` or in ``function(x) { }`` +- VarRef_: a VarAccess_ or a VarDecl_ +- Label_: an identifier that refers to a statement label or a property, not a variable; in the following examples, ``l`` and ``p`` are labels: + + - ``break l;`` + - ``l: for(;;) {}`` + - ``x.p`` + - ``{ p: 42 }`` + + +Primary expressions +~~~~~~~~~~~~~~~~~~~ + +All classes in this subsection are subclasses of Expr_. + ++-------------------------------------------------------------+---------------------+--------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| Expression syntax | CodeQL class | Superclasses | Remarks | ++=============================================================+=====================+==============+============================================================================================================================================================================================================+ +| ``this`` | ThisExpr_ | | | ++-------------------------------------------------------------+---------------------+--------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| ``[`` Expr_... ``]`` | ArrayExpr_ | | | ++-------------------------------------------------------------+---------------------+--------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| ``{`` Property_... ``}`` | ObjectExpr_ | | | ++-------------------------------------------------------------+---------------------+--------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| ``function`` ``(`` Parameter_... ``)`` ``{`` Stmt_... ``}`` | FunctionExpr_ | Function_ | | ++-------------------------------------------------------------+---------------------+--------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| ``(`` Parameter_... ``)`` ``=>`` Expr_ | ArrowFunctionExpr_ | Function_ | | ++-------------------------------------------------------------+---------------------+--------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| ``(`` Expr_ ``)`` | ParExpr_ | | | ++-------------------------------------------------------------+---------------------+--------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| ````` ... ````` | TemplateLiteral_ | | an element in a TemplateLiteral_ is either a TemplateElement_ representing a constant template element, or some other expression representing an interpolated expression of the form ``${`` Expr_ ``}`` | ++-------------------------------------------------------------+---------------------+--------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| Expr_ ````` ... ````` | TaggedTemplateExpr_ | | an element in a TaggedTemplateExpr_ is either a TemplateElement_ representing a constant template element, or some other expression representing an interpolated expression of the form ``${`` Expr_ ``}`` | ++-------------------------------------------------------------+---------------------+--------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ + +Properties +~~~~~~~~~~ + +All classes in this subsection are subclasses of Property_. Note that Property_ is not a subclass of Expr_. + ++------------------------------------------------------------------+-----------------+-------------------+ +| Property syntax | CodeQL class | Superclasses | ++==================================================================+=================+===================+ +| Identifier_ ``:`` Expr_ | ValueProperty_ | | ++------------------------------------------------------------------+-----------------+-------------------+ +| ``get`` Identifier_ ``()`` ``{`` Stmt_... ``}`` | PropertyGetter_ | PropertyAccessor_ | ++------------------------------------------------------------------+-----------------+-------------------+ +| ``set`` Identifier_ ``(`` Identifier_ ``)`` ``{`` Stmt_... ``}`` | PropertySetter_ | PropertyAccessor_ | ++------------------------------------------------------------------+-----------------+-------------------+ + +Property accesses +~~~~~~~~~~~~~~~~~ + +All classes in this subsection are subclasses of PropAccess_. + ++-------------------------+--------------+ +| Expression syntax | CodeQL class | ++=========================+==============+ +| Expr_ ``.`` Identifier_ | DotExpr_ | ++-------------------------+--------------+ +| Expr_ ``[`` Expr_ ``]`` | IndexExpr_ | ++-------------------------+--------------+ + +Function calls and ``new`` +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +All classes in this subsection are subclasses of InvokeExpr_. + ++-----------------------------------------------+-----------------+-----------------------------------------------------------------------------------+ +| Expression syntax | CodeQL class | Remarks | ++===============================================+=================+===================================================================================+ +| Expr_ ``(`` Expr_... ``)`` | CallExpr_ | | ++-----------------------------------------------+-----------------+-----------------------------------------------------------------------------------+ +| Expr_ ``.`` Identifier_ ``(`` Expr_... ``)`` | MethodCallExpr_ | this also includes calls of the form Expr_ ``[`` Expr_ ``]`` ``(`` Expr_... ``)`` | ++-----------------------------------------------+-----------------+-----------------------------------------------------------------------------------+ +| ``new`` Expr_ ``(`` Expr_... ``)`` | NewExpr_ | | ++-----------------------------------------------+-----------------+-----------------------------------------------------------------------------------+ + +Unary expressions +~~~~~~~~~~~~~~~~~ + +All classes in this subsection are subclasses of UnaryExpr_. + ++-------------------+----------------+ +| Expression syntax | CodeQL class | ++===================+================+ +| ``~`` Expr_ | BitNotExpr_ | ++-------------------+----------------+ +| ``-`` Expr_ | NegExpr_ | ++-------------------+----------------+ +| ``+`` Expr_ | PlusExpr_ | ++-------------------+----------------+ +| ``!`` Expr_ | LogNotExpr_ | ++-------------------+----------------+ +| ``typeof`` Expr_ | TypeofExpr_ | ++-------------------+----------------+ +| ``void`` Expr_ | VoidExpr_ | ++-------------------+----------------+ +| ``delete`` Expr_ | DeleteExpr_ | ++-------------------+----------------+ +| ``...`` Expr_ | SpreadElement_ | ++-------------------+----------------+ + +Binary expressions +~~~~~~~~~~~~~~~~~~ + +All classes in this subsection are subclasses of BinaryExpr_. + ++----------------------------+-----------------+----------------------------+ +| Expression syntax | CodeQL class | Superclasses | ++============================+=================+============================+ +| Expr_ ``*`` Expr_ | MulExpr_ | | ++----------------------------+-----------------+----------------------------+ +| Expr_ ``/`` Expr_ | DivExpr_ | | ++----------------------------+-----------------+----------------------------+ +| Expr_ ``%`` Expr_ | ModExpr_ | | ++----------------------------+-----------------+----------------------------+ +| Expr_ ``**`` Expr_ | ExpExpr_ | | ++----------------------------+-----------------+----------------------------+ +| Expr_ ``+`` Expr_ | AddExpr_ | | ++----------------------------+-----------------+----------------------------+ +| Expr_ ``-`` Expr_ | SubExpr_ | | ++----------------------------+-----------------+----------------------------+ +| Expr_ ``<<`` Expr_ | LShiftExpr_ | | ++----------------------------+-----------------+----------------------------+ +| Expr_ ``>>`` Expr_ | RShiftExpr_ | | ++----------------------------+-----------------+----------------------------+ +| Expr_ ``>>>`` Expr_ | URShiftExpr_ | | ++----------------------------+-----------------+----------------------------+ +| Expr_ ``&&`` Expr_ | LogAndExpr_ | | ++----------------------------+-----------------+----------------------------+ +| Expr_ ``||`` Expr_ | LogOrExpr_ | | ++----------------------------+-----------------+----------------------------+ +| Expr_ ``<`` Expr_ | LTExpr_ | Comparison_ | ++----------------------------+-----------------+----------------------------+ +| Expr_ ``>`` Expr_ | GTExpr_ | Comparison_ | ++----------------------------+-----------------+----------------------------+ +| Expr_ ``<=`` Expr_ | LEExpr_ | Comparison_ | ++----------------------------+-----------------+----------------------------+ +| Expr_ ``>=`` Expr_ | GEExpr_ | Comparison_ | ++----------------------------+-----------------+----------------------------+ +| Expr_ ``==`` Expr_ | EqExpr_ | EqualityTest_, Comparison_ | ++----------------------------+-----------------+----------------------------+ +| Expr_ ``!=`` Expr_ | NEqExpr_ | EqualityTest_, Comparison_ | ++----------------------------+-----------------+----------------------------+ +| Expr_ ``===`` Expr_ | StrictEqExpr_ | EqualityTest_, Comparison_ | ++----------------------------+-----------------+----------------------------+ +| Expr_ ``!==`` Expr_ | StrictNEqExpr_ | EqualityTest_, Comparison_ | ++----------------------------+-----------------+----------------------------+ +| Expr_ ``&`` Expr_ | BitAndExpr_ | | ++----------------------------+-----------------+----------------------------+ +| Expr_ ``|`` Expr_ | BitOrExpr_ | | ++----------------------------+-----------------+----------------------------+ +| Expr_ ``^`` Expr_ | XOrExpr_ | | ++----------------------------+-----------------+----------------------------+ +| Expr_ ``in`` Expr_ | InExpr_ | | ++----------------------------+-----------------+----------------------------+ +| Expr_ ``instanceof`` Expr_ | InstanceofExpr_ | | ++----------------------------+-----------------+----------------------------+ + +Assignment expressions +~~~~~~~~~~~~~~~~~~~~~~ + +All classes in this table are subclasses of Assignment_. + ++----------------------+--------------------+---------------------+ +| Expression syntax | CodeQL class | Superclasses | ++======================+====================+=====================+ +| Expr_ ``=`` Expr_ | AssignExpr_ | | ++----------------------+--------------------+---------------------+ +| Expr_ ``+=`` Expr_ | AssignAddExpr_ | CompoundAssignExpr_ | ++----------------------+--------------------+---------------------+ +| Expr_ ``-=`` Expr_ | AssignSubExpr_ | CompoundAssignExpr_ | ++----------------------+--------------------+---------------------+ +| Expr_ ``*=`` Expr_ | AssignMulExpr_ | CompoundAssignExpr_ | ++----------------------+--------------------+---------------------+ +| Expr_ ``**=`` Expr_ | AssignExpExpr_ | CompoundAssignExpr_ | ++----------------------+--------------------+---------------------+ +| Expr_ ``/=`` Expr_ | AssignDivExpr_ | CompoundAssignExpr_ | ++----------------------+--------------------+---------------------+ +| Expr_ ``%=`` Expr_ | AssignModExpr_ | CompoundAssignExpr_ | ++----------------------+--------------------+---------------------+ +| Expr_ ``&=`` Expr_ | AssignAndExpr_ | CompoundAssignExpr_ | ++----------------------+--------------------+---------------------+ +| Expr_ ``|=`` Expr_ | AssignOrExpr_ | CompoundAssignExpr_ | ++----------------------+--------------------+---------------------+ +| Expr_ ``^=`` Expr_ | AssignXOrExpr_ | CompoundAssignExpr_ | ++----------------------+--------------------+---------------------+ +| Expr_ ``<<=`` Expr_ | AssignLShiftExpr_ | CompoundAssignExpr_ | ++----------------------+--------------------+---------------------+ +| Expr_ ``>>=`` Expr_ | AssignRShiftExpr_ | CompoundAssignExpr_ | ++----------------------+--------------------+---------------------+ +| Expr_ ``>>>=`` Expr_ | AssignURShiftExpr_ | CompoundAssignExpr_ | ++----------------------+--------------------+---------------------+ + +Update expressions +~~~~~~~~~~~~~~~~~~ + +All classes in this table are subclasses of UpdateExpr_. + ++-------------------+--------------+ +| Expression syntax | CodeQL class | ++===================+==============+ +| Expr_ ``++`` | PostIncExpr_ | ++-------------------+--------------+ +| Expr_ ``--`` | PostDecExpr_ | ++-------------------+--------------+ +| ``++`` Expr_ | PreIncExpr_ | ++-------------------+--------------+ +| ``--`` Expr_ | PreDecExpr_ | ++-------------------+--------------+ + +Miscellaneous +~~~~~~~~~~~~~ + +All classes in this table are subclasses of Expr_. + ++-------------------------------+------------------+ +| Expression syntax | CodeQL class | ++===============================+==================+ +| Expr_ ``?`` Expr_ ``:`` Expr_ | ConditionalExpr_ | ++-------------------------------+------------------+ +| Expr_ ``,`` ... ``,`` Expr_ | SeqExpr_ | ++-------------------------------+------------------+ +| ``await`` Expr_ | AwaitExpr_ | ++-------------------------------+------------------+ +| ``yield`` Expr_ | YieldExpr_ | ++-------------------------------+------------------+ + +Further reading +--------------- + +.. include:: ../reusables/javascript-further-reading.rst +.. include:: ../reusables/codeql-ref-tools-further-reading.rst + + +.. Links used in tables. For information about using these links, see + https://www.sphinx-doc.org/en/master/usage/restructuredtext/basics.html#hyperlinks. + +.. _Stmt: https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Stmt.qll/type.Stmt$Stmt.html +.. _Expr: https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$Expr.html +.. _ExprStmt: https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Stmt.qll/type.Stmt$ExprStmt.html +.. _Label: https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$Label.html +.. _LabeledStmt: https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Stmt.qll/type.Stmt$LabeledStmt.html +.. _EmptyStmt: https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Stmt.qll/type.Stmt$EmptyStmt.html +.. _BreakStmt: https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Stmt.qll/type.Stmt$BreakStmt.html +.. _JumpStmt: https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Stmt.qll/type.Stmt$JumpStmt.html +.. _BreakOrContinueStmt: https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Stmt.qll/type.Stmt$BreakOrContinueStmt.html +.. _Case: https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Stmt.qll/type.Stmt$Case.html +.. _SwitchStmt: https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Stmt.qll/type.Stmt$SwitchStmt.html +.. _Identifier: https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$Identifier.html +.. _CatchClause: https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Stmt.qll/type.Stmt$CatchClause.html +.. _ControlStmt: https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Stmt.qll/type.Stmt$ControlStmt.html +.. _TryStmt: https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Stmt.qll/type.Stmt$TryStmt.html +.. _MemberDeclaration: https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Classes.qll/type.Classes$MemberDeclaration.html +.. _ClassDeclStmt: https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Classes.qll/type.Classes$ClassDeclStmt.html +.. _ClassDefinition: https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Classes.qll/type.Classes$ClassDefinition.html +.. _ClassOrInterface: https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Classes.qll/type.Classes$ClassOrInterface.html +.. _TypeParameterized: https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/TypeScript.qll/type.TypeScript$TypeParameterized.html +.. _ConstDeclStmt: https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Stmt.qll/type.Stmt$ConstDeclStmt.html +.. _DeclStmt: https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Stmt.qll/type.Stmt$DeclStmt.html +.. _ContinueStmt: https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Stmt.qll/type.Stmt$ContinueStmt.html +.. _DebuggerStmt: https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Stmt.qll/type.Stmt$DebuggerStmt.html +.. _GlobalAugmentationDeclaration: https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/TypeScript.qll/type.TypeScript$GlobalAugmentationDeclaration.html +.. _StringLiteral: https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$StringLiteral.html +.. _ExternalModuleDeclaration: https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/TypeScript.qll/type.TypeScript$ExternalModuleDeclaration.html +.. _DoWhileStmt: https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Stmt.qll/type.Stmt$DoWhileStmt.html +.. _LoopStmt: https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Stmt.qll/type.Stmt$LoopStmt.html +.. _EnumDeclaration: https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/TypeScript.qll/type.TypeScript$EnumDeclaration.html +.. _NamespaceDefinition: https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/TypeScript.qll/type.TypeScript$NamespaceDefinition.html +.. _BulkReExportDeclaration: https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/ES2015Modules.qll/type.ES2015Modules$BulkReExportDeclaration.html +.. _ReExportDeclaration: https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/ES2015Modules.qll/type.ES2015Modules$ReExportDeclaration.html +.. _ExportDeclaration: https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/ES2015Modules.qll/type.ES2015Modules$ExportDeclaration.html +.. _ExportDefaultDeclaration: https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/ES2015Modules.qll/type.ES2015Modules$ExportDefaultDeclaration.html +.. _FunctionDeclStmt: https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Stmt.qll/type.Stmt$FunctionDeclStmt.html +.. _ExportSpecifier: https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/ES2015Modules.qll/type.ES2015Modules$ExportSpecifier.html +.. _ExportNamedDeclaration: https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/ES2015Modules.qll/type.ES2015Modules$ExportNamedDeclaration.html +.. _ExportAssignDeclaration: https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/TypeScript.qll/type.TypeScript$ExportAssignDeclaration.html +.. _ExportAsNamespaceDeclaration: https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/TypeScript.qll/type.TypeScript$ExportAsNamespaceDeclaration.html +.. _ForStmt: https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Stmt.qll/type.Stmt$ForStmt.html +.. _VarAccess: https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Variables.qll/type.Variables$VarAccess.html +.. _ForInStmt: https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Stmt.qll/type.Stmt$ForInStmt.html +.. _EnhancedForLoop: https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Stmt.qll/type.Stmt$EnhancedForLoop.html +.. _ForOfStmt: https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Stmt.qll/type.Stmt$ForOfStmt.html +.. _Parameter: https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Variables.qll/type.Variables$Parameter.html +.. _Function: https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Functions.qll/type.Functions$Function.html +.. _IfStmt: https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Stmt.qll/type.Stmt$IfStmt.html +.. _ImportSpecifier: https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/ES2015Modules.qll/type.ES2015Modules$ImportSpecifier.html +.. _ImportDeclaration: https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/ES2015Modules.qll/type.ES2015Modules$ImportDeclaration.html +.. _Import: https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Modules.qll/type.Modules$Import.html +.. _ImportEqualsDeclaration: https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/TypeScript.qll/type.TypeScript$ImportEqualsDeclaration.html +.. _InterfaceDeclaration: https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/TypeScript.qll/type.TypeScript$InterfaceDeclaration.html +.. _InterfaceDefinition: https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/TypeScript.qll/type.TypeScript$InterfaceDefinition.html +.. _LetStmt: https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Stmt.qll/type.Stmt$LetStmt.html +.. _NamespaceDeclaration: https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/TypeScript.qll/type.TypeScript$NamespaceDeclaration.html +.. _ReturnStmt: https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Stmt.qll/type.Stmt$ReturnStmt.html +.. _ThrowStmt: https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Stmt.qll/type.Stmt$ThrowStmt.html +.. _TypeExpr: https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/TypeScript.qll/type.TypeScript$TypeExpr.html +.. _TypeAliasDeclaration: https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/TypeScript.qll/type.TypeScript$TypeAliasDeclaration.html +.. _VarDeclStmt: https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Stmt.qll/type.Stmt$VarDeclStmt.html +.. _WhileStmt: https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Stmt.qll/type.Stmt$WhileStmt.html +.. _WithStmt: https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Stmt.qll/type.Stmt$WithStmt.html +.. _BlockStmt: https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Stmt.qll/type.Stmt$BlockStmt.html +.. _Literal: https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$Literal.html +.. _BooleanLiteral: https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$BooleanLiteral.html +.. _NumberLiteral: https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$NumberLiteral.html +.. _RegExpLiteral: https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$RegExpLiteral.html +.. _NullLiteral: https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$NullLiteral.html +.. _VarDecl: https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Variables.qll/type.Variables$VarDecl.html +.. _VarRef: https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Variables.qll/type.Variables$VarRef.html +.. _ThisExpr: https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$ThisExpr.html +.. _ArrayExpr: https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$ArrayExpr.html +.. _Property: https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$Property.html +.. _ObjectExpr: https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$ObjectExpr.html +.. _FunctionExpr: https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$FunctionExpr.html +.. _ArrowFunctionExpr: https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$ArrowFunctionExpr.html +.. _ParExpr: https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$ParExpr.html +.. _TemplateLiteral: https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Templates.qll/type.Templates$TemplateLiteral.html +.. _TemplateElement: https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Templates.qll/type.Templates$TemplateElement.html +.. _TaggedTemplateExpr: https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Templates.qll/type.Templates$TaggedTemplateExpr.html +.. _ValueProperty: https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$ValueProperty.html +.. _PropertyGetter: https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$PropertyGetter.html +.. _PropertyAccessor: https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$PropertyAccessor.html +.. _PropertySetter: https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$PropertySetter.html +.. _PropAccess: https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$PropAccess.html +.. _DotExpr: https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$DotExpr.html +.. _IndexExpr: https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$IndexExpr.html +.. _InvokeExpr: https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$InvokeExpr.html +.. _CallExpr: https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$CallExpr.html +.. _MethodCallExpr: https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$MethodCallExpr.html +.. _NewExpr: https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$NewExpr.html +.. _UnaryExpr: https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$UnaryExpr.html +.. _BitNotExpr: https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$BitNotExpr.html +.. _NegExpr: https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$NegExpr.html +.. _PlusExpr: https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$PlusExpr.html +.. _LogNotExpr: https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$LogNotExpr.html +.. _TypeofExpr: https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$TypeofExpr.html +.. _VoidExpr: https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$VoidExpr.html +.. _DeleteExpr: https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$DeleteExpr.html +.. _SpreadElement: https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$SpreadElement.html +.. _BinaryExpr: https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$BinaryExpr.html +.. _MulExpr: https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$MulExpr.html +.. _DivExpr: https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$DivExpr.html +.. _ModExpr: https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$ModExpr.html +.. _ExpExpr: https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$ExpExpr.html +.. _AddExpr: https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$AddExpr.html +.. _SubExpr: https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$SubExpr.html +.. _LShiftExpr: https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$LShiftExpr.html +.. _RShiftExpr: https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$RShiftExpr.html +.. _URShiftExpr: https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$URShiftExpr.html +.. _LogAndExpr: https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$LogAndExpr.html +.. _LogOrExpr: https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$LogOrExpr.html +.. _LTExpr: https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$LTExpr.html +.. _Comparison: https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$Comparison.html +.. _GTExpr: https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$GTExpr.html +.. _LEExpr: https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$LEExpr.html +.. _GEExpr: https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$GEExpr.html +.. _EqExpr: https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$EqExpr.html +.. _EqualityTest: https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$EqualityTest.html +.. _NEqExpr: https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$NEqExpr.html +.. _StrictEqExpr: https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$StrictEqExpr.html +.. _StrictNEqExpr: https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$StrictNEqExpr.html +.. _BitAndExpr: https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$BitAndExpr.html +.. _BitOrExpr: https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$BitOrExpr.html +.. _XOrExpr: https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$XOrExpr.html +.. _InExpr: https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$InExpr.html +.. _InstanceofExpr: https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$InstanceofExpr.html +.. _Assignment: https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$Assignment.html +.. _AssignExpr: https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$AssignExpr.html +.. _AssignAddExpr: https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$AssignAddExpr.html +.. _CompoundAssignExpr: https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$CompoundAssignExpr.html +.. _AssignSubExpr: https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$AssignSubExpr.html +.. _AssignMulExpr: https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$AssignMulExpr.html +.. _AssignExpExpr: https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$AssignExpExpr.html +.. _AssignDivExpr: https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$AssignDivExpr.html +.. _AssignModExpr: https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$AssignModExpr.html +.. _AssignAndExpr: https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$AssignAndExpr.html +.. _AssignOrExpr: https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$AssignOrExpr.html +.. _AssignXOrExpr: https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$AssignXOrExpr.html +.. _AssignLShiftExpr: https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$AssignLShiftExpr.html +.. _AssignRShiftExpr: https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$AssignRShiftExpr.html +.. _AssignURShiftExpr: https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$AssignURShiftExpr.html +.. _UpdateExpr: https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$UpdateExpr.html +.. _PostIncExpr: https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$PostIncExpr.html +.. _PostDecExpr: https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$PostDecExpr.html +.. _PreIncExpr: https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$PreIncExpr.html +.. _PreDecExpr: https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$PreDecExpr.html +.. _ConditionalExpr: https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$ConditionalExpr.html +.. _SeqExpr: https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$SeqExpr.html +.. _AwaitExpr: https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$AwaitExpr.html +.. _YieldExpr: https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$YieldExpr.html + diff --git a/docs/codeql/codeql-language-guides/codeql-for-python/analyzing-control-flow-in-python.rst b/docs/codeql/codeql-language-guides/analyzing-control-flow-in-python.rst similarity index 93% rename from docs/codeql/codeql-language-guides/codeql-for-python/analyzing-control-flow-in-python.rst rename to docs/codeql/codeql-language-guides/analyzing-control-flow-in-python.rst index 16678f273ba..22b7cd1edb5 100644 --- a/docs/codeql/codeql-language-guides/codeql-for-python/analyzing-control-flow-in-python.rst +++ b/docs/codeql/codeql-language-guides/analyzing-control-flow-in-python.rst @@ -8,7 +8,7 @@ You can write CodeQL queries to explore the control-flow graph of a Python progr About analyzing control flow -------------------------------------- -To analyze the control-flow graph of a ``Scope`` we can use the two CodeQL classes ``ControlFlowNode`` and ``BasicBlock``. These classes allow you to ask such questions as "can you reach point A from point B?" or "Is it possible to reach point B *without* going through point A?". To report results we use the class ``AstNode``, which represents a syntactic element and corresponds to the source code - allowing the results of the query to be more easily understood. For more information, see `Control-flow graph <http://en.wikipedia.org/wiki/Control_flow_graph>`__ on Wikipedia. +To analyze the control-flow graph of a ``Scope`` we can use the two CodeQL classes ``ControlFlowNode`` and ``BasicBlock``. These classes allow you to ask such questions as "can you reach point A from point B?" or "Is it possible to reach point B *without* going through point A?". To report results we use the class ``AstNode``, which represents a syntactic element and corresponds to the source code - allowing the results of the query to be more easily understood. For more information, see `Control-flow graph <https://en.wikipedia.org/wiki/Control_flow_graph>`__ on Wikipedia. The ``ControlFlowNode`` class ----------------------------- @@ -32,7 +32,7 @@ An annotated flow graph: |Python control flow graph| -.. |Python control flow graph| image:: ../../images/python-flow-graph.png +.. |Python control flow graph| image:: ../images/python-flow-graph.png The simplest use of the ``ControlFlowNode`` and ``AstNode`` classes is to find unreachable code. There is one ``ControlFlowNode`` per path through any ``AstNode`` and any ``AstNode`` that is unreachable has no paths flowing through it. Therefore, any ``AstNode`` without a corresponding ``ControlFlowNode`` is unreachable. @@ -65,7 +65,7 @@ Example finding unreachable statements The ``BasicBlock`` class ------------------------ -The ``BasicBlock`` class represents a basic block of control flow nodes. The ``BasicBlock`` class is not that useful for writing queries directly, but is very useful for building complex analyses, such as data flow. The reason it is useful is that it shares many of the interesting properties of control flow nodes, such as, what can reach what, and what dominates what, but there are fewer basic blocks than control flow nodes - resulting in queries that are faster and use less memory. For more information, see `Basic block <http://en.wikipedia.org/wiki/Basic_block>`__ and `Dominator <http://en.wikipedia.org/wiki/Dominator_%28graph_theory%29>`__ on Wikipedia. +The ``BasicBlock`` class represents a basic block of control flow nodes. The ``BasicBlock`` class is not that useful for writing queries directly, but is very useful for building complex analyses, such as data flow. The reason it is useful is that it shares many of the interesting properties of control flow nodes, such as, what can reach what, and what dominates what, but there are fewer basic blocks than control flow nodes - resulting in queries that are faster and use less memory. For more information, see `Basic block <https://en.wikipedia.org/wiki/Basic_block>`__ and `Dominator <https://en.wikipedia.org/wiki/Dominator_%28graph_theory%29>`__ on Wikipedia. Example finding mutually exclusive basic blocks ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -119,6 +119,6 @@ Example finding mutually exclusive blocks within the same function Further reading --------------- -.. include:: ../../reusables/python-further-reading.rst -.. include:: ../../reusables/codeql-ref-tools-further-reading.rst +.. include:: ../reusables/python-further-reading.rst +.. include:: ../reusables/codeql-ref-tools-further-reading.rst diff --git a/docs/codeql/codeql-language-guides/codeql-for-python/analyzing-data-flow-and-tracking-tainted-data-in-python.rst b/docs/codeql/codeql-language-guides/analyzing-data-flow-and-tracking-tainted-data-in-python.rst similarity index 86% rename from docs/codeql/codeql-language-guides/codeql-for-python/analyzing-data-flow-and-tracking-tainted-data-in-python.rst rename to docs/codeql/codeql-language-guides/analyzing-data-flow-and-tracking-tainted-data-in-python.rst index 1971c5a3e7a..5d9d1eb844a 100644 --- a/docs/codeql/codeql-language-guides/codeql-for-python/analyzing-data-flow-and-tracking-tainted-data-in-python.rst +++ b/docs/codeql/codeql-language-guides/analyzing-data-flow-and-tracking-tainted-data-in-python.rst @@ -17,7 +17,7 @@ Taint tracking differs from basic data flow in that it considers non-value-prese For example, in the assignment ``dir = path + "/"``, if ``path`` is tainted then ``dir`` is also tainted, even though there is no data flow from ``path`` to ``path + "/"``. -Separate CodeQL libraries have been written to handle 'normal' data flow and taint tracking in :doc:`C/C++ <../codeql-for-cpp/analyzing-data-flow-in-cpp>`, :doc:`C# <../codeql-for-csharp/analyzing-data-flow-in-csharp>`, :doc:`Java <../codeql-for-java/analyzing-data-flow-in-java>`, and :doc:`JavaScript <../codeql-for-javascript/analyzing-data-flow-in-javascript>`. You can access the appropriate classes and predicates that reason about these different modes of data flow by importing the appropriate library in your query. +Separate CodeQL libraries have been written to handle 'normal' data flow and taint tracking in :doc:`C/C++ <analyzing-data-flow-in-cpp>`, :doc:`C# <analyzing-data-flow-in-csharp>`, :doc:`Java <analyzing-data-flow-in-java>`, and :doc:`JavaScript <analyzing-data-flow-in-javascript-and-typescript>`. You can access the appropriate classes and predicates that reason about these different modes of data flow by importing the appropriate library in your query. In Python analysis, we can use the same taint tracking library to model both 'normal' data flow and taint flow, but we are still able make the distinction between steps that preserve values and those that don't by defining additional data flow properties. For further information on data flow and taint tracking with CodeQL, see ":ref:`Introduction to data flow <about-data-flow-analysis>`." @@ -25,20 +25,20 @@ For further information on data flow and taint tracking with CodeQL, see ":ref:` Fundamentals of taint tracking using data flow analysis ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -The taint tracking library is in the `TaintTracking <https://help.semmle.com/qldoc/python/semmle/python/dataflow/TaintTracking.qll/module.TaintTracking.html>`__ module. +The taint tracking library is in the `TaintTracking <https://codeql.github.com/codeql-standard-libraries/python/semmle/python/dataflow/TaintTracking.qll/module.TaintTracking.html>`__ module. Any taint tracking or data flow analysis query has three explicit components, one of which is optional, and an implicit component. The explicit components are: -1. One or more ``sources`` of potentially insecure or unsafe data, represented by the `TaintTracking::Source <https://help.semmle.com/qldoc/python/semmle/python/dataflow/TaintTracking.qll/type.TaintTracking$TaintSource.html>`__ class. -2. One or more ``sinks``, to where the data or taint may flow, represented by the `TaintTracking::Sink <https://help.semmle.com/qldoc/python/semmle/python/dataflow/TaintTracking.qll/type.TaintTracking$TaintSink.html>`__ class. -3. Zero or more ``sanitizers``, represented by the `Sanitizer <https://help.semmle.com/qldoc/python/semmle/python/dataflow/TaintTracking.qll/type.TaintTracking$Sanitizer.html>`__ class. +1. One or more ``sources`` of potentially insecure or unsafe data, represented by the `TaintTracking::Source <https://codeql.github.com/codeql-standard-libraries/python/semmle/python/dataflow/old/TaintTracking.qll/type.TaintTracking$TaintSource.html>`__ class. +2. One or more ``sinks``, to where the data or taint may flow, represented by the `TaintTracking::Sink <https://codeql.github.com/codeql-standard-libraries/python/semmle/python/dataflow/old/TaintTracking.qll/type.TaintTracking$TaintSink.html>`__ class. +3. Zero or more ``sanitizers``, represented by the `Sanitizer <https://codeql.github.com/codeql-standard-libraries/python/semmle/python/dataflow/old/TaintTracking.qll/type.TaintTracking$Sanitizer.html>`__ class. A taint tracking or data flow query gives results when there is the flow of data from a source to a sink, which is not blocked by a sanitizer. -These three components are bound together using a `TaintTracking::Configuration <https://help.semmle.com/qldoc/python/semmle/python/dataflow/Configuration.qll/type.Configuration$TaintTracking$Configuration.html>`__. +These three components are bound together using a `TaintTracking::Configuration <https://codeql.github.com/codeql-standard-libraries/python/semmle/python/dataflow/old/Configuration.qll/type.Configuration$TaintTracking$Configuration.html>`__. The purpose of the configuration is to specify exactly which sources and sinks are relevant to the specific query. -The final, implicit component is the "kind" of taint, represented by the `TaintKind <https://help.semmle.com/qldoc/python/semmle/python/dataflow/TaintTracking.qll/type.TaintTracking$TaintKind.html>`__ class. +The final, implicit component is the "kind" of taint, represented by the `TaintKind <https://codeql.github.com/codeql-standard-libraries/python/semmle/python/dataflow/old/TaintTracking.qll/type.TaintTracking$TaintKind.html>`__ class. The kind of taint determines which non-value-preserving steps are possible, in addition to value-preserving steps that are built into the analysis. In the above example ``dir = path + "/"``, taint flows from ``path`` to ``dir`` if the taint represents a string, but not if the taint is ``None``. @@ -264,6 +264,6 @@ Further reading - ":ref:`Exploring data flow with path queries <exploring-data-flow-with-path-queries>`" -.. include:: ../../reusables/python-further-reading.rst -.. include:: ../../reusables/codeql-ref-tools-further-reading.rst +.. include:: ../reusables/python-further-reading.rst +.. include:: ../reusables/codeql-ref-tools-further-reading.rst diff --git a/docs/codeql/codeql-language-guides/codeql-for-cpp/analyzing-data-flow-in-cpp.rst b/docs/codeql/codeql-language-guides/analyzing-data-flow-in-cpp.rst similarity index 98% rename from docs/codeql/codeql-language-guides/codeql-for-cpp/analyzing-data-flow-in-cpp.rst rename to docs/codeql/codeql-language-guides/analyzing-data-flow-in-cpp.rst index 09e0ebbb6ff..815425a425a 100644 --- a/docs/codeql/codeql-language-guides/codeql-for-cpp/analyzing-data-flow-in-cpp.rst +++ b/docs/codeql/codeql-language-guides/analyzing-data-flow-in-cpp.rst @@ -143,7 +143,7 @@ Global data flow tracks data flow throughout the entire program, and is therefor .. pull-quote:: Note - .. include:: ../../reusables/path-problem.rst + .. include:: ../reusables/path-problem.rst Using global data flow ~~~~~~~~~~~~~~~~~~~~~~ @@ -395,5 +395,5 @@ Further reading - ":ref:`Exploring data flow with path queries <exploring-data-flow-with-path-queries>`" -.. include:: ../../reusables/cpp-further-reading.rst -.. include:: ../../reusables/codeql-ref-tools-further-reading.rst \ No newline at end of file +.. include:: ../reusables/cpp-further-reading.rst +.. include:: ../reusables/codeql-ref-tools-further-reading.rst \ No newline at end of file diff --git a/docs/codeql/codeql-language-guides/codeql-for-csharp/analyzing-data-flow-in-csharp.rst b/docs/codeql/codeql-language-guides/analyzing-data-flow-in-csharp.rst similarity index 98% rename from docs/codeql/codeql-language-guides/codeql-for-csharp/analyzing-data-flow-in-csharp.rst rename to docs/codeql/codeql-language-guides/analyzing-data-flow-in-csharp.rst index 6a9304925dc..88a6d231dc9 100644 --- a/docs/codeql/codeql-language-guides/codeql-for-csharp/analyzing-data-flow-in-csharp.rst +++ b/docs/codeql/codeql-language-guides/analyzing-data-flow-in-csharp.rst @@ -141,7 +141,7 @@ Global data flow tracks data flow throughout the entire program, and is therefor .. pull-quote:: Note - .. include:: ../../reusables/path-problem.rst + .. include:: ../reusables/path-problem.rst Using global data flow ~~~~~~~~~~~~~~~~~~~~~~ @@ -480,7 +480,7 @@ Exercise 4 Configuration() { this="Environment to System.Uri" } override predicate isSource(DataFlow::Node src) { - src.asExpr() instanceof EnvironmentVariableFlowSource + src instanceof EnvironmentVariableFlowSource } override predicate isSink(DataFlow::Node sink) { @@ -558,5 +558,5 @@ Further reading - ":ref:`Exploring data flow with path queries <exploring-data-flow-with-path-queries>`" -.. include:: ../../reusables/csharp-further-reading.rst -.. include:: ../../reusables/codeql-ref-tools-further-reading.rst +.. include:: ../reusables/csharp-further-reading.rst +.. include:: ../reusables/codeql-ref-tools-further-reading.rst diff --git a/docs/codeql/codeql-language-guides/codeql-for-java/analyzing-data-flow-in-java.rst b/docs/codeql/codeql-language-guides/analyzing-data-flow-in-java.rst similarity index 98% rename from docs/codeql/codeql-language-guides/codeql-for-java/analyzing-data-flow-in-java.rst rename to docs/codeql/codeql-language-guides/analyzing-data-flow-in-java.rst index ebcdb91cad9..75309842ad5 100644 --- a/docs/codeql/codeql-language-guides/codeql-for-java/analyzing-data-flow-in-java.rst +++ b/docs/codeql/codeql-language-guides/analyzing-data-flow-in-java.rst @@ -151,7 +151,7 @@ Global data flow tracks data flow throughout the entire program, and is therefor .. pull-quote:: Note - .. include:: ../../reusables/path-problem.rst + .. include:: ../reusables/path-problem.rst Using global data flow ~~~~~~~~~~~~~~~~~~~~~~ @@ -363,5 +363,5 @@ Further reading - ":ref:`Exploring data flow with path queries <exploring-data-flow-with-path-queries>`" -.. include:: ../../reusables/java-further-reading.rst -.. include:: ../../reusables/codeql-ref-tools-further-reading.rst \ No newline at end of file +.. include:: ../reusables/java-further-reading.rst +.. include:: ../reusables/codeql-ref-tools-further-reading.rst \ No newline at end of file diff --git a/docs/codeql/codeql-language-guides/codeql-for-javascript/analyzing-data-flow-in-javascript.rst b/docs/codeql/codeql-language-guides/analyzing-data-flow-in-javascript-and-typescript.rst similarity index 98% rename from docs/codeql/codeql-language-guides/codeql-for-javascript/analyzing-data-flow-in-javascript.rst rename to docs/codeql/codeql-language-guides/analyzing-data-flow-in-javascript-and-typescript.rst index 6e4c9c2a32a..7fc5ffd56af 100644 --- a/docs/codeql/codeql-language-guides/codeql-for-javascript/analyzing-data-flow-in-javascript.rst +++ b/docs/codeql/codeql-language-guides/analyzing-data-flow-in-javascript-and-typescript.rst @@ -1,4 +1,4 @@ -.. _analyzing-data-flow-in-javascript: +.. _analyzing-data-flow-in-javascript-and-typescript: Analyzing data flow in JavaScript and TypeScript ================================================ @@ -175,7 +175,7 @@ There are two points worth making about the source node API: 2. Strings are not source nodes and cannot be tracked using this API. You can, however, use the ``mayHaveStringValue`` predicate on class ``DataFlow::Node`` to reason about the possible string values flowing into a data flow node. -For a full description of the ``DataFlow::SourceNode`` API, see the `JavaScript standard library <https://help.semmle.com/qldoc/javascript/semmle/javascript/dataflow/Sources.qll/type.Sources$SourceNode.html>`__. +For a full description of the ``DataFlow::SourceNode`` API, see the `JavaScript standard library <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/dataflow/Sources.qll/type.Sources$SourceNode.html>`__. Exercises ~~~~~~~~~ @@ -192,7 +192,7 @@ more time and memory than local analysis. .. pull-quote:: Note - .. include:: ../../reusables/path-problem.rst + .. include:: ../reusables/path-problem.rst Using global data flow ~~~~~~~~~~~~~~~~~~~~~~ @@ -559,5 +559,5 @@ Further reading - ":ref:`Exploring data flow with path queries <exploring-data-flow-with-path-queries>`" -.. include:: ../../reusables/java-further-reading.rst -.. include:: ../../reusables/codeql-ref-tools-further-reading.rst \ No newline at end of file +.. include:: ../reusables/java-further-reading.rst +.. include:: ../reusables/codeql-ref-tools-further-reading.rst \ No newline at end of file diff --git a/docs/codeql/codeql-language-guides/codeql-for-java/annotations-in-java.rst b/docs/codeql/codeql-language-guides/annotations-in-java.rst similarity index 98% rename from docs/codeql/codeql-language-guides/codeql-for-java/annotations-in-java.rst rename to docs/codeql/codeql-language-guides/annotations-in-java.rst index a9d8fcee923..3439fb6ff0e 100644 --- a/docs/codeql/codeql-language-guides/codeql-for-java/annotations-in-java.rst +++ b/docs/codeql/codeql-language-guides/annotations-in-java.rst @@ -242,5 +242,5 @@ Now we can extend our query to filter out calls in methods carrying a ``Suppress Further reading --------------- -.. include:: ../../reusables/java-further-reading.rst -.. include:: ../../reusables/codeql-ref-tools-further-reading.rst +.. include:: ../reusables/java-further-reading.rst +.. include:: ../reusables/codeql-ref-tools-further-reading.rst diff --git a/docs/codeql/codeql-language-guides/codeql-for-cpp/basic-query-for-cpp-code.rst b/docs/codeql/codeql-language-guides/basic-query-for-cpp-code.rst similarity index 98% rename from docs/codeql/codeql-language-guides/codeql-for-cpp/basic-query-for-cpp-code.rst rename to docs/codeql/codeql-language-guides/basic-query-for-cpp-code.rst index b0068587fb7..a2be15c2fed 100644 --- a/docs/codeql/codeql-language-guides/codeql-for-cpp/basic-query-for-cpp-code.rst +++ b/docs/codeql/codeql-language-guides/basic-query-for-cpp-code.rst @@ -48,7 +48,7 @@ Running the query The name of the project you are querying, and the ID of the most recently analyzed commit to the project, are listed below the query box. To the right of this is an icon that indicates the progress of the query operation: - .. image:: ../../images/query-progress.png + .. image:: ../images/query-progress.png :align: center .. pull-quote:: @@ -143,5 +143,5 @@ To exclude ``if`` statements that have an ``else`` branch: Further reading --------------- -.. include:: ../../reusables/cpp-further-reading.rst -.. include:: ../../reusables/codeql-ref-tools-further-reading.rst +.. include:: ../reusables/cpp-further-reading.rst +.. include:: ../reusables/codeql-ref-tools-further-reading.rst diff --git a/docs/codeql/codeql-language-guides/codeql-for-csharp/basic-query-for-csharp-code.rst b/docs/codeql/codeql-language-guides/basic-query-for-csharp-code.rst similarity index 98% rename from docs/codeql/codeql-language-guides/codeql-for-csharp/basic-query-for-csharp-code.rst rename to docs/codeql/codeql-language-guides/basic-query-for-csharp-code.rst index 8439c424d19..f61edbac0f9 100644 --- a/docs/codeql/codeql-language-guides/codeql-for-csharp/basic-query-for-csharp-code.rst +++ b/docs/codeql/codeql-language-guides/basic-query-for-csharp-code.rst @@ -48,7 +48,7 @@ Running the query The name of the project you are querying, and the ID of the most recently analyzed commit to the project, are listed below the query box. To the right of this is an icon that indicates the progress of the query operation: - .. image:: ../../images/query-progress.png + .. image:: ../images/query-progress.png :align: center .. pull-quote:: @@ -148,5 +148,5 @@ To exclude ``if`` statements that have an ``else`` branch: Further reading --------------- -.. include:: ../../reusables/csharp-further-reading.rst -.. include:: ../../reusables/codeql-ref-tools-further-reading.rst +.. include:: ../reusables/csharp-further-reading.rst +.. include:: ../reusables/codeql-ref-tools-further-reading.rst diff --git a/docs/codeql/codeql-language-guides/codeql-for-go/basic-query-for-go-code.rst b/docs/codeql/codeql-language-guides/basic-query-for-go-code.rst similarity index 98% rename from docs/codeql/codeql-language-guides/codeql-for-go/basic-query-for-go-code.rst rename to docs/codeql/codeql-language-guides/basic-query-for-go-code.rst index 32a41e44a24..15ae9caee7d 100644 --- a/docs/codeql/codeql-language-guides/codeql-for-go/basic-query-for-go-code.rst +++ b/docs/codeql/codeql-language-guides/basic-query-for-go-code.rst @@ -58,7 +58,7 @@ Running the query The name of the project you are querying, and the ID of the most recently analyzed commit to the project, are listed below the query box. To the right of this is an icon that indicates the progress of the query operation: - .. image:: ../../images/query-progress.png + .. image:: ../images/query-progress.png :align: center .. pull-quote:: @@ -149,5 +149,5 @@ To exclude these values: Further reading --------------- -.. include:: ../../reusables/go-further-reading.rst -.. include:: ../../reusables/codeql-ref-tools-further-reading.rst +.. include:: ../reusables/go-further-reading.rst +.. include:: ../reusables/codeql-ref-tools-further-reading.rst diff --git a/docs/codeql/codeql-language-guides/codeql-for-java/basic-query-for-java-code.rst b/docs/codeql/codeql-language-guides/basic-query-for-java-code.rst similarity index 98% rename from docs/codeql/codeql-language-guides/codeql-for-java/basic-query-for-java-code.rst rename to docs/codeql/codeql-language-guides/basic-query-for-java-code.rst index 56e03e07ca1..bc721ce9371 100644 --- a/docs/codeql/codeql-language-guides/codeql-for-java/basic-query-for-java-code.rst +++ b/docs/codeql/codeql-language-guides/basic-query-for-java-code.rst @@ -48,7 +48,7 @@ Running the query The name of the project you are querying, and the ID of the most recently analyzed commit to the project, are listed below the query box. To the right of this is an icon that indicates the progress of the query operation: - .. image:: ../../images/query-progress.png + .. image:: ../images/query-progress.png :align: center .. pull-quote:: @@ -143,5 +143,5 @@ To exclude ``if`` statements that have an ``else`` branch: Further reading --------------- -.. include:: ../../reusables/java-further-reading.rst -.. include:: ../../reusables/codeql-ref-tools-further-reading.rst +.. include:: ../reusables/java-further-reading.rst +.. include:: ../reusables/codeql-ref-tools-further-reading.rst diff --git a/docs/codeql/codeql-language-guides/codeql-for-javascript/basic-query-for-javascript-code.rst b/docs/codeql/codeql-language-guides/basic-query-for-javascript-code.rst similarity index 98% rename from docs/codeql/codeql-language-guides/codeql-for-javascript/basic-query-for-javascript-code.rst rename to docs/codeql/codeql-language-guides/basic-query-for-javascript-code.rst index ac79cb3c8c7..123336d699e 100644 --- a/docs/codeql/codeql-language-guides/codeql-for-javascript/basic-query-for-javascript-code.rst +++ b/docs/codeql/codeql-language-guides/basic-query-for-javascript-code.rst @@ -46,7 +46,7 @@ Running the query The name of the project you are querying, and the ID of the most recently analyzed commit to the project, are listed below the query box. To the right of this is an icon that indicates the progress of the query operation: - .. image:: ../../images/query-progress.png + .. image:: ../images/query-progress.png :align: center .. pull-quote:: @@ -134,5 +134,5 @@ As written, this statement compares ``point.bias`` against ``-1`` and then disca Further reading --------------- -.. include:: ../../reusables/javascript-further-reading.rst -.. include:: ../../reusables/codeql-ref-tools-further-reading.rst +.. include:: ../reusables/javascript-further-reading.rst +.. include:: ../reusables/codeql-ref-tools-further-reading.rst diff --git a/docs/codeql/codeql-language-guides/codeql-for-python/basic-query-for-python-code.rst b/docs/codeql/codeql-language-guides/basic-query-for-python-code.rst similarity index 98% rename from docs/codeql/codeql-language-guides/codeql-for-python/basic-query-for-python-code.rst rename to docs/codeql/codeql-language-guides/basic-query-for-python-code.rst index 1519054e0f3..f8424b00d4e 100644 --- a/docs/codeql/codeql-language-guides/codeql-for-python/basic-query-for-python-code.rst +++ b/docs/codeql/codeql-language-guides/basic-query-for-python-code.rst @@ -48,7 +48,7 @@ Running the query The name of the project you are querying, and the ID of the most recently analyzed commit to the project, are listed below the query box. To the right of this is an icon that indicates the progress of the query operation: - .. image:: ../../images/query-progress.png + .. image:: ../images/query-progress.png :align: center .. pull-quote:: @@ -142,5 +142,5 @@ To exclude ``if`` statements that have an ``else`` branch: Further reading --------------- -.. include:: ../../reusables/python-further-reading.rst -.. include:: ../../reusables/codeql-ref-tools-further-reading.rst +.. include:: ../reusables/python-further-reading.rst +.. include:: ../reusables/codeql-ref-tools-further-reading.rst diff --git a/docs/codeql/codeql-language-guides/codeql-for-cpp/index.rst b/docs/codeql/codeql-language-guides/codeql-for-cpp.rst similarity index 100% rename from docs/codeql/codeql-language-guides/codeql-for-cpp/index.rst rename to docs/codeql/codeql-language-guides/codeql-for-cpp.rst diff --git a/docs/codeql/codeql-language-guides/codeql-for-cpp/codeql-library-for-cpp.rst b/docs/codeql/codeql-language-guides/codeql-for-cpp/codeql-library-for-cpp.rst deleted file mode 100644 index 95d88e6cdc5..00000000000 --- a/docs/codeql/codeql-language-guides/codeql-for-cpp/codeql-library-for-cpp.rst +++ /dev/null @@ -1,531 +0,0 @@ -.. _codeql-library-for-cpp: - -CodeQL library for C and C++ -============================ - -When analyzing C or C++ code, you can use the large collection of classes in the CodeQL library for C and C++. - -About the CodeQL library for C and C++ --------------------------------------- - -There is an extensive library for analyzing CodeQL databases extracted from C/C++ projects. The classes in this library present the data from a database in an object-oriented form and provide abstractions and predicates to help you with common analysis tasks. -The library is implemented as a set of QL modules, that is, files with the extension ``.qll``. The module ``cpp.qll`` imports all the core C/C++ library modules, so you can include the complete library by beginning your query with: - -.. code-block:: ql - - import cpp - -The rest of this topic summarizes the available CodeQL classes and corresponding C/C++ constructs. - -Commonly-used library classes ------------------------------- - -The most commonly used standard library classes are listed below. The listing is broken down by functionality. Each library class is annotated with a C/C++ construct it corresponds to. - -Declaration classes -~~~~~~~~~~~~~~~~~~~ - -This table lists `Declaration <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/Declaration.qll/type.Declaration$Declaration.html>`__ classes representing C/C++ declarations. - -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| Example syntax | CodeQL class | Remarks | -+=================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================+=======================================================================================================================================================================+====================================================================================================================================================================================================+ -| ``int`` *var* ``;`` | `GlobalVariable <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/Variable.qll/type.Variable$GlobalVariable.html>`__ | | -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``namespace`` *N* ``{`` ... ``float`` *var* ``;`` ... ``}`` | `NamespaceVariable <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/Variable.qll/type.Variable$NamespaceVariable.html>`__ | | -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``int`` *func* ``( void ) {`` ... ``float`` *var* ``;`` ... ``}`` | `LocalVariable <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/Variable.qll/type.Variable$LocalVariable.html>`__ | See also `Initializer <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/Initializer.qll/type.Initializer$Initializer.html>`__ | -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``class`` *C* ``{`` ... ``int`` *var* ``;`` ... ``}`` | `MemberVariable <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/Variable.qll/type.Variable$MemberVariable.html>`__ | | -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``int`` *func* ``(const char`` *param* ``);`` | `Function <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/Function.qll/type.Function$Function.html>`__ | | -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| | ``template < typename`` *T* ``>`` | `TemplateFunction <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/Function.qll/type.Function$TemplateFunction.html>`__ | | -| | ``void`` *func* ``(`` *T* ``param);`` | | | -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| | ``int`` *func* ``(const char*`` *format* ``, ...)`` | `FormattingFunction <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/models/interfaces/FormattingFunction.qll/type.FormattingFunction$FormattingFunction.html>`__ | | -| | ``{`` ... ``}`` | | | -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| *func* ``< int, float > (`` ... ``);`` | `FunctionTemplateInstantiation <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/Function.qll/type.Function$FunctionTemplateInstantiation.html>`__ | | -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| | ``template < typename`` *T* ``>`` | `FunctionTemplateSpecialization <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/Function.qll/type.Function$FunctionTemplateSpecialization.html>`__ | | -| | *func* ``< int,`` *T* ``> (`` ... ``) {`` ... ``}`` | | | -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| | ``class`` *C* ``{`` ... | `MemberFunction <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/MemberFunction.qll/type.MemberFunction$MemberFunction.html>`__ | | -| | ``int`` *func* ``( float`` *param* ``);`` ... ``};`` | | | -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| | ``class`` *C* ``{`` ... | `ConstMemberFunction <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/MemberFunction.qll/type.MemberFunction$ConstMemberFunction.html>`__ | | -| | ``int`` *func* ``( float`` *param* ``) const;`` ... ``};`` | | | -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``class`` *C* ``{`` ... ``virtual int`` *func* ``(`` ... ``) {`` ... ``} };`` | `VirtualFunction <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/MemberFunction.qll/type.MemberFunction$VirtualFunction.html>`__ | | -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``class`` *C* ``{`` ... *C* ``(`` ... ``) {`` ... ``}`` ... ``};`` | `Constructor <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/MemberFunction.qll/type.MemberFunction$Constructor.html>`__ | | -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``C::operator float () const;`` | `ConversionOperator <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/MemberFunction.qll/type.MemberFunction$ConversionOperator.html>`__ | | -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``class`` *C* ``{`` ... ``~`` *C* ``( void ) {`` ... ``}`` ... ``};`` | `Destructor <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/MemberFunction.qll/type.MemberFunction$Destructor.html>`__ | | -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| | ``class`` *C* ``{`` ... | `ConversionConstructor <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/MemberFunction.qll/type.MemberFunction$ConversionConstructor.html>`__ | | -| | *C* ``( const`` *D* ``&`` *d* ``) {`` ... ``}`` ... ``};`` | | | -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| *C* ``&`` *C* ``:: operator= (const`` *C* ``& );`` | `CopyAssignmentOperator <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/MemberFunction.qll/type.MemberFunction$CopyAssignmentOperator.html>`__ | | -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| *C* ``&`` *C* ``:: operator= (`` *C* ``&& );`` | `MoveAssignmentOperator <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/MemberFunction.qll/type.MemberFunction$MoveAssignmentOperator.html>`__ | | -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| *C* ``::`` *C* ``(const`` *C* ``& );`` | `CopyConstructor <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/MemberFunction.qll/type.MemberFunction$CopyConstructor.html>`__ | | -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| *C* ``::`` *C* ``(`` *C* ``&& );`` | `MoveConstructor <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/MemberFunction.qll/type.MemberFunction$MoveConstructor.html>`__ | | -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| *C* ``::`` *C* ``(void);`` | `NoArgConstructor <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/MemberFunction.qll/type.MemberFunction$NoArgConstructor.html>`__ | Default constructor | -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``enum`` *en* ``{`` *val1* ``,`` *val2* ... ``}`` | `EnumConstant <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/Enum.qll/type.Enum$EnumConstant.html>`__ | | -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| | ``friend void`` *func* ``( int );`` | `FriendDecl <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/FriendDecl.qll/type.FriendDecl$FriendDecl.html>`__ | | -| | ``friend class`` *B* ``;`` | | | -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| | ``int`` *func* ``( void ) {`` ... | `LocalEnum <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/Enum.qll/type.Enum$LocalEnum.html>`__ | | -| | ``enum`` *en* ``{`` *val1* ``,`` *val2* ... ``};`` ... ``}`` | | | -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| | ``class`` *C* ``{`` ... | `NestedEnum <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/Enum.qll/type.Enum$NestedEnum.html>`__ | | -| | ``enum`` *en* ``{`` *val1* ``,`` *val2* ... ``}`` ... ``}`` | | | -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``enum class`` *en* ``: short {`` *val1* ``,`` *val2* ... ``}`` | `ScopedEnum <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/Enum.qll/type.Enum$ScopedEnum.html>`__ | | -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| | ``class`` *C* ``{`` ... | `AbstractClass <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/Class.qll/type.Class$AbstractClass.html>`__ | | -| | ``virtual void`` *func* ``( int ) = 0;`` ... ``};`` | | | -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``template < int , float > class`` *C* ``{`` ... ``};`` | `ClassTemplateInstantiation <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/Class.qll/type.Class$ClassTemplateInstantiation.html>`__ | | -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``template < > class`` *C* ``<`` `Type <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/Type.qll/type.Type$Type.html>`__ ``> {`` ... ``};`` | `FullClassTemplateSpecialization <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/Class.qll/type.Class$FullClassTemplateSpecialization.html>`__ | | -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| | ``template < typename`` *T* ``>`` | `PartialClassTemplateSpecialization <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/Class.qll/type.Class$PartialClassTemplateSpecialization.html>`__ | | -| | ``class`` *C* ``<`` *T* ``,`` *5* ``> {`` ... ``};`` | | | -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``int`` *func* ``( void ) {`` ... ``class`` *C* ``{`` ... ``};`` ... ``}`` | `LocalClass <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/Class.qll/type.Class$LocalClass.html>`__ | | -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``class`` *C* ``{`` ... ``class`` *D* ``{`` ... ``};`` ... ``};`` | `NestedClass <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/Class.qll/type.Class$NestedClass.html>`__ | | -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| | ``class`` *C* ``{`` | `Class <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/Class.qll/type.Class$Class.html>`__ | | -| | `Type <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/Type.qll/type.Type$Type.html>`__ *var* ``;`` | | | -| | `Type <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/Type.qll/type.Type$Type.html>`__ *func* ``(`` `Parameter <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/Parameter.qll/type.Parameter$Parameter.html>`__... ``) {`` ... ``}``... ``};`` | | | -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| | ``struct`` *S* ``{`` ... | | `Struct <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/Struct.qll/type.Struct$Struct.html>`__ | | -| | `Type <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/Type.qll/type.Type$Type.html>`__ *var* ``;`` | | `Class <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/Class.qll/type.Class$Class.html>`__ | | -| | `Type <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/Type.qll/type.Type$Type.html>`__ *func* ``(`` `Parameter <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/Parameter.qll/type.Parameter$Parameter.html>`__... ``) {`` ... ``}``... ``};`` | | | -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| | ``union`` *U* ``{`` | | `Union <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/Union.qll/type.Union$Union.html>`__ | | -| | `Type <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/Type.qll/type.Type$Type.html>`__ *var1* ``;`` | | `Struct <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/Struct.qll/type.Struct$Struct.html>`__ | | -| | `Type <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/Type.qll/type.Type$Type.html>`__ *var2* ``;`` ... ``};`` | | `Class <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/Class.qll/type.Class$Class.html>`__ | | -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| | ``template < typename`` *T* ``>`` | `ProxyClass <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/Class.qll/type.Class$ProxyClass.html>`__ | Appears only in *uninstantiated* templates | -| | ``struct`` *C* ``:`` *T* ``{`` ... ``};`` | | | -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| | ``int`` *func* ``( void ) {`` ... | `LocalStruct <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/Struct.qll/type.Struct$LocalStruct.html>`__ | | -| | ``struct`` *S* ``{`` ... ``};`` ... ``}`` | | | -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| | ``class`` *C* ``{`` ... | `NestedStruct <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/Struct.qll/type.Struct$NestedStruct.html>`__ | | -| | ``struct`` *S* ``{`` ... ``};`` ... ``};`` | | | -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``int *`` *func* ``( void ) {`` ... ``union`` *U* ``{`` ... ``};`` ... ``}`` | `LocalUnion <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/Union.qll/type.Union$LocalUnion.html>`__ | | -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``class`` *C* ``{`` ... ``union`` *U* ``{`` ... ``};`` ... ``};`` | `NestedUnion <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/Union.qll/type.Union$NestedUnion.html>`__ | | -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``typedef int`` *T* ``;`` | `TypedefType <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/TypedefType.qll/type.TypedefType$TypedefType.html>`__ | | -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| | ``int`` *func* ``( void ) {`` ... | `LocalTypedefType <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/TypedefType.qll/type.TypedefType$LocalTypedefType.html>`__ | | -| | ``typedef int`` *T* ``;`` ... ``}`` | | | -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| | ``class`` *C* ``{`` ... | `NestedTypedefType <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/TypedefType.qll/type.TypedefType$NestedTypedefType.html>`__ | | -| | ``typedef int`` *T* ``;`` ... ``};`` | | | -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``class`` *V* ``:`` ... ``public`` *B* ... ``{`` ... ``};`` | `ClassDerivation <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/Class.qll/type.Class$ClassDerivation.html>`__ | | -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``class`` *V* ``:`` ... ``virtual`` *B* ... ``{`` ... ``};`` | `VirtualClassDerivation <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/Class.qll/type.Class$VirtualClassDerivation.html>`__ | | -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| | ``template < typename`` *T* ``>`` | `TemplateClass <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/Class.qll/type.Class$TemplateClass.html>`__ | | -| | ``class`` *C* ``{`` ... ``};`` | | | -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``int`` *foo* ``(`` `Type <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/Type.qll/type.Type$Type.html>`__ *param1* ``,`` `Type <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/Type.qll/type.Type$Type.html>`__ *param2* ... ``);`` | `Parameter <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/Parameter.qll/type.Parameter$Parameter.html>`__ | | -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``template <typename`` *T* ``>`` *T* *t* ``;`` | `TemplateVariable <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/Variable.qll/type.Variable$TemplateVariable.html>`__ | Since C++14 | -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - - -Statement classes -~~~~~~~~~~~~~~~~~ - -This table lists subclasses of `Stmt <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/stmts/Stmt.qll/type.Stmt$Stmt.html>`__ representing C/C++ statements. - -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| Example syntax | CodeQL class | Remarks | -+===============================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================+==================================================================================================================================================================+===================================================================================================================================================================================================================================================================================================+ -| ``__asm__ ("`` *movb %bh, (%eax)* ``");`` | `AsmStmt <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/stmts/Stmt.qll/type.Stmt$AsmStmt.html>`__ | Specific to a given CPU instruction set | -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``{`` `Stmt <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/stmts/Stmt.qll/type.Stmt$Stmt.html>`__... ``}`` | `Block <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/stmts/Block.qll/type.Block$Block.html>`__ | | -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``catch (`` `Parameter <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/Parameter.qll/type.Parameter$Parameter.html>`__ ``)`` `Block <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/stmts/Block.qll/type.Block$Block.html>`__ | `CatchBlock <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/stmts/Stmt.qll/type.Stmt$CatchBlock.html>`__ | | -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``catch ( ... )`` `Block <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/stmts/Block.qll/type.Block$Block.html>`__ | `CatchAnyBlock <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/stmts/Stmt.qll/type.Stmt$CatchAnyBlock.html>`__ | | -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``goto *`` *labelptr* ``;`` | `ComputedGotoStmt <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/stmts/Stmt.qll/type.Stmt$ComputedGotoStmt.html>`__ | GNU extension; use with `LabelLiteral <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/Literal.qll/type.Literal$LabelLiteral.html>`__ | -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| `Type <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/Type.qll/type.Type$Type.html>`__ *i* ``,`` *j* ``;`` | `DeclStmt <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/stmts/Stmt.qll/type.Stmt$DeclStmt.html>`__ | | -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``if (`` `Expr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/Expr.qll/type.Expr$Expr.html>`__ ``)`` `Stmt <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/stmts/Stmt.qll/type.Stmt$Stmt.html>`__ ``else`` `Stmt <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/stmts/Stmt.qll/type.Stmt$Stmt.html>`__ | `IfStmt <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/stmts/Stmt.qll/type.Stmt$IfStmt.html>`__ | | -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``switch (`` `Expr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/Expr.qll/type.Expr$Expr.html>`__ ``) {`` `SwitchCase <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/stmts/Stmt.qll/type.Stmt$SwitchCase.html>`__... ``}`` | `SwitchStmt <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/stmts/Stmt.qll/type.Stmt$SwitchStmt.html>`__ | | -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``do`` `Stmt <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/stmts/Stmt.qll/type.Stmt$Stmt.html>`__ ``while (`` `Expr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/Expr.qll/type.Expr$Expr.html>`__ ``)`` | `DoStmt <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/stmts/Stmt.qll/type.Stmt$DoStmt.html>`__ | | -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``for (`` `DeclStmt <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/stmts/Stmt.qll/type.Stmt$DeclStmt.html>`__ ``;`` `Expr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/Expr.qll/type.Expr$Expr.html>`__ ``;`` `Expr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/Expr.qll/type.Expr$Expr.html>`__ ``)`` `Stmt <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/stmts/Stmt.qll/type.Stmt$Stmt.html>`__ | `ForStmt <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/stmts/Stmt.qll/type.Stmt$ForStmt.html>`__ | | -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``for (`` `DeclStmt <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/stmts/Stmt.qll/type.Stmt$DeclStmt.html>`__ ``:`` `Expr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/Expr.qll/type.Expr$Expr.html>`__ ``)`` `Stmt <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/stmts/Stmt.qll/type.Stmt$Stmt.html>`__ | `RangeBasedForStmt <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/stmts/Stmt.qll/type.Stmt$RangeBasedForStmt.html>`__ | | -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``while (`` `Expr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/Expr.qll/type.Expr$Expr.html>`__ ``)`` `Stmt <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/stmts/Stmt.qll/type.Stmt$Stmt.html>`__ | `WhileStmt <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/stmts/Stmt.qll/type.Stmt$WhileStmt.html>`__ | | -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| `Expr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/Expr.qll/type.Expr$Expr.html>`__ ``;`` | `ExprStmt <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/stmts/Stmt.qll/type.Stmt$ExprStmt.html>`__ | | -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``__try {`` ... ``} __except (`` `Expr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/Expr.qll/type.Expr$Expr.html>`__ ``) {`` ... ``}`` | `MicrosoftTryExceptStmt <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/stmts/Stmt.qll/type.Stmt$MicrosoftTryExceptStmt.html>`__ | Structured exception handling (SEH) under Windows | -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``__try {`` ... ``} __finally {`` ... ``}`` | `MicrosoftTryFinallyStmt <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/stmts/Stmt.qll/type.Stmt$MicrosoftTryFinallyStmt.html>`__ | Structured exception handling (SEH) under Windows | -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``return`` `Expr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/Expr.qll/type.Expr$Expr.html>`__ ``;`` | `ReturnStmt <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/stmts/Stmt.qll/type.Stmt$ReturnStmt.html>`__ | | -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``case`` `Expr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/Expr.qll/type.Expr$Expr.html>`__ ``:`` | `SwitchCase <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/stmts/Stmt.qll/type.Stmt$SwitchCase.html>`__ | | -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``try {`` `Stmt <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/stmts/Stmt.qll/type.Stmt$Stmt.html>`__... ``}`` `CatchBlock <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/stmts/Stmt.qll/type.Stmt$CatchBlock.html>`__... `CatchAnyBlock <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/stmts/Stmt.qll/type.Stmt$CatchAnyBlock.html>`__ | `TryStmt <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/stmts/Stmt.qll/type.Stmt$TryStmt.html>`__ | | -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| | ``void`` *func* ``(void) try {`` `Stmt <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/stmts/Stmt.qll/type.Stmt$Stmt.html>`__... ``}`` | `FunctionTryStmt <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/stmts/Stmt.qll/type.Stmt$FunctionTryStmt.html>`__ | | -| | `CatchBlock <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/stmts/Stmt.qll/type.Stmt$CatchBlock.html>`__... `CatchAnyBlock <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/stmts/Stmt.qll/type.Stmt$CatchAnyBlock.html>`__ | | | -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``;`` | `EmptyStmt <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/stmts/Stmt.qll/type.Stmt$EmptyStmt.html>`__ | | -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``break;`` | `BreakStmt <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/stmts/Stmt.qll/type.Stmt$BreakStmt.html>`__ | | -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``continue;`` | `ContinueStmt <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/stmts/Stmt.qll/type.Stmt$ContinueStmt.html>`__ | | -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``goto`` `LabelStmt <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/stmts/Stmt.qll/type.Stmt$LabelStmt.html>`__ ``;`` | `GotoStmt <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/stmts/Stmt.qll/type.Stmt$GotoStmt.html>`__ | | -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| *slabel* ``:`` | `LabelStmt <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/stmts/Stmt.qll/type.Stmt$LabelStmt.html>`__ | | -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``float`` *arr* ``[`` `Expr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/Expr.qll/type.Expr$Expr.html>`__ ``] [`` `Expr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/Expr.qll/type.Expr$Expr.html>`__ ``];`` | `VlaDeclStmt <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/stmts/Stmt.qll/type.Stmt$VlaDeclStmt.html>`__ | C99 variable-length array | -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - - -Expression classes -~~~~~~~~~~~~~~~~~~ - -This table lists subclasses of `Expr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/Expr.qll/type.Expr$Expr.html>`__ representing C/C++ expressions. - -+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| Example syntax | CodeQL class(es) | Remarks | -+========================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================+==========================================================================================================================================================================================================+=============================================================================================================================================================================================================================================================================================================+ -| ``{`` `Expr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/Expr.qll/type.Expr$Expr.html>`__... ``}`` | | `ArrayAggregateLiteral <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/Literal.qll/type.Literal$ArrayAggregateLiteral.html>`__ | | -| | | `ClassAggregateLiteral <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/Literal.qll/type.Literal$ClassAggregateLiteral.html>`__ | | -+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``alignof (`` `Expr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/Expr.qll/type.Expr$Expr.html>`__ ``)`` | `AlignofExprOperator <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/Cast.qll/type.Cast$AlignofExprOperator.html>`__ | | -+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``alignof (`` `Type <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/Type.qll/type.Type$Type.html>`__ ``)`` | `AlignofTypeOperator <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/Cast.qll/type.Cast$AlignofTypeOperator.html>`__ | | -+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| `Expr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/Expr.qll/type.Expr$Expr.html>`__ ``[`` `Expr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/Expr.qll/type.Expr$Expr.html>`__ ``]`` | `ArrayExpr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/Access.qll/type.Access$ArrayExpr.html>`__ | | -+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``__assume (`` `Expr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/Expr.qll/type.Expr$Expr.html>`__ ``)`` | `AssumeExpr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/Expr.qll/type.Expr$AssumeExpr.html>`__ | Microsoft extension | -+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``static_assert (`` `Expr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/Expr.qll/type.Expr$Expr.html>`__ ``,`` `StringLiteral <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/Literal.qll/type.Literal$StringLiteral.html>`__ ``)`` | `StaticAssert <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/Element.qll/type.Element$StaticAssert.html>`__ | | C++11 | -| ``_Static_assert (`` `Expr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/Expr.qll/type.Expr$Expr.html>`__ ``,`` `StringLiteral <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/Literal.qll/type.Literal$StringLiteral.html>`__ ``)`` | | | C11 | -+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``__noop;`` | `BuiltInNoOp <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/BuiltInOperations.qll/type.BuiltInOperations$BuiltInNoOp.html>`__ | Microsoft extension | -+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| `Expr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/Expr.qll/type.Expr$Expr.html>`__ ``(`` `Expr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/Expr.qll/type.Expr$Expr.html>`__... ``)`` | `ExprCall <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/Call.qll/type.Call$ExprCall.html>`__ | | -+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| | *func* ``(`` `Expr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/Expr.qll/type.Expr$Expr.html>`__... ``)`` | `FunctionCall <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/Call.qll/type.Call$FunctionCall.html>`__ | | -| | *instance* ``.`` *func* ``(`` `Expr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/Expr.qll/type.Expr$Expr.html>`__... ``)`` | | | -+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| `Expr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/Expr.qll/type.Expr$Expr.html>`__ ``,`` `Expr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/Expr.qll/type.Expr$Expr.html>`__ | `CommaExpr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/Expr.qll/type.Expr$CommaExpr.html>`__ | | -+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``if (`` `Type <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/Type.qll/type.Type$Type.html>`__ *arg* ``=`` `Expr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/Expr.qll/type.Expr$Expr.html>`__ ``)`` | `ConditionDeclExpr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/Assignment.qll/type.Assignment$ConditionDeclExpr.html>`__ | | -+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``(`` `Type <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/Type.qll/type.Type$Type.html>`__ ``)`` `Expr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/Expr.qll/type.Expr$Expr.html>`__ | `CStyleCast <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/Cast.qll/type.Cast$CStyleCast.html>`__ | | -+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``const_cast <`` `Type <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/Type.qll/type.Type$Type.html>`__ ``> (`` `Expr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/Expr.qll/type.Expr$Expr.html>`__ ``)`` | `ConstCast <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/Cast.qll/type.Cast$ConstCast.html>`__ | | -+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``dynamic_cast <`` `Type <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/Type.qll/type.Type$Type.html>`__ ``> (`` `Expr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/Expr.qll/type.Expr$Expr.html>`__ ``)`` | `DynamicCast <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/Cast.qll/type.Cast$DynamicCast.html>`__ | | -+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``reinterpret_cast <`` `Type <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/Type.qll/type.Type$Type.html>`__ ``> (`` `Expr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/Expr.qll/type.Expr$Expr.html>`__ ``)`` | `ReinterpretCast <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/Cast.qll/type.Cast$ReinterpretCast.html>`__ | | -+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``static_cast <`` `Type <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/Type.qll/type.Type$Type.html>`__ ``> (`` `Expr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/Expr.qll/type.Expr$Expr.html>`__ ``)`` | `StaticCast <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/Cast.qll/type.Cast$StaticCast.html>`__ | | -+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| | ``template < typename...`` *T* ``>`` | `FoldExpr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/Expr.qll/type.Expr$FoldExpr.html>`__ | Appears only in *uninstantiated* templates | -| | ``auto`` *sum* ``(`` *T* `...` *t* ``)`` | | | -| | ``{ return (`` *t* ``+ ... + 0 ); }`` | | | -+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``int`` *func* ``(`` *format* ``, ... );`` | `FormattingFunctionCall <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/commons/Printf.qll/type.Printf$FormattingFunctionCall.html>`__ | | -+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| | ``[ = ] ( float`` *b* ``) -> float`` | `LambdaExpression <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/Lambda.qll/type.Lambda$LambdaExpression.html>`__ | C++11 | -| | ``{ return`` *captured* ``*`` *b* ``; }`` | | | -+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| | ``^ int ( int`` *x* ``, int`` *y* ``) {`` | `BlockExpr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/Expr.qll/type.Expr$BlockExpr.html>`__ | Apple extension | -| | ``{`` `Stmt <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/stmts/Stmt.qll/type.Stmt$Stmt.html>`__... ``; return`` *x* ``+`` *y* ``; }`` | | | -+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``void *`` *labelptr* ``= &&`` *label* ``;`` | `LabelLiteral <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/Literal.qll/type.Literal$LabelLiteral.html>`__ | GNU extension; use with `ComputedGotoStmt <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/stmts/Stmt.qll/type.Stmt$ComputedGotoStmt.html>`__ | -+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| *"%3d %s\\n"* | `FormatLiteral <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/commons/Printf.qll/type.Printf$FormatLiteral.html>`__ | | -+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| *0xdbceffca* | `HexLiteral <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/Literal.qll/type.Literal$HexLiteral.html>`__ | | -+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| *0167* | `OctalLiteral <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/Literal.qll/type.Literal$OctalLiteral.html>`__ | | -+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| *'c'* | `CharLiteral <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/Literal.qll/type.Literal$CharLiteral.html>`__ | | -+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| *"abcdefgh"*, *L"wide"* | `StringLiteral <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/Literal.qll/type.Literal$StringLiteral.html>`__ | | -+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``new`` `Type <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/Type.qll/type.Type$Type.html>`__ ``[`` `Expr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/Expr.qll/type.Expr$Expr.html>`__ ``]`` | `NewArrayExpr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/Expr.qll/type.Expr$NewArrayExpr.html>`__ | | -+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``new`` `Type <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/Type.qll/type.Type$Type.html>`__ | `NewExpr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/Expr.qll/type.Expr$NewExpr.html>`__ | | -+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``delete [ ]`` `Expr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/Expr.qll/type.Expr$Expr.html>`__ ``;`` | `DeleteArrayExpr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/Expr.qll/type.Expr$DeleteArrayExpr.html>`__ | | -+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``delete`` `Expr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/Expr.qll/type.Expr$Expr.html>`__ ``;`` | `DeleteExpr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/Expr.qll/type.Expr$DeleteExpr.html>`__ | | -+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``noexcept (`` `Expr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/Expr.qll/type.Expr$Expr.html>`__ ``)`` | `NoExceptExpr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/Expr.qll/type.Expr$NoExceptExpr.html>`__ | | -+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| `Expr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/Expr.qll/type.Expr$Expr.html>`__ ``=`` `Expr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/Expr.qll/type.Expr$Expr.html>`__ | `AssignExpr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/Assignment.qll/type.Assignment$AssignExpr.html>`__ | See also `Initializer <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/Initializer.qll/type.Initializer$Initializer.html>`__ | -+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| `Expr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/Expr.qll/type.Expr$Expr.html>`__ ``+=`` `Expr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/Expr.qll/type.Expr$Expr.html>`__ | | `AssignAddExpr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/Assignment.qll/type.Assignment$AssignAddExpr.html>`__ | | -| | | `AssignPointerAddExpr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/Assignment.qll/type.Assignment$AssignPointerAddExpr.html>`__ | | -+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| `Expr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/Expr.qll/type.Expr$Expr.html>`__ ``/=`` `Expr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/Expr.qll/type.Expr$Expr.html>`__ | `AssignDivExpr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/Assignment.qll/type.Assignment$AssignDivExpr.html>`__ | | -+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| `Expr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/Expr.qll/type.Expr$Expr.html>`__ ``*=`` `Expr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/Expr.qll/type.Expr$Expr.html>`__ | `AssignMulExpr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/Assignment.qll/type.Assignment$AssignMulExpr.html>`__ | | -+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| `Expr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/Expr.qll/type.Expr$Expr.html>`__ ``%=`` `Expr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/Expr.qll/type.Expr$Expr.html>`__ | `AssignRemExpr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/Assignment.qll/type.Assignment$AssignRemExpr.html>`__ | | -+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| `Expr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/Expr.qll/type.Expr$Expr.html>`__ ``-=`` `Expr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/Expr.qll/type.Expr$Expr.html>`__ | | `AssignSubExpr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/Assignment.qll/type.Assignment$AssignSubExpr.html>`__ | | -| | | `AssignPointerSubExpr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/Assignment.qll/type.Assignment$AssignPointerSubExpr.html>`__ | | -+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| `Expr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/Expr.qll/type.Expr$Expr.html>`__ ``&=`` `Expr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/Expr.qll/type.Expr$Expr.html>`__ | `AssignAndExpr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/Assignment.qll/type.Assignment$AssignAndExpr.html>`__ | | -+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| `Expr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/Expr.qll/type.Expr$Expr.html>`__ ``<<=`` `Expr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/Expr.qll/type.Expr$Expr.html>`__ | `AssignLShiftExpr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/Assignment.qll/type.Assignment$AssignLShiftExpr.html>`__ | | -+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| `Expr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/Expr.qll/type.Expr$Expr.html>`__ ``|=`` `Expr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/Expr.qll/type.Expr$Expr.html>`__ | `AssignOrExpr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/Assignment.qll/type.Assignment$AssignOrExpr.html>`__ | | -+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| `Expr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/Expr.qll/type.Expr$Expr.html>`__ ``>>=`` `Expr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/Expr.qll/type.Expr$Expr.html>`__ | `AssignRShiftExpr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/Assignment.qll/type.Assignment$AssignRShiftExpr.html>`__ | | -+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| `Expr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/Expr.qll/type.Expr$Expr.html>`__ ``^=`` `Expr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/Expr.qll/type.Expr$Expr.html>`__ | `AssignXorExpr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/Assignment.qll/type.Assignment$AssignXorExpr.html>`__ | | -+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| `Expr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/Expr.qll/type.Expr$Expr.html>`__ ``+`` `Expr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/Expr.qll/type.Expr$Expr.html>`__ | | `AddExpr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/ArithmeticOperation.qll/type.ArithmeticOperation$AddExpr.html>`__ | | | -| | | `PointerAddExpr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/ArithmeticOperation.qll/type.ArithmeticOperation$PointerAddExpr.html>`__ | | | -| | | `ImaginaryRealAddExpr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/ArithmeticOperation.qll/type.ArithmeticOperation$ImaginaryRealAddExpr.html>`__ | | C99 | -| | | `RealImaginaryAddExpr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/ArithmeticOperation.qll/type.ArithmeticOperation$RealImaginaryAddExpr.html>`__ | | C99 | -+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| `Expr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/Expr.qll/type.Expr$Expr.html>`__ ``/`` `Expr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/Expr.qll/type.Expr$Expr.html>`__ | | `DivExpr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/ArithmeticOperation.qll/type.ArithmeticOperation$DivExpr.html>`__ | | | -| | | `ImaginaryDivExpr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/ArithmeticOperation.qll/type.ArithmeticOperation$ImaginaryDivExpr.html>`__ | | C99 | -+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| `Expr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/Expr.qll/type.Expr$Expr.html>`__ ``>?`` `Expr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/Expr.qll/type.Expr$Expr.html>`__ | `MaxExpr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/ArithmeticOperation.qll/type.ArithmeticOperation$MaxExpr.html>`__ | GNU extension | -+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| `Expr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/Expr.qll/type.Expr$Expr.html>`__ ``<?`` `Expr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/Expr.qll/type.Expr$Expr.html>`__ | `MinExpr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/ArithmeticOperation.qll/type.ArithmeticOperation$MinExpr.html>`__ | GNU extension | -+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| `Expr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/Expr.qll/type.Expr$Expr.html>`__ ``*`` `Expr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/Expr.qll/type.Expr$Expr.html>`__ | | `MulExpr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/ArithmeticOperation.qll/type.ArithmeticOperation$MulExpr.html>`__ | | | -| | | `ImaginaryMulExpr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/ArithmeticOperation.qll/type.ArithmeticOperation$ImaginaryMulExpr.html>`__ | | C99 | -+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| `Expr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/Expr.qll/type.Expr$Expr.html>`__ ``%`` `Expr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/Expr.qll/type.Expr$Expr.html>`__ | `RemExpr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/ArithmeticOperation.qll/type.ArithmeticOperation$RemExpr.html>`__ | | -+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| `Expr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/Expr.qll/type.Expr$Expr.html>`__ ``-`` `Expr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/Expr.qll/type.Expr$Expr.html>`__ | | `SubExpr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/ArithmeticOperation.qll/type.ArithmeticOperation$SubExpr.html>`__ | | | -| | | `PointerDiffExpr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/ArithmeticOperation.qll/type.ArithmeticOperation$PointerDiffExpr.html>`__ | | | -| | | `PointerSubExpr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/ArithmeticOperation.qll/type.ArithmeticOperation$PointerSubExpr.html>`__ | | | -| | | `ImaginaryRealSubExpr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/ArithmeticOperation.qll/type.ArithmeticOperation$ImaginaryRealSubExpr.html>`__ | | C99 | -| | | `RealImaginarySubExpr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/ArithmeticOperation.qll/type.ArithmeticOperation$RealImaginarySubExpr.html>`__ | | C99 | -+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| `Expr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/Expr.qll/type.Expr$Expr.html>`__ ``&`` `Expr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/Expr.qll/type.Expr$Expr.html>`__ | `BitwiseAndExpr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/BitwiseOperation.qll/type.BitwiseOperation$BitwiseAndExpr.html>`__ | | -+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| `Expr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/Expr.qll/type.Expr$Expr.html>`__ ``|`` `Expr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/Expr.qll/type.Expr$Expr.html>`__ | `BitwiseOrExpr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/BitwiseOperation.qll/type.BitwiseOperation$BitwiseOrExpr.html>`__ | | -+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| `Expr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/Expr.qll/type.Expr$Expr.html>`__ ``^`` `Expr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/Expr.qll/type.Expr$Expr.html>`__ | `BitwiseXorExpr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/BitwiseOperation.qll/type.BitwiseOperation$BitwiseXorExpr.html>`__ | | -+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| `Expr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/Expr.qll/type.Expr$Expr.html>`__ ``<<`` `Expr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/Expr.qll/type.Expr$Expr.html>`__ | `LShiftExpr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/BitwiseOperation.qll/type.BitwiseOperation$LShiftExpr.html>`__ | | -+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| `Expr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/Expr.qll/type.Expr$Expr.html>`__ ``>>`` `Expr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/Expr.qll/type.Expr$Expr.html>`__ | `RShiftExpr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/BitwiseOperation.qll/type.BitwiseOperation$RShiftExpr.html>`__ | | -+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| `Expr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/Expr.qll/type.Expr$Expr.html>`__ ``&&`` `Expr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/Expr.qll/type.Expr$Expr.html>`__ | `LogicalAndExpr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/LogicalOperation.qll/type.LogicalOperation$LogicalAndExpr.html>`__ | | -+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| `Expr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/Expr.qll/type.Expr$Expr.html>`__ ``||`` `Expr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/Expr.qll/type.Expr$Expr.html>`__ | `LogicalOrExpr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/LogicalOperation.qll/type.LogicalOperation$LogicalOrExpr.html>`__ | | -+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| `Expr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/Expr.qll/type.Expr$Expr.html>`__ ``==`` `Expr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/Expr.qll/type.Expr$Expr.html>`__ | `EQExpr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/ComparisonOperation.qll/type.ComparisonOperation$EQExpr.html>`__ | | -+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| `Expr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/Expr.qll/type.Expr$Expr.html>`__ ``!=`` `Expr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/Expr.qll/type.Expr$Expr.html>`__ | `NEExpr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/ComparisonOperation.qll/type.ComparisonOperation$NEExpr.html>`__ | | -+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| `Expr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/Expr.qll/type.Expr$Expr.html>`__ ``>=`` `Expr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/Expr.qll/type.Expr$Expr.html>`__ | `GEExpr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/ComparisonOperation.qll/type.ComparisonOperation$GEExpr.html>`__ | | -+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| `Expr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/Expr.qll/type.Expr$Expr.html>`__ ``>`` `Expr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/Expr.qll/type.Expr$Expr.html>`__ | `GTExpr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/ComparisonOperation.qll/type.ComparisonOperation$GTExpr.html>`__ | | -+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| `Expr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/Expr.qll/type.Expr$Expr.html>`__ ``<=`` `Expr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/Expr.qll/type.Expr$Expr.html>`__ | `LEExpr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/ComparisonOperation.qll/type.ComparisonOperation$LEExpr.html>`__ | | -+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| `Expr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/Expr.qll/type.Expr$Expr.html>`__ ``<`` `Expr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/Expr.qll/type.Expr$Expr.html>`__ | `LTExpr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/ComparisonOperation.qll/type.ComparisonOperation$LTExpr.html>`__ | | -+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| `Expr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/Expr.qll/type.Expr$Expr.html>`__ ``?`` `Expr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/Expr.qll/type.Expr$Expr.html>`__ ``:`` `Expr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/Expr.qll/type.Expr$Expr.html>`__ | `ConditionalExpr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/LogicalOperation.qll/type.LogicalOperation$ConditionalExpr.html>`__ | | -+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``&`` `Expr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/Expr.qll/type.Expr$Expr.html>`__ | `AddressOfExpr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/Expr.qll/type.Expr$AddressOfExpr.html>`__ | | -+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``*`` `Expr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/Expr.qll/type.Expr$Expr.html>`__ | `PointerDereferenceExpr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/Expr.qll/type.Expr$PointerDereferenceExpr.html>`__ | | -+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| `Expr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/Expr.qll/type.Expr$Expr.html>`__ ``--`` | `PostfixDecrExpr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/ArithmeticOperation.qll/type.ArithmeticOperation$PostfixDecrExpr.html>`__ | | -+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``--`` `Expr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/Expr.qll/type.Expr$Expr.html>`__ | `PrefixDecrExpr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/ArithmeticOperation.qll/type.ArithmeticOperation$PrefixDecrExpr.html>`__ | | -+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| `Expr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/Expr.qll/type.Expr$Expr.html>`__ ``++`` | `PostfixIncrExpr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/ArithmeticOperation.qll/type.ArithmeticOperation$PostfixIncrExpr.html>`__ | | -+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``++`` `Expr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/Expr.qll/type.Expr$Expr.html>`__ | `PrefixIncrExpr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/ArithmeticOperation.qll/type.ArithmeticOperation$PrefixIncrExpr.html>`__ | | -+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``__imag (`` `Expr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/Expr.qll/type.Expr$Expr.html>`__ ``)`` | `ImaginaryPartExpr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/ArithmeticOperation.qll/type.ArithmeticOperation$ImaginaryPartExpr.html>`__ | GNU extension | -+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``__real (`` `Expr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/Expr.qll/type.Expr$Expr.html>`__ ``)`` | `RealPartExpr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/ArithmeticOperation.qll/type.ArithmeticOperation$RealPartExpr.html>`__ | GNU extension | -+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``-`` `Expr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/Expr.qll/type.Expr$Expr.html>`__ | `UnaryMinusExpr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/ArithmeticOperation.qll/type.ArithmeticOperation$UnaryMinusExpr.html>`__ | | -+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``+`` `Expr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/Expr.qll/type.Expr$Expr.html>`__ | `UnaryPlusExpr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/ArithmeticOperation.qll/type.ArithmeticOperation$UnaryPlusExpr.html>`__ | | -+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``~`` `Expr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/Expr.qll/type.Expr$Expr.html>`__ | | `ComplementExpr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/BitwiseOperation.qll/type.BitwiseOperation$ComplementExpr.html>`__ | | | -| | | `ConjugationExpr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/ArithmeticOperation.qll/type.ArithmeticOperation$ConjugationExpr.html>`__ | | GNU extension | -+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``!`` `Expr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/Expr.qll/type.Expr$Expr.html>`__ | `NotExpr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/LogicalOperation.qll/type.LogicalOperation$NotExpr.html>`__ | | -+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| | ``int`` *vect* ``__attribute__`` | `VectorFillOperation <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/BuiltInOperations.qll/type.BuiltInOperations$VectorFillOperation.html>`__ | GNU extension | -| | ``( ( vector_size (`` *16* ``) ) )`` | | | -| | ``= {`` *3* ``,`` *8* ``,`` *32* ``,`` *33* ``};`` | | | -+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``sizeof (`` `Expr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/Expr.qll/type.Expr$Expr.html>`__ ``)`` | `SizeofExprOperator <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/Cast.qll/type.Cast$SizeofExprOperator.html>`__ | | -+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``sizeof (`` `Type <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/Type.qll/type.Type$Type.html>`__ ``)`` | `SizeofTypeOperator <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/Cast.qll/type.Cast$SizeofTypeOperator.html>`__ | | -+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| | ``template < typename...`` *T* ``>`` | `SizeofPackOperator <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/Cast.qll/type.Cast$SizeofPackOperator.html>`__ | | -| | ``int`` *count* ``(`` *T* ``&&...`` *t* ``)`` | | | -| | ``{ return sizeof... (`` *t* ``); }`` | | | -+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``( {`` `Stmt <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/stmts/Stmt.qll/type.Stmt$Stmt.html>`__... ``;`` `Expr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/Expr.qll/type.Expr$Expr.html>`__ ``} )`` | `StmtExpr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/Expr.qll/type.Expr$StmtExpr.html>`__ | GNU/Clang extension | -+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``this`` | `ThisExpr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/Expr.qll/type.Expr$ThisExpr.html>`__ | | -+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``throw (`` `Expr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/Expr.qll/type.Expr$Expr.html>`__ ``);`` | `ThrowExpr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/Call.qll/type.Call$ThrowExpr.html>`__ | | -+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``throw;`` | `ReThrowExpr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/Call.qll/type.Call$ReThrowExpr.html>`__ | | -+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| | ``typeid (`` `Expr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/Expr.qll/type.Expr$Expr.html>`__ ``)`` | `TypeidOperator <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/Cast.qll/type.Cast$TypeidOperator.html>`__ | | -| | ``typeid (`` `Type <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/Type.qll/type.Type$Type.html>`__ ``)`` | | | -+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``__uuidof (`` `Expr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/Expr.qll/type.Expr$Expr.html>`__ ``)`` | `UuidofOperator <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/Cast.qll/type.Cast$UuidofOperator.html>`__ | Microsoft extension | -+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - - -Type classes -~~~~~~~~~~~~ - -This table lists subclasses of `Type <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/Type.qll/type.Type$Type.html>`__ representing C/C++ types. - -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| Example syntax | CodeQL class | Remarks | -+=============================================================================================================================================================================================================================================================================================================================================================================================================================================+==================================================================================================================================================================+==================================================================================================================================================================================================================================================================================+ -| ``void`` | `VoidType <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/Type.qll/type.Type$VoidType.html>`__ | | -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``_Bool`` or ``bool`` | `BoolType <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/Type.qll/type.Type$BoolType.html>`__ | | -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``char16_t`` | `Char16Type <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/Type.qll/type.Type$Char16Type.html>`__ | C11, C++11 | -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``char32_t`` | `Char32Type <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/Type.qll/type.Type$Char32Type.html>`__ | C11, C++11 | -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``char`` | `PlainCharType <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/Type.qll/type.Type$PlainCharType.html>`__ | | -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``signed char`` | `SignedCharType <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/Type.qll/type.Type$SignedCharType.html>`__ | | -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``unsigned char`` | `UnsignedCharType <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/Type.qll/type.Type$UnsignedCharType.html>`__ | | -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``int`` | `IntType <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/Type.qll/type.Type$IntType.html>`__ | | -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``long long`` | `LongLongType <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/Type.qll/type.Type$LongLongType.html>`__ | | -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``long`` | `LongType <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/Type.qll/type.Type$LongType.html>`__ | | -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``short`` | `ShortType <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/Type.qll/type.Type$ShortType.html>`__ | | -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``wchar_t`` | `WideCharType <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/Type.qll/type.Type$WideCharType.html>`__ | | -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``nullptr_t`` | `NullPointerType <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/Type.qll/type.Type$NullPointerType.html>`__ | | -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``double`` | `DoubleType <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/Type.qll/type.Type$DoubleType.html>`__ | | -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``long double`` | `LongDoubleType <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/Type.qll/type.Type$LongDoubleType.html>`__ | | -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``float`` | `FloatType <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/Type.qll/type.Type$FloatType.html>`__ | | -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``auto`` | `AutoType <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/Type.qll/type.Type$AutoType.html>`__ | | -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``decltype (`` `Expr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/Expr.qll/type.Expr$Expr.html>`__ ``)`` | `Decltype <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/Type.qll/type.Type$Decltype.html>`__ | | -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| `Type <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/Type.qll/type.Type$Type.html>`__ ``[`` *n* ``]`` | `ArrayType <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/Type.qll/type.Type$ArrayType.html>`__ | | -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| `Type <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/Type.qll/type.Type$Type.html>`__ ``( ^`` *blockptr* ``) (`` `Parameter <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/Parameter.qll/type.Parameter$Parameter.html>`__... ``)`` | `BlockType <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/Type.qll/type.Type$BlockType.html>`__ | Apple extension | -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| `Type <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/Type.qll/type.Type$Type.html>`__ ``( *`` *funcptr* ``) (`` `Parameter <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/Parameter.qll/type.Parameter$Parameter.html>`__... ``)`` | `FunctionPointerType <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/Type.qll/type.Type$FunctionPointerType.html>`__ | | -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| `Type <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/Type.qll/type.Type$Type.html>`__ ``( &`` *funcref* ``) (`` `Parameter <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/Parameter.qll/type.Parameter$Parameter.html>`__... ``)`` | `FunctionReferenceType <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/Type.qll/type.Type$FunctionReferenceType.html>`__ | | -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| `Type <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/Type.qll/type.Type$Type.html>`__ ``__attribute__ ( ( vector_size (`` *n* ``) ) )`` | `GNUVectorType <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/Type.qll/type.Type$GNUVectorType.html>`__ | | -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| `Type <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/Type.qll/type.Type$Type.html>`__ ``*`` | `PointerType <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/Type.qll/type.Type$PointerType.html>`__ | | -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| `Type <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/Type.qll/type.Type$Type.html>`__ ``&`` | `LValueReferenceType <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/Type.qll/type.Type$LValueReferenceType.html>`__ | | -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| `Type <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/Type.qll/type.Type$Type.html>`__ ``&&`` | `RValueReferenceType <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/Type.qll/type.Type$RValueReferenceType.html>`__ | | -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| `Type <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/Type.qll/type.Type$Type.html>`__ ``(`` `Class <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/Class.qll/type.Class$Class.html>`__ ``*::`` *membptr* ``) (`` `Parameter <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/Parameter.qll/type.Parameter$Parameter.html>`__... ``)`` | `PointerToMemberType <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/Type.qll/type.Type$PointerToMemberType.html>`__ | | -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``template < template < typename > class`` *C* ``>`` | `TemplateTemplateParameter <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/Type.qll/type.Type$TemplateTemplateParameter.html>`__ | | -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``template < typename`` *T* ``>`` | `TemplateParameter <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/Type.qll/type.Type$TemplateParameter.html>`__ | | -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - - -Preprocessor classes -~~~~~~~~~~~~~~~~~~~~ - -This table lists `Preprocessor <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/Preprocessor.qll/module.Preprocessor.html>`__ classes representing C/C++ preprocessing directives. - -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| Example syntax | CodeQL class | Remarks | -+=============================================================================================================================================================================================================================================================================================================================================================================================================================================+==================================================================================================================================================================+===================================================================================================================================================================================================================================================================================+ -| ``#elif`` *condition* | `PreprocessorElif <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/Preprocessor.qll/type.Preprocessor$PreprocessorElif.html>`__ | | -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``#if`` *condition* | `PreprocessorIf <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/Preprocessor.qll/type.Preprocessor$PreprocessorIf.html>`__ | | -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``#ifdef`` *macro* | `PreprocessorIfdef <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/Preprocessor.qll/type.Preprocessor$PreprocessorIfdef.html>`__ | | -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``#ifndef`` *macro* | `PreprocessorIfndef <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/Preprocessor.qll/type.Preprocessor$PreprocessorIfndef.html>`__ | | -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``#else`` | `PreprocessorElse <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/Preprocessor.qll/type.Preprocessor$PreprocessorElse.html>`__ | | -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``#endif`` | `PreprocessorEndif <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/Preprocessor.qll/type.Preprocessor$PreprocessorEndif.html>`__ | | -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``#line`` *line_number* *file_name* | `PreprocessorLine <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/Preprocessor.qll/type.Preprocessor$PreprocessorLine.html>`__ | | -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``#pragma`` *pragma_property* | `PreprocessorPragma <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/Preprocessor.qll/type.Preprocessor$PreprocessorPragma.html>`__ | | -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``#undef`` *macro* | `PreprocessorUndef <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/Preprocessor.qll/type.Preprocessor$PreprocessorUndef.html>`__ | | -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``#warning`` *message* | `PreprocessorWarning <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/Preprocessor.qll/type.Preprocessor$PreprocessorWarning.html>`__ | | -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``#error`` *message* | `PreprocessorError <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/Preprocessor.qll/type.Preprocessor$PreprocessorError.html>`__ | | -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``#include`` *file_name* | `Include <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/Include.qll/type.Include$Include.html>`__ | | -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``#import`` *file_name* | `Import <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/Include.qll/type.Include$Import.html>`__ | Apple/NeXT extension | -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``#include_next`` *file_name* | `IncludeNext <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/Include.qll/type.Include$IncludeNext.html>`__ | Apple/NeXT extension | -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``#define`` *macro* ... | `Macro <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/Macro.qll/type.Macro$Macro.html>`__ | | -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - - -Further reading ---------------- - -.. include:: ../../reusables/cpp-further-reading.rst -.. include:: ../../reusables/codeql-ref-tools-further-reading.rst diff --git a/docs/codeql/codeql-language-guides/codeql-for-csharp/index.rst b/docs/codeql/codeql-language-guides/codeql-for-csharp.rst similarity index 100% rename from docs/codeql/codeql-language-guides/codeql-for-csharp/index.rst rename to docs/codeql/codeql-language-guides/codeql-for-csharp.rst diff --git a/docs/codeql/codeql-language-guides/codeql-for-go/index.rst b/docs/codeql/codeql-language-guides/codeql-for-go.rst similarity index 100% rename from docs/codeql/codeql-language-guides/codeql-for-go/index.rst rename to docs/codeql/codeql-language-guides/codeql-for-go.rst diff --git a/docs/codeql/codeql-language-guides/codeql-for-go/abstract-syntax-tree-classes-for-working-with-go-programs.rst b/docs/codeql/codeql-language-guides/codeql-for-go/abstract-syntax-tree-classes-for-working-with-go-programs.rst deleted file mode 100644 index 22a1722b8a6..00000000000 --- a/docs/codeql/codeql-language-guides/codeql-for-go/abstract-syntax-tree-classes-for-working-with-go-programs.rst +++ /dev/null @@ -1,485 +0,0 @@ -.. _abstract-syntax-tree-classes-for-working-with-go-programs: - -Abstract syntax tree classes for working with Go programs -========================================================= - -CodeQL has a large selection of classes for representing the abstract syntax tree of Go programs. - -.. include:: ../../reusables/abstract-syntax-tree.rst - -Statement classes ------------------ - -This table lists all subclasses of `Stmt <https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$Stmt.html>`__. - -+-------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+ -| Statement syntax | CodeQL class | Superclasses | Remarks | -+===================================================================================================================+===================================================================================================================+===============================================================================================================+===================================================================================================================+ -| ``;`` | EmptyStmt_ | | | -| | | | | -| | .. _EmptyStmt: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$EmptyStmt.html | | | -+-------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+ -| Expr_ | ExprStmt_ | | | -| | | | | -| .. _Expr: https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html | .. _ExprStmt: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$ExprStmt.html | | | -+-------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+ -| ``{`` Stmt_ ``...`` ``}`` | BlockStmt_ | | | -| | | | | -| .. _Stmt: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$Stmt.html | .. _BlockStmt: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$BlockStmt.html | | | -+-------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+ -| ``if`` Expr_ BlockStmt_ | IfStmt_ | | | -| | | | | -| .. _Expr: https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html | .. _IfStmt: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$IfStmt.html | | | -| .. _BlockStmt: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$BlockStmt.html | | | | -+-------------------------------------------------------------------------------------------------------------------+ | | | -| ``if`` Expr_ BlockStmt_ ``else`` Stmt_ | | | | -| | | | | -| .. _Expr: https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html | | | | -| .. _BlockStmt: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$BlockStmt.html | | | | -| .. _Stmt: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$Stmt.html | | | | -+-------------------------------------------------------------------------------------------------------------------+ | | | -| ``if`` Stmt_\ ``;`` Expr_ BlockStmt_ | | | | -| | | | | -| .. _Stmt: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$Stmt.html | | | | -| .. _Expr: https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html | | | | -| .. _BlockStmt: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$BlockStmt.html | | | | -+-------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+ -| ``for`` Expr_ BlockStmt_ | ForStmt_ | LoopStmt_ | | -| | | | | -| .. _Expr: https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html | .. _ForStmt: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$ForStmt.html | .. _LoopStmt: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$LoopStmt.html | | -| .. _BlockStmt: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$BlockStmt.html | | | | -+-------------------------------------------------------------------------------------------------------------------+ | | | -| ``for`` Stmt_\ ``;`` Expr_\ ``;`` Stmt_ BlockStmt_ | | | | -| | | | | -| .. _Stmt: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$Stmt.html | | | | -| .. _Expr: https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html | | | | -| .. _Stmt: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$Stmt.html | | | | -| .. _BlockStmt: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$BlockStmt.html | | | | -+-------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+ -| ``for`` Expr_ ``...`` ``=`` ``range`` Expr_ BlockStmt_ | RangeStmt_ | LoopStmt_ | | -| | | | | -| .. _Expr: https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html | .. _RangeStmt: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$RangeStmt.html | .. _LoopStmt: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$LoopStmt.html | | -| .. _Expr: https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html | | | | -| .. _BlockStmt: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$BlockStmt.html | | | | -+-------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+ -| ``switch`` Expr_ ``{`` CaseClause_ ``...`` ``}`` | ExpressionSwitchStmt_ | SwitchStmt_ | | -| | | | | -| .. _Expr: https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html | .. _ExpressionSwitchStmt: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$ExpressionSwitchStmt.html | .. _SwitchStmt: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$SwitchStmt.html | | -| .. _CaseClause: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$CaseClause.html | | | | -+-------------------------------------------------------------------------------------------------------------------+ | | | -| ``switch`` Stmt_\ ``;`` Expr_ ``{`` CaseClause_ ``...`` ``}`` | | | | -| | | | | -| .. _Stmt: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$Stmt.html | | | | -| .. _Expr: https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html | | | | -| .. _CaseClause: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$CaseClause.html | | | | -+-------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+ -| ``switch`` Expr_\ ``.(type)`` ``{`` CaseClause_ ``...`` ``}`` | TypeSwitchStmt_ | SwitchStmt_ | | -| | | | | -| .. _Expr: https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html | .. _TypeSwitchStmt: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$TypeSwitchStmt.html | .. _SwitchStmt: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$SwitchStmt.html | | -| .. _CaseClause: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$CaseClause.html | | | | -+-------------------------------------------------------------------------------------------------------------------+ | | | -| ``switch`` SimpleAssignStmt_\ ``.(type)`` ``{`` CaseClause_ ``...`` ``}`` | | | | -| | | | | -| .. _SimpleAssignStmt: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$SimpleAssignStmt.html | | | | -| .. _CaseClause: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$CaseClause.html | | | | -+-------------------------------------------------------------------------------------------------------------------+ | | | -| ``switch`` Stmt_\ ``;`` Expr_\ ``.(type)`` ``{`` CaseClause_ ``...`` ``}`` | | | | -| | | | | -| .. _Stmt: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$Stmt.html | | | | -| .. _Expr: https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html | | | | -| .. _CaseClause: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$CaseClause.html | | | | -+-------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+ -| ``select`` ``{`` CommClause_ ``...`` ``}`` | SelectStmt_ | | | -| | | | | -| .. _CommClause: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$CommClause.html | .. _SelectStmt: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$SelectStmt.html | | | -+-------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+ -| ``return`` | ReturnStmt_ | | | -+-------------------------------------------------------------------------------------------------------------------+ | | | -| ``return`` Expr_ ``...`` | .. _ReturnStmt: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$ReturnStmt.html | | | -| | | | | -| .. _Expr: https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html | | | | -+-------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+ -| ``break`` | BreakStmt_ | BranchStmt_ | | -+-------------------------------------------------------------------------------------------------------------------+ | | | -| ``break`` LabelName_ | .. _BreakStmt: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$BreakStmt.html | .. _BranchStmt: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$BranchStmt.html | | -| | | | | -| .. _LabelName: https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$LabelName.html | | | | -+-------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+ -| ``continue`` | ContinueStmt_ | BranchStmt_ | | -+-------------------------------------------------------------------------------------------------------------------+ | | | -| ``continue`` LabelName_ | .. _ContinueStmt: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$ContinueStmt.html | .. _BranchStmt: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$BranchStmt.html | | -| | | | | -| .. _LabelName: https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$LabelName.html | | | | -+-------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+ -| ``goto`` LabelName_ | GotoStmt_ | BranchStmt_ | | -| | | | | -| .. _LabelName: https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$LabelName.html | .. _GotoStmt: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$GotoStmt.html | .. _BranchStmt: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$BranchStmt.html | | -+-------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+ -| ``fallthrough`` | FallthroughStmt_ | BranchStmt_ | can only occur as final non-empty child of a CaseClause_ in an ExpressionSwitchStmt_ | -| | | | | -| | .. _FallthroughStmt: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$FallthroughStmt.html | .. _BranchStmt: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$BranchStmt.html | .. _CaseClause: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$CaseClause.html | -| | | | .. _ExpressionSwitchStmt: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$ExpressionSwitchStmt.html | -+-------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+ -| LabelName_\ ``:`` Stmt_ | LabeledStmt_ | | | -| | | | | -| .. _LabelName: https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$LabelName.html | .. _LabeledStmt: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$LabeledStmt.html | | | -| .. _Stmt: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$Stmt.html | | | | -+-------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+ -| ``var`` VariableName_ TypeName_ | DeclStmt_ | | | -| | | | | -| .. _VariableName: https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$VariableName.html | .. _DeclStmt: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$DeclStmt.html | | | -| .. _TypeName: https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$TypeName.html | | | | -+-------------------------------------------------------------------------------------------------------------------+ | | | -| ``const`` VariableName_ ``=`` Expr_ | | | | -| | | | | -| .. _VariableName: https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$VariableName.html | | | | -| .. _Expr: https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html | | | | -+-------------------------------------------------------------------------------------------------------------------+ | | | -| ``type`` TypeName_ TypeExpr_ | | | | -| | | | | -| .. _TypeName: https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$TypeName.html | | | | -| .. _TypeExpr: https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$TypeExpr.html | | | | -+-------------------------------------------------------------------------------------------------------------------+ | | | -| ``type`` TypeName_ ``=`` TypeExpr_ | | | | -| | | | | -| .. _TypeName: https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$TypeName.html | | | | -| .. _TypeExpr: https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$TypeExpr.html | | | | -+-------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+ -| Expr_ ``...`` ``=`` Expr_ ``...`` | AssignStmt_ | SimpleAssignStmt_, Assignment_ | | -| | | | | -| .. _Expr: https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html | .. _AssignStmt: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$AssignStmt.html | .. _SimpleAssignStmt: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$SimpleAssignStmt.html | | -| .. _Expr: https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html | | .. _Assignment: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$Assignment.html | | -+-------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+ -| VariableName_ ``...`` ``:=`` Expr_ ``...`` | DefineStmt_ | SimpleAssignStmt_, Assignment_ | | -| | | | | -| .. _VariableName: https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$VariableName.html | .. _DefineStmt: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$DefineStmt.html | .. _SimpleAssignStmt: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$SimpleAssignStmt.html | | -| .. _Expr: https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html | | .. _Assignment: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$Assignment.html | | -+-------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+ -| Expr_ ``+=`` Expr_ | AddAssignStmt_ | CompoundAssignStmt_, Assignment_ | | -| | | | | -| .. _Expr: https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html | .. _AddAssignStmt: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$AddAssignStmt.html | .. _CompoundAssignStmt: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$CompoundAssignStmt.html | | -| .. _Expr: https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html | | .. _Assignment: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$Assignment.html | | -+-------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+ -| Expr_ ``-=`` Expr_ | SubAssignStmt_ | CompoundAssignStmt_, Assignment_ | | -| | | | | -| .. _Expr: https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html | .. _SubAssignStmt: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$SubAssignStmt.html | .. _CompoundAssignStmt: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$CompoundAssignStmt.html | | -| .. _Expr: https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html | | .. _Assignment: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$Assignment.html | | -+-------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+ -| Expr_ ``*=`` Expr_ | MulAssignStmt_ | CompoundAssignStmt_, Assignment_ | | -| | | | | -| .. _Expr: https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html | .. _MulAssignStmt: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$MulAssignStmt.html | .. _CompoundAssignStmt: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$CompoundAssignStmt.html | | -| .. _Expr: https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html | | .. _Assignment: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$Assignment.html | | -+-------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+ -| Expr_ ``/=`` Expr_ | QuoAssignStmt_ | CompoundAssignStmt_, Assignment_ | | -| | | | | -| .. _Expr: https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html | .. _QuoAssignStmt: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$QuoAssignStmt.html | .. _CompoundAssignStmt: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$CompoundAssignStmt.html | | -| .. _Expr: https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html | | .. _Assignment: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$Assignment.html | | -+-------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+ -| Expr_ ``%=`` Expr_ | RemAssignStmt_ | CompoundAssignStmt_, Assignment_ | | -| | | | | -| .. _Expr: https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html | .. _RemAssignStmt: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$RemAssignStmt.html | .. _CompoundAssignStmt: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$CompoundAssignStmt.html | | -| .. _Expr: https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html | | .. _Assignment: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$Assignment.html | | -+-------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+ -| Expr_ ``*=`` Expr_ | MulAssignStmt_ | CompoundAssignStmt_, Assignment_ | | -| | | | | -| .. _Expr: https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html | .. _MulAssignStmt: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$MulAssignStmt.html | .. _CompoundAssignStmt: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$CompoundAssignStmt.html | | -| .. _Expr: https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html | | .. _Assignment: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$Assignment.html | | -+-------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+ -| Expr_ ``&=`` Expr_ | AndAssignStmt_ | CompoundAssignStmt_, Assignment_ | | -| | | | | -| .. _Expr: https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html | .. _AndAssignStmt: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$AndAssignStmt.html | .. _CompoundAssignStmt: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$CompoundAssignStmt.html | | -| .. _Expr: https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html | | .. _Assignment: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$Assignment.html | | -+-------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+ -| Expr_ ``|=`` Expr_ | OrAssignStmt_ | CompoundAssignStmt_, Assignment_ | | -| | | | | -| .. _Expr: https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html | .. _OrAssignStmt: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$OrAssignStmt.html | .. _CompoundAssignStmt: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$CompoundAssignStmt.html | | -| .. _Expr: https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html | | .. _Assignment: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$Assignment.html | | -+-------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+ -| Expr_ ``^=`` Expr_ | XorAssignStmt_ | CompoundAssignStmt_, Assignment_ | | -| | | | | -| .. _Expr: https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html | .. _XorAssignStmt: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$XorAssignStmt.html | .. _CompoundAssignStmt: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$CompoundAssignStmt.html | | -| .. _Expr: https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html | | .. _Assignment: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$Assignment.html | | -+-------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+ -| Expr_ ``<<=`` Expr_ | ShlAssignStmt_ | CompoundAssignStmt_, Assignment_ | | -| | | | | -| .. _Expr: https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html | .. _ShlAssignStmt: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$ShlAssignStmt.html | .. _CompoundAssignStmt: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$CompoundAssignStmt.html | | -| .. _Expr: https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html | | .. _Assignment: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$Assignment.html | | -+-------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+ -| Expr_ ``>>=`` Expr_ | ShrAssignStmt_ | CompoundAssignStmt_, Assignment_ | | -| | | | | -| .. _Expr: https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html | .. _ShrAssignStmt: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$ShrAssignStmt.html | .. _CompoundAssignStmt: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$CompoundAssignStmt.html | | -| .. _Expr: https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html | | .. _Assignment: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$Assignment.html | | -+-------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+ -| Expr_ ``&^=`` Expr_ | AndNotAssignStmt_ | CompoundAssignStmt_, Assignment_ | | -| | | | | -| .. _Expr: https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html | .. _AndNotAssignStmt: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$AndNotAssignStmt.html | .. _CompoundAssignStmt: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$CompoundAssignStmt.html | | -| .. _Expr: https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html | | .. _Assignment: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$Assignment.html | | -+-------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+ -| Expr_ ``++`` | IncStmt_ | IncDecStmt_ | | -| | | | | -| .. _Expr: https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html | .. _IncStmt: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$IncStmt.html | .. _IncDecStmt: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$IncDecStmt.html | | -+-------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+ -| Expr_ ``--`` | DecStmt_ | IncDecStmt_ | | -| | | | | -| .. _Expr: https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html | .. _DecStmt: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$DecStmt.html | .. _IncDecStmt: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$IncDecStmt.html | | -+-------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+ -| ``go`` CallExpr_ | GoStmt_ | | | -| | | | | -| .. _CallExpr: https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$CallExpr.html | .. _GoStmt: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$GoStmt.html | | | -+-------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+ -| ``defer`` CallExpr_ | DeferStmt_ | | | -| | | | | -| .. _CallExpr: https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$CallExpr.html | .. _DeferStmt: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$DeferStmt.html | | | -+-------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+ -| Expr_ ``<-`` Expr_ | SendStmt_ | | | -| | | | | -| .. _Expr: https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html | .. _SendStmt: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$SendStmt.html | | | -| .. _Expr: https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html | | | | -+-------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+ -| ``case`` Expr_ ``...``\ ``:`` Stmt_ ``...`` | CaseClause_ | | can only occur as child of a SwitchStmt_ | -| | | | | -| .. _Expr: https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html | .. _CaseClause: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$CaseClause.html | | .. _SwitchStmt: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$SwitchStmt.html | -| .. _Stmt: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$Stmt.html | | | | -+-------------------------------------------------------------------------------------------------------------------+ | | | -| ``case`` TypeExpr_ ``...``\ ``:`` Stmt_ ``...`` | | | | -| | | | | -| .. _TypeExpr: https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$TypeExpr.html | | | | -| .. _Stmt: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$Stmt.html | | | | -+-------------------------------------------------------------------------------------------------------------------+ | | | -| ``default:`` Stmt_ ``...`` | | | | -| | | | | -| .. _Stmt: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$Stmt.html | | | | -+-------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+ -| ``case`` SendStmt_\ ``:`` Stmt_ ``...`` | CommClause_ | | can only occur as child of a SelectStmt_ | -| | | | | -| .. _SendStmt: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$SendStmt.html | .. _CommClause: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$CommClause.html | | .. _SelectStmt: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$SelectStmt.html | -| .. _Stmt: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$Stmt.html | | | | -+-------------------------------------------------------------------------------------------------------------------+ | | | -| ``case`` RecvStmt_\ ``:`` Stmt_ ``...`` | | | | -| | | | | -| .. _RecvStmt: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$RecvStmt.html | | | | -| .. _Stmt: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$Stmt.html | | | | -+-------------------------------------------------------------------------------------------------------------------+ | | | -| ``default:`` Stmt_ ``...`` | | | | -| | | | | -| .. _Stmt: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$Stmt.html | | | | -+-------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+ -| Expr_ ``...`` ``=`` RecvExpr_ | RecvStmt_ | | can only occur as child of a CommClause_ | -| | | | | -| .. _Expr: https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html | .. _RecvStmt: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$RecvStmt.html | | .. _CommClause: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$CommClause.html | -| .. _RecvExpr: https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$RecvExpr.html | | | | -+-------------------------------------------------------------------------------------------------------------------+ | | | -| VariableName_ ``...`` ``:=`` RecvExpr_ | | | | -| | | | | -| .. _VariableName: https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$VariableName.html | | | | -| .. _RecvExpr: https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$RecvExpr.html | | | | -+-------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+ -| (anything unparseable) | BadStmt_ | | | -| | | | | -| | .. _BadStmt: https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$BadStmt.html | | | -+-------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+ - -Expression classes ------------------- - -There are many expression classes, so we present them by category. -All classes in this section are subclasses of -`Expr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html>`__. - -Literals -~~~~~~~~ - -+-----------------------------------------+----------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------+ -| Expression syntax example | CodeQL class | Superclass | -+=========================================+==============================================================================================+====================================================================================================+ -| ``23`` | `IntLit <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$IntLit.html>`__ | `BasicLit <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$BasicLit.html>`__ | -+-----------------------------------------+----------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------+ -| ``4.2`` | `FloatLit <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$FloatLit.html>`__ | `BasicLit <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$BasicLit.html>`__ | -+-----------------------------------------+----------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------+ -| ``4.2 + 2.7i`` | `ImagLit <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$ImagLit.html>`__ | `BasicLit <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$BasicLit.html>`__ | -+-----------------------------------------+----------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------+ -| ``'a'`` | `CharLit <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$CharLit.html>`__ | `BasicLit <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$BasicLit.html>`__ | -+-----------------------------------------+----------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------+ -| ``"Hello"`` | `StringLit <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$StringLit.html>`__ | `BasicLit <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$BasicLit.html>`__ | -+-----------------------------------------+----------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------+ -| ``func(x, y int) int { return x + y }`` | `FuncLit <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$FuncLit.html>`__ | `FuncDef <https://help.semmle.com/qldoc/go/semmle/go/Decls.qll/type.Decls$FuncDef.html>`__ | -+-----------------------------------------+----------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------+ -| ``map[string]int{"A": 1, "B": 2}`` | `MapLit <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$MapLit.html>`__ | `CompositeLit <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$CompositeLit.html>`__ | -+-----------------------------------------+----------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------+ -| ``Point3D{0.5, -0.5, 0.5}`` | `StructLit <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$StructLit.html>`__ | `CompositeLit <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$CompositeLit.html>`__ | -+-----------------------------------------+----------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------+ - -Unary expressions -~~~~~~~~~~~~~~~~~ - -All classes in this subsection are subclasses of -`UnaryExpr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$UnaryExpr.html>`__. - -+--------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------+ -| Expression syntax | CodeQL class | Superclasses | -+============================================================================================+========================================================================================================+==================================================================================================================+ -| ``+``\ `Expr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html>`__ | `PlusExpr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$PlusExpr.html>`__ | `ArithmeticUnaryExpr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$ArithmeticUnaryExpr.html>`__ | -+--------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------+ -| ``-``\ `Expr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html>`__ | `MinusExpr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$MinusExpr.html>`__ | `ArithmeticUnaryExpr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$ArithmeticUnaryExpr.html>`__ | -+--------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------+ -| ``!``\ `Expr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html>`__ | `NotExpr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$NotExpr.html>`__ | `LogicalUnaryExpr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$LogicalUnaryExpr.html>`__ | -+--------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------+ -| ``^``\ `Expr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html>`__ | `ComplementExpr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$ComplementExpr.html>`__ | `BitwiseUnaryExpr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$BitwiseUnaryExpr.html>`__ | -+--------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------+ -| ``&``\ `Expr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html>`__ | `AddressExpr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$AddressExpr.html>`__ | | -+--------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------+ -| ``<-``\ `Expr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html>`__ | `RecvExpr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$RecvExpr.html>`__ | | -+--------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------+ - -Binary expressions -~~~~~~~~~~~~~~~~~~ - -All classes in this subsection are subclasses of -`BinaryExpr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$BinaryExpr.html>`__. - -+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------+ -| Expression syntax | CodeQL class | Superclasses | -+==============================================================================================================================================================================+================================================================================================+============================================================================================================================+ -| `Expr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html>`__ ``*`` `Expr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html>`__ | `MulExpr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$MulExpr.html>`__ | `ArithmeticBinaryExpr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$ArithmeticBinaryExpr.html>`__ | -+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------+ -| `Expr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html>`__ ``/`` `Expr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html>`__ | `QuoExpr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$QuoExpr.html>`__ | `ArithmeticBinaryExpr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$ArithmeticBinaryExpr.html>`__ | -+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------+ -| `Expr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html>`__ ``%`` `Expr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html>`__ | `RemExpr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$RemExpr.html>`__ | `ArithmeticBinaryExpr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$ArithmeticBinaryExpr.html>`__ | -+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------+ -| `Expr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html>`__ ``+`` `Expr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html>`__ | `AddExpr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$AddExpr.html>`__ | `ArithmeticBinaryExpr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$ArithmeticBinaryExpr.html>`__ | -+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------+ -| `Expr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html>`__ ``-`` `Expr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html>`__ | `SubExpr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$SubExpr.html>`__ | `ArithmeticBinaryExpr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$ArithmeticBinaryExpr.html>`__ | -+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------+ -| `Expr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html>`__ ``<<`` `Expr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html>`__ | `ShlExpr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$ShlExpr.html>`__ | `ShiftExpr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$ShiftExpr.html>`__ | -+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------+ -| `Expr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html>`__ ``>>`` `Expr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html>`__ | `ShrExpr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$ShrExpr.html>`__ | `ShiftExpr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$ShiftExpr.html>`__ | -+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------+ -| `Expr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html>`__ ``&&`` `Expr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html>`__ | `LandExpr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$LandExpr.html>`__ | `LogicalBinaryExpr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$LogicalBinaryExpr.html>`__ | -+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------+ -| `Expr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html>`__ ``||`` `Expr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html>`__ | `LorExpr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$LorExpr.html>`__ | `LogicalBinaryExpr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$LogicalBinaryExpr.html>`__ | -+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------+ -| `Expr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html>`__ ``<`` `Expr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html>`__ | `LssExpr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$LssExpr.html>`__ | `RelationalComparisonExpr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$RelationalComparisonExpr.html>`__ | -+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------+ -| `Expr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html>`__ ``>`` `Expr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html>`__ | `GtrExpr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$GtrExpr.html>`__ | `RelationalComparisonExpr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$RelationalComparisonExpr.html>`__ | -+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------+ -| `Expr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html>`__ ``<=`` `Expr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html>`__ | `LeqExpr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$LeqExpr.html>`__ | `RelationalComparisonExpr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$RelationalComparisonExpr.html>`__ | -+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------+ -| `Expr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html>`__ ``>=`` `Expr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html>`__ | `GeqExpr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$GeqExpr.html>`__ | `RelationalComparisonExpr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$RelationalComparisonExpr.html>`__ | -+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------+ -| `Expr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html>`__ ``==`` `Expr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html>`__ | `EqlExpr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$EqlExpr.html>`__ | `EqualityTestExpr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$EqualityTestExpr.html>`__ | -+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------+ -| `Expr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html>`__ ``!=`` `Expr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html>`__ | `NeqExpr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$NeqExpr.html>`__ | `EqualityTestExpr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$EqualityTestExpr.html>`__ | -+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------+ -| `Expr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html>`__ ``&`` `Expr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html>`__ | `AndExpr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$AndExpr.html>`__ | `BitwiseBinaryExpr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$BitwiseBinaryExpr.html>`__ | -+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------+ -| `Expr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html>`__ ``|`` `Expr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html>`__ | `OrExpr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$OrExpr.html>`__ | `BitwiseBinaryExpr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$BitwiseBinaryExpr.html>`__ | -+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------+ -| `Expr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html>`__ ``^`` `Expr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html>`__ | `XorExpr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$XorExpr.html>`__ | `BitwiseBinaryExpr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$BitwiseBinaryExpr.html>`__ | -+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------+ -| `Expr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html>`__ ``&^`` `Expr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html>`__ | `AndNotExpr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$AndNotExpr.html>`__ | `BitwiseBinaryExpr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$BitwiseBinaryExpr.html>`__ | -+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------+ - -Type expressions -~~~~~~~~~~~~~~~~ - -These classes represent different expressions for types. They do -not have a common superclass. - -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------+ -| Expression syntax | CodeQL class | Superclasses | -+=========================================================================================================================================================================================================+====================================================================================================================+====================================================================================================+ -| ``[``\ `Expr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html>`__\ ``]`` `TypeExpr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$TypeExpr.html>`__ | `ArrayTypeExpr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$ArrayTypeExpr.html>`__ | | -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------+ -| ``struct { ... }`` | `StructTypeExpr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$StructTypeExpr.html>`__ | | -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------+ -| ``func`` `FunctionName <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$FunctionName.html>`__\ ``(...) (...)`` | `FuncTypeExpr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$FuncTypeExpr.html>`__ | | -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------+ -| ``interface { ... }`` | `InterfaceTypeExpr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$InterfaceTypeExpr.html>`__ | | -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------+ -| ``map[``\ `TypeExpr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$TypeExpr.html>`__\ ``]``\ `TypeExpr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$TypeExpr.html>`__ | `MapTypeExpr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$MapTypeExpr.html>`__ | | -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------+ -| ``chan<-`` `TypeExpr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$TypeExpr.html>`__ | `SendChanTypeExpr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$SendChanTypeExpr.html>`__ | `ChanTypeExpr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$ChanTypeExpr.html>`__ | -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------+ -| ``<-chan`` `TypeExpr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$TypeExpr.html>`__ | `RecvChanTypeExpr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$RecvChanTypeExpr.html>`__ | `ChanTypeExpr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$ChanTypeExpr.html>`__ | -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------+ -| ``chan`` `TypeExpr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$TypeExpr.html>`__ | `SendRecvChanTypeExpr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$SendRecvChanTypeExpr.html>`__ | `ChanTypeExpr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$ChanTypeExpr.html>`__ | -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------+ - -Name expressions -~~~~~~~~~~~~~~~~ - -All classes in this subsection are subclasses of -`Name <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Name.html>`__. - -The following classes relate to the structure of the name. - -+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------+ -| Expression syntax | CodeQL class | Superclasses | -+===================================================================================================================================================================================+======================================================================================================+====================================================================================================+ -| `Ident <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Ident.html>`__ | `SimpleName <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$SimpleName.html>`__ | `Ident <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Ident.html>`__ | -+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------+ -| `Ident <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Ident.html>`__\ ``.``\ `Ident <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Ident.html>`__ | `QualifiedName <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$QualifiedName.html>`__ | `SelectorExpr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$SelectorExpr.html>`__ | -+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------+ - -The following classes relate to what sort of entity the name refers to. - - -- `PackageName <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$PackageName.html>`__ -- `TypeName <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$TypeName.html>`__ -- `LabelName <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$LabelName.html>`__ -- `ValueName <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$ValueName.html>`__ - - - `ConstantName <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$ConstantName.html>`__ - - `VariableName <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$VariableName.html>`__ - - `FunctionName <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$FunctionName.html>`__ - -Miscellaneous -~~~~~~~~~~~~~ - -+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| Expression syntax | CodeQL class | Superclasses | Remarks | -+============================================================================================================================================================================================================================================================================================================================================================================+========================================================================================================+====================================================================================================================+==========================================================================================================================================================================================================================+ -| ``foo`` | `Ident <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Ident.html>`__ | | | -+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``_`` | `BlankIdent <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$BlankIdent.html>`__ | | | -+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``...`` | `Ellipsis <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Ellipsis.html>`__ | | | -+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``(``\ `Expr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html>`__\ ``)`` | `ParenExpr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$ParenExpr.html>`__ | | | -+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| `Ident <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Ident.html>`__\ ``.``\ `Ident <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Ident.html>`__ | `SelectorExpr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$SelectorExpr.html>`__ | | | -+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| `Expr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html>`__\ ``[``\ `Expr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html>`__\ ``]`` | `IndexExpr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$IndexExpr.html>`__ | | | -+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| `Expr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html>`__\ ``[``\ `Expr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html>`__\ ``:``\ `Expr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html>`__\ ``:``\ `Expr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html>`__\ ``]`` | `SliceExpr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$SliceExpr.html>`__ | | | -+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| `Expr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html>`__\ ``.(``\ `TypeExpr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$TypeExpr.html>`__\ ``)`` | `TypeAssertExpr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$TypeAssertExpr.html>`__ | | | -+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``*``\ `Expr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html>`__ | `StarExpr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$StarExpr.html>`__ | | can be a `ValueExpr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$ValueExpr.html>`__ or `TypeExpr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$TypeExpr.html>`__ depending on context | -+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| `Expr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html>`__\ ``:`` `Expr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html>`__ | `KeyValueExpr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$KeyValueExpr.html>`__ | | | -+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| `TypeExpr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$TypeExpr.html>`__\ ``(``\ `Expr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html>`__\ ``)`` | `ConversionExpr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$ConversionExpr.html>`__ | `CallOrConversionExpr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$CallOrConversionExpr.html>`__ | | -+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| `Expr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html>`__\ ``(...)`` | `CallExpr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$CallExpr.html>`__ | `CallOrConversionExpr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$CallOrConversionExpr.html>`__ | | -+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| (anything unparseable) | `BadExpr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$BadExpr.html>`__ | | | -+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - -The following classes organize expressions by the kind of entity they refer to. - -+------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| CodeQL class | Explanation | -+======================================================================================================+=========================================================================================================================================================================================================================================================+ -| `TypeExpr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$TypeExpr.html>`__ | an expression that denotes a type | -+------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| `ReferenceExpr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$ReferenceExpr.html>`__ | an expression that refers to a variable, a constant, a function, a field, or an element of an array or a slice | -+------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| `ValueExpr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$BadExpr.html>`__ | an expression that can be evaluated to a value (as opposed to expressions that refer to a package, a type, or a statement label). This generalizes `ReferenceExpr <https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$ReferenceExpr.html>`__ | -+------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - -Further reading ---------------- - -.. include:: ../../reusables/go-further-reading.rst -.. include:: ../../reusables/codeql-ref-tools-further-reading.rst \ No newline at end of file diff --git a/docs/codeql/codeql-language-guides/codeql-for-java/index.rst b/docs/codeql/codeql-language-guides/codeql-for-java.rst similarity index 100% rename from docs/codeql/codeql-language-guides/codeql-for-java/index.rst rename to docs/codeql/codeql-language-guides/codeql-for-java.rst diff --git a/docs/codeql/codeql-language-guides/codeql-for-java/abstract-syntax-tree-classes-for-working-with-java-programs.rst b/docs/codeql/codeql-language-guides/codeql-for-java/abstract-syntax-tree-classes-for-working-with-java-programs.rst deleted file mode 100644 index aae621d8314..00000000000 --- a/docs/codeql/codeql-language-guides/codeql-for-java/abstract-syntax-tree-classes-for-working-with-java-programs.rst +++ /dev/null @@ -1,347 +0,0 @@ -.. _abstract-syntax-tree-classes-for-working-with-java-programs: - -Abstract syntax tree classes for working with Java programs -=========================================================== - -CodeQL has a large selection of classes for representing the abstract syntax tree of Java programs. - -.. include:: ../../reusables/abstract-syntax-tree.rst - -Statement classes ------------------ - -This table lists all subclasses of `Stmt`_. - -+----------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------+--------------------------------------------+ -| Statement syntax | CodeQL class | Superclasses | Remarks | -+============================================================================+===========================================================================================================================================================+=================================+============================================+ -| ``;`` | `EmptyStmt <https://help.semmle.com/qldoc/java/semmle/code/java/Statement.qll/type.Statement$EmptyStmt.html>`__ | | | -+----------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------+--------------------------------------------+ -| `Expr`_ ``;`` | `ExprStmt <https://help.semmle.com/qldoc/java/semmle/code/java/Statement.qll/type.Statement$ExprStmt.html>`__ | | | -+----------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------+--------------------------------------------+ -| ``{`` `Stmt`_ ``... }`` | `Block <https://help.semmle.com/qldoc/java/semmle/code/java/Statement.qll/type.Statement$Block.html>`__ | | | -+----------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------+--------------------------------------------+ -| ``if (`` `Expr`_ ``)`` `Stmt`_ ``else`` `Stmt`_ | `IfStmt <https://help.semmle.com/qldoc/java/semmle/code/java/Statement.qll/type.Statement$IfStmt.html>`__ | `ConditionalStmt`_ | | -+----------------------------------------------------------------------------+ | | | -| ``if (`` `Expr`_ ``)`` `Stmt`_ | | | | -+----------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------+--------------------------------------------+ -| ``while (`` `Expr`_ ``)`` `Stmt`_ | `WhileStmt <https://help.semmle.com/qldoc/java/semmle/code/java/Statement.qll/type.Statement$WhileStmt.html>`__ | `ConditionalStmt`_, `LoopStmt`_ | | -+----------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------+--------------------------------------------+ -| ``do`` `Stmt`_ ``while (`` `Expr`_ ``)`` | `DoStmt <https://help.semmle.com/qldoc/java/semmle/code/java/Statement.qll/type.Statement$DoStmt.html>`__ | `ConditionalStmt`_, `LoopStmt`_ | | -+----------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------+--------------------------------------------+ -| ``for (`` `Expr`_ ``;`` `Expr`_ ``;`` `Expr`_ ``)`` `Stmt`_ | `ForStmt <https://help.semmle.com/qldoc/java/semmle/code/java/Statement.qll/type.Statement$ForStmt.html>`__ | `ConditionalStmt`_, `LoopStmt`_ | | -+----------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------+--------------------------------------------+ -| ``for (`` `VarAccess`_ ``:`` `Expr`_ ``)`` `Stmt`_ | `EnhancedForStmt <https://help.semmle.com/qldoc/java/semmle/code/java/Statement.qll/type.Statement$EnhancedForStmt.html>`__ | `LoopStmt`_ | | -+----------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------+--------------------------------------------+ -| ``switch (`` `Expr`_ ``) {`` `SwitchCase`_ ``... }`` | `SwitchStmt <https://help.semmle.com/qldoc/java/semmle/code/java/Statement.qll/type.Statement$SwitchStmt.html>`__ | | | -+----------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------+--------------------------------------------+ -| ``try {`` `Stmt`_ ``... } finally {`` `Stmt`_ ``... }`` | `TryStmt <https://help.semmle.com/qldoc/java/semmle/code/java/Statement.qll/type.Statement$TryStmt.html>`__ | | | -+----------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------+--------------------------------------------+ -| ``return`` `Expr`_ ``;`` | `ReturnStmt <https://help.semmle.com/qldoc/java/semmle/code/java/Statement.qll/type.Statement$ReturnStmt.html>`__ | | | -+----------------------------------------------------------------------------+ | | | -| ``return ;`` | | | | -+----------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------+--------------------------------------------+ -| ``throw`` `Expr`_ ``;`` | `ThrowStmt <https://help.semmle.com/qldoc/java/semmle/code/java/Statement.qll/type.Statement$ThrowStmt.html>`__ | | | -+----------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------+--------------------------------------------+ -| ``break ;`` | `BreakStmt <https://help.semmle.com/qldoc/java/semmle/code/java/Statement.qll/type.Statement$BreakStmt.html>`__ | `JumpStmt`_ | | -+----------------------------------------------------------------------------+ | | | -| ``break label ;`` | | | | -+----------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------+--------------------------------------------+ -| ``continue ;`` | `ContinueStmt <https://help.semmle.com/qldoc/java/semmle/code/java/Statement.qll/type.Statement$ContinueStmt.html>`__ | `JumpStmt`_ | | -+----------------------------------------------------------------------------+ | | | -| ``continue label ;`` | | | | -+----------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------+--------------------------------------------+ -| ``label :`` `Stmt`_ | `LabeledStmt <https://help.semmle.com/qldoc/java/semmle/code/java/Statement.qll/type.Statement$LabeledStmt.html>`__ | | | -+----------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------+--------------------------------------------+ -| ``synchronized (`` `Expr`_ ``)`` `Stmt`_ | `SynchronizedStmt <https://help.semmle.com/qldoc/java/semmle/code/java/Statement.qll/type.Statement$SynchronizedStmt.html>`__ | | | -+----------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------+--------------------------------------------+ -| ``assert`` `Expr`_ ``:`` `Expr`_ ``;`` | `AssertStmt <https://help.semmle.com/qldoc/java/semmle/code/java/Statement.qll/type.Statement$AssertStmt.html>`__ | | | -+----------------------------------------------------------------------------+ | | | -| ``assert`` `Expr`_ ``;`` | | | | -+----------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------+--------------------------------------------+ -| `TypeAccess`_ ``name ;`` | `LocalVariableDeclStmt <https://help.semmle.com/qldoc/java/semmle/code/java/Statement.qll/type.Statement$LocalVariableDeclStmt.html>`__ | | | -+----------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------+--------------------------------------------+ -| ``class name {`` `Member`_ ``... } ;`` | `LocalClassDeclStmt <https://help.semmle.com/qldoc/java/semmle/code/java/Statement.qll/type.Statement$LocalClassDeclStmt.html>`__ | | | -+----------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------+--------------------------------------------+ -| ``this (`` `Expr`_ ``, ... ) ;`` | `ThisConstructorInvocationStmt <https://help.semmle.com/qldoc/java/semmle/code/java/Statement.qll/type.Statement$ThisConstructorInvocationStmt.html>`__ | | | -+----------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------+--------------------------------------------+ -| ``super (`` `Expr`_ ``, ... ) ;`` | `SuperConstructorInvocationStmt <https://help.semmle.com/qldoc/java/semmle/code/java/Statement.qll/type.Statement$SuperConstructorInvocationStmt.html>`__ | | | -+----------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------+--------------------------------------------+ -| ``catch (`` `TypeAccess`_ ``name ) {`` `Stmt`_ ``... }`` | `CatchClause <https://help.semmle.com/qldoc/java/semmle/code/java/Statement.qll/type.Statement$CatchClause.html>`__ | | can only occur as child of a `TryStmt`_ | -+----------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------+--------------------------------------------+ -| ``case`` `Literal`_ ``:`` `Stmt`_ ``...`` | `ConstCase <https://help.semmle.com/qldoc/java/semmle/code/java/Statement.qll/type.Statement$ConstCase.html>`__ | | can only occur as child of a `SwitchStmt`_ | -+----------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------+--------------------------------------------+ -| ``default :`` `Stmt`_ ``...`` | `DefaultCase <https://help.semmle.com/qldoc/java/semmle/code/java/Statement.qll/type.Statement$DefaultCase.html>`__ | | can only occur as child of a `SwitchStmt`_ | -+----------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------+--------------------------------------------+ - -Expression classes ------------------- - -There are many expression classes, so we present them by category. All classes in this section are subclasses of `Expr <https://help.semmle.com/qldoc/java/semmle/code/java/Expr.qll/type.Expr$Expr.html>`__. - -Literals -~~~~~~~~ - -All classes in this subsection are subclasses of `Literal <https://help.semmle.com/qldoc/java/semmle/code/java/Expr.qll/type.Expr$Literal.html>`__. - -+---------------------------+-------------------------+ -| Expression syntax example | CodeQL class | -+===========================+=========================+ -| ``true`` | `BooleanLiteral`_ | -+---------------------------+-------------------------+ -| ``23`` | `IntegerLiteral`_ | -+---------------------------+-------------------------+ -| ``23l`` | `LongLiteral`_ | -+---------------------------+-------------------------+ -| ``4.2f`` | `FloatingPointLiteral`_ | -+---------------------------+-------------------------+ -| ``4.2`` | `DoubleLiteral`_ | -+---------------------------+-------------------------+ -| ``'a'`` | `CharacterLiteral`_ | -+---------------------------+-------------------------+ -| ``"Hello"`` | `StringLiteral`_ | -+---------------------------+-------------------------+ -| ``null`` | `NullLiteral`_ | -+---------------------------+-------------------------+ - -Unary expressions -~~~~~~~~~~~~~~~~~ - -All classes in this subsection are subclasses of `UnaryExpr <https://help.semmle.com/qldoc/java/semmle/code/java/Expr.qll/type.Expr$UnaryExpr.html>`__. - -+-------------------+----------------+--------------------+--------------------------------------------------+ -| Expression syntax | CodeQL class | Superclasses | Remarks | -+===================+================+====================+==================================================+ -| `Expr`_\ ``++`` | `PostIncExpr`_ | `UnaryAssignExpr`_ | | -+-------------------+----------------+--------------------+--------------------------------------------------+ -| `Expr`_\ ``--`` | `PostDecExpr`_ | `UnaryAssignExpr`_ | | -+-------------------+----------------+--------------------+--------------------------------------------------+ -| ``++``\ `Expr`_ | `PreIncExpr`_ | `UnaryAssignExpr`_ | | -+-------------------+----------------+--------------------+--------------------------------------------------+ -| ``--``\ `Expr`_ | `PreDecExpr`_ | `UnaryAssignExpr`_ | | -+-------------------+----------------+--------------------+--------------------------------------------------+ -| ``~``\ `Expr`_ | `BitNotExpr`_ | `BitwiseExpr`_ | see below for other subclasses of `BitwiseExpr`_ | -+-------------------+----------------+--------------------+--------------------------------------------------+ -| ``-``\ `Expr`_ | `MinusExpr`_ | | | -+-------------------+----------------+--------------------+--------------------------------------------------+ -| ``+``\ `Expr`_ | `PlusExpr`_ | | | -+-------------------+----------------+--------------------+--------------------------------------------------+ -| ``!``\ `Expr`_ | `LogNotExpr`_ | `LogicExpr`_ | see below for other subclasses of `LogicExpr`_ | -+-------------------+----------------+--------------------+--------------------------------------------------+ - -Binary expressions -~~~~~~~~~~~~~~~~~~ - -All classes in this subsection are subclasses of `BinaryExpr <https://help.semmle.com/qldoc/java/semmle/code/java/Expr.qll/type.Expr$BinaryExpr.html>`__. - -+-------------------------+-------------------+-------------------+ -| Expression syntax | CodeQL class | Superclasses | -+=========================+===================+===================+ -| `Expr`_ ``*`` `Expr`_ | `MulExpr`_ | | -+-------------------------+-------------------+-------------------+ -| `Expr`_ ``/`` `Expr`_ | `DivExpr`_ | | -+-------------------------+-------------------+-------------------+ -| `Expr`_ ``%`` `Expr`_ | `RemExpr`_ | | -+-------------------------+-------------------+-------------------+ -| `Expr`_ ``+`` `Expr`_ | `AddExpr`_ | | -+-------------------------+-------------------+-------------------+ -| `Expr`_ ``-`` `Expr`_ | `SubExpr`_ | | -+-------------------------+-------------------+-------------------+ -| `Expr`_ ``<<`` `Expr`_ | `LShiftExpr`_ | | -+-------------------------+-------------------+-------------------+ -| `Expr`_ ``>>`` `Expr`_ | `RShiftExpr`_ | | -+-------------------------+-------------------+-------------------+ -| `Expr`_ ``>>>`` `Expr`_ | `URShiftExpr`_ | | -+-------------------------+-------------------+-------------------+ -| `Expr`_ ``&&`` `Expr`_ | `AndLogicalExpr`_ | `LogicExpr`_ | -+-------------------------+-------------------+-------------------+ -| `Expr`_ ``||`` `Expr`_ | `OrLogicalExpr`_ | `LogicExpr`_ | -+-------------------------+-------------------+-------------------+ -| `Expr`_ ``<`` `Expr`_ | `LTExpr`_ | `ComparisonExpr`_ | -+-------------------------+-------------------+-------------------+ -| `Expr`_ ``>`` `Expr`_ | `GTExpr`_ | `ComparisonExpr`_ | -+-------------------------+-------------------+-------------------+ -| `Expr`_ ``<=`` `Expr`_ | `LEExpr`_ | `ComparisonExpr`_ | -+-------------------------+-------------------+-------------------+ -| `Expr`_ ``>=`` `Expr`_ | `GEExpr`_ | `ComparisonExpr`_ | -+-------------------------+-------------------+-------------------+ -| `Expr`_ ``==`` `Expr`_ | `EQExpr`_ | `EqualityTest`_ | -+-------------------------+-------------------+-------------------+ -| `Expr`_ ``!=`` `Expr`_ | `NEExpr`_ | `EqualityTest`_ | -+-------------------------+-------------------+-------------------+ -| `Expr`_ ``&`` `Expr`_ | `AndBitwiseExpr`_ | `BitwiseExpr`_ | -+-------------------------+-------------------+-------------------+ -| `Expr`_ ``|`` `Expr`_ | `OrBitwiseExpr`_ | `BitwiseExpr`_ | -+-------------------------+-------------------+-------------------+ -| `Expr`_ ``^`` `Expr`_ | `XorBitwiseExpr`_ | `BitwiseExpr`_ | -+-------------------------+-------------------+-------------------+ - -Assignment expressions -~~~~~~~~~~~~~~~~~~~~~~ - -All classes in this table are subclasses of `Assignment <https://help.semmle.com/qldoc/java/semmle/code/java/Expr.qll/type.Expr$Assignment.html>`__. - -+--------------------------+----------------------+--------------+ -| Expression syntax | CodeQL class | Superclasses | -+==========================+======================+==============+ -| `Expr`_ ``=`` `Expr`_ | `AssignExpr`_ | | -+--------------------------+----------------------+--------------+ -| `Expr`_ ``+=`` `Expr`_ | `AssignAddExpr`_ | `AssignOp`_ | -+--------------------------+----------------------+--------------+ -| `Expr`_ ``-=`` `Expr`_ | `AssignSubExpr`_ | `AssignOp`_ | -+--------------------------+----------------------+--------------+ -| `Expr`_ ``*=`` `Expr`_ | `AssignMulExpr`_ | `AssignOp`_ | -+--------------------------+----------------------+--------------+ -| `Expr`_ ``/=`` `Expr`_ | `AssignDivExpr`_ | `AssignOp`_ | -+--------------------------+----------------------+--------------+ -| `Expr`_ ``%=`` `Expr`_ | `AssignRemExpr`_ | `AssignOp`_ | -+--------------------------+----------------------+--------------+ -| `Expr`_ ``&=`` `Expr`_ | `AssignAndExpr`_ | `AssignOp`_ | -+--------------------------+----------------------+--------------+ -| `Expr`_ ``|=`` `Expr`_ | `AssignOrExpr`_ | `AssignOp`_ | -+--------------------------+----------------------+--------------+ -| `Expr`_ ``^=`` `Expr`_ | `AssignXorExpr`_ | `AssignOp`_ | -+--------------------------+----------------------+--------------+ -| `Expr`_ ``<<=`` `Expr`_ | `AssignLShiftExpr`_ | `AssignOp`_ | -+--------------------------+----------------------+--------------+ -| `Expr`_ ``>>=`` `Expr`_ | `AssignRShiftExpr`_ | `AssignOp`_ | -+--------------------------+----------------------+--------------+ -| `Expr`_ ``>>>=`` `Expr`_ | `AssignURShiftExpr`_ | `AssignOp`_ | -+--------------------------+----------------------+--------------+ - -Accesses -~~~~~~~~ - -+--------------------------------------+-------------------------------------------------------------------------------------------------------------------------+ -| Expression syntax examples | CodeQL class | -+======================================+=========================================================================================================================+ -| ``this`` | `ThisAccess <https://help.semmle.com/qldoc/java/semmle/code/java/Expr.qll/type.Expr$ThisAccess.html>`__ | -+--------------------------------------+ + -| ``Outer.this`` | | -+--------------------------------------+-------------------------------------------------------------------------------------------------------------------------+ -| ``super`` | `SuperAccess <https://help.semmle.com/qldoc/java/semmle/code/java/Expr.qll/type.Expr$SuperAccess.html>`__ | -+--------------------------------------+ + -| ``Outer.super`` | | -+--------------------------------------+-------------------------------------------------------------------------------------------------------------------------+ -| ``x`` | `VarAccess <https://help.semmle.com/qldoc/java/semmle/code/java/Expr.qll/type.Expr$VarAccess.html>`__ | -+--------------------------------------+ + -| ``e.f`` | | -+--------------------------------------+-------------------------------------------------------------------------------------------------------------------------+ -| ``a[i]`` | `ArrayAccess <https://help.semmle.com/qldoc/java/semmle/code/java/Expr.qll/type.Expr$ArrayAccess.html>`__ | -+--------------------------------------+-------------------------------------------------------------------------------------------------------------------------+ -| ``f(...)`` | `MethodAccess <https://help.semmle.com/qldoc/java/semmle/code/java/Expr.qll/type.Expr$MethodAccess.html>`__ | -+--------------------------------------+ + -| ``e.m(...)`` | | -+--------------------------------------+-------------------------------------------------------------------------------------------------------------------------+ -| ``String`` | `TypeAccess <https://help.semmle.com/qldoc/java/semmle/code/java/Expr.qll/type.Expr$TypeAccess.html>`__ | -+--------------------------------------+ + -| ``java.lang.String`` | | -+--------------------------------------+-------------------------------------------------------------------------------------------------------------------------+ -| ``? extends Number`` | `WildcardTypeAccess <https://help.semmle.com/qldoc/java/semmle/code/java/Expr.qll/type.Expr$WildcardTypeAccess.html>`__ | -+--------------------------------------+ + -| ``? super Double`` | | -+--------------------------------------+-------------------------------------------------------------------------------------------------------------------------+ - -A `VarAccess <https://help.semmle.com/qldoc/java/semmle/code/java/Expr.qll/type.Expr$VarAccess.html>`__ that refers to a field is a `FieldAccess <https://help.semmle.com/qldoc/java/semmle/code/java/Expr.qll/type.Expr$FieldAccess.html>`__. - -Miscellaneous -~~~~~~~~~~~~~ - -+------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------+ -| Expression syntax examples | CodeQL class | Remarks | -+==================================================================+=======================================================================================================================+=============================================================================+ -| ``(int) f`` | `CastExpr <https://help.semmle.com/qldoc/java/semmle/code/java/Expr.qll/type.Expr$CastExpr.html>`__ | | -+------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------+ -| ``(23 + 42)`` | `ParExpr <https://help.semmle.com/qldoc/java/semmle/code/java/Expr.qll/type.Expr$ParExpr.html>`__ | | -+------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------+ -| ``o instanceof String`` | `InstanceOfExpr <https://help.semmle.com/qldoc/java/semmle/code/java/Expr.qll/type.Expr$InstanceOfExpr.html>`__ | | -+------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------+ -| `Expr`_ ``?`` `Expr`_ ``:`` `Expr`_ | `ConditionalExpr <https://help.semmle.com/qldoc/java/semmle/code/java/Expr.qll/type.Expr$ConditionalExpr.html>`__ | | -+------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------+ -| ``String. class`` | `TypeLiteral <https://help.semmle.com/qldoc/java/semmle/code/java/Expr.qll/type.Expr$TypeLiteral.html>`__ | | -+------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------+ -| ``new A()`` | `ClassInstanceExpr <https://help.semmle.com/qldoc/java/semmle/code/java/Expr.qll/type.Expr$ClassInstanceExpr.html>`__ | | -+------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------+ -| ``new String[3][2]`` | `ArrayCreationExpr <https://help.semmle.com/qldoc/java/semmle/code/java/Expr.qll/type.Expr$ArrayCreationExpr.html>`__ | | -+------------------------------------------------------------------+ + + -| ``new int[] { 23, 42 }`` | | | -+------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------+ -| ``{ 23, 42 }`` | `ArrayInit <https://help.semmle.com/qldoc/java/semmle/code/java/Expr.qll/type.Expr$ArrayInit.html>`__ | can only appear as an initializer or as a child of an `ArrayCreationExpr`_ | -+------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------+ -| ``@Annot(key=val)`` | `Annotation <https://help.semmle.com/qldoc/java/semmle/code/java/Annotation.qll/type.Annotation$Annotation.html>`__ |   | -+------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------+ - -Further reading ---------------- - -.. include:: ../../reusables/java-further-reading.rst -.. include:: ../../reusables/codeql-ref-tools-further-reading.rst - -.. _Expr: https://help.semmle.com/qldoc/java/semmle/code/java/Expr.qll/type.Expr$Expr.html -.. _Stmt: https://help.semmle.com/qldoc/java/semmle/code/java/Statement.qll/type.Statement$Stmt.html -.. _VarAccess: https://help.semmle.com/qldoc/java/semmle/code/java/Expr.qll/type.Expr$VarAccess.html -.. _SwitchCase: https://help.semmle.com/qldoc/java/semmle/code/java/Statement.qll/type.Statement$SwitchCase.html -.. _TypeAccess: https://help.semmle.com/qldoc/java/semmle/code/java/Expr.qll/type.Expr$TypeAccess.html -.. _Member: https://help.semmle.com/qldoc/java/semmle/code/java/Member.qll/type.Member$Member.html -.. _Literal: https://help.semmle.com/qldoc/java/semmle/code/java/Expr.qll/type.Expr$Literal.html -.. _ConditionalStmt: https://help.semmle.com/qldoc/java/semmle/code/java/Statement.qll/type.Statement$ConditionalStmt.html -.. _LoopStmt: https://help.semmle.com/qldoc/java/semmle/code/java/Statement.qll/type.Statement$LoopStmt.html -.. _JumpStmt: https://help.semmle.com/qldoc/java/semmle/code/java/Statement.qll/type.Statement$JumpStmt.html -.. _TryStmt: https://help.semmle.com/qldoc/java/semmle/code/java/Statement.qll/type.Statement$TryStmt.html -.. _SwitchStmt: https://help.semmle.com/qldoc/java/semmle/code/java/Statement.qll/type.Statement$SwitchStmt.html -.. _BooleanLiteral: https://help.semmle.com/qldoc/java/semmle/code/java/Expr.qll/type.Expr$BooleanLiteral.html -.. _IntegerLiteral: https://help.semmle.com/qldoc/java/semmle/code/java/Expr.qll/type.Expr$IntegerLiteral.html -.. _LongLiteral: https://help.semmle.com/qldoc/java/semmle/code/java/Expr.qll/type.Expr$LongLiteral.html -.. _FloatingPointLiteral: https://help.semmle.com/qldoc/java/semmle/code/java/Expr.qll/type.Expr$FloatingPointLiteral.html -.. _DoubleLiteral: https://help.semmle.com/qldoc/java/semmle/code/java/Expr.qll/type.Expr$DoubleLiteral.html -.. _CharacterLiteral: https://help.semmle.com/qldoc/java/semmle/code/java/Expr.qll/type.Expr$CharacterLiteral.html -.. _StringLiteral: https://help.semmle.com/qldoc/java/semmle/code/java/Expr.qll/type.Expr$StringLiteral.html -.. _NullLiteral: https://help.semmle.com/qldoc/java/semmle/code/java/Expr.qll/type.Expr$NullLiteral.html -.. _PostIncExpr: https://help.semmle.com/qldoc/java/semmle/code/java/Expr.qll/type.Expr$PostIncExpr.html -.. _PostDecExpr: https://help.semmle.com/qldoc/java/semmle/code/java/Expr.qll/type.Expr$PostDecExpr.html -.. _PreIncExpr: https://help.semmle.com/qldoc/java/semmle/code/java/Expr.qll/type.Expr$PreIncExpr.html -.. _PreDecExpr: https://help.semmle.com/qldoc/java/semmle/code/java/Expr.qll/type.Expr$PreDecExpr.html -.. _BitNotExpr: https://help.semmle.com/qldoc/java/semmle/code/java/Expr.qll/type.Expr$BitNotExpr.html -.. _MinusExpr: https://help.semmle.com/qldoc/java/semmle/code/java/Expr.qll/type.Expr$MinusExpr.html -.. _PlusExpr: https://help.semmle.com/qldoc/java/semmle/code/java/Expr.qll/type.Expr$PlusExpr.html -.. _LogNotExpr: https://help.semmle.com/qldoc/java/semmle/code/java/Expr.qll/type.Expr$LogNotExpr.html -.. _UnaryAssignExpr: https://help.semmle.com/qldoc/java/semmle/code/java/Expr.qll/type.Expr$UnaryAssignExpr.html -.. _BitwiseExpr: https://help.semmle.com/qldoc/java/semmle/code/java/Expr.qll/type.Expr$BitwiseExpr.html -.. _LogicExpr: https://help.semmle.com/qldoc/java/semmle/code/java/Expr.qll/type.Expr$LogicExpr.html -.. _MulExpr: https://help.semmle.com/qldoc/java/semmle/code/java/Expr.qll/type.Expr$MulExpr.html -.. _DivExpr: https://help.semmle.com/qldoc/java/semmle/code/java/Expr.qll/type.Expr$DivExpr.html -.. _RemExpr: https://help.semmle.com/qldoc/java/semmle/code/java/Expr.qll/type.Expr$RemExpr.html -.. _AddExpr: https://help.semmle.com/qldoc/java/semmle/code/java/Expr.qll/type.Expr$AddExpr.html -.. _SubExpr: https://help.semmle.com/qldoc/java/semmle/code/java/Expr.qll/type.Expr$SubExpr.html -.. _LShiftExpr: https://help.semmle.com/qldoc/java/semmle/code/java/Expr.qll/type.Expr$LShiftExpr.html -.. _RShiftExpr: https://help.semmle.com/qldoc/java/semmle/code/java/Expr.qll/type.Expr$RShiftExpr.html -.. _URShiftExpr: https://help.semmle.com/qldoc/java/semmle/code/java/Expr.qll/type.Expr$URShiftExpr.html -.. _AndLogicalExpr: https://help.semmle.com/qldoc/java/semmle/code/java/Expr.qll/type.Expr$AndLogicalExpr.html -.. _OrLogicalExpr: https://help.semmle.com/qldoc/java/semmle/code/java/Expr.qll/type.Expr$OrLogicalExpr.html -.. _LTExpr: https://help.semmle.com/qldoc/java/semmle/code/java/Expr.qll/type.Expr$LTExpr.html -.. _GTExpr: https://help.semmle.com/qldoc/java/semmle/code/java/Expr.qll/type.Expr$GTExpr.html -.. _LEExpr: https://help.semmle.com/qldoc/java/semmle/code/java/Expr.qll/type.Expr$LEExpr.html -.. _GEExpr: https://help.semmle.com/qldoc/java/semmle/code/java/Expr.qll/type.Expr$GEExpr.html -.. _EQExpr: https://help.semmle.com/qldoc/java/semmle/code/java/Expr.qll/type.Expr$EQExpr.html -.. _NEExpr: https://help.semmle.com/qldoc/java/semmle/code/java/Expr.qll/type.Expr$NEExpr.html -.. _AndBitwiseExpr: https://help.semmle.com/qldoc/java/semmle/code/java/Expr.qll/type.Expr$AndBitwiseExpr.html -.. _OrBitwiseExpr: https://help.semmle.com/qldoc/java/semmle/code/java/Expr.qll/type.Expr$OrBitwiseExpr.html -.. _XorBitwiseExpr: https://help.semmle.com/qldoc/java/semmle/code/java/Expr.qll/type.Expr$XorBitwiseExpr.html -.. _LogicExpr: https://help.semmle.com/qldoc/java/semmle/code/java/Expr.qll/type.Expr$LogicExpr.html -.. _ComparisonExpr: https://help.semmle.com/qldoc/java/semmle/code/java/Expr.qll/type.Expr$ComparisonExpr.html -.. _EqualityTest: https://help.semmle.com/qldoc/java/semmle/code/java/Expr.qll/type.Expr$EqualityTest.html -.. _BitwiseExpr: https://help.semmle.com/qldoc/java/semmle/code/java/Expr.qll/type.Expr$BitwiseExpr.html -.. _AssignExpr: https://help.semmle.com/qldoc/java/semmle/code/java/Expr.qll/type.Expr$AssignExpr.html -.. _AssignAddExpr: https://help.semmle.com/qldoc/java/semmle/code/java/Expr.qll/type.Expr$AssignAddExpr.html -.. _AssignSubExpr: https://help.semmle.com/qldoc/java/semmle/code/java/Expr.qll/type.Expr$AssignSubExpr.html -.. _AssignMulExpr: https://help.semmle.com/qldoc/java/semmle/code/java/Expr.qll/type.Expr$AssignMulExpr.html -.. _AssignDivExpr: https://help.semmle.com/qldoc/java/semmle/code/java/Expr.qll/type.Expr$AssignDivExpr.html -.. _AssignRemExpr: https://help.semmle.com/qldoc/java/semmle/code/java/Expr.qll/type.Expr$AssignRemExpr.html -.. _AssignAndExpr: https://help.semmle.com/qldoc/java/semmle/code/java/Expr.qll/type.Expr$AssignAndExpr.html -.. _AssignOrExpr: https://help.semmle.com/qldoc/java/semmle/code/java/Expr.qll/type.Expr$AssignOrExpr.html -.. _AssignXorExpr: https://help.semmle.com/qldoc/java/semmle/code/java/Expr.qll/type.Expr$AssignXorExpr.html -.. _AssignLShiftExpr: https://help.semmle.com/qldoc/java/semmle/code/java/Expr.qll/type.Expr$AssignLShiftExpr.html -.. _AssignRShiftExpr: https://help.semmle.com/qldoc/java/semmle/code/java/Expr.qll/type.Expr$AssignRShiftExpr.html -.. _AssignURShiftExpr: https://help.semmle.com/qldoc/java/semmle/code/java/Expr.qll/type.Expr$AssignURShiftExpr.html -.. _AssignOp: https://help.semmle.com/qldoc/java/semmle/code/java/Expr.qll/type.Expr$AssignOp.html -.. _ArrayCreationExpr: https://help.semmle.com/qldoc/java/semmle/code/java/Expr.qll/type.Expr$ArrayCreationExpr.html diff --git a/docs/codeql/codeql-language-guides/codeql-for-javascript/index.rst b/docs/codeql/codeql-language-guides/codeql-for-javascript.rst similarity index 76% rename from docs/codeql/codeql-language-guides/codeql-for-javascript/index.rst rename to docs/codeql/codeql-language-guides/codeql-for-javascript.rst index 3739988abf2..ce6651acb79 100644 --- a/docs/codeql/codeql-language-guides/codeql-for-javascript/index.rst +++ b/docs/codeql/codeql-language-guides/codeql-for-javascript.rst @@ -11,8 +11,9 @@ Experiment and learn how to write effective and efficient queries for CodeQL dat basic-query-for-javascript-code codeql-library-for-javascript codeql-library-for-typescript - analyzing-data-flow-in-javascript + analyzing-data-flow-in-javascript-and-typescript using-flow-labels-for-precise-data-flow-analysis + specifying-additional-remote-flow-sources-for-javascript using-type-tracking-for-api-modeling abstract-syntax-tree-classes-for-working-with-javascript-and-typescript-programs data-flow-cheat-sheet-for-javascript @@ -23,10 +24,12 @@ Experiment and learn how to write effective and efficient queries for CodeQL dat - :doc:`CodeQL library for TypeScript <codeql-library-for-typescript>`: When you're analyzing a TypeScript program, you can make use of the large collection of classes in the CodeQL library for TypeScript. -- :doc:`Analyzing data flow in JavaScript and TypeScript <analyzing-data-flow-in-javascript>`: This topic describes how data flow analysis is implemented in the CodeQL libraries for JavaScript/TypeScript and includes examples to help you write your own data flow queries. +- :doc:`Analyzing data flow in JavaScript and TypeScript <analyzing-data-flow-in-javascript-and-typescript>`: This topic describes how data flow analysis is implemented in the CodeQL libraries for JavaScript/TypeScript and includes examples to help you write your own data flow queries. - :doc:`Using flow labels for precise data flow analysis <using-flow-labels-for-precise-data-flow-analysis>`: You can associate flow labels with each value tracked by the flow analysis to determine whether the flow contains potential vulnerabilities. +- :doc:`Specifying remote flow sources for JavaScript <specifying-additional-remote-flow-sources-for-javascript>`: You can model potential sources of untrusted user input in your code without making changes to the CodeQL standard library by specifying extra remote flow sources in an external file. + - :doc:`Using type tracking for API modeling <using-type-tracking-for-api-modeling>`: You can track data through an API by creating a model using the CodeQL type-tracking library for JavaScript. - :doc:`Abstract syntax tree classes for working with JavaScript and TypeScript programs <abstract-syntax-tree-classes-for-working-with-javascript-and-typescript-programs>`: CodeQL has a large selection of classes for representing the abstract syntax tree of JavaScript and TypeScript programs. diff --git a/docs/codeql/codeql-language-guides/codeql-for-javascript/abstract-syntax-tree-classes-for-working-with-javascript-and-typescript-programs.rst b/docs/codeql/codeql-language-guides/codeql-for-javascript/abstract-syntax-tree-classes-for-working-with-javascript-and-typescript-programs.rst deleted file mode 100644 index 351e608b01a..00000000000 --- a/docs/codeql/codeql-language-guides/codeql-for-javascript/abstract-syntax-tree-classes-for-working-with-javascript-and-typescript-programs.rst +++ /dev/null @@ -1,368 +0,0 @@ -.. _abstract-syntax-tree-classes-for-working-with-javascript-and-typescript-programs: - -Abstract syntax tree classes for working with JavaScript and TypeScript programs -================================================================================ - -CodeQL has a large selection of classes for representing the abstract syntax tree of JavaScript and TypeScript programs. - -.. include:: ../../reusables/abstract-syntax-tree.rst - -Statement classes ------------------ - -This table lists subclasses of `Stmt <https://help.semmle.com/qldoc/javascript/semmle/javascript/Stmt.qll/type.Stmt$Stmt.html>`__ representing ECMAScript and TypeScript statements. - -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| Statement syntax | CodeQL class | Superclasses | Remarks | -+=============================================================================================================================================================================================================================================================================================================================================================================================================================================+==================================================================================================================================================================+==========================================================================================================================================================================================================================================================================================================================================================================================================================+===================================================================================================================================================================================================+ -| `Expr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Expr.html>`__ ``;`` | `ExprStmt <https://help.semmle.com/qldoc/javascript/semmle/javascript/Stmt.qll/type.Stmt$ExprStmt.html>`__ | | | -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| `Label <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Label.html>`__ ``:`` `Stmt <https://help.semmle.com/qldoc/javascript/semmle/javascript/Stmt.qll/type.Stmt$Stmt.html>`__ | `LabeledStmt <https://help.semmle.com/qldoc/javascript/semmle/javascript/Stmt.qll/type.Stmt$LabeledStmt.html>`__ | | | -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``;`` | `EmptyStmt <https://help.semmle.com/qldoc/javascript/semmle/javascript/Stmt.qll/type.Stmt$EmptyStmt.html>`__ | | | -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``break`` `Label <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Label.html>`__ ``;`` | `BreakStmt <https://help.semmle.com/qldoc/javascript/semmle/javascript/Stmt.qll/type.Stmt$BreakStmt.html>`__ | `JumpStmt <https://help.semmle.com/qldoc/javascript/semmle/javascript/Stmt.qll/type.Stmt$JumpStmt.html>`__, `BreakOrContinueStmt <https://help.semmle.com/qldoc/javascript/semmle/javascript/Stmt.qll/type.Stmt$BreakOrContinueStmt.html>`__ | | -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``case`` `Expr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Expr.html>`__ ``:`` `Stmt <https://help.semmle.com/qldoc/javascript/semmle/javascript/Stmt.qll/type.Stmt$Stmt.html>`__... | `Case <https://help.semmle.com/qldoc/javascript/semmle/javascript/Stmt.qll/type.Stmt$Case.html>`__ | | can only occur as child of a `SwitchStmt <https://help.semmle.com/qldoc/javascript/semmle/javascript/Stmt.qll/type.Stmt$SwitchStmt.html>`__ | -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``catch(`` `Identifier <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Identifier.html>`__ ``)`` ``{`` `Stmt <https://help.semmle.com/qldoc/javascript/semmle/javascript/Stmt.qll/type.Stmt$Stmt.html>`__... ``}`` | `CatchClause <https://help.semmle.com/qldoc/javascript/semmle/javascript/Stmt.qll/type.Stmt$CatchClause.html>`__ | `ControlStmt <https://help.semmle.com/qldoc/javascript/semmle/javascript/Stmt.qll/type.Stmt$ControlStmt.html>`__ | can only occur as child of a `TryStmt <https://help.semmle.com/qldoc/javascript/semmle/javascript/Stmt.qll/type.Stmt$TryStmt.html>`__ | -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``class`` `Identifier <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Identifier.html>`__ ``extends`` `Expr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Expr.html>`__ ``{`` `MemberDeclaration <https://help.semmle.com/qldoc/javascript/semmle/javascript/Classes.qll/type.Classes$MemberDeclaration.html>`__... ``}`` | `ClassDeclStmt <https://help.semmle.com/qldoc/javascript/semmle/javascript/Classes.qll/type.Classes$ClassDeclStmt.html>`__ | `ClassDefinition <https://help.semmle.com/qldoc/javascript/semmle/javascript/Classes.qll/type.Classes$ClassDefinition.html>`__, `ClassOrInterface <https://help.semmle.com/qldoc/javascript/semmle/javascript/Classes.qll/type.Classes$ClassOrInterface.html>`__, `TypeParameterized <https://help.semmle.com/qldoc/javascript/semmle/javascript/TypeScript.qll/type.TypeScript$TypeParameterized.html>`__ | | -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``const`` `Identifier <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Identifier.html>`__ ``=`` `Expr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Expr.html>`__ ``;`` | `ConstDeclStmt <https://help.semmle.com/qldoc/javascript/semmle/javascript/Stmt.qll/type.Stmt$ConstDeclStmt.html>`__ | `DeclStmt <https://help.semmle.com/qldoc/javascript/semmle/javascript/Stmt.qll/type.Stmt$DeclStmt.html>`__ | | -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``continue`` `Label <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Label.html>`__ ``;`` | `ContinueStmt <https://help.semmle.com/qldoc/javascript/semmle/javascript/Stmt.qll/type.Stmt$ContinueStmt.html>`__ | `JumpStmt <https://help.semmle.com/qldoc/javascript/semmle/javascript/Stmt.qll/type.Stmt$JumpStmt.html>`__, `BreakOrContinueStmt <https://help.semmle.com/qldoc/javascript/semmle/javascript/Stmt.qll/type.Stmt$BreakOrContinueStmt.html>`__ | | -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``debugger;`` | `DebuggerStmt <https://help.semmle.com/qldoc/javascript/semmle/javascript/Stmt.qll/type.Stmt$DebuggerStmt.html>`__ | | | -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``declare`` ``global`` ``{`` `Stmt <https://help.semmle.com/qldoc/javascript/semmle/javascript/Stmt.qll/type.Stmt$Stmt.html>`__... ``}`` | `GlobalAugmentationDeclaration <https://help.semmle.com/qldoc/javascript/semmle/javascript/TypeScript.qll/type.TypeScript$GlobalAugmentationDeclaration.html>`__ | | | -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``declare`` ``module`` `StringLiteral <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$StringLiteral.html>`__ ``{`` `Stmt <https://help.semmle.com/qldoc/javascript/semmle/javascript/Stmt.qll/type.Stmt$Stmt.html>`__... ``}`` | `ExternalModuleDeclaration <https://help.semmle.com/qldoc/javascript/semmle/javascript/TypeScript.qll/type.TypeScript$ExternalModuleDeclaration.html>`__ | | | -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``default:`` `Stmt <https://help.semmle.com/qldoc/javascript/semmle/javascript/Stmt.qll/type.Stmt$Stmt.html>`__... | `Case <https://help.semmle.com/qldoc/javascript/semmle/javascript/Stmt.qll/type.Stmt$Case.html>`__ | | can only occur as child of a `SwitchStmt <https://help.semmle.com/qldoc/javascript/semmle/javascript/Stmt.qll/type.Stmt$SwitchStmt.html>`__; use `isDefault` to distinguish `default` from `case` | -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``do`` `Stmt <https://help.semmle.com/qldoc/javascript/semmle/javascript/Stmt.qll/type.Stmt$Stmt.html>`__ ``while`` ``(`` `Expr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Expr.html>`__ ``)`` | `DoWhileStmt <https://help.semmle.com/qldoc/javascript/semmle/javascript/Stmt.qll/type.Stmt$DoWhileStmt.html>`__ | `ControlStmt <https://help.semmle.com/qldoc/javascript/semmle/javascript/Stmt.qll/type.Stmt$ControlStmt.html>`__, `LoopStmt <https://help.semmle.com/qldoc/javascript/semmle/javascript/Stmt.qll/type.Stmt$LoopStmt.html>`__ | | -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``enum`` `Identifier <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Identifier.html>`__ ``{`` `MemberDeclaration <https://help.semmle.com/qldoc/javascript/semmle/javascript/Classes.qll/type.Classes$MemberDeclaration.html>`__... ``}`` | `EnumDeclaration <https://help.semmle.com/qldoc/javascript/semmle/javascript/TypeScript.qll/type.TypeScript$EnumDeclaration.html>`__ | `NamespaceDefinition <https://help.semmle.com/qldoc/javascript/semmle/javascript/TypeScript.qll/type.TypeScript$NamespaceDefinition.html>`__ | | -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``export * from`` `StringLiteral <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$StringLiteral.html>`__ | `BulkReExportDeclaration <https://help.semmle.com/qldoc/javascript/semmle/javascript/ES2015Modules.qll/type.ES2015Modules$BulkReExportDeclaration.html>`__ | `ReExportDeclaration <https://help.semmle.com/qldoc/javascript/semmle/javascript/ES2015Modules.qll/type.ES2015Modules$ReExportDeclaration.html>`__, `ExportDeclaration <https://help.semmle.com/qldoc/javascript/semmle/javascript/ES2015Modules.qll/type.ES2015Modules$ExportDeclaration.html>`__ | | -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``export default`` `ClassDeclStmt <https://help.semmle.com/qldoc/javascript/semmle/javascript/Classes.qll/type.Classes$ClassDeclStmt.html>`__ | `ExportDefaultDeclaration <https://help.semmle.com/qldoc/javascript/semmle/javascript/ES2015Modules.qll/type.ES2015Modules$ExportDefaultDeclaration.html>`__ | `ExportDeclaration <https://help.semmle.com/qldoc/javascript/semmle/javascript/ES2015Modules.qll/type.ES2015Modules$ExportDeclaration.html>`__ | | -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``export default`` `Expr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Expr.html>`__ ``;`` | `ExportDefaultDeclaration <https://help.semmle.com/qldoc/javascript/semmle/javascript/ES2015Modules.qll/type.ES2015Modules$ExportDefaultDeclaration.html>`__ | `ExportDeclaration <https://help.semmle.com/qldoc/javascript/semmle/javascript/ES2015Modules.qll/type.ES2015Modules$ExportDeclaration.html>`__ | | -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``export default`` `FunctionDeclStmt <https://help.semmle.com/qldoc/javascript/semmle/javascript/Stmt.qll/type.Stmt$FunctionDeclStmt.html>`__ | `ExportDefaultDeclaration <https://help.semmle.com/qldoc/javascript/semmle/javascript/ES2015Modules.qll/type.ES2015Modules$ExportDefaultDeclaration.html>`__ | `ExportDeclaration <https://help.semmle.com/qldoc/javascript/semmle/javascript/ES2015Modules.qll/type.ES2015Modules$ExportDeclaration.html>`__ | | -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``export {`` `ExportSpecifier <https://help.semmle.com/qldoc/javascript/semmle/javascript/ES2015Modules.qll/type.ES2015Modules$ExportSpecifier.html>`__... ``};`` | `ExportNamedDeclaration <https://help.semmle.com/qldoc/javascript/semmle/javascript/ES2015Modules.qll/type.ES2015Modules$ExportNamedDeclaration.html>`__ | `ExportDeclaration <https://help.semmle.com/qldoc/javascript/semmle/javascript/ES2015Modules.qll/type.ES2015Modules$ExportDeclaration.html>`__ | | -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``export`` `DeclStmt <https://help.semmle.com/qldoc/javascript/semmle/javascript/Stmt.qll/type.Stmt$DeclStmt.html>`__ | `ExportNamedDeclaration <https://help.semmle.com/qldoc/javascript/semmle/javascript/ES2015Modules.qll/type.ES2015Modules$ExportNamedDeclaration.html>`__ | `ExportDeclaration <https://help.semmle.com/qldoc/javascript/semmle/javascript/ES2015Modules.qll/type.ES2015Modules$ExportDeclaration.html>`__ | | -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``export`` ``=`` `Expr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Expr.html>`__ ``;`` | `ExportAssignDeclaration <https://help.semmle.com/qldoc/javascript/semmle/javascript/TypeScript.qll/type.TypeScript$ExportAssignDeclaration.html>`__ | | | -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``export`` ``as`` ``namespace`` `Identifier <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Identifier.html>`__ ``;`` | `ExportAsNamespaceDeclaration <https://help.semmle.com/qldoc/javascript/semmle/javascript/TypeScript.qll/type.TypeScript$ExportAsNamespaceDeclaration.html>`__ | | | -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``for`` ``(`` `Expr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Expr.html>`__ ``;`` `Expr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Expr.html>`__ ``;`` `Expr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Expr.html>`__ ``)`` `Stmt <https://help.semmle.com/qldoc/javascript/semmle/javascript/Stmt.qll/type.Stmt$Stmt.html>`__ | `ForStmt <https://help.semmle.com/qldoc/javascript/semmle/javascript/Stmt.qll/type.Stmt$ForStmt.html>`__ | `ControlStmt <https://help.semmle.com/qldoc/javascript/semmle/javascript/Stmt.qll/type.Stmt$ControlStmt.html>`__, `LoopStmt <https://help.semmle.com/qldoc/javascript/semmle/javascript/Stmt.qll/type.Stmt$LoopStmt.html>`__ | | -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``for`` ``(`` `VarAccess <https://help.semmle.com/qldoc/javascript/semmle/javascript/Variables.qll/type.Variables$VarAccess.html>`__ ``in`` `Expr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Expr.html>`__ ``)`` `Stmt <https://help.semmle.com/qldoc/javascript/semmle/javascript/Stmt.qll/type.Stmt$Stmt.html>`__ | `ForInStmt <https://help.semmle.com/qldoc/javascript/semmle/javascript/Stmt.qll/type.Stmt$ForInStmt.html>`__ | `ControlStmt <https://help.semmle.com/qldoc/javascript/semmle/javascript/Stmt.qll/type.Stmt$ControlStmt.html>`__, `LoopStmt <https://help.semmle.com/qldoc/javascript/semmle/javascript/Stmt.qll/type.Stmt$LoopStmt.html>`__, `EnhancedForLoop <https://help.semmle.com/qldoc/javascript/semmle/javascript/Stmt.qll/type.Stmt$EnhancedForLoop.html>`__ | | -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``for`` ``(`` `VarAccess <https://help.semmle.com/qldoc/javascript/semmle/javascript/Variables.qll/type.Variables$VarAccess.html>`__ ``of`` `Expr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Expr.html>`__ ``)`` `Stmt <https://help.semmle.com/qldoc/javascript/semmle/javascript/Stmt.qll/type.Stmt$Stmt.html>`__ | `ForOfStmt <https://help.semmle.com/qldoc/javascript/semmle/javascript/Stmt.qll/type.Stmt$ForOfStmt.html>`__ | `ControlStmt <https://help.semmle.com/qldoc/javascript/semmle/javascript/Stmt.qll/type.Stmt$ControlStmt.html>`__, `LoopStmt <https://help.semmle.com/qldoc/javascript/semmle/javascript/Stmt.qll/type.Stmt$LoopStmt.html>`__, `EnhancedForLoop <https://help.semmle.com/qldoc/javascript/semmle/javascript/Stmt.qll/type.Stmt$EnhancedForLoop.html>`__ | | -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``function`` `Identifier <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Identifier.html>`__ ``(`` `Parameter <https://help.semmle.com/qldoc/javascript/semmle/javascript/Variables.qll/type.Variables$Parameter.html>`__... ``)`` ``{`` `Stmt <https://help.semmle.com/qldoc/javascript/semmle/javascript/Stmt.qll/type.Stmt$Stmt.html>`__... ``}`` | `FunctionDeclStmt <https://help.semmle.com/qldoc/javascript/semmle/javascript/Stmt.qll/type.Stmt$FunctionDeclStmt.html>`__ | `Function <https://help.semmle.com/qldoc/javascript/semmle/javascript/Functions.qll/type.Functions$Function.html>`__ | | -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``if`` ``(`` `Expr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Expr.html>`__ ``)`` `Stmt <https://help.semmle.com/qldoc/javascript/semmle/javascript/Stmt.qll/type.Stmt$Stmt.html>`__ ``else`` `Stmt <https://help.semmle.com/qldoc/javascript/semmle/javascript/Stmt.qll/type.Stmt$Stmt.html>`__ | `IfStmt <https://help.semmle.com/qldoc/javascript/semmle/javascript/Stmt.qll/type.Stmt$IfStmt.html>`__ | `ControlStmt <https://help.semmle.com/qldoc/javascript/semmle/javascript/Stmt.qll/type.Stmt$ControlStmt.html>`__ | | -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``import {`` `ImportSpecifier <https://help.semmle.com/qldoc/javascript/semmle/javascript/ES2015Modules.qll/type.ES2015Modules$ImportSpecifier.html>`__... ``from`` `StringLiteral <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$StringLiteral.html>`__ | `ImportDeclaration <https://help.semmle.com/qldoc/javascript/semmle/javascript/ES2015Modules.qll/type.ES2015Modules$ImportDeclaration.html>`__ | `Import <https://help.semmle.com/qldoc/javascript/semmle/javascript/Modules.qll/type.Modules$Import.html>`__ | | -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``import`` `Identifier <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Identifier.html>`__ ``=`` `Expr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Expr.html>`__ ``;`` | `ImportEqualsDeclaration <https://help.semmle.com/qldoc/javascript/semmle/javascript/TypeScript.qll/type.TypeScript$ImportEqualsDeclaration.html>`__ | | | -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``interface`` `Identifier <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Identifier.html>`__ ``{`` `MemberDeclaration <https://help.semmle.com/qldoc/javascript/semmle/javascript/Classes.qll/type.Classes$MemberDeclaration.html>`__... ``}`` | `InterfaceDeclaration <https://help.semmle.com/qldoc/javascript/semmle/javascript/TypeScript.qll/type.TypeScript$InterfaceDeclaration.html>`__ | `InterfaceDefinition <https://help.semmle.com/qldoc/javascript/semmle/javascript/TypeScript.qll/type.TypeScript$InterfaceDefinition.html>`__, `ClassOrInterface <https://help.semmle.com/qldoc/javascript/semmle/javascript/Classes.qll/type.Classes$ClassOrInterface.html>`__, `TypeParameterized <https://help.semmle.com/qldoc/javascript/semmle/javascript/TypeScript.qll/type.TypeScript$TypeParameterized.html>`__ | | -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``let`` `Identifier <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Identifier.html>`__ ``=`` `Expr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Expr.html>`__ ``;`` | `LetStmt <https://help.semmle.com/qldoc/javascript/semmle/javascript/Stmt.qll/type.Stmt$LetStmt.html>`__ | `DeclStmt <https://help.semmle.com/qldoc/javascript/semmle/javascript/Stmt.qll/type.Stmt$DeclStmt.html>`__ | | -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``namespace`` `Identifier <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Identifier.html>`__ ``{`` `Stmt <https://help.semmle.com/qldoc/javascript/semmle/javascript/Stmt.qll/type.Stmt$Stmt.html>`__... ``}`` | `NamespaceDeclaration <https://help.semmle.com/qldoc/javascript/semmle/javascript/TypeScript.qll/type.TypeScript$NamespaceDeclaration.html>`__ | `NamespaceDefinition <https://help.semmle.com/qldoc/javascript/semmle/javascript/TypeScript.qll/type.TypeScript$NamespaceDefinition.html>`__ | | -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``return`` `Expr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Expr.html>`__ ``;`` | `ReturnStmt <https://help.semmle.com/qldoc/javascript/semmle/javascript/Stmt.qll/type.Stmt$ReturnStmt.html>`__ | `JumpStmt <https://help.semmle.com/qldoc/javascript/semmle/javascript/Stmt.qll/type.Stmt$JumpStmt.html>`__ | | -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``switch`` ``(`` `Expr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Expr.html>`__ ``) {`` `Case <https://help.semmle.com/qldoc/javascript/semmle/javascript/Stmt.qll/type.Stmt$Case.html>`__... ``}`` | `SwitchStmt <https://help.semmle.com/qldoc/javascript/semmle/javascript/Stmt.qll/type.Stmt$SwitchStmt.html>`__ | `ControlStmt <https://help.semmle.com/qldoc/javascript/semmle/javascript/Stmt.qll/type.Stmt$ControlStmt.html>`__ | | -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``throw`` `Expr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Expr.html>`__ ``;`` | `ThrowStmt <https://help.semmle.com/qldoc/javascript/semmle/javascript/Stmt.qll/type.Stmt$ThrowStmt.html>`__ | `JumpStmt <https://help.semmle.com/qldoc/javascript/semmle/javascript/Stmt.qll/type.Stmt$JumpStmt.html>`__ | | -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``try`` ``{`` `Stmt <https://help.semmle.com/qldoc/javascript/semmle/javascript/Stmt.qll/type.Stmt$Stmt.html>`__... ``}`` `CatchClause <https://help.semmle.com/qldoc/javascript/semmle/javascript/Stmt.qll/type.Stmt$CatchClause.html>`__... ``finally`` ``{`` `Stmt <https://help.semmle.com/qldoc/javascript/semmle/javascript/Stmt.qll/type.Stmt$Stmt.html>`__... ``}`` | `TryStmt <https://help.semmle.com/qldoc/javascript/semmle/javascript/Stmt.qll/type.Stmt$TryStmt.html>`__ | `ControlStmt <https://help.semmle.com/qldoc/javascript/semmle/javascript/Stmt.qll/type.Stmt$ControlStmt.html>`__ | | -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``type`` `Identifier <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Identifier.html>`__ ``=`` `TypeExpr <https://help.semmle.com/qldoc/javascript/semmle/javascript/TypeScript.qll/type.TypeScript$TypeExpr.html>`__ ``;`` | `TypeAliasDeclaration <https://help.semmle.com/qldoc/javascript/semmle/javascript/TypeScript.qll/type.TypeScript$TypeAliasDeclaration.html>`__ | `TypeParameterized <https://help.semmle.com/qldoc/javascript/semmle/javascript/TypeScript.qll/type.TypeScript$TypeParameterized.html>`__ | | -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``var`` `Identifier <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Identifier.html>`__ ``=`` `Expr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Expr.html>`__ ``;`` | `VarDeclStmt <https://help.semmle.com/qldoc/javascript/semmle/javascript/Stmt.qll/type.Stmt$VarDeclStmt.html>`__ | `DeclStmt <https://help.semmle.com/qldoc/javascript/semmle/javascript/Stmt.qll/type.Stmt$DeclStmt.html>`__ | | -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``while`` ``(`` `Expr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Expr.html>`__ ``)`` `Stmt <https://help.semmle.com/qldoc/javascript/semmle/javascript/Stmt.qll/type.Stmt$Stmt.html>`__ | `WhileStmt <https://help.semmle.com/qldoc/javascript/semmle/javascript/Stmt.qll/type.Stmt$WhileStmt.html>`__ | `ControlStmt <https://help.semmle.com/qldoc/javascript/semmle/javascript/Stmt.qll/type.Stmt$ControlStmt.html>`__, `LoopStmt <https://help.semmle.com/qldoc/javascript/semmle/javascript/Stmt.qll/type.Stmt$LoopStmt.html>`__ | | -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``with`` ``(`` `Expr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Expr.html>`__ ``)`` `Stmt <https://help.semmle.com/qldoc/javascript/semmle/javascript/Stmt.qll/type.Stmt$Stmt.html>`__ | `WithStmt <https://help.semmle.com/qldoc/javascript/semmle/javascript/Stmt.qll/type.Stmt$WithStmt.html>`__ | `ControlStmt <https://help.semmle.com/qldoc/javascript/semmle/javascript/Stmt.qll/type.Stmt$ControlStmt.html>`__ | | -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``{`` `Stmt <https://help.semmle.com/qldoc/javascript/semmle/javascript/Stmt.qll/type.Stmt$Stmt.html>`__... ``}`` | `BlockStmt <https://help.semmle.com/qldoc/javascript/semmle/javascript/Stmt.qll/type.Stmt$BlockStmt.html>`__ | | | -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - -Expression classes ------------------- - -There is a large number of expression classes, so we present them by category. All classes in this section are subclasses of `Expr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Expr.html>`__, except where noted otherwise. - -Literals -~~~~~~~~ - -All classes in this subsection are subclasses of `Literal <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Literal.html>`__. - -+-------------------+------------------------------------------------------------------------------------------------------------------------+ -| Expression syntax | CodeQL class | -+===================+========================================================================================================================+ -| ``true`` | `BooleanLiteral <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$BooleanLiteral.html>`__ | -+-------------------+------------------------------------------------------------------------------------------------------------------------+ -| ``23`` | `NumberLiteral <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$NumberLiteral.html>`__ | -+-------------------+------------------------------------------------------------------------------------------------------------------------+ -| ``4.2`` | `NumberLiteral <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$NumberLiteral.html>`__ | -+-------------------+------------------------------------------------------------------------------------------------------------------------+ -| ``"Hello"`` | `StringLiteral <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$StringLiteral.html>`__ | -+-------------------+------------------------------------------------------------------------------------------------------------------------+ -| ``/ab*c?/`` | `RegExpLiteral <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$RegExpLiteral.html>`__ | -+-------------------+------------------------------------------------------------------------------------------------------------------------+ -| ``null`` | `NullLiteral <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$NullLiteral.html>`__ | -+-------------------+------------------------------------------------------------------------------------------------------------------------+ - -Identifiers -~~~~~~~~~~~ - -All identifiers are represented by the class `Identifier <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Identifier.html>`__, which has subclasses to represent specific kinds of identifiers: - -- `VarAccess <https://help.semmle.com/qldoc/javascript/semmle/javascript/Variables.qll/type.Variables$VarAccess.html>`__: an identifier that refers to a variable -- `VarDecl <https://help.semmle.com/qldoc/javascript/semmle/javascript/Variables.qll/type.Variables$VarDecl.html>`__: an identifier that declares a variable, for example ``x`` in ``var x = "hi"`` or in ``function(x) { }`` -- `VarRef <https://help.semmle.com/qldoc/javascript/semmle/javascript/Variables.qll/type.Variables$VarRef.html>`__: a `VarAccess <https://help.semmle.com/qldoc/javascript/semmle/javascript/Variables.qll/type.Variables$VarAccess.html>`__ or a `VarDecl <https://help.semmle.com/qldoc/javascript/semmle/javascript/Variables.qll/type.Variables$VarDecl.html>`__ -- `Label <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Label.html>`__: an identifier that refers to a statement label or a property, not a variable; in the following examples, ``l`` and ``p`` are labels: - - - ``break l;`` - - ``l: for(;;) {}`` - - ``x.p`` - - ``{ p: 42 }`` - - -Primary expressions -~~~~~~~~~~~~~~~~~~~ - -All classes in this subsection are subclasses of `Expr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Expr.html>`__. - -+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| Expression syntax | CodeQL class | Superclasses | Remarks | -+======================================================================================================================================================================================================================================================================+==========================================================================================================================================+======================================================================================================================+================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================+ -| ``this`` | `ThisExpr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$ThisExpr.html>`__ | | | -+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``[`` `Expr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Expr.html>`__... ``]`` | `ArrayExpr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$ArrayExpr.html>`__ | | | -+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``{`` `Property <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Property.html>`__... ``}`` | `ObjectExpr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$ObjectExpr.html>`__ | | | -+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``function`` ``(`` `Parameter <https://help.semmle.com/qldoc/javascript/semmle/javascript/Variables.qll/type.Variables$Parameter.html>`__... ``)`` ``{`` `Stmt <https://help.semmle.com/qldoc/javascript/semmle/javascript/Stmt.qll/type.Stmt$Stmt.html>`__... ``}`` | `FunctionExpr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$FunctionExpr.html>`__ | `Function <https://help.semmle.com/qldoc/javascript/semmle/javascript/Functions.qll/type.Functions$Function.html>`__ | | -+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``(`` `Parameter <https://help.semmle.com/qldoc/javascript/semmle/javascript/Variables.qll/type.Variables$Parameter.html>`__... ``)`` ``=>`` `Expr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Expr.html>`__ | `ArrowFunctionExpr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$ArrowFunctionExpr.html>`__ | `Function <https://help.semmle.com/qldoc/javascript/semmle/javascript/Functions.qll/type.Functions$Function.html>`__ | | -+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``(`` `Expr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Expr.html>`__ ``)`` | `ParExpr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$ParExpr.html>`__ | | | -+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ````` ... ````` | `TemplateLiteral <https://help.semmle.com/qldoc/javascript/semmle/javascript/Templates.qll/type.Templates$TemplateLiteral.html>`__ | | an element in a `TemplateLiteral <https://help.semmle.com/qldoc/javascript/semmle/javascript/Templates.qll/type.Templates$TemplateLiteral.html>`__ is either a `TemplateElement <https://help.semmle.com/qldoc/javascript/semmle/javascript/Templates.qll/type.Templates$TemplateElement.html>`__ representing a constant template element, or some other expression representing an interpolated expression of the form ``${`` `Expr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Expr.html>`__ ``}`` | -+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| `Expr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Expr.html>`__ ````` ... ````` | `TaggedTemplateExpr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Templates.qll/type.Templates$TaggedTemplateExpr.html>`__ | | an element in a `TaggedTemplateExpr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Templates.qll/type.Templates$TaggedTemplateExpr.html>`__ is either a `TemplateElement <https://help.semmle.com/qldoc/javascript/semmle/javascript/Templates.qll/type.Templates$TemplateElement.html>`__ representing a constant template element, or some other expression representing an interpolated expression of the form ``${`` `Expr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Expr.html>`__ ``}`` | -+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - -Properties -~~~~~~~~~~ - -All classes in this subsection are subclasses of `Property <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Property.html>`__. Note that `Property <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Property.html>`__ is not a subclass of `Expr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Expr.html>`__. - -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------+ -| Property syntax | CodeQL class | Superclasses | -+=====================================================================================================================================================================================================================================================================================================================================================================+========================================================================================================================+============================================================================================================================+ -| `Identifier <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Identifier.html>`__ ``:`` `Expr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Expr.html>`__ | `ValueProperty <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$ValueProperty.html>`__ | | -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------+ -| ``get`` `Identifier <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Identifier.html>`__ ``()`` ``{`` `Stmt <https://help.semmle.com/qldoc/javascript/semmle/javascript/Stmt.qll/type.Stmt$Stmt.html>`__... ``}`` | `PropertyGetter <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$PropertyGetter.html>`__ | `PropertyAccessor <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$PropertyAccessor.html>`__ | -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------+ -| ``set`` `Identifier <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Identifier.html>`__ ``(`` `Identifier <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Identifier.html>`__ ``)`` ``{`` `Stmt <https://help.semmle.com/qldoc/javascript/semmle/javascript/Stmt.qll/type.Stmt$Stmt.html>`__... ``}`` | `PropertySetter <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$PropertySetter.html>`__ | `PropertyAccessor <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$PropertyAccessor.html>`__ | -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------+ - -Property accesses -~~~~~~~~~~~~~~~~~ - -All classes in this subsection are subclasses of `PropAccess <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$PropAccess.html>`__. - -+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------+ -| Expression syntax | CodeQL class | -+=========================================================================================================================================================================================================================+==============================================================================================================+ -| `Expr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Expr.html>`__ ``.`` `Identifier <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Identifier.html>`__ | `DotExpr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$DotExpr.html>`__ | -+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------+ -| `Expr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Expr.html>`__ ``[`` `Expr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Expr.html>`__ ``]`` | `IndexExpr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$IndexExpr.html>`__ | -+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------+ - -Function calls and ``new`` -~~~~~~~~~~~~~~~~~~~~~~~~~~ - -All classes in this subsection are subclasses of `InvokeExpr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$InvokeExpr.html>`__. - -+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| Expression syntax | CodeQL class | Remarks | -+============================================================================================================================================================================================================================================================================================================================================+========================================================================================================================+==========================================================================================================================================================================================================================================================================================================================================================================+ -| `Expr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Expr.html>`__ ``(`` `Expr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Expr.html>`__... ``)`` | `CallExpr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$CallExpr.html>`__ | | -+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| `Expr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Expr.html>`__ ``.`` `Identifier <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Identifier.html>`__ ``(`` `Expr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Expr.html>`__... ``)`` | `MethodCallExpr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$MethodCallExpr.html>`__ | this also includes calls of the form `Expr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Expr.html>`__ ``[`` `Expr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Expr.html>`__ ``]`` ``(`` `Expr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Expr.html>`__... ``)`` | -+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``new`` `Expr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Expr.html>`__ ``(`` `Expr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Expr.html>`__... ``)`` | `NewExpr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$NewExpr.html>`__ | | -+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - -Unary expressions -~~~~~~~~~~~~~~~~~ - -All classes in this subsection are subclasses of `UnaryExpr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$UnaryExpr.html>`__. - -+---------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------+ -| Expression syntax | CodeQL class | -+===============================================================================================================+======================================================================================================================+ -| ``~`` `Expr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Expr.html>`__ | `BitNotExpr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$BitNotExpr.html>`__ | -+---------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------+ -| ``-`` `Expr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Expr.html>`__ | `NegExpr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$NegExpr.html>`__ | -+---------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------+ -| ``+`` `Expr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Expr.html>`__ | `PlusExpr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$PlusExpr.html>`__ | -+---------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------+ -| ``!`` `Expr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Expr.html>`__ | `LogNotExpr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$LogNotExpr.html>`__ | -+---------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------+ -| ``typeof`` `Expr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Expr.html>`__ | `TypeofExpr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$TypeofExpr.html>`__ | -+---------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------+ -| ``void`` `Expr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Expr.html>`__ | `VoidExpr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$VoidExpr.html>`__ | -+---------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------+ -| ``delete`` `Expr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Expr.html>`__ | `DeleteExpr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$DeleteExpr.html>`__ | -+---------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------+ -| ``...`` `Expr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Expr.html>`__ | `SpreadElement <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$SpreadElement.html>`__ | -+---------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------+ - -Binary expressions -~~~~~~~~~~~~~~~~~~ - -All classes in this subsection are subclasses of `BinaryExpr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$BinaryExpr.html>`__. - -+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| Expression syntax | CodeQL class | Superclasses | -+======================================================================================================================================================================================================================+========================================================================================================================+====================================================================================================================================================================================================================================+ -| `Expr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Expr.html>`__ ``*`` `Expr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Expr.html>`__ | `MulExpr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$MulExpr.html>`__ | | -+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| `Expr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Expr.html>`__ ``/`` `Expr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Expr.html>`__ | `DivExpr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$DivExpr.html>`__ | | -+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| `Expr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Expr.html>`__ ``%`` `Expr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Expr.html>`__ | `ModExpr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$ModExpr.html>`__ | | -+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| `Expr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Expr.html>`__ ``**`` `Expr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Expr.html>`__ | `ExpExpr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$ExpExpr.html>`__ | | -+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| `Expr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Expr.html>`__ ``+`` `Expr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Expr.html>`__ | `AddExpr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$AddExpr.html>`__ | | -+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| `Expr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Expr.html>`__ ``-`` `Expr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Expr.html>`__ | `SubExpr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$SubExpr.html>`__ | | -+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| `Expr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Expr.html>`__ ``<<`` `Expr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Expr.html>`__ | `LShiftExpr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$LShiftExpr.html>`__ | | -+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| `Expr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Expr.html>`__ ``>>`` `Expr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Expr.html>`__ | `RShiftExpr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$RShiftExpr.html>`__ | | -+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| `Expr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Expr.html>`__ ``>>>`` `Expr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Expr.html>`__ | `URShiftExpr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$URShiftExpr.html>`__ | | -+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| `Expr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Expr.html>`__ ``&&`` `Expr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Expr.html>`__ | `LogAndExpr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$LogAndExpr.html>`__ | | -+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| `Expr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Expr.html>`__ ``||`` `Expr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Expr.html>`__ | `LogOrExpr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$LogOrExpr.html>`__ | | -+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| `Expr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Expr.html>`__ ``<`` `Expr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Expr.html>`__ | `LTExpr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$LTExpr.html>`__ | `Comparison <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Comparison.html>`__ | -+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| `Expr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Expr.html>`__ ``>`` `Expr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Expr.html>`__ | `GTExpr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$GTExpr.html>`__ | `Comparison <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Comparison.html>`__ | -+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| `Expr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Expr.html>`__ ``<=`` `Expr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Expr.html>`__ | `LEExpr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$LEExpr.html>`__ | `Comparison <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Comparison.html>`__ | -+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| `Expr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Expr.html>`__ ``>=`` `Expr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Expr.html>`__ | `GEExpr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$GEExpr.html>`__ | `Comparison <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Comparison.html>`__ | -+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| `Expr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Expr.html>`__ ``==`` `Expr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Expr.html>`__ | `EqExpr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$EqExpr.html>`__ | `EqualityTest <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$EqualityTest.html>`__, `Comparison <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Comparison.html>`__ | -+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| `Expr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Expr.html>`__ ``!=`` `Expr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Expr.html>`__ | `NEqExpr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$NEqExpr.html>`__ | `EqualityTest <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$EqualityTest.html>`__, `Comparison <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Comparison.html>`__ | -+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| `Expr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Expr.html>`__ ``===`` `Expr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Expr.html>`__ | `StrictEqExpr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$StrictEqExpr.html>`__ | `EqualityTest <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$EqualityTest.html>`__, `Comparison <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Comparison.html>`__ | -+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| `Expr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Expr.html>`__ ``!==`` `Expr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Expr.html>`__ | `StrictNEqExpr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$StrictNEqExpr.html>`__ | `EqualityTest <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$EqualityTest.html>`__, `Comparison <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Comparison.html>`__ | -+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| `Expr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Expr.html>`__ ``&`` `Expr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Expr.html>`__ | `BitAndExpr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$BitAndExpr.html>`__ | | -+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| `Expr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Expr.html>`__ ``|`` `Expr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Expr.html>`__ | `BitOrExpr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$BitOrExpr.html>`__ | | -+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| `Expr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Expr.html>`__ ``^`` `Expr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Expr.html>`__ | `XOrExpr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$XOrExpr.html>`__ | | -+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| `Expr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Expr.html>`__ ``in`` `Expr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Expr.html>`__ | `InExpr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$InExpr.html>`__ | | -+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| `Expr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Expr.html>`__ ``instanceof`` `Expr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Expr.html>`__ | `InstanceofExpr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$InstanceofExpr.html>`__ | | -+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ - -Assignment expressions -~~~~~~~~~~~~~~~~~~~~~~ - -All classes in this table are subclasses of `Assignment <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Assignment.html>`__. - -+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------+ -| Expression syntax | CodeQL class | Superclasses | -+================================================================================================================================================================================================================+==============================================================================================================================+================================================================================================================================+ -| `Expr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Expr.html>`__ ``=`` `Expr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Expr.html>`__ | `AssignExpr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$AssignExpr.html>`__ | | -+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------+ -| `Expr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Expr.html>`__ ``+=`` `Expr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Expr.html>`__ | `AssignAddExpr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$AssignAddExpr.html>`__ | `CompoundAssignExpr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$CompoundAssignExpr.html>`__ | -+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------+ -| `Expr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Expr.html>`__ ``-=`` `Expr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Expr.html>`__ | `AssignSubExpr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$AssignSubExpr.html>`__ | `CompoundAssignExpr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$CompoundAssignExpr.html>`__ | -+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------+ -| `Expr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Expr.html>`__ ``*=`` `Expr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Expr.html>`__ | `AssignMulExpr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$AssignMulExpr.html>`__ | `CompoundAssignExpr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$CompoundAssignExpr.html>`__ | -+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------+ -| `Expr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Expr.html>`__ ``**=`` `Expr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Expr.html>`__ | `AssignExpExpr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$AssignExpExpr.html>`__ | `CompoundAssignExpr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$CompoundAssignExpr.html>`__ | -+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------+ -| `Expr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Expr.html>`__ ``/=`` `Expr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Expr.html>`__ | `AssignDivExpr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$AssignDivExpr.html>`__ | `CompoundAssignExpr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$CompoundAssignExpr.html>`__ | -+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------+ -| `Expr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Expr.html>`__ ``%=`` `Expr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Expr.html>`__ | `AssignModExpr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$AssignModExpr.html>`__ | `CompoundAssignExpr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$CompoundAssignExpr.html>`__ | -+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------+ -| `Expr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Expr.html>`__ ``&=`` `Expr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Expr.html>`__ | `AssignAndExpr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$AssignAndExpr.html>`__ | `CompoundAssignExpr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$CompoundAssignExpr.html>`__ | -+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------+ -| `Expr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Expr.html>`__ ``|=`` `Expr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Expr.html>`__ | `AssignOrExpr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$AssignOrExpr.html>`__ | `CompoundAssignExpr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$CompoundAssignExpr.html>`__ | -+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------+ -| `Expr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Expr.html>`__ ``^=`` `Expr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Expr.html>`__ | `AssignXOrExpr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$AssignXOrExpr.html>`__ | `CompoundAssignExpr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$CompoundAssignExpr.html>`__ | -+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------+ -| `Expr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Expr.html>`__ ``<<=`` `Expr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Expr.html>`__ | `AssignLShiftExpr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$AssignLShiftExpr.html>`__ | `CompoundAssignExpr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$CompoundAssignExpr.html>`__ | -+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------+ -| `Expr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Expr.html>`__ ``>>=`` `Expr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Expr.html>`__ | `AssignRShiftExpr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$AssignRShiftExpr.html>`__ | `CompoundAssignExpr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$CompoundAssignExpr.html>`__ | -+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------+ -| `Expr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Expr.html>`__ ``>>>=`` `Expr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Expr.html>`__ | `AssignURShiftExpr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$AssignURShiftExpr.html>`__ | `CompoundAssignExpr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$CompoundAssignExpr.html>`__ | -+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------+ - -Update expressions -~~~~~~~~~~~~~~~~~~ - -All classes in this table are subclasses of `UpdateExpr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$UpdateExpr.html>`__. - -+-----------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------+ -| Expression syntax | CodeQL class | -+===========================================================================================================+==================================================================================================================+ -| `Expr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Expr.html>`__ ``++`` | `PostIncExpr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$PostIncExpr.html>`__ | -+-----------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------+ -| `Expr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Expr.html>`__ ``--`` | `PostDecExpr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$PostDecExpr.html>`__ | -+-----------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------+ -| ``++`` `Expr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Expr.html>`__ | `PreIncExpr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$PreIncExpr.html>`__ | -+-----------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------+ -| ``--`` `Expr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Expr.html>`__ | `PreDecExpr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$PreDecExpr.html>`__ | -+-----------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------+ - -Miscellaneous -~~~~~~~~~~~~~ - -All classes in this table are subclasses of `Expr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Expr.html>`__. - -+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------+ -| Expression syntax | CodeQL class | -+======================================================================================================================================================================================================================================================================================================================+==========================================================================================================================+ -| `Expr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Expr.html>`__ ``?`` `Expr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Expr.html>`__ ``:`` `Expr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Expr.html>`__ | `ConditionalExpr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$ConditionalExpr.html>`__ | -+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------+ -| `Expr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Expr.html>`__ ``,`` ... ``,`` `Expr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Expr.html>`__ | `SeqExpr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$SeqExpr.html>`__ | -+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------+ -| ``await`` `Expr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Expr.html>`__ | `AwaitExpr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$AwaitExpr.html>`__ | -+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------+ -| ``yield`` `Expr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Expr.html>`__ | `YieldExpr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$YieldExpr.html>`__ | -+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------+ - -Further reading ---------------- - -.. include:: ../../reusables/javascript-further-reading.rst -.. include:: ../../reusables/codeql-ref-tools-further-reading.rst \ No newline at end of file diff --git a/docs/codeql/codeql-language-guides/codeql-for-javascript/codeql-library-for-javascript.rst b/docs/codeql/codeql-language-guides/codeql-for-javascript/codeql-library-for-javascript.rst deleted file mode 100644 index f00d28c69e7..00000000000 --- a/docs/codeql/codeql-language-guides/codeql-for-javascript/codeql-library-for-javascript.rst +++ /dev/null @@ -1,1037 +0,0 @@ -.. _codeql-library-for-javascript: - -CodeQL library for JavaScript -============================= - -When you're analyzing a JavaScript program, you can make use of the large collection of classes in the CodeQL library for JavaScript. - -Overview --------- - -There is an extensive CodeQL library for analyzing JavaScript code. The classes in this library present the data from a CodeQL database in an object-oriented form and provide abstractions and predicates to help you with common analysis tasks. - -The library is implemented as a set of QL modules, that is, files with the extension ``.qll``. The module ``javascript.qll`` imports most other standard library modules, so you can include the complete library by beginning your query with: - -.. code-block:: ql - - import javascript - -The rest of this tutorial briefly summarizes the most important classes and predicates provided by this library, including references to the `detailed API documentation <https://help.semmle.com/qldoc/javascript/>`__ where applicable. - -Introducing the library ------------------------ - -The CodeQL library for JavaScript presents information about JavaScript source code at different levels: - -- **Textual** — classes that represent source code as unstructured text files -- **Lexical** — classes that represent source code as a series of tokens and comments -- **Syntactic** — classes that represent source code as an abstract syntax tree -- **Name binding** — classes that represent scopes and variables -- **Control flow** — classes that represent the flow of control during execution -- **Data flow** — classes that you can use to reason about data flow in JavaScript source code -- **Type inference** — classes that you can use to approximate types for JavaScript expressions and variables -- **Call graph** — classes that represent the caller-callee relationship between functions -- **Inter-procedural data flow** — classes that you can use to define inter-procedural data flow and taint tracking analyses -- **Frameworks** — classes that represent source code entities that have a special meaning to JavaScript tools and frameworks - -Note that representations above the textual level (for example the lexical representation or the flow graphs) are only available for JavaScript code that does not contain fatal syntax errors. For code with such errors, the only information available is at the textual level, as well as information about the errors themselves. - -Additionally, there is library support for working with HTML documents, JSON, and YAML data, JSDoc comments, and regular expressions. - -Textual level -~~~~~~~~~~~~~ - -At its most basic level, a JavaScript code base can simply be viewed as a collection of files organized into folders, where each file is composed of zero or more lines of text. - -Note that the textual content of a program is not included in the CodeQL database unless you specifically request it during extraction. In particular, databases on LGTM (also known as "snapshots") do not normally include textual information. - -Files and folders -^^^^^^^^^^^^^^^^^ - -In the CodeQL libraries, files are represented as entities of class `File <https://help.semmle.com/qldoc/javascript/semmle/javascript/Files.qll/type.Files$File.html>`__, and folders as entities of class `Folder <https://help.semmle.com/qldoc/javascript/semmle/javascript/Files.qll/type.Files$Folder.html>`__, both of which are subclasses of class `Container <https://help.semmle.com/qldoc/javascript/semmle/javascript/Files.qll/type.Files$Container.html>`__. - -Class `Container <https://help.semmle.com/qldoc/javascript/semmle/javascript/Files.qll/type.Files$Container.html>`__ provides the following member predicates: - -- ``Container.getParentContainer()`` returns the parent folder of the file or folder. -- ``Container.getAFile()`` returns a file within the folder. -- ``Container.getAFolder()`` returns a folder nested within the folder. - -Note that while ``getAFile`` and ``getAFolder`` are declared on class `Container <https://help.semmle.com/qldoc/javascript/semmle/javascript/Files.qll/type.Files$Container.html>`__, they currently only have results for `Folder <https://help.semmle.com/qldoc/javascript/semmle/javascript/Files.qll/type.Files$Folder.html>`__\ s. - -Both files and folders have paths, which can be accessed by the predicate ``Container.getAbsolutePath()``. For example, if ``f`` represents a file with the path ``/home/user/project/src/index.js``, then ``f.getAbsolutePath()`` evaluates to the string ``"/home/user/project/src/index.js"``, while ``f.getParentContainer().getAbsolutePath()`` returns ``"/home/user/project/src"``. - -These paths are absolute file system paths. If you want to obtain the path of a file relative to the source location in the CodeQL database, use ``Container.getRelativePath()`` instead. Note, however, that a database may contain files that are not located underneath the source location; for such files, ``getRelativePath()`` will not return anything. - -The following member predicates of class `Container <https://help.semmle.com/qldoc/javascript/semmle/javascript/Files.qll/type.Files$Container.html>`__ provide more information about the name of a file or folder: - -- ``Container.getBaseName()`` returns the base name of a file or folder, not including its parent folder, but including its extension. In the above example, ``f.getBaseName()`` would return the string ``"index.js"``. -- ``Container.getStem()`` is similar to ``Container.getBaseName()``, but it does *not* include the file extension; so ``f.getStem()`` returns ``"index"``. -- ``Container.getExtension()`` returns the file extension, not including the dot; so ``f.getExtension()`` returns ``"js"``. - -For example, the following query computes, for each folder, the number of JavaScript files (that is, files with extension ``js``) contained in the folder: - -.. code-block:: ql - - import javascript - - from Folder d - select d.getRelativePath(), count(File f | f = d.getAFile() and f.getExtension() = "js") - -➤ `See this in the query console on LGTM.com <https://lgtm.com/query/1506075865985/>`__. When you run the query on most projects, the results include folders that contain files with a ``js`` extension and folders that don't. - -Locations -^^^^^^^^^ - -Most entities in a CodeQL database have an associated source location. Locations are identified by four pieces of information: a file, a start line, a start column, an end line, and an end column. Line and column counts are 1-based (so the first character of a file is at line 1, column 1), and the end position is inclusive. - -All entities associated with a source location belong to the class `Locatable <https://help.semmle.com/qldoc/javascript/semmle/javascript/Locations.qll/type.Locations$Locatable.html>`__. The location itself is modeled by the class `Location <https://help.semmle.com/qldoc/javascript/semmle/javascript/Locations.qll/type.Locations$Location.html>`__ and can be accessed through the member predicate ``Locatable.getLocation()``. The `Location <https://help.semmle.com/qldoc/javascript/semmle/javascript/Locations.qll/type.Locations$Location.html>`__ class provides the following member predicates: - -- ``Location.getFile()``, ``Location.getStartLine()``, ``Location.getStartColumn()``, ``Location.getEndLine()``, ``Location.getEndColumn()`` return detailed information about the location. -- ``Location.getNumLines()`` returns the number of (whole or partial) lines covered by the location. -- ``Location.startsBefore(Location)`` and ``Location.endsAfter(Location)`` determine whether one location starts before or ends after another location. -- ``Location.contains(Location)`` indicates whether one location completely contains another location; ``l1.contains(l2)`` holds if, and only if, ``l1.startsBefore(l2)`` and ``l1.endsAfter(l2)``. - -Lines -^^^^^ - -Lines of text in files are represented by the class `Line <https://help.semmle.com/qldoc/javascript/semmle/javascript/Lines.qll/type.Lines$Line.html>`__. This class offers the following member predicates: - -- ``Line.getText()`` returns the text of the line, excluding any terminating newline characters. -- ``Line.getTerminator()`` returns the terminator character(s) of the line. The last line in a file may not have any terminator characters, in which case this predicate does not return anything; otherwise it returns either the two-character string ``"\r\n"`` (carriage-return followed by newline), or one of the one-character strings ``"\n"`` (newline), ``"\r"`` (carriage-return), ``"\u2028"`` (Unicode character LINE SEPARATOR), ``"\u2029"`` (Unicode character PARAGRAPH SEPARATOR). - -Note that, as mentioned above, the textual representation of the program is not included in the CodeQL database by default. - -Lexical level -~~~~~~~~~~~~~ - -A slightly more structured view of a JavaScript program is provided by the classes `Token <https://help.semmle.com/qldoc/javascript/semmle/javascript/Tokens.qll/type.Tokens$Token.html>`__ and `Comment <https://help.semmle.com/qldoc/javascript/semmle/javascript/Comments.qll/type.Comments$Comment.html>`__, which represent tokens and comments, respectively. - -Tokens -^^^^^^ - -The most important member predicates of class `Token <https://help.semmle.com/qldoc/javascript/semmle/javascript/Tokens.qll/type.Tokens$Token.html>`__ are as follows: - -- ``Token.getValue()`` returns the source text of the token. -- ``Token.getIndex()`` returns the index of the token within its enclosing script. -- ``Token.getNextToken()`` and ``Token.getPreviousToken()`` navigate between tokens. - -The `Token <https://help.semmle.com/qldoc/javascript/semmle/javascript/Tokens.qll/type.Tokens$Token.html>`__ class has nine subclasses, each representing a particular kind of token: - -- `EOFToken <https://help.semmle.com/qldoc/javascript/semmle/javascript/Tokens.qll/type.Tokens$EOFToken.html>`__: a marker token representing the end of a script -- `NullLiteralToken <https://help.semmle.com/qldoc/javascript/semmle/javascript/Tokens.qll/type.Tokens$NullLiteralToken.html>`__, `BooleanLiteralToken <https://help.semmle.com/qldoc/javascript/semmle/javascript/Tokens.qll/type.Tokens$BooleanLiteralToken.html>`__, `NumericLiteralToken <https://help.semmle.com/qldoc/javascript/semmle/javascript/Tokens.qll/type.Tokens$NumericLiteralToken.html>`__, `StringLiteralToken <https://help.semmle.com/qldoc/javascript/semmle/javascript/Tokens.qll/type.Tokens$StringLiteralToken.html>`__ and `RegularExpressionToken <https://help.semmle.com/qldoc/javascript/semmle/javascript/Tokens.qll/type.Tokens$RegularExpressionToken.html>`__: different kinds of literals -- `IdentifierToken <https://help.semmle.com/qldoc/javascript/semmle/javascript/Tokens.qll/type.Tokens$IdentifierToken.html>`__ and `KeywordToken <https://help.semmle.com/qldoc/javascript/semmle/javascript/Tokens.qll/type.Tokens$KeywordToken.html>`__: identifiers and keywords (including reserved words) respectively -- `PunctuatorToken <https://help.semmle.com/qldoc/javascript/semmle/javascript/Tokens.qll/type.Tokens$PunctuatorToken.html>`__: operators and other punctuation symbols - -As an example of a query operating entirely on the lexical level, consider the following query, which finds consecutive comma tokens arising from an omitted element in an array expression: - -.. code-block:: ql - - import javascript - - class CommaToken extends PunctuatorToken { - CommaToken() { - getValue() = "," - } - } - - from CommaToken comma - where comma.getNextToken() instanceof CommaToken - select comma, "Omitted array elements are bad style." - -➤ `See this in the query console on LGTM.com <https://lgtm.com/query/659662177/>`__. If the query returns no results, this pattern isn't used in the projects that you analyzed. - -You can use predicate ``Locatable.getFirstToken()`` and ``Locatable.getLastToken()`` to access the first and last token (if any) belonging to an element with a source location. - -Comments -^^^^^^^^ - -The class `Comment <https://help.semmle.com/qldoc/javascript/semmle/javascript/Comments.qll/type.Comments$Comment.html>`__ and its subclasses represent the different kinds of comments that can occur in JavaScript programs: - -- `Comment <https://help.semmle.com/qldoc/javascript/semmle/javascript/Comments.qll/type.Comments$Comment.html>`__: any comment - - - `LineComment <https://help.semmle.com/qldoc/javascript/semmle/javascript/Comments.qll/type.Comments$LineComment.html>`__: a single-line comment terminated by an end-of-line character - - - `SlashSlashComment <https://help.semmle.com/qldoc/javascript/semmle/javascript/Comments.qll/type.Comments$SlashSlashComment.html>`__: a plain JavaScript single-line comment starting with ``//`` - - `HtmlLineComment <https://help.semmle.com/qldoc/javascript/semmle/javascript/Comments.qll/type.Comments$HtmlLineComment.html>`__: a (non-standard) HTML comment - - - `HtmlCommentStart <https://help.semmle.com/qldoc/javascript/semmle/javascript/Comments.qll/type.Comments$HtmlCommentStart.html>`__: an HTML comment starting with ``<!--`` - - - `HtmlCommentEnd <https://help.semmle.com/qldoc/javascript/semmle/javascript/Comments.qll/type.Comments$HtmlCommentEnd.html>`__: an HTML comment ending with ``-->`` - -- `BlockComment <https://help.semmle.com/qldoc/javascript/semmle/javascript/Comments.qll/type.Comments$BlockComment.html>`__: a block comment potentially spanning multiple lines - - - `SlashStarComment <https://help.semmle.com/qldoc/javascript/semmle/javascript/Comments.qll/type.Comments$SlashStarComment.html>`__: a plain JavaScript block comment surrounded with ``/*...*/`` - - `DocComment <https://help.semmle.com/qldoc/javascript/semmle/javascript/Comments.qll/type.Comments$DocComment.html>`__: a documentation block comment surrounded with ``/**...*/`` - -The most important member predicates are as follows: - -- ``Comment.getText()`` returns the source text of the comment, not including delimiters. -- ``Comment.getLine(i)`` returns the ``i``\ th line of text within the comment (0-based). -- ``Comment.getNumLines()`` returns the number of lines in the comment. -- ``Comment.getNextToken()`` returns the token immediately following a comment. Note that such a token always exists: if a comment appears at the end of a file, its following token is an `EOFToken <https://help.semmle.com/qldoc/javascript/semmle/javascript/Tokens.qll/type.Tokens$EOFToken.html>`__. - -As an example of a query using only lexical information, consider the following query for finding HTML comments, which are not a standard ECMAScript feature and should be avoided: - -.. code-block:: ql - - import javascript - - from HtmlLineComment c - select c, "Do not use HTML comments." - -➤ `See this in the query console on LGTM.com <https://lgtm.com/query/686330023/>`__. When we ran this query on the *mozilla/pdf.js* project in LGTM.com, we found three HTML comments. - -Syntactic level -~~~~~~~~~~~~~~~ - -The majority of classes in the JavaScript library is concerned with representing a JavaScript program as a collection of `abstract syntax trees <http://en.wikipedia.org/wiki/Abstract_syntax_tree>`__ (ASTs). - -The class `ASTNode <https://help.semmle.com/qldoc/javascript/semmle/javascript/AST.qll/type.AST$ASTNode.html>`__ contains all entities representing nodes in the abstract syntax trees and defines generic tree traversal predicates: - -- ``ASTNode.getChild(i)``: returns the ``i``\ th child of this AST node. -- ``ASTNode.getAChild()``: returns any child of this AST node. -- ``ASTNode.getParent()``: returns the parent node of this AST node, if any. - -.. pull-quote:: - - Note - - These predicates should only be used to perform generic AST traversal. To access children of specific AST node types, the specialized predicates introduced below should be used instead. In particular, queries should not rely on the numeric indices of child nodes relative to their parent nodes: these are considered an implementation detail that may change between versions of the library. - -Top-levels -^^^^^^^^^^ - -From a syntactic point of view, each JavaScript program is composed of one or more top-level code blocks (or *top-levels* for short), which are blocks of JavaScript code that do not belong to a larger code block. Top-levels are represented by the class `TopLevel <https://help.semmle.com/qldoc/javascript/semmle/javascript/AST.qll/type.AST$TopLevel.html>`__ and its subclasses: - -- `TopLevel <https://help.semmle.com/qldoc/javascript/semmle/javascript/AST.qll/type.AST$TopLevel.html>`__ - - - `Script <https://help.semmle.com/qldoc/javascript/semmle/javascript/AST.qll/type.AST$Script.html>`__: a stand-alone file or HTML ``<script>`` element - - - `ExternalScript <https://help.semmle.com/qldoc/javascript/semmle/javascript/AST.qll/type.AST$ExternalScript.html>`__: a stand-alone JavaScript file - - `InlineScript <https://help.semmle.com/qldoc/javascript/semmle/javascript/AST.qll/type.AST$InlineScript.html>`__: code embedded inline in an HTML ``<script>`` tag - - - `CodeInAttribute <https://help.semmle.com/qldoc/javascript/semmle/javascript/AST.qll/type.AST$CodeInAttribute.html>`__: a code block originating from an HTML attribute value - - - `EventHandlerCode <https://help.semmle.com/qldoc/javascript/semmle/javascript/AST.qll/type.AST$EventHandlerCode.html>`__: code from an event handler attribute such as ``onload`` - - `JavaScriptURL <https://help.semmle.com/qldoc/javascript/semmle/javascript/AST.qll/type.AST$JavaScriptURL.html>`__: code from a URL with the ``javascript:`` scheme - - - `Externs <https://help.semmle.com/qldoc/javascript/semmle/javascript/AST.qll/type.AST$Externs.html>`__: a JavaScript file containing `externs <https://developers.google.com/closure/compiler/docs/api-tutorial3#externs>`__ definitions - -Every `TopLevel <https://help.semmle.com/qldoc/javascript/semmle/javascript/AST.qll/type.AST$TopLevel.html>`__ class is contained in a `File <https://help.semmle.com/qldoc/javascript/semmle/javascript/Files.qll/type.Files$File.html>`__ class, but a single `File <https://help.semmle.com/qldoc/javascript/semmle/javascript/Files.qll/type.Files$File.html>`__ may contain more than one `TopLevel <https://help.semmle.com/qldoc/javascript/semmle/javascript/AST.qll/type.AST$TopLevel.html>`__. To go from a ``TopLevel tl`` to its `File <https://help.semmle.com/qldoc/javascript/semmle/javascript/Files.qll/type.Files$File.html>`__, use ``tl.getFile()``; conversely, for a ``File f``, predicate ``f.getATopLevel()`` returns a top-level contained in ``f``. For every AST node, predicate ``ASTNode.getTopLevel()`` can be used to find the top-level it belongs to. - -The `TopLevel <https://help.semmle.com/qldoc/javascript/semmle/javascript/AST.qll/type.AST$TopLevel.html>`__ class additionally provides the following member predicates: - -- ``TopLevel.getNumberOfLines()`` returns the total number of lines (including code, comments and whitespace) in the top-level. -- ``TopLevel.getNumberOfLinesOfCode()`` returns the number of lines of code, that is, lines that contain at least one token. -- ``TopLevel.getNumberOfLinesOfComments()`` returns the number of lines containing or belonging to a comment. -- ``TopLevel.isMinified()`` determines whether the top-level contains minified code, using a heuristic based on the average number of statements per line. - -.. pull-quote:: - - Note - - By default, LGTM filters out alerts in minified top-levels, since they are often hard to interpret. When writing your own queries in the LGTM query console, this filtering is *not* done automatically, so you may want to explicitly add a condition of the form ``and not e.getTopLevel().isMinified()`` or similar to your query to exclude results in minified code. - -Statements and expressions -^^^^^^^^^^^^^^^^^^^^^^^^^^ - -The most important subclasses of `ASTNode <https://help.semmle.com/qldoc/javascript/semmle/javascript/AST.qll/type.AST$ASTNode.html>`__ besides `TopLevel <https://help.semmle.com/qldoc/javascript/semmle/javascript/AST.qll/type.AST$TopLevel.html>`__ are `Stmt <https://help.semmle.com/qldoc/javascript/semmle/javascript/Stmt.qll/type.Stmt$Stmt.html>`__ and `Expr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Expr.html>`__, which, together with their subclasses, represent statements and expressions, respectively. This section briefly discusses some of the more important classes and predicates. For a full reference of all the subclasses of `Stmt <https://help.semmle.com/qldoc/javascript/semmle/javascript/Stmt.qll/type.Stmt$Stmt.html>`__ and `Expr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Expr.html>`__ and their API, see -`Stmt.qll <https://help.semmle.com/qldoc/javascript/semmle/javascript/Stmt.qll/module.Stmt.html>`__ and `Expr.qll <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/module.Expr.html>`__. - -- `Stmt <https://help.semmle.com/qldoc/javascript/semmle/javascript/Stmt.qll/type.Stmt$Stmt.html>`__: use ``Stmt.getContainer()`` to access the innermost function or top-level in which the statement is contained. - - - `ControlStmt <https://help.semmle.com/qldoc/javascript/semmle/javascript/Stmt.qll/type.Stmt$ControlStmt.html>`__: a statement that controls the execution of other statements, that is, a conditional, loop, ``try`` or ``with`` statement; use ``ControlStmt.getAControlledStmt()`` to access the statements that it controls. - - - `IfStmt <https://help.semmle.com/qldoc/javascript/semmle/javascript/Stmt.qll/type.Stmt$IfStmt.html>`__: an ``if`` statement; use ``IfStmt.getCondition()``, ``IfStmt.getThen()`` and ``IfStmt.getElse()`` to access its condition expression, "then" branch and "else" branch, respectively. - - `LoopStmt <https://help.semmle.com/qldoc/javascript/semmle/javascript/Stmt.qll/type.Stmt$LoopStmt.html>`__: a loop; use ``Loop.getBody()`` and ``Loop.getTest()`` to access its body and its test expression, respectively. - - - `WhileStmt <https://help.semmle.com/qldoc/javascript/semmle/javascript/Stmt.qll/type.Stmt$WhileStmt.html>`__, `DoWhileStmt <https://help.semmle.com/qldoc/javascript/semmle/javascript/Stmt.qll/type.Stmt$DoWhileStmt.html>`__: a "while" or "do-while" loop, respectively. - - `ForStmt <https://help.semmle.com/qldoc/javascript/semmle/javascript/Stmt.qll/type.Stmt$ForStmt.html>`__: a "for" statement; use ``ForStmt.getInit()`` and ``ForStmt.getUpdate()`` to access the init and update expressions, respectively. - - `EnhancedForLoop <https://help.semmle.com/qldoc/javascript/semmle/javascript/Stmt.qll/type.Stmt$EnhancedForLoop.html>`__: a "for-in" or "for-of" loop; use ``EnhancedForLoop.getIterator()`` to access the loop iterator (which may be a expression or variable declaration), and ``EnhancedForLoop.getIterationDomain()`` to access the expression being iterated over. - - - `ForInStmt <https://help.semmle.com/qldoc/javascript/semmle/javascript/Stmt.qll/type.Stmt$ForInStmt.html>`__, `ForOfStmt <https://help.semmle.com/qldoc/javascript/semmle/javascript/Stmt.qll/type.Stmt$ForOfStmt.html>`__: a "for-in" or "for-of" loop, respectively. - - - `WithStmt <https://help.semmle.com/qldoc/javascript/semmle/javascript/Stmt.qll/type.Stmt$WithStmt.html>`__: a "with" statement; use ``WithStmt.getExpr()`` and ``WithStmt.getBody()`` to access the controlling expression and the body of the with statement, respectively. - - `SwitchStmt <https://help.semmle.com/qldoc/javascript/semmle/javascript/Stmt.qll/type.Stmt$SwitchStmt.html>`__: a switch statement; use ``SwitchStmt.getExpr()`` to access the expression on which the statement switches; use ``SwitchStmt.getCase(int)`` and ``SwitchStmt.getACase()`` to access individual switch cases; each case is modeled by an entity of class `Case <https://help.semmle.com/qldoc/javascript/semmle/javascript/Stmt.qll/type.Stmt$Case.html>`__, whose member predicates ``Case.getExpr()`` and ``Case.getBodyStmt(int)`` provide access to the expression checked by the switch case (which is undefined for ``default``), and its body. - - `TryStmt <https://help.semmle.com/qldoc/javascript/semmle/javascript/Stmt.qll/type.Stmt$TryStmt.html>`__: a "try" statement; use ``TryStmt.getBody()``, ``TryStmt.getCatchClause()`` and ``TryStmt.getFinally`` to access its body, "catch" clause and "finally" block, respectively. - - - `BlockStmt <https://help.semmle.com/qldoc/javascript/semmle/javascript/Stmt.qll/type.Stmt$BlockStmt.html>`__: a block of statements; use ``BlockStmt.getStmt(int)`` to access the individual statements in the block. - - `ExprStmt <https://help.semmle.com/qldoc/javascript/semmle/javascript/Stmt.qll/type.Stmt$ExprStmt.html>`__: an expression statement; use ``ExprStmt.getExpr()`` to access the expression itself. - - `JumpStmt <https://help.semmle.com/qldoc/javascript/semmle/javascript/Stmt.qll/type.Stmt$JumpStmt.html>`__: a statement that disrupts structured control flow, that is, one of ``break``, ``continue``, ``return`` and ``throw``; use predicate ``JumpStmt.getTarget()`` to determine the target of the jump, which is either a statement or (for ``return`` and uncaught ``throw`` statements) the enclosing function. - - - `BreakStmt <https://help.semmle.com/qldoc/javascript/semmle/javascript/Stmt.qll/type.Stmt$BreakStmt.html>`__: a "break" statement; use ``BreakStmt.getLabel()`` to access its (optional) target label. - - `ContinueStmt <https://help.semmle.com/qldoc/javascript/semmle/javascript/Stmt.qll/type.Stmt$ContinueStmt.html>`__: a "continue" statement; use ``ContinueStmt.getLabel()`` to access its (optional) target label. - - `ReturnStmt <https://help.semmle.com/qldoc/javascript/semmle/javascript/Stmt.qll/type.Stmt$ReturnStmt.html>`__: a "return" statement; use ``ReturnStmt.getExpr()`` to access its (optional) result expression. - - `ThrowStmt <https://help.semmle.com/qldoc/javascript/semmle/javascript/Stmt.qll/type.Stmt$ThrowStmt.html>`__: a "throw" statement; use ``ThrowStmt.getExpr()`` to access its thrown expression. - - - `FunctionDeclStmt <https://help.semmle.com/qldoc/javascript/semmle/javascript/Stmt.qll/type.Stmt$FunctionDeclStmt.html>`__: a function declaration statement; see below for available member predicates. - - `ClassDeclStmt <https://help.semmle.com/qldoc/javascript/semmle/javascript/Classes.qll/type.Classes$ClassDeclStmt.html>`__: a class declaration statement; see below for available member predicates. - - `DeclStmt <https://help.semmle.com/qldoc/javascript/semmle/javascript/Stmt.qll/type.Stmt$DeclStmt.html>`__: a declaration statement containing one or more declarators which can be accessed by predicate ``DeclStmt.getDeclarator(int)``. - - - `VarDeclStmt <https://help.semmle.com/qldoc/javascript/semmle/javascript/Stmt.qll/type.Stmt$VarDeclStmt.html>`__, `ConstDeclStmt <https://help.semmle.com/qldoc/javascript/semmle/javascript/Stmt.qll/type.Stmt$ConstDeclStmt.html>`__, `LetStmt <https://help.semmle.com/qldoc/javascript/semmle/javascript/Stmt.qll/type.Stmt$LetStmt.html>`__: a ``var``, ``const`` or ``let`` declaration statement. - -- `Expr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Expr.html>`__: use ``Expr.getEnclosingStmt()`` to obtain the innermost statement to which this expression belongs; ``Expr.isPure()`` determines whether the expression is side-effect-free. - - - `Identifier <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Identifier.html>`__: an identifier; use ``Identifier.getName()`` to obtain its name. - - `Literal <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Literal.html>`__: a literal value; use ``Literal.getValue()`` to obtain a string representation of its value, and ``Literal.getRawValue()`` to obtain its raw source text (including surrounding quotes for string literals). - - - `NullLiteral <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$NullLiteral.html>`__, `BooleanLiteral <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$BooleanLiteral.html>`__, `NumberLiteral <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$NumberLiteral.html>`__, `StringLiteral <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$StringLiteral.html>`__, `RegExpLiteral <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$RegExpLiteral.html>`__: different kinds of literals. - - - `ThisExpr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$ThisExpr.html>`__: a "this" expression. - - `SuperExpr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Classes.qll/type.Classes$SuperExpr.html>`__: a "super" expression. - - `ArrayExpr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$ArrayExpr.html>`__: an array expression; use ``ArrayExpr.getElement(i)`` to obtain the ``i``\ th element expression, and ``ArrayExpr.elementIsOmitted(i)`` to check whether the ``i``\ th element is omitted. - - `ObjectExpr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$ObjectExpr.html>`__: an object expression; use ``ObjectExpr.getProperty(i)`` to obtain the ``i``\ th property in the object expression; properties are modeled by class `Property <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Property.html>`__, which is described in more detail below. - - `FunctionExpr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$FunctionExpr.html>`__: a function expression; see below for available member predicates. - - `ArrowFunctionExpr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$ArrowFunctionExpr.html>`__: an ECMAScript 2015-style arrow function expression; see below for available member predicates. - - `ClassExpr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Classes.qll/type.Classes$ClassExpr.html>`__: a class expression; see below for available member predicates. - - `ParExpr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$ParExpr.html>`__: a parenthesized expression; use ``ParExpr.getExpression()`` to obtain the operand expression; for any expression, ``Expr.stripParens()`` can be used to recursively strip off any parentheses - - `SeqExpr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$SeqExpr.html>`__: a sequence of two or more expressions connected by the comma operator; use ``SeqExpr.getOperand(i)`` to obtain the ``i``\ th sub-expression. - - `ConditionalExpr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$ConditionalExpr.html>`__: a ternary conditional expression; member predicates ``ConditionalExpr.getCondition()``, ``ConditionalExpr.getConsequent()`` and ``ConditionalExpr.getAlternate()`` provide access to the condition expression, the "then" expression and the "else" expression, respectively. - - `InvokeExpr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$InvokeExpr.html>`__: a function call or a "new" expression; use ``InvokeExpr.getCallee()`` to obtain the expression specifying the function to be called, and ``InvokeExpr.getArgument(i)`` to obtain the ``i``\ th argument expression. - - - `CallExpr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$CallExpr.html>`__: a function call. - - `NewExpr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$NewExpr.html>`__: a "new" expression. - - `MethodCallExpr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$MethodCallExpr.html>`__: a function call whose callee expression is a property access; use ``MethodCallExpr.getReceiver`` to access the receiver expression of the method call, and ``MethodCallExpr.getMethodName()`` to get the method name (if it can be determined statically). - - - `PropAccess <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$PropAccess.html>`__: a property access, that is, either a "dot" expression of the form ``e.f`` or an index expression of the form ``e[p]``; use ``PropAccess.getBase()`` to obtain the base expression on which the property is accessed (``e`` in the example), and ``PropAccess.getPropertyName()`` to determine the name of the accessed property; if the name cannot be statically determined, ``getPropertyName()`` does not return any value. - - - `DotExpr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$DotExpr.html>`__: a "dot" expression. - - `IndexExpr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$IndexExpr.html>`__: an index expression (also known as computed property access). - - - `UnaryExpr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$UnaryExpr.html>`__: a unary expression; use ``UnaryExpr.getOperand()`` to obtain the operand expression. - - - `NegExpr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$NegExpr.html>`__ ("-"), `PlusExpr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$PlusExpr.html>`__ ("+"), `LogNotExpr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$LogNotExpr.html>`__ ("!"), `BitNotExpr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$BitNotExpr.html>`__ ("~"), `TypeofExpr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$TypeofExpr.html>`__, `VoidExpr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$VoidExpr.html>`__, `DeleteExpr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$DeleteExpr.html>`__, `SpreadElement <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$SpreadElement.html>`__ ("..."): various types of unary expressions. - - - `BinaryExpr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$BinaryExpr.html>`__: a binary expression; use ``BinaryExpr.getLeftOperand()`` and ``BinaryExpr.getRightOperand()`` to access the operand expressions. - - - `Comparison <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Comparison.html>`__: any comparison expression. - - - `EqualityTest <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$EqualityTest.html>`__: any equality or inequality test. - - - `EqExpr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$EqExpr.html>`__ ("=="), `NEqExpr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$NEqExpr.html>`__ ("!="): non-strict equality and inequality tests. - - `StrictEqExpr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$StrictEqExpr.html>`__ ("==="), `StrictNEqExpr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$StrictNEqExpr.html>`__ ("!=="): strict equality and inequality tests. - - - `LTExpr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$LTExpr.html>`__ ("<"), `LEExpr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$LEExpr.html>`__ ("<="), `GTExpr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$GTExpr.html>`__ (">"), `GEExpr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$GEExpr.html>`__ (">="): numeric comparisons. - - - `LShiftExpr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$LShiftExpr.html>`__ ("<<"), `RShiftExpr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$RShiftExpr.html>`__ (">>"), `URShiftExpr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$URShiftExpr.html>`__ (">>>"): shift operators. - - `AddExpr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$AddExpr.html>`__ ("+"), `SubExpr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$SubExpr.html>`__ ("-"), `MulExpr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$MulExpr.html>`__ ("*"), `DivExpr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$DivExpr.html>`__ ("/"), `ModExpr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$ModExpr.html>`__ ("%"), `ExpExpr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$ExpExpr.html>`__ ("**"): arithmetic operators. - - `BitOrExpr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$BitOrExpr.html>`__ ("|"), `XOrExpr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$XOrExpr.html>`__ ("^"), `BitAndExpr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$BitAndExpr.html>`__ ("&"): bitwise operators. - - `InExpr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$InExpr.html>`__: an ``in`` test. - - `InstanceofExpr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$InstanceofExpr.html>`__: an ``instanceof`` test. - - `LogAndExpr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$LogAndExpr.html>`__ ("&&"), `LogOrExpr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$LogOrExpr.html>`__ ("||"): short-circuiting logical operators. - - - `Assignment <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Assignment.html>`__: assignment expressions, either simple or compound; use ``Assignment.getLhs()`` and ``Assignment.getRhs()`` to access the left- and right-hand side, respectively. - - - `AssignExpr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$AssignExpr.html>`__: a simple assignment expression. - - `CompoundAssignExpr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$CompoundAssignExpr.html>`__: a compound assignment expression. - - - `AssignAddExpr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$AssignAddExpr.html>`__, `AssignSubExpr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$AssignSubExpr.html>`__, `AssignMulExpr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$AssignMulExpr.html>`__, `AssignDivExpr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$AssignDivExpr.html>`__, `AssignModExpr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$AssignModExpr.html>`__, `AssignLShiftExpr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$AssignLShiftExpr.html>`__, `AssignRShiftExpr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$AssignRShiftExpr.html>`__, - `AssignURShiftExpr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$AssignURShiftExpr.html>`__, `AssignOrExpr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$AssignOrExpr.html>`__, `AssignXOrExpr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$AssignXOrExpr.html>`__, `AssignAndExpr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$AssignAndExpr.html>`__, `AssignExpExpr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$AssignExpExpr.html>`__: different kinds of compound assignment expressions. - - - `UpdateExpr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$UpdateExpr.html>`__: an increment or decrement expression; use ``UpdateExpr.getOperand()`` to obtain the operand expression. - - - `PreIncExpr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$PreIncExpr.html>`__, `PostIncExpr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$PostIncExpr.html>`__: an increment expression. - - `PreDecExpr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$PreDecExpr.html>`__, `PostDecExpr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$PostDecExpr.html>`__: a decrement expression. - - - `YieldExpr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$YieldExpr.html>`__: a "yield" expression; use ``YieldExpr.getOperand()`` to access the (optional) operand expression; use ``YieldExpr.isDelegating()`` to check whether this is a delegating ``yield*``. - - `TemplateLiteral <https://help.semmle.com/qldoc/javascript/semmle/javascript/Templates.qll/type.Templates$TemplateLiteral.html>`__: an ECMAScript 2015 template literal; ``TemplateLiteral.getElement(i)`` returns the ``i``\ th element of the template, which may either be an interpolated expression or a constant template element. - - `TaggedTemplateExpr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Templates.qll/type.Templates$TaggedTemplateExpr.html>`__: an ECMAScript 2015 tagged template literal; use ``TaggedTemplateExpr.getTag()`` to access the tagging expression, and ``TaggedTemplateExpr.getTemplate()`` to access the template literal being tagged. - - `TemplateElement <https://help.semmle.com/qldoc/javascript/semmle/javascript/Templates.qll/type.Templates$TemplateElement.html>`__: a constant template element; as for literals, use ``TemplateElement.getValue()`` to obtain the value of the element, and ``TemplateElement.getRawValue()`` for its raw value - - `AwaitExpr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$AwaitExpr.html>`__: an "await" expression; use ``AwaitExpr.getOperand()`` to access the operand expression. - -`Stmt <https://help.semmle.com/qldoc/javascript/semmle/javascript/Stmt.qll/type.Stmt$Stmt.html>`__ and `Expr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Expr.html>`__ share a common superclass `ExprOrStmt <https://help.semmle.com/qldoc/javascript/semmle/javascript/AST.qll/type.AST$ExprOrStmt.html>`__ which is useful for queries that should operate either on statements or on expressions, but not on any other AST nodes. - -As an example of how to use expression AST nodes, here is a query that finds expressions of the form ``e + f >> g``; such expressions should be rewritten as ``(e + f) >> g`` to clarify operator precedence: - -.. code-block:: ql - - import javascript - - from ShiftExpr shift, AddExpr add - where add = shift.getAnOperand() - select add, "This expression should be bracketed to clarify precedence rules." - -➤ `See this in the query console on LGTM.com <https://lgtm.com/query/690010024/>`__. When we ran this query on the *meteor/meteor* project in LGTM.com, we found many results where precedence could be clarified using brackets. - -Functions -^^^^^^^^^ - -JavaScript provides several ways of defining functions: in ECMAScript 5, there are function declaration statements and function expressions, and ECMAScript 2015 adds arrow function expressions. These different syntactic forms are represented by the classes `FunctionDeclStmt <https://help.semmle.com/qldoc/javascript/semmle/javascript/Stmt.qll/type.Stmt$FunctionDeclStmt.html>`__ (a subclass of `Stmt <https://help.semmle.com/qldoc/javascript/semmle/javascript/Stmt.qll/type.Stmt$Stmt.html>`__), `FunctionExpr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$FunctionExpr.html>`__ (a subclass of `Expr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Expr.html>`__) and `ArrowFunctionExpr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$ArrowFunctionExpr.html>`__ (also a subclass of -`Expr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Expr.html>`__), respectively. All three are subclasses of `Function <https://help.semmle.com/qldoc/javascript/semmle/javascript/Functions.qll/type.Functions$Function.html>`__, which provides common member predicates for accessing function parameters or the function body: - -- ``Function.getId()`` returns the `Identifier <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Identifier.html>`__ naming the function, which may not be defined for function expressions. -- ``Function.getParameter(i)`` and ``Function.getAParameter()`` access the ``i``\ th parameter or any parameter, respectively; parameters are modeled by the class `Parameter <https://help.semmle.com/qldoc/javascript/semmle/javascript/Variables.qll/type.Variables$Parameter.html>`__, which is a subclass of `BindingPattern <https://help.semmle.com/qldoc/javascript/semmle/javascript/Variables.qll/type.Variables$BindingPattern.html>`__ (see below). -- ``Function.getBody()`` returns the body of the function, which is usually a `Stmt <https://help.semmle.com/qldoc/javascript/semmle/javascript/Stmt.qll/type.Stmt$Stmt.html>`__, but may be an `Expr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Expr.html>`__ for arrow function expressions and legacy `expression closures <https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Expression_closures>`__. - -As an example, here is a query that finds all expression closures: - -.. code-block:: ql - - import javascript - - from FunctionExpr fe - where fe.getBody() instanceof Expr - select fe, "Use arrow expressions instead of expression closures." - -➤ `See this in the query console on LGTM.com <https://lgtm.com/query/668510056/>`__. None of the LGTM.com demo projects uses expression closures, but you may find this query gets results on other projects. - -As another example, this query finds functions that have two parameters that bind the same variable: - -.. code-block:: ql - - import javascript - - from Function fun, Parameter p, Parameter q, int i, int j - where p = fun.getParameter(i) and - q = fun.getParameter(j) and - i < j and - p.getAVariable() = q.getAVariable() - select fun, "This function has two parameters that bind the same variable." - -➤ `See this in the query console on LGTM.com <https://lgtm.com/query/673860037/>`__. None of the LGTM.com demo projects has functions where two parameters bind the same variable. - -Classes -^^^^^^^ - -Classes can be defined either by class declaration statements, represented by the CodeQL class `ClassDeclStmt <https://help.semmle.com/qldoc/javascript/semmle/javascript/Classes.qll/type.Classes$ClassDeclStmt.html>`__ (which is a subclass of `Stmt <https://help.semmle.com/qldoc/javascript/semmle/javascript/Stmt.qll/type.Stmt$Stmt.html>`__), or by class expressions, represented by the CodeQL class `ClassExpr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Classes.qll/type.Classes$ClassExpr.html>`__ (which is a subclass of `Expr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Expr.html>`__). Both of these classes are also subclasses of `ClassDefinition <https://help.semmle.com/qldoc/javascript/semmle/javascript/Classes.qll/type.Classes$ClassDefinition.html>`__, which provides common member predicates for accessing the name of a class, its superclass, and its body: - -- ``ClassDefinition.getIdentifier()`` returns the `Identifier <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Identifier.html>`__ naming the function, which may not be defined for class expressions. -- ``ClassDefinition.getSuperClass()`` returns the `Expr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Expr.html>`__ specifying the superclass, which may not be defined. -- ``ClassDefinition.getMember(n)`` returns the definition of member ``n`` of this class. -- ``ClassDefinition.getMethod(n)`` restricts ``ClassDefinition.getMember(n)`` to methods (as opposed to fields). -- ``ClassDefinition.getField(n)`` restricts ``ClassDefinition.getMember(n)`` to fields (as opposed to methods). -- ``ClassDefinition.getConstructor()`` gets the constructor of this class, possibly a synthetic default constructor. - -Note that class fields are not a standard language feature yet, so details of their representation may change. - -Method definitions are represented by the class `MethodDefinition <https://help.semmle.com/qldoc/javascript/semmle/javascript/Classes.qll/type.Classes$MethodDefinition.html>`__, which (like its counterpart `FieldDefinition <https://help.semmle.com/qldoc/javascript/semmle/javascript/Classes.qll/type.Classes$FieldDefinition.html>`__ for fields) is a subclass of `MemberDefinition <https://help.semmle.com/qldoc/javascript/semmle/javascript/Classes.qll/type.Classes$MemberDefinition.html>`__. That class provides the following important member predicates: - -- ``MemberDefinition.isStatic()``: holds if this is a static member. -- ``MemberDefinition.isComputed()``: holds if the name of this member is computed at runtime. -- ``MemberDefinition.getName()``: gets the name of this member if it can be determined statically. -- ``MemberDefinition.getInit()``: gets the initializer of this field; for methods, the initializer is a function expressions, for fields it may be an arbitrary expression, and may be undefined. - -There are three classes for modeling special methods: `ConstructorDefinition <https://help.semmle.com/qldoc/javascript/semmle/javascript/Classes.qll/type.Classes$ConstructorDefinition.html>`__ models constructors, while `GetterMethodDefinition <https://help.semmle.com/qldoc/javascript/semmle/javascript/Classes.qll/type.Classes$GetterMethodDefinition.html>`__ and `SetterMethodDefinition <https://help.semmle.com/qldoc/javascript/semmle/javascript/Classes.qll/type.Classes$SetterMethodDefinition.html>`__ model getter and setter methods, respectively. - -Declarations and binding patterns -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -Variables are declared by declaration statements (class `DeclStmt <https://help.semmle.com/qldoc/javascript/semmle/javascript/Stmt.qll/type.Stmt$DeclStmt.html>`__), which come in three flavors: ``var`` statements (represented by class `VarDeclStmt <https://help.semmle.com/qldoc/javascript/semmle/javascript/Stmt.qll/type.Stmt$VarDeclStmt.html>`__), ``const`` statements (represented by class `ConstDeclStmt <https://help.semmle.com/qldoc/javascript/semmle/javascript/Stmt.qll/type.Stmt$ConstDeclStmt.html>`__), and ``let`` statements (represented by class `LetStmt <https://help.semmle.com/qldoc/javascript/semmle/javascript/Stmt.qll/type.Stmt$LetStmt.html>`__). Every declaration statement has one or more declarators, represented by class `VariableDeclarator <https://help.semmle.com/qldoc/javascript/semmle/javascript/Variables.qll/type.Variables$VariableDeclarator.html>`__. - -Each declarator consists of a binding pattern, returned by predicate ``VariableDeclarator.getBindingPattern()``, and an optional initializing expression, returned by ``VariableDeclarator.getInit()``. - -Often, the binding pattern is a simple identifier, as in ``var x = 42``. In ECMAScript 2015 and later, however, it can also be a more complex destructuring pattern, as in ``var [x, y] = arr``. - -The various kinds of binding patterns are represented by class `BindingPattern <https://help.semmle.com/qldoc/javascript/semmle/javascript/Variables.qll/type.Variables$BindingPattern.html>`__ and its subclasses: - -- `VarRef <https://help.semmle.com/qldoc/javascript/semmle/javascript/Variables.qll/type.Variables$VarRef.html>`__: a simple identifier in an l-value position, for example the ``x`` in ``var x`` or in ``x = 42`` -- `Parameter <https://help.semmle.com/qldoc/javascript/semmle/javascript/Variables.qll/type.Variables$Parameter.html>`__: a function or catch clause parameter -- `ArrayPattern <https://help.semmle.com/qldoc/javascript/semmle/javascript/Variables.qll/type.Variables$ArrayPattern.html>`__: an array pattern, for example, the left-hand side of ``[x, y] = arr`` -- `ObjectPattern <https://help.semmle.com/qldoc/javascript/semmle/javascript/Variables.qll/type.Variables$ObjectPattern.html>`__: an object pattern, for example, the left-hand side of ``{x, y: z} = o`` - -Here is an example of a query to find declaration statements that declare the same variable more than once, excluding results in minified code: - -.. code-block:: ql - - import javascript - - from DeclStmt ds, VariableDeclarator d1, VariableDeclarator d2, Variable v, int i, int j - where d1 = ds.getDecl(i) and - d2 = ds.getDecl(j) and - i < j and - v = d1.getBindingPattern().getAVariable() and - v = d2.getBindingPattern().getAVariable() and - not ds.getTopLevel().isMinified() - select ds, "Variable " + v.getName() + " is declared both $@ and $@.", d1, "here", d2, "here" - -➤ `See this in the query console on LGTM.com <https://lgtm.com/query/668700496/>`__. This is not a common problem, so you may not find any results in your own projects. The *angular/angular.js* project on LGTM.com has one instance of this problem at the time of writing. - - Notice the use of ``not ... isMinified()`` here and in the next few queries. This excludes any results found in minified code. If you delete ``and not ds.getTopLevel().isMinified()`` and re-run the query, two results in minified code in the *meteor/meteor* project are reported. - -Properties -^^^^^^^^^^ - -Properties in object literals are represented by class `Property <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Property.html>`__, which is also a subclass of `ASTNode <https://help.semmle.com/qldoc/javascript/semmle/javascript/AST.qll/type.AST$ASTNode.html>`__, but neither of `Expr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Expr.html>`__ nor of `Stmt <https://help.semmle.com/qldoc/javascript/semmle/javascript/Stmt.qll/type.Stmt$Stmt.html>`__. - -Class `Property <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Property.html>`__ has two subclasses `ValueProperty <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$ValueProperty.html>`__ and `PropertyAccessor <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$PropertyAccessor.html>`__, which represent, respectively, normal value properties and getter/setter properties. Class `PropertyAccessor <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$PropertyAccessor.html>`__, in turn, has two subclasses `PropertyGetter <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$PropertyGetter.html>`__ and `PropertySetter <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$PropertySetter.html>`__ representing getters and setters, respectively. - -The predicates ``Property.getName()`` and ``Property.getInit()`` provide access to the defined property's name and its initial value. For `PropertyAccessor <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$PropertyAccessor.html>`__ and its subclasses, ``getInit()`` is overloaded to return the getter/setter function. - -As an example of a query involving properties, consider the following query that flags object expressions containing two identically named properties, excluding results in minified code: - -.. code-block:: ql - - import javascript - - from ObjectExpr oe, Property p1, Property p2, int i, int j - where p1 = oe.getProperty(i) and - p2 = oe.getProperty(j) and - i < j and - p1.getName() = p2.getName() and - not oe.getTopLevel().isMinified() - select oe, "Property " + p1.getName() + " is defined both $@ and $@.", p1, "here", p2, "here" - -➤ `See this in the query console on LGTM.com <https://lgtm.com/query/660700064/>`__. Many projects have a few instances of object expressions with two identically named properties. - -Modules -^^^^^^^ - -The JavaScript library has support for working with ECMAScript 2015 modules, as well as legacy CommonJS modules (still commonly employed by Node.js code bases) and AMD-style modules. The classes `ES2015Module <https://help.semmle.com/qldoc/javascript/semmle/javascript/ES2015Modules.qll/type.ES2015Modules$ES2015Module.html>`__, `NodeModule <https://help.semmle.com/qldoc/javascript/semmle/javascript/NodeJS.qll/type.NodeJS$NodeModule.html>`__, and `AMDModule <https://help.semmle.com/qldoc/javascript/semmle/javascript/AMD.qll/type.AMD$AmdModule.html>`__ represent these three types of modules, and all three extend the common superclass `Module <https://help.semmle.com/qldoc/javascript/semmle/javascript/Modules.qll/type.Modules$Module.html>`__. - -The most important member predicates defined by `Module <https://help.semmle.com/qldoc/javascript/semmle/javascript/Modules.qll/type.Modules$Module.html>`__ are: - -- ``Module.getName()``: gets the name of the module, which is just the stem (that is, the basename without extension) of the enclosing file. -- ``Module.getAnImportedModule()``: gets another module that is imported (through ``import`` or ``require``) by this module. -- ``Module.getAnExportedSymbol()``: gets the name of a symbol that this module exports. - -Moreover, there is a class `Import <https://help.semmle.com/qldoc/javascript/semmle/javascript/Modules.qll/type.Modules$Import.html>`__ that models both ECMAScript 2015-style ``import`` declarations and CommonJS/AMD-style ``require`` calls; its member predicate ``Import.getImportedModule`` provides access to the module the import refers to, if it can be determined statically. - -Name binding -~~~~~~~~~~~~ - -Name binding is modeled in the JavaScript libraries using four concepts: *scopes*, *variables*, *variable declarations*, and *variable accesses*, represented by the classes `Scope <https://help.semmle.com/qldoc/javascript/semmle/javascript/Variables.qll/type.Variables$Scope.html>`__, `Variable <https://help.semmle.com/qldoc/javascript/semmle/javascript/Variables.qll/type.Variables$Variable.html>`__, `VarDecl <https://help.semmle.com/qldoc/javascript/semmle/javascript/Variables.qll/type.Variables$VarDecl.html>`__ and `VarAccess <https://help.semmle.com/qldoc/javascript/semmle/javascript/Variables.qll/type.Variables$VarAccess.html>`__, respectively. - -Scopes -^^^^^^ - -In ECMAScript 5, there are three kinds of scopes: the global scope (one per program), function scopes (one per function), and catch clause scopes (one per ``catch`` clause). These three kinds of scopes are represented by the classes `GlobalScope <https://help.semmle.com/qldoc/javascript/semmle/javascript/Variables.qll/type.Variables$GlobalScope.html>`__, `FunctionScope <https://help.semmle.com/qldoc/javascript/semmle/javascript/Variables.qll/type.Variables$FunctionScope.html>`__ and `CatchScope <https://help.semmle.com/qldoc/javascript/semmle/javascript/Variables.qll/type.Variables$CatchScope.html>`__. ECMAScript 2015 adds block scopes for ``let``-bound variables, which are also represented by class `Scope <https://help.semmle.com/qldoc/javascript/semmle/javascript/Variables.qll/type.Variables$Scope.html>`__, class expression scopes (`ClassExprScope <https://help.semmle.com/qldoc/javascript/semmle/javascript/Classes.qll/type.Classes$ClassExprScope.html>`__), -and module scopes (`ModuleScope <https://help.semmle.com/qldoc/javascript/semmle/javascript/Variables.qll/type.Variables$ModuleScope.html>`__). - -Class `Scope <https://help.semmle.com/qldoc/javascript/semmle/javascript/Variables.qll/type.Variables$Scope.html>`__ provides the following API: - -- ``Scope.getScopeElement()`` returns the AST node inducing this scope; undefined for `GlobalScope <https://help.semmle.com/qldoc/javascript/semmle/javascript/Variables.qll/type.Variables$GlobalScope.html>`__. -- ``Scope.getOuterScope()`` returns the lexically enclosing scope of this scope. -- ``Scope.getAnInnerScope()`` returns a scope lexically nested inside this scope. -- ``Scope.getVariable(name)``, ``Scope.getAVariable()`` return a variable declared (implicitly or explicitly) in this scope. - -Variables -^^^^^^^^^ - -The `Variable <https://help.semmle.com/qldoc/javascript/semmle/javascript/Variables.qll/type.Variables$Variable.html>`__ class models all variables in a JavaScript program, including global variables, local variables, and parameters (both of functions and ``catch`` clauses), whether explicitly declared or not. - -It is important not to confuse variables and their declarations: local variables may have more than one declaration, while global variables and the implicitly declared local ``arguments`` variable need not have a declaration at all. - -Variable declarations and accesses -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -Variables may be declared by variable declarators, by function declaration statements and expressions, by class declaration statements or expressions, or by parameters of functions and ``catch`` clauses. While these declarations differ in their syntactic form, in each case there is an identifier naming the declared variable. We consider that identifier to be the declaration proper, and assign it the class `VarDecl <https://help.semmle.com/qldoc/javascript/semmle/javascript/Variables.qll/type.Variables$VarDecl.html>`__. Identifiers that reference a variable, on the other hand, are given the class `VarAccess <https://help.semmle.com/qldoc/javascript/semmle/javascript/Variables.qll/type.Variables$VarAccess.html>`__. - -The most important predicates involving variables, their declarations, and their accesses are as follows: - -- ``Variable.getName()``, ``VarDecl.getName()``, ``VarAccess.getName()`` return the name of the variable. -- ``Variable.getScope()`` returns the scope to which the variable belongs. -- ``Variable.isGlobal()``, ``Variable.isLocal()``, ``Variable.isParameter()`` determine whether the variable is a global variable, a local variable, or a parameter variable, respectively. -- ``Variable.getAnAccess()`` maps a `Variable <https://help.semmle.com/qldoc/javascript/semmle/javascript/Variables.qll/type.Variables$Variable.html>`__ to all `VarAccess <https://help.semmle.com/qldoc/javascript/semmle/javascript/Variables.qll/type.Variables$VarAccess.html>`__\ es that refer to it. -- ``Variable.getADeclaration()`` maps a `Variable <https://help.semmle.com/qldoc/javascript/semmle/javascript/Variables.qll/type.Variables$Variable.html>`__ to all `VarDecl <https://help.semmle.com/qldoc/javascript/semmle/javascript/Variables.qll/type.Variables$VarDecl.html>`__\ s that declare it (of which there may be none, one, or more than one). -- ``Variable.isCaptured()`` determines whether the variable is ever accessed in a scope that is lexically nested within the scope where it is declared. - -As an example, consider the following query which finds distinct function declarations that declare the same variable, that is, two conflicting function declarations within the same scope (again excluding minified code): - -.. code-block:: ql - - import javascript - - from FunctionDeclStmt f, FunctionDeclStmt g - where f != g and f.getVariable() = g.getVariable() and - not f.getTopLevel().isMinified() and - not g.getTopLevel().isMinified() - select f, g - -➤ `See this in the query console on LGTM.com <https://lgtm.com/query/667290067/>`__. Some projects declare conflicting functions of the same name and rely on platform-specific behavior to disambiguate the two declarations. - -Control flow -~~~~~~~~~~~~ - -A different program representation in terms of intraprocedural control flow graphs (CFGs) is provided by the classes in library `CFG.qll <https://help.semmle.com/qldoc/javascript/semmle/javascript/CFG.qll/module.CFG.html>`__. - -Class `ControlFlowNode <https://help.semmle.com/qldoc/javascript/semmle/javascript/CFG.qll/type.CFG$ControlFlowNode.html>`__ represents a single node in the control flow graph, which is either an expression, a statement, or a synthetic control flow node. Note that `Expr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Expr.html>`__ and `Stmt <https://help.semmle.com/qldoc/javascript/semmle/javascript/Stmt.qll/type.Stmt$Stmt.html>`__ do not inherit from `ControlFlowNode <https://help.semmle.com/qldoc/javascript/semmle/javascript/CFG.qll/type.CFG$ControlFlowNode.html>`__ at the CodeQL level, although their entity types are compatible, so you can explicitly cast from one to the other if you need to map between the AST-based and the CFG-based program representations. - -There are two kinds of synthetic control flow nodes: entry nodes (class `ControlFlowEntryNode <https://help.semmle.com/qldoc/javascript/semmle/javascript/CFG.qll/type.CFG$ControlFlowEntryNode.html>`__), which represent the beginning of a top-level or function, and exit nodes (class `ControlFlowExitNode <https://help.semmle.com/qldoc/javascript/semmle/javascript/CFG.qll/type.CFG$ControlFlowExitNode.html>`__), which represent their end. They do not correspond to any AST nodes, but simply serve as the unique entry point and exit point of a control flow graph. Entry and exit nodes can be accessed through the predicates ``StmtContainer.getEntry()`` and ``StmtContainer.getExit()``. - -Most, but not all, top-levels and functions have another distinguished CFG node, the *start node*. This is the CFG node at which execution begins. Unlike the entry node, which is a synthetic construct, the start node corresponds to an actual program element: for top-levels, it is the first CFG node of the first statement; for functions, it is the CFG node corresponding to their first parameter or, if there are no parameters, the first CFG node of the body. Empty top-levels do not have a start node. - -For most purposes, using start nodes is preferable to using entry nodes. - -The structure of the control flow graph is reflected in the member predicates of `ControlFlowNode <https://help.semmle.com/qldoc/javascript/semmle/javascript/CFG.qll/type.CFG$ControlFlowNode.html>`__: - -- ``ControlFlowNode.getASuccessor()`` returns a `ControlFlowNode <https://help.semmle.com/qldoc/javascript/semmle/javascript/CFG.qll/type.CFG$ControlFlowNode.html>`__ that is a successor of this `ControlFlowNode <https://help.semmle.com/qldoc/javascript/semmle/javascript/CFG.qll/type.CFG$ControlFlowNode.html>`__ in the control flow graph. -- ``ControlFlowNode.getAPredecessor()`` is the inverse of ``getASuccessor()``. -- ``ControlFlowNode.isBranch()`` determines whether this node has more than one successor. -- ``ControlFlowNode.isJoin()`` determines whether this node has more than one predecessor. -- ``ControlFlowNode.isStart()`` determines whether this node is a start node. - -Many control-flow-based analyses are phrased in terms of `basic blocks <http://en.wikipedia.org/wiki/Basic_block>`__ rather than single control flow nodes, where a basic block is a maximal sequence of control flow nodes without branches or joins. The class `BasicBlock <https://help.semmle.com/qldoc/javascript/semmle/javascript/BasicBlocks.qll/type.BasicBlocks$BasicBlock.html>`__ from `BasicBlocks.qll <https://help.semmle.com/qldoc/javascript/semmle/javascript/BasicBlocks.qll/module.BasicBlocks.html>`__ represents all such basic blocks. Similar to `ControlFlowNode <https://help.semmle.com/qldoc/javascript/semmle/javascript/CFG.qll/type.CFG$ControlFlowNode.html>`__, it provides member predicates ``getASuccessor()`` and ``getAPredecessor()`` to navigate the control flow graph at the level of basic blocks, and member predicates ``getANode()``, ``getNode(int)``, ``getFirstNode()`` and ``getLastNode()`` to access individual control flow nodes within a basic block. The predicate -``Function.getEntryBB()`` returns the entry basic block in a function, that is, the basic block containing the function's entry node. Similarly, ``Function.getStartBB()`` provides access to the start basic block, which contains the function's start node. As for CFG nodes, ``getStartBB()`` should normally be preferred over ``getEntryBB()``. - -As an example of an analysis using basic blocks, ``BasicBlock.isLiveAtEntry(v, u)`` determines whether variable ``v`` is `live <http://en.wikipedia.org/wiki/Live_variable_analysis>`__ at the entry of the given basic block, and if so binds ``u`` to a use of ``v`` that refers to its value at the entry. We can use it to find global variables that are used in a function where they are not live (that is, every read of the variable is preceded by a write), suggesting that the variable was meant to be declared as a local variable instead: - -.. code-block:: ql - - import javascript - - from Function f, GlobalVariable gv - where gv.getAnAccess().getEnclosingFunction() = f and - not f.getStartBB().isLiveAtEntry(gv, _) - select f, "This function uses " + gv + " like a local variable." - -➤ `See this in the query console on LGTM.com <https://lgtm.com/query/686320048/>`__. Many projects have some variables which look as if they were intended to be local. - -Data flow -~~~~~~~~~ - -Definitions and uses -^^^^^^^^^^^^^^^^^^^^ - -Library `DefUse.qll <https://help.semmle.com/qldoc/javascript/semmle/javascript/DefUse.qll/module.DefUse.html>`__ provides classes and predicates to determine `def-use <http://en.wikipedia.org/wiki/Use-define_chain>`__ relationships between definitions and uses of variables. - -Classes `VarDef <https://help.semmle.com/qldoc/javascript/semmle/javascript/DefUse.qll/type.DefUse$VarDef.html>`__ and `VarUse <https://help.semmle.com/qldoc/javascript/semmle/javascript/DefUse.qll/type.DefUse$VarUse.html>`__ contain all expressions that define and use a variable, respectively. For the former, you can use predicate ``VarDef.getAVariable()`` to find out which variables are defined by a given variable definition (recall that destructuring assignments in ECMAScript 2015 define several variables at the same time). Similarly, predicate ``VarUse.getVariable()`` returns the (single) variable being accessed by a variable use. - -The def-use information itself is provided by predicate ``VarUse.getADef()``, that connects a use of a variable to a definition of the same variable, where the definition may reach the use. - -As an example, the following query finds definitions of local variables that are not used anywhere; that is, the variable is either not referenced at all after the definition, or its value is overwritten: - -.. code-block:: ql - - import javascript - - from VarDef def, LocalVariable v - where v = def.getAVariable() and - not exists (VarUse use | def = use.getADef()) - select def, "Dead store of local variable." - -➤ `See this in the query console on LGTM.com <https://lgtm.com/query/2086440429/>`__. Many projects have some examples of useless assignments to local variables. - -SSA -^^^ - -A more fine-grained representation of a program's data flow based on `Static Simple Assignment Form (SSA) <https://en.wikipedia.org/wiki/Static_single_assignment_form>`__ is provided by the library ``semmle.javascript.SSA``. - -In SSA form, each use of a local variable has exactly one (SSA) definition that reaches it. SSA definitions are represented by class `SsaDefinition <https://help.semmle.com/qldoc/javascript/semmle/javascript/SSA.qll/type.SSA$SsaDefinition.html>`__. They are not AST nodes, since not every SSA definition corresponds to an explicit element in the source code. - -Altogether, there are five kinds of SSA definitions: - -#. Explicit definitions (`SsaExplicitDefinition <https://help.semmle.com/qldoc/javascript/semmle/javascript/SSA.qll/type.SSA$SsaExplicitDefinition.html>`__): these simply wrap a `VarDef <https://help.semmle.com/qldoc/javascript/semmle/javascript/DefUse.qll/type.DefUse$VarDef.html>`__, that is, a definition like ``x = 1`` appearing explicitly in the source code. -#. Implicit initializations (`SsaImplicitInit <https://help.semmle.com/qldoc/javascript/semmle/javascript/SSA.qll/type.SSA$SsaImplicitInit.html>`__): these represent the implicit initialization of local variables with ``undefined`` at the beginning of their scope. -#. Phi nodes (`SsaPhiNode <https://help.semmle.com/qldoc/javascript/semmle/javascript/SSA.qll/type.SSA$SsaPhiNode.html>`__): these are pseudo-definitions that merge two or more SSA definitions where necessary; see the Wikipedia page linked to above for an explanation. -#. Variable captures (`SsaVariableCapture <https://help.semmle.com/qldoc/javascript/semmle/javascript/SSA.qll/type.SSA$SsaVariableCapture.html>`__): these are pseudo-definitions appearing at places in the code where the value of a captured variable may change without there being an explicit assignment, for example due to a function call. -#. Refinement nodes (`SsaRefinementNode <https://help.semmle.com/qldoc/javascript/semmle/javascript/SSA.qll/type.SSA$SsaRefinementNode.html>`__): these are pseudo-definitions appearing at places in the code where something becomes known about a variable; for example, a conditional ``if (x === null)`` induces a refinement node at the beginning of its "then" branch recording the fact that ``x`` is known to be ``null`` there. (In the literature, these are sometimes known as "pi nodes.") - -Data flow nodes -^^^^^^^^^^^^^^^ - -Moving beyond just variable definitions and uses, library ``semmle.javascript.dataflow.DataFlow`` provides a representation of the program as a data flow graph. Its nodes are values of class `DataFlow::Node <https://help.semmle.com/qldoc/javascript/semmle/javascript/dataflow/DataFlow.qll/type.DataFlow$DataFlow$Node.html>`__, which has two subclasses ``ValueNode`` and ``SsaDefinitionNode``. Nodes of the former kind wrap an expression or a statement that is considered to produce a value (specifically, a function or class declaration statement, or a TypeScript namespace or enum declaration). Nodes of the latter kind wrap SSA definitions. - -You can use the predicate ``DataFlow::valueNode`` to convert an expression, function or class into its corresponding ``ValueNode``, and similarly ``DataFlow::ssaDefinitionNode`` to map an SSA definition to its corresponding ``SsaDefinitionNode``. - -There is also an auxiliary predicate ``DataFlow::parameterNode`` that maps a parameter to its corresponding data flow node. (This is really just a convenience wrapper around ``DataFlow::ssaDefinitionNode``, since parameters are also considered to be SSA definitions.) - -Going in the other direction, there is a predicate ``ValueNode.getAstNode()`` for mapping from ``ValueNode``\ s to ``ASTNode``\ s, and ``SsaDefinitionNode.getSsaVariable()`` for mapping from ``SsaDefinitionNode``\ s to ``SsaVariable``\ s. There is also a utility predicate ``Node.asExpr()`` that gets the underlying expression for a ``ValueNode``, and is undefined for all nodes that do not correspond to an expression. (Note in particular that this predicate is not defined for ``ValueNode``\ s wrapping function or class declaration statements!) - -You can use the predicate ``DataFlow::Node.getAPredecessor()`` to find other data flow nodes from which values may flow into this node, and ``getASuccessor`` for the other direction. - -For example, here is a query that finds all invocations of a method called ``send`` on a value that comes from a parameter named ``res``, indicating that it is perhaps sending an HTTP response: - -.. code-block:: ql - - import javascript - - from SimpleParameter res, DataFlow::Node resNode, MethodCallExpr send - where res.getName() = "res" and - resNode = DataFlow::parameterNode(res) and - resNode.getASuccessor+() = DataFlow::valueNode(send.getReceiver()) and - send.getMethodName() = "send" - select send - -➤ `See this in the query console on LGTM.com <https://lgtm.com/query/1506058347056/>`__. The query finds HTTP response sends in the `AMP HTML <https://lgtm.com/projects/g/ampproject/amphtml>`__ project. - -Note that the data flow modeling in this library is intraprocedural, that is, flow across function calls and returns is *not* modeled. Likewise, flow through object properties and global variables is not modeled. - -Type inference -~~~~~~~~~~~~~~ - -The library ``semmle.javascript.dataflow.TypeInference`` implements a simple type inference for JavaScript based on intraprocedural, heap-insensitive flow analysis. Basically, the inference algorithm approximates the possible concrete runtime values of variables and expressions as sets of abstract values (represented by the class `AbstractValue <https://help.semmle.com/qldoc/javascript/semmle/javascript/dataflow/AbstractValues.qll/type.AbstractValues$AbstractValue.html>`__), each of which stands for a set of concrete values. - -For example, there is an abstract value representing all non-zero numbers, and another representing all non-empty strings except for those that can be converted to a number. Both of these abstract values are fairly coarse approximations that represent very large sets of concrete values. - -Other abstract values are more precise, to the point where they represent single concrete values: for example, there is an abstract value representing the concrete ``null`` value, and another representing the number zero. - -There is a special group of abstract values called *indefinite* abstract values that represent all concrete values. The analysis uses these to handle expressions for which it cannot infer a more precise value, such as function parameters (as mentioned above, the analysis is intraprocedural and hence does not model argument passing) or property reads (the analysis does not model property values either). - -Each indefinite abstract value is associated with a string value describing the cause of imprecision. In the above examples, the indefinite value for the parameter would have cause ``"call"``, while the indefinite value for the property would have cause ``"heap"``. - -To check whether an abstract value is indefinite, you can use the ``isIndefinite`` member predicate. Its single argument describes the cause of imprecision. - -Each abstract value has one or more associated types (CodeQL class `InferredType <https://help.semmle.com/qldoc/javascript/semmle/javascript/dataflow/InferredTypes.qll/type.InferredTypes$InferredType.html>`__ corresponding roughly to the type tags computed by the ``typeof`` operator. The types are ``null``, ``undefined``, ``boolean``, ``number``, ``string``, ``function``, ``class``, ``date`` and ``object``. - -To access the results of the type inference, use class `DataFlow::AnalyzedNode <https://help.semmle.com/qldoc/javascript/semmle/javascript/dataflow/TypeInference.qll/type.TypeInference$AnalyzedNode.html>`__: any `DataFlow::Node <https://help.semmle.com/qldoc/javascript/semmle/javascript/dataflow/DataFlow.qll/type.DataFlow$DataFlow$Node.html>`__ can be cast to this class, and additionally there is a convenience predicate ``Expr::analyze`` that maps expressions directly to their corresponding ``AnalyzedNode``\ s. - -Once you have an ``AnalyzedNode``, you can use predicate ``AnalyzedNode.getAValue()`` to access the abstract values inferred for it, and ``getAType()`` to get the inferred types. - -For example, here is a query that looks for ``null`` checks on expressions that cannot, in fact, be null: - -.. code-block:: ql - - import javascript - - from StrictEqualityTest eq, DataFlow::AnalyzedNode nd, NullLiteral null - where eq.hasOperands(nd.asExpr(), null) and - not nd.getAValue().isIndefinite(_) and - not nd.getAValue() instanceof AbstractNull - select eq, "Spurious null check." - -To paraphrase, the query looks for equality tests ``eq`` where one operand is a ``null`` literal and the other some expression that we convert to an ``AnalyzedNode``. If the type inference results for that node are precise (that is, none of the inferred values is indefinite) and (the abstract representation of) ``null`` is not among them, we flag ``eq``. - -You can add custom type inference rules by defining new subclasses of ``DataFlow::AnalyzedNode`` and overriding ``getAValue``. You can also introduce new abstract values by extending the abstract class ``CustomAbstractValueTag``, which is a subclass of ``string``: each string belonging to that class induces a corresponding abstract value of type ``CustomAbstractValue``. You can use the predicate ``CustomAbstractValue.getTag()`` to map from the abstract value to its tag. By implementing the abstract predicates of class ``CustomAbstractValueTag`` you can define the semantics of your custom abstract values, such as what primitive value they coerce to and what type they have. - -Call graph -~~~~~~~~~~ - -The JavaScript library implements a simple `call graph <http://en.wikipedia.org/wiki/Call_graph>`__ construction algorithm to statically approximate the possible call targets of function calls and ``new`` expressions. Due to the dynamically typed nature of JavaScript and its support for higher-order functions and reflective language features, building static call graphs is quite difficult. Simple call graph algorithms tend to be incomplete, that is, they often fail to resolve all possible call targets. More sophisticated algorithms can suffer from the opposite problem of imprecision, that is, they may infer many spurious call targets. - -The call graph is represented by the member predicate ``getACallee()`` of class `DataFlow::InvokeNode <https://help.semmle.com/qldoc/javascript/semmle/javascript/dataflow/Nodes.qll/type.Nodes$InvokeNode.html>`__, which computes possible callees of the given invocation, that is, functions that may at runtime be invoked by this expression. - -Furthermore, there are three member predicates that indicate the quality of the callee information for this invocation: - -- ``DataFlow::InvokeNode.isImprecise()``: holds for invocations where the call graph builder might infer spurious call targets. -- ``DataFlow::InvokeNode.isIncomplete()``: holds for invocations where the call graph builder might fail to infer possible call targets. -- ``DataFlow::InvokeNode.isUncertain()``: holds if either ``isImprecise()`` or ``isUncertain()`` holds. - -As an example of a call-graph-based query, here is a query to find invocations for which the call graph builder could not find any callees, despite the analysis being complete for this invocation: - -.. code-block:: ql - - import javascript - - from DataFlow::InvokeNode invk - where not invk.isIncomplete() and - not exists(invk.getACallee()) - select invk, "Unable to find a callee for this invocation." - -➤ `See this in the query console on LGTM.com <https://lgtm.com/query/3260345690335671362/>`__ - -Inter-procedural data flow -~~~~~~~~~~~~~~~~~~~~~~~~~~ - -The data flow graph-based analyses described so far are all intraprocedural: they do not take flow from function arguments to parameters or from a ``return`` to the function's caller into account. The data flow library also provides a framework for constructing custom inter-procedural analyses. - -We distinguish here between data flow proper, and *taint tracking*: the latter not only considers value-preserving flow (such as from variable definitions to uses), but also cases where one value influences ("taints") another without determining it entirely. For example, in the assignment ``s2 = s1.substring(i)``, the value of ``s1`` influences the value of ``s2``, because ``s2`` is assigned a substring of ``s1``. In general, ``s2`` will not be assigned ``s1`` itself, so there is no data flow from ``s1`` to ``s2``, but ``s1`` still taints ``s2``. - -The simplest way of implementing an interprocedural data flow analysis is to extend either class ``DataFlow::TrackedNode`` or ``DataFlow::TrackedExpr``. The former is a subclass of ``DataFlow::Node``, the latter of ``Expr``, and extending them ensures that the newly added values are tracked interprocedurally. You can use the predicate ``flowsTo`` to find out which nodes/expressions the tracked value flows to. - -For example, suppose that we are developing an analysis to find hard-coded passwords. We might start by writing a simple query that looks for string constants flowing into variables named ``"password"``. To do this, we can extend ``TrackedExpr`` to track all constant strings, ``flowsTo`` to find cases where such a string flows into a (SSA) definition of a password variable: - -.. code-block:: ql - - import javascript - - class TrackedStringLiteral extends DataFlow::TrackedNode { - TrackedStringLiteral() { - this.asExpr() instanceof ConstantString - } - } - - from TrackedStringLiteral source, DataFlow::Node sink, SsaExplicitDefinition def - where source.flowsTo(sink) and sink = DataFlow::ssaDefinitionNode(def) and - def.getSourceVariable().getName().toLowerCase() = "password" - select sink - -Note that ``TrackedNode`` and ``TrackedExpr`` do not restrict the set of "sinks" for the inter-procedural flow analysis, tracking flow into any expression that they might flow to. This can be expensive for large code bases, and is often unnecessary, since usually you are only interested in flow to a particular set of sinks. For example, the above query only looks for flow into assignments to password variables. - -This is a particular instance of a general pattern, whereby we want to specify a data flow or taint analysis in terms of its *sources* (where flow starts), *sinks* (where it should be tracked), and *barriers* or *sanitizers* (where flow is interrupted). The example does not include any sanitizers, but they are very common in security analyses: for example, an analysis that tracks the flow of untrusted user input into, say, a SQL query has to keep track of code that validates the input, thereby making it safe to use. Such a validation step is an example of a sanitizer. - -The classes ``DataFlow::Configuration`` and ``TaintTracking::Configuration`` allow specifying a data flow or taint analysis, respectively, by overriding the following predicates: - -- ``isSource(DataFlow::Node nd)`` selects all nodes ``nd`` from where flow tracking starts. -- ``isSink(DataFlow::Node nd)`` selects all nodes ``nd`` to which the flow is tracked. -- ``isBarrier(DataFlow::Node nd)`` selects all nodes ``nd`` that act as a barrier for data flow; ``isSanitizer`` is the corresponding predicate for taint tracking configurations. -- ``isBarrierEdge(DataFlow::Node src, DataFlow::Node trg)`` is a variant of ``isBarrier(nd)`` that allows specifying barrier *edges* in addition to barrier nodes; again, ``isSanitizerEdge`` is the corresponding predicate for taint tracking; -- ``isAdditionalFlowStep(DataFlow::Node src, DataFlow::Node trg)`` allows specifying custom additional flow steps for this analysis; ``isAdditionalTaintStep`` is the corresponding predicate for taint tracking configurations. - -Since for technical reasons both ``Configuration`` classes are subtypes of ``string``, you have to choose a unique name for each flow configuration and equate ``this`` with it in the characteristic predicate (as in the example below). - -The predicate ``Configuration.hasFlow`` performs the actual flow tracking, starting at a source and looking for flow to a sink that does not pass through a barrier node or edge. - -To continue with our above example, we can phrase it as a data flow configuration as follows: - -.. code-block:: ql - - class PasswordTracker extends DataFlow::Configuration { - PasswordTracker() { - // unique identifier for this configuration - this = "PasswordTracker" - } - - override predicate isSource(DataFlow::Node nd) { - nd.asExpr() instanceof StringLiteral - } - - override predicate isSink(DataFlow::Node nd) { - passwordVarAssign(_, nd) - } - - predicate passwordVarAssign(Variable v, DataFlow::Node nd) { - exists (SsaExplicitDefinition def | - nd = DataFlow::ssaDefinitionNode(def) and - def.getSourceVariable() = v and - v.getName().toLowerCase() = "password" - ) - } - } - -Now we can rephrase our query to use ``Configuration.hasFlow``: - -.. code-block:: ql - - from PasswordTracker pt, DataFlow::Node source, DataFlow::Node sink, Variable v - where pt.hasFlow(source, sink) and pt.passwordVarAssign(v, sink) - select sink, "Password variable " + v + " is assigned a constant string." - -Note that while analyses implemented in this way are inter-procedural in that they track flow and taint across function calls and returns, flow through global variables is not tracked. Flow through object properties is only tracked in limited cases, for example through properties of object literals or CommonJS ``module`` and ``exports`` objects. - -Syntax errors -~~~~~~~~~~~~~ - -JavaScript code that contains syntax errors cannot usually be analyzed. For such code, the lexical and syntactic representations are not available, and hence no name binding information, call graph or control and data flow. All that is available in this case is a value of class `JSParseError <https://help.semmle.com/qldoc/javascript/semmle/javascript/Errors.qll/type.Errors$JSParseError.html>`__ representing the syntax error. It provides information about the syntax error location (`JSParseError <https://help.semmle.com/qldoc/javascript/semmle/javascript/Errors.qll/type.Errors$JSParseError.html>`__ is a subclass of `Locatable <https://help.semmle.com/qldoc/javascript/semmle/javascript/Locations.qll/type.Locations$Locatable.html>`__) and the error message through predicate ``JSParseError.getMessage``. - -Note that for some very simple syntax errors the parser can recover and continue parsing. If this happens, lexical and syntactic information is available in addition to the `JSParseError <https://help.semmle.com/qldoc/javascript/semmle/javascript/Errors.qll/type.Errors$JSParseError.html>`__ values representing the (recoverable) syntax errors encountered during parsing. - -Frameworks -~~~~~~~~~~ - -AngularJS -^^^^^^^^^ - -The ``semmle.javascript.frameworks.AngularJS`` library provides support for working with `AngularJS (Angular 1.x) <https://www.angularjs.org/>`__ code. Its most important classes are: - -- `AngularJS::AngularModule <https://help.semmle.com/qldoc/javascript/semmle/javascript/frameworks/AngularJS/AngularJSCore.qll/type.AngularJSCore$AngularModule.html>`__: an Angular module -- `AngularJS::DirectiveDefinition <https://help.semmle.com/qldoc/javascript/semmle/javascript/frameworks/AngularJS/ServiceDefinitions.qll/type.ServiceDefinitions$DirectiveDefinition.html>`__, `AngularJS::FactoryRecipeDefinition <https://help.semmle.com/qldoc/javascript/semmle/javascript/frameworks/AngularJS/ServiceDefinitions.qll/type.ServiceDefinitions$FactoryRecipeDefinition.html>`__, `AngularJS::FilterDefinition <https://help.semmle.com/qldoc/javascript/semmle/javascript/frameworks/AngularJS/ServiceDefinitions.qll/type.ServiceDefinitions$FilterDefinition.html>`__, `AngularJS::ControllerDefinition <https://help.semmle.com/qldoc/javascript/semmle/javascript/frameworks/AngularJS/ServiceDefinitions.qll/type.ServiceDefinitions$ControllerDefinition.html>`__: a definition of a directive, service, filter or controller, respectively -- `AngularJS::InjectableFunction <https://help.semmle.com/qldoc/javascript/semmle/javascript/frameworks/AngularJS/DependencyInjections.qll/type.DependencyInjections$InjectableFunction.html>`__: a function that is subject to dependency injection - -HTTP framework libraries -^^^^^^^^^^^^^^^^^^^^^^^^ - -The library ``semmle.javacript.frameworks.HTTP`` provides classes modeling common concepts from various HTTP frameworks. - -Currently supported frameworks are `Express <https://expressjs.com/>`__, the standard Node.js ``http`` and ``https`` modules, `Connect <https://github.com/senchalabs/connect>`__, `Koa <https://koajs.com>`__, `Hapi <https://hapijs.com/>`__ and `Restify <http://restify.com/>`__. - -The most important classes include (all in module ``HTTP``): - -- ``ServerDefinition``: an expression that creates a new HTTP server. -- ``RouteHandler``: a callback for handling an HTTP request. -- ``RequestExpr``: an expression that may contain an HTTP request object. -- ``ResponseExpr``: an expression that may contain an HTTP response object. -- ``HeaderDefinition``: an expression that sets one or more HTTP response headers. -- ``CookieDefinition``: an expression that sets a cookie in an HTTP response. -- ``RequestInputAccess``: an expression that accesses user-controlled request data. - -For each framework library, there is a corresponding CodeQL library (for example ``semmle.javacript.frameworks.Express``) that instantiates the above classes for that framework and adds framework-specific classes. - -Node.js -^^^^^^^ - -The ``semmle.javascript.NodeJS`` library provides support for working with `Node.js <http://nodejs.org/>`__ modules through the following classes: - -- `NodeModule <https://help.semmle.com/qldoc/javascript/semmle/javascript/NodeJS.qll/type.NodeJS$NodeModule.html>`__: a top-level that defines a Node.js module; see the section on `Modules <#modules>`__ for more information. -- `Require <https://help.semmle.com/qldoc/javascript/semmle/javascript/NodeJS.qll/type.NodeJS$Require.html>`__: a call to the special ``require`` function that imports a module. - -As an example of the use of these classes, here is a query that counts for every module how many other modules it imports: - -.. code-block:: ql - - import javascript - - from NodeModule m - select m, count(m.getAnImportedModule()) - -➤ `See this in the query console on LGTM.com <https://lgtm.com/query/659662207/>`__. When you analyze a project, for each module you can see how many other modules it imports. - -NPM -^^^ - -The ``semmle.javascript.NPM`` library provides support for working with `NPM <http://npmjs.org/>`__ packages through the following classes: - -- `PackageJSON <https://help.semmle.com/qldoc/javascript/semmle/javascript/NPM.qll/type.NPM$PackageJSON.html>`__: a ``package.json`` file describing an NPM package; various getter predicates are available for accessing detailed information about the package, which are described in the `online API documentation <https://help.semmle.com/qldoc/javascript/semmle/javascript/NPM.qll/module.NPM.html>`__. -- `BugTrackerInfo <https://help.semmle.com/qldoc/javascript/semmle/javascript/NPM.qll/type.NPM$BugTrackerInfo.html>`__, `ContributorInfo <https://help.semmle.com/qldoc/javascript/semmle/javascript/NPM.qll/type.NPM$ContributorInfo.html>`__, `RepositoryInfo <https://help.semmle.com/qldoc/javascript/semmle/javascript/NPM.qll/type.NPM$RepositoryInfo.html>`__: these classes model parts of the ``package.json`` file providing information on bug tracking systems, contributors and repositories. -- `PackageDependencies <https://help.semmle.com/qldoc/javascript/semmle/javascript/NPM.qll/type.NPM$PackageDependencies.html>`__: models the dependencies of an NPM package; the predicate ``PackageDependencies.getADependency(pkg, v)`` binds ``pkg`` to the name and ``v`` to the version of a package required by a ``package.json`` file. -- `NPMPackage <https://help.semmle.com/qldoc/javascript/semmle/javascript/NPM.qll/type.NPM$NPMPackage.html>`__: a subclass of `Folder <https://help.semmle.com/qldoc/javascript/semmle/javascript/Files.qll/type.Files$Folder.html>`__ that models an NPM package; important member predicates include: - - - ``NPMPackage.getPackageName()`` returns the name of this package. - - ``NPMPackage.getPackageJSON()`` returns the ``package.json`` file for this package. - - ``NPMPackage.getNodeModulesFolder()`` returns the ``node_modules`` folder for this package. - - ``NPMPackage.getAModule()`` returns a Node.js module belonging to this package (not including modules in the ``node_modules`` folder). - -As an example of the use of these classes, here is a query that identifies unused dependencies, that is, module dependencies that are listed in the ``package.json`` file, but which are not imported by any ``require`` call: - -.. code-block:: ql - - import javascript - - from NPMPackage pkg, PackageDependencies deps, string name - where deps = pkg.getPackageJSON().getDependencies() and - deps.getADependency(name, _) and - not exists (Require req | req.getTopLevel() = pkg.getAModule() | name = req.getImportedPath().getValue()) - select deps, "Unused dependency '" + name + "'." - -➤ `See this in the query console on LGTM.com <https://lgtm.com/query/666680077/>`__. It is not uncommon for projects to have some unused dependencies. - -React -^^^^^ - -The ``semmle.javascript.frameworks.React`` library provides support for working with `React <https://facebook.github.io/react/>`__ code through the `ReactComponent <https://help.semmle.com/qldoc/javascript/semmle/javascript/frameworks/React.qll/type.React$ReactComponent.html>`__ class, which models a React component defined either in the functional style or the class-based style (both ECMAScript 2015 classes and old-style ``React.createClass`` classes are supported). - -Databases -^^^^^^^^^ - -The class ``SQL::SqlString`` represents an expression that is interpreted as a SQL command. Currently, we model SQL commands issued through the following npm packages: -`mysql <https://www.npmjs.com/package/mysql>`__, `pg <https://www.npmjs.com/package/pg>`__, `pg-pool <https://www.npmjs.com/package/pg-pool>`__, `sqlite3 <https://www.npmjs.com/package/sqlite3>`__, `mssql <https://www.npmjs.com/package/mssql>`__ and `sequelize <https://www.npmjs.com/package/sequelize>`__. - -Similarly, the class ``NoSQL::Query`` represents an expression that is interpreted as a NoSQL query by the ``mongodb`` or ``mongoose`` package. - -Finally, the class ``DatabaseAccess`` contains all data flow nodes that perform a database access using any of the packages above. - -For example, here is a query to find SQL queries that use string concatenation (instead of a templating-based solution, which is usually safer): - -.. code-block:: ql - - import javascript - - from SQL::SqlString ss - where ss instanceof AddExpr - select ss, "Use templating instead of string concatenation." - -➤ `See this in the query console on LGTM.com <https://lgtm.com/query/1506076336224/>`__, showing two (benign) results on `strong-arc <https://lgtm.com/projects/g/strongloop/strong-arc/>`__. - -Miscellaneous -~~~~~~~~~~~~~ - -Externs -^^^^^^^ - -The ``semmle.javascript.Externs`` library provides support for working with `externs <https://developers.google.com/closure/compiler/docs/api-tutorial3>`__ through the following classes: - -- `ExternalDecl <https://help.semmle.com/qldoc/javascript/semmle/javascript/Externs.qll/type.Externs$ExternalDecl.html>`__: common superclass modeling all different kinds of externs declarations; it defines two member predicates: - - - ``ExternalDecl.getQualifiedName()`` returns the fully qualified name of the declared entity. - - ``ExternalDecl.getName()`` returns the unqualified name of the declared entity. - -- `ExternalTypedef <https://help.semmle.com/qldoc/javascript/semmle/javascript/Externs.qll/type.Externs$ExternalTypedef.html>`__: a subclass of `ExternalDecl <https://help.semmle.com/qldoc/javascript/semmle/javascript/Externs.qll/type.Externs$ExternalDecl.html>`__ representing type declarations; unlike other externs declarations, such declarations do not declare a function or object that is present at runtime, but simply introduce an alias for a type. -- `ExternalVarDecl <https://help.semmle.com/qldoc/javascript/semmle/javascript/Externs.qll/type.Externs$ExternalVarDecl.html>`__: a subclass of `ExternalDecl <https://help.semmle.com/qldoc/javascript/semmle/javascript/Externs.qll/type.Externs$ExternalDecl.html>`__ representing a variable or function declaration; it defines two member predicates: - - - ``ExternalVarDecl.getInit()`` returns the initializer associated with this declaration, if any; this can either be a `Function <https://help.semmle.com/qldoc/javascript/semmle/javascript/Functions.qll/type.Functions$Function.html>`__ or an `Expr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Expr.html>`__. - - ``ExternalVarDecl.getDocumentation()`` returns the JSDoc comment associated with this declaration. - -Variables and functions declared in an externs file are either globals (represented by class `ExternalGlobalDecl <https://help.semmle.com/qldoc/javascript/semmle/javascript/Externs.qll/type.Externs$ExternalGlobalDecl.html>`__), or members (represented by class `ExternalMemberDecl <https://help.semmle.com/qldoc/javascript/semmle/javascript/Externs.qll/type.Externs$ExternalMemberDecl.html>`__). - -Members are further subdivided into static members (class `ExternalStaticMemberDecl <https://help.semmle.com/qldoc/javascript/semmle/javascript/Externs.qll/type.Externs$ExternalStaticMemberDecl.html>`__) and instance members (class `ExternalInstanceMemberDecl <https://help.semmle.com/qldoc/javascript/semmle/javascript/Externs.qll/type.Externs$ExternalInstanceMemberDecl.html>`__). - -For more details on these and other classes representing externs, see `the API documentation <https://help.semmle.com/qldoc/javascript/semmle/javascript/Externs.qll/module.Externs.html>`__. - -HTML -^^^^ - -The ``semmle.javascript.HTML`` library provides support for working with HTML documents. They are represented as a tree of ``HTML::Element`` nodes, each of which may have zero or more attributes represented by class ``HTML::Attribute``. - -Similar to the abstract syntax tree representation, ``HTML::Element`` has member predicates ``getChild(i)`` and ``getParent()`` to navigate from an element to its ``i``\ th child element and its parent element, respectively. Use predicate ``HTML::Element.getAttribute(i)`` to get the ``i``\ th attribute of the element, and ``HTML::Element.getAttributeByName(n)`` to get the attribute with name ``n``. - -For ``HTML::Attribute``, predicates ``getName()`` and ``getValue()`` provide access to the attribute's name and value, respectively. - -Both ``HTML::Element`` and ``HTML::Attribute`` have a predicate ``getRoot()`` that gets the root ``HTML::Element`` of the document to which they belong. - -JSDoc -^^^^^ - -The ``semmle.javascript.JSDoc`` library provides support for working with `JSDoc comments <http://usejsdoc.org/>`__. Documentation comments are parsed into an abstract syntax tree representation closely following the format employed by the `Doctrine <https://github.com/Constellation/doctrine>`__ JSDoc parser. - -A JSDoc comment as a whole is represented by an entity of class `JSDoc <https://help.semmle.com/qldoc/javascript/semmle/javascript/JSDoc.qll/type.JSDoc$JSDoc.html>`__, while individual tags are represented by class `JSDocTag <https://help.semmle.com/qldoc/javascript/semmle/javascript/JSDoc.qll/type.JSDoc$JSDocTag.html>`__. Important member predicates of these two classes include: - -- ``JSDoc.getDescription()`` returns the descriptive header of the JSDoc comment, if any. -- ``JSDoc.getComment()`` maps the `JSDoc <https://help.semmle.com/qldoc/javascript/semmle/javascript/JSDoc.qll/type.JSDoc$JSDoc.html>`__ entity to its underlying `Comment <https://help.semmle.com/qldoc/javascript/semmle/javascript/Comments.qll/type.Comments$Comment.html>`__ entity. -- ``JSDocTag.getATag()`` returns a tag in this JSDoc comment. -- ``JSDocTag.getTitle()`` returns the title of his tag; for instance, an ``@param`` tag has title ``"param"``. -- ``JSDocTag.getName()`` returns the name of the parameter or variable documented by this tag. -- ``JSDocTag.getType()`` returns the type of the parameter or variable documented by this tag. -- ``JSDocTag.getDescription()`` returns the description associated with this tag. - -Types in JSDoc comments are represented by the class `JSDocTypeExpr <https://help.semmle.com/qldoc/javascript/semmle/javascript/JSDoc.qll/type.JSDoc$JSDocTypeExpr.html>`__ and its subclasses, which again represent type expressions as abstract syntax trees. Examples of type expressions are `JSDocAnyTypeExpr <https://help.semmle.com/qldoc/javascript/semmle/javascript/JSDoc.qll/type.JSDoc$JSDocAnyTypeExpr.html>`__, representing the "any" type ``*``, or `JSDocNullTypeExpr <https://help.semmle.com/qldoc/javascript/semmle/javascript/JSDoc.qll/type.JSDoc$JSDocNullTypeExpr.html>`__, representing the null type. - -As an example, here is a query that finds ``@param`` tags that do not specify the name of the documented parameter: - -.. code-block:: ql - - import javascript - - from JSDocTag t - where t.getTitle() = "param" and - not exists(t.getName()) - select t, "@param tag is missing name." - -➤ `See this in the query console on LGTM.com <https://lgtm.com/query/673060054/>`__. Of the LGTM.com demo projects analyzed, only *Semantic-Org/Semantic-UI* has an example where the ``@param`` tag omits the name. - -For full details on these and other classes representing JSDoc comments and type expressions, see `the API documentation <https://help.semmle.com/qldoc/javascript/semmle/javascript/JSDoc.qll/module.JSDoc.html>`__. - -JSX -^^^ - -The ``semmle.javascript.JSX`` library provides support for working with `JSX code <https://facebook.github.io/react/docs/jsx-in-depth.html>`__. - -Similar to the representation of HTML documents, JSX fragments are modeled as a tree of `JSXElement <https://help.semmle.com/qldoc/javascript/semmle/javascript/JSX.qll/type.JSX$JSXElement.html>`__\ s, each of which may have zero or more `JSXAttribute <https://help.semmle.com/qldoc/javascript/semmle/javascript/JSX.qll/type.JSX$JSXAttribute.html>`__\ s. - -However, unlike HTML, JSX is interleaved with JavaScript, hence `JSXElement <https://help.semmle.com/qldoc/javascript/semmle/javascript/JSX.qll/type.JSX$JSXElement.html>`__ is a subclass of `Expr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$Expr.html>`__. Like ``HTML::Element``, it has predicates ``getAttribute(i)`` and ``getAttributeByName(n)`` to look up attributes of a JSX element. Its body elements can be accessed by predicate ``getABodyElement()``; note that the results of this predicate are arbitrary expressions, which may either be further `JSXElement <https://help.semmle.com/qldoc/javascript/semmle/javascript/JSX.qll/type.JSX$JSXElement.html>`__\ s, or other expressions that are interpolated into the body of the outer element. - -`JSXAttribute <https://help.semmle.com/qldoc/javascript/semmle/javascript/JSX.qll/type.JSX$JSXAttribute.html>`__, again not unlike ``HTML::Attribute``, has predicates ``getName()`` and ``getValue()`` to access the attribute name and value. - -JSON -^^^^ - -The ``semmle.javascript.JSON`` library provides support for working with `JSON <http://json.org/>`__ files that were processed by the JavaScript extractor when building the CodeQL database. - -JSON files are modeled as trees of JSON values. Each JSON value is represented by an entity of class `JSONValue <https://help.semmle.com/qldoc/javascript/semmle/javascript/JSON.qll/type.JSON$JSONValue.html>`__, which provides the following member predicates: - -- ``JSONValue.getParent()`` returns the JSON object or array in which this value occurs. -- ``JSONValue.getChild(i)`` returns the ``i``\ th child of this JSON object or array. - -Note that `JSONValue <https://help.semmle.com/qldoc/javascript/semmle/javascript/JSON.qll/type.JSON$JSONValue.html>`__ is a subclass of `Locatable <https://help.semmle.com/qldoc/javascript/semmle/javascript/Locations.qll/type.Locations$Locatable.html>`__, so the usual member predicates of `Locatable <https://help.semmle.com/qldoc/javascript/semmle/javascript/Locations.qll/type.Locations$Locatable.html>`__ can be used to determine the file in which a JSON value appears, and its location within that file. - -Class `JSONValue <https://help.semmle.com/qldoc/javascript/semmle/javascript/JSON.qll/type.JSON$JSONValue.html>`__ has the following subclasses: - -- `JSONPrimitiveValue <https://help.semmle.com/qldoc/javascript/semmle/javascript/JSON.qll/type.JSON$JSONPrimitiveValue.html>`__: a JSON-encoded primitive value; use ``JSONPrimitiveValue.getValue()`` to obtain a string representation of the value. - - - `JSONNull <https://help.semmle.com/qldoc/javascript/semmle/javascript/JSON.qll/type.JSON$JSONNull.html>`__, `JSONBoolean <https://help.semmle.com/qldoc/javascript/semmle/javascript/JSON.qll/type.JSON$JSONBoolean.html>`__, `JSONNumber <https://help.semmle.com/qldoc/javascript/semmle/javascript/JSON.qll/type.JSON$JSONNumber.html>`__, `JSONString <https://help.semmle.com/qldoc/javascript/semmle/javascript/JSON.qll/type.JSON$JSONString.html>`__: subclasses of `JSONPrimitiveValue <https://help.semmle.com/qldoc/javascript/semmle/javascript/JSON.qll/type.JSON$JSONPrimitiveValue.html>`__ representing the various kinds of primitive values. - -- `JSONArray <https://help.semmle.com/qldoc/javascript/semmle/javascript/JSON.qll/type.JSON$JSONArray.html>`__: a JSON-encoded array; use ``JSONArray.getElementValue(i)`` to access the ``i``\ th element of the array. -- `JSONObject <https://help.semmle.com/qldoc/javascript/semmle/javascript/JSON.qll/type.JSON$JSONObject.html>`__: a JSON-encoded object; use ``JSONObject.getValue(n)`` to access the value of property ``n`` of the object. - -Regular expressions -^^^^^^^^^^^^^^^^^^^ - -The ``semmle.javascript.Regexp`` library provides support for working with regular expression literals. The syntactic structure of regular expression literals is represented as an abstract syntax tree of regular expression terms, modeled by the class `RegExpTerm <https://help.semmle.com/qldoc/javascript/semmle/javascript/Regexp.qll/type.Regexp$RegExpTerm.html>`__. Similar to `ASTNode <https://help.semmle.com/qldoc/javascript/semmle/javascript/AST.qll/type.AST$ASTNode.html>`__, class `RegExpTerm <https://help.semmle.com/qldoc/javascript/semmle/javascript/Regexp.qll/type.Regexp$RegExpTerm.html>`__ provides member predicates ``getParent()`` and ``getChild(i)`` to navigate the structure of the syntax tree. - -Various subclasses of `RegExpTerm <https://help.semmle.com/qldoc/javascript/semmle/javascript/Regexp.qll/type.Regexp$RegExpTerm.html>`__ model different kinds of regular expression constructs and operators; see `the API documentation <https://help.semmle.com/qldoc/javascript/semmle/javascript/Regexp.qll/module.Regexp.html>`__ for details. - -YAML -^^^^ - -The ``semmle.javascript.YAML`` library provides support for working with `YAML <http://yaml.org/>`__ files that were processed by the JavaScript extractor when building the CodeQL database. - -YAML files are modeled as trees of YAML nodes. Each YAML node is represented by an entity of class `YAMLNode <https://help.semmle.com/qldoc/javascript/semmle/javascript/YAML.qll/type.YAML$YAMLNode.html>`__, which provides, among others, the following member predicates: - -- ``YAMLNode.getParentNode()`` returns the YAML collection in which this node is syntactically nested. -- ``YAMLNode.getChildNode(i)`` returns the ``i``\ th child node of this node, ``YAMLNode.getAChildNode()`` returns any child node of this node. -- ``YAMLNode.getTag()`` returns the tag of this YAML node. -- ``YAMLNode.getAnchor()`` returns the anchor associated with this YAML node, if any. -- ``YAMLNode.eval()`` returns the `YAMLValue <https://help.semmle.com/qldoc/javascript/semmle/javascript/YAML.qll/type.YAML$YAMLValue.html>`__ this YAML node evaluates to after resolving aliases and includes. - -The various kinds of scalar values available in YAML are represented by classes `YAMLInteger <https://help.semmle.com/qldoc/javascript/semmle/javascript/YAML.qll/type.YAML$YAMLInteger.html>`__, `YAMLFloat <https://help.semmle.com/qldoc/javascript/semmle/javascript/YAML.qll/type.YAML$YAMLFloat.html>`__, `YAMLTimestamp <https://help.semmle.com/qldoc/javascript/semmle/javascript/YAML.qll/type.YAML$YAMLTimestamp.html>`__, `YAMLBool <https://help.semmle.com/qldoc/javascript/semmle/javascript/YAML.qll/type.YAML$YAMLBool.html>`__, `YAMLNull <https://help.semmle.com/qldoc/javascript/semmle/javascript/YAML.qll/type.YAML$YAMLNull.html>`__ and `YAMLString <https://help.semmle.com/qldoc/javascript/semmle/javascript/YAML.qll/type.YAML$YAMLString.html>`__. Their common superclass is `YAMLScalar <https://help.semmle.com/qldoc/javascript/semmle/javascript/YAML.qll/type.YAML$YAMLScalar.html>`__, which has a member predicate ``getValue()`` to obtain the value of a scalar as a -string. - -`YAMLMapping <https://help.semmle.com/qldoc/javascript/semmle/javascript/YAML.qll/type.YAML$YAMLMapping.html>`__ and `YAMLSequence <https://help.semmle.com/qldoc/javascript/semmle/javascript/YAML.qll/type.YAML$YAMLSequence.html>`__ represent mappings and sequences, respectively, and are subclasses of `YAMLCollection <https://help.semmle.com/qldoc/javascript/semmle/javascript/YAML.qll/type.YAML$YAMLCollection.html>`__. - -Alias nodes are represented by class `YAMLAliasNode <https://help.semmle.com/qldoc/javascript/semmle/javascript/YAML.qll/type.YAML$YAMLAliasNode.html>`__, while `YAMLMergeKey <https://help.semmle.com/qldoc/javascript/semmle/javascript/YAML.qll/type.YAML$YAMLMergeKey.html>`__ and `YAMLInclude <https://help.semmle.com/qldoc/javascript/semmle/javascript/YAML.qll/type.YAML$YAMLInclude.html>`__ represent merge keys and ``!include`` directives, respectively. - -Predicate ``YAMLMapping.maps(key, value)`` models the key-value relation represented by a mapping, taking merge keys into account. - -Further reading ---------------- - -.. include:: ../../reusables/javascript-further-reading.rst -.. include:: ../../reusables/codeql-ref-tools-further-reading.rst diff --git a/docs/codeql/codeql-language-guides/codeql-for-javascript/data-flow-cheat-sheet-for-javascript.rst b/docs/codeql/codeql-language-guides/codeql-for-javascript/data-flow-cheat-sheet-for-javascript.rst deleted file mode 100644 index 78c3bc0c811..00000000000 --- a/docs/codeql/codeql-language-guides/codeql-for-javascript/data-flow-cheat-sheet-for-javascript.rst +++ /dev/null @@ -1,229 +0,0 @@ -.. _data-flow-cheat-sheet-for-javascript: - -Data flow cheat sheet for JavaScript -==================================== - -This article describes parts of the JavaScript libraries commonly used for variant analysis and in data flow queries. - -Taint tracking path queries ---------------------------- - -Use the following template to create a taint tracking path query: - -.. code-block:: ql - - /** - * @kind path-problem - */ - import javascript - import DataFlow - import DataFlow::PathGraph - - class MyConfig extends TaintTracking::Configuration { - MyConfig() { this = "MyConfig" } - override predicate isSource(Node node) { ... } - override predicate isSink(Node node) { ... } - override predicate isAdditionalTaintStep(Node pred, Node succ) { ... } - } - - from MyConfig cfg, PathNode source, PathNode sink - where cfg.hasFlowPath(source, sink) - select sink.getNode(), source, sink, "taint from $@.", source.getNode(), "here" - -This query reports flow paths which: - -- Begin at a node matched by `isSource <https://help.semmle.com/qldoc/javascript/semmle/javascript/dataflow/Configuration.qll/predicate.Configuration$Configuration$isSource.1.html>`__. -- Step through variables, function calls, properties, strings, arrays, promises, exceptions, and steps added by `isAdditionalTaintStep <https://help.semmle.com/qldoc/javascript/semmle/javascript/dataflow/TaintTracking.qll/predicate.TaintTracking$TaintTracking$Configuration$isAdditionalTaintStep.2.html>`__. -- End at a node matched by `isSink <https://help.semmle.com/qldoc/javascript/semmle/javascript/dataflow/Configuration.qll/predicate.Configuration$Configuration$isSink.1.html>`__. - -See also: "`Global data flow <analyzing-data-flow-in-javascript.html#global-data-flow>`__" and ":ref:`Creating path queries <creating-path-queries>`." - -DataFlow module ---------------- - -Use data flow nodes to match program elements independently of syntax. See also: ":doc:`Analyzing data flow in JavaScript and TypeScript <analyzing-data-flow-in-javascript>`." - -Predicates in the ``DataFlow::`` module: - -- `moduleImport <https://help.semmle.com/qldoc/javascript/semmle/javascript/dataflow/Nodes.qll/predicate.Nodes$moduleImport.1.html>`__ -- finds uses of a module -- `moduleMember <https://help.semmle.com/qldoc/javascript/semmle/javascript/dataflow/Nodes.qll/predicate.Nodes$moduleMember.2.html>`__ -- finds uses of a module member -- `globalVarRef <https://help.semmle.com/qldoc/javascript/semmle/javascript/dataflow/Nodes.qll/predicate.Nodes$globalVarRef.1.html>`__ -- finds uses of a global variable - -Classes and member predicates in the ``DataFlow::`` module: - -- `Node <https://help.semmle.com/qldoc/javascript/semmle/javascript/dataflow/DataFlow.qll/type.DataFlow$DataFlow$Node.html>`__ -- something that can have a value, such as an expression, declaration, or SSA variable - - `getALocalSource <https://help.semmle.com/qldoc/javascript/semmle/javascript/dataflow/DataFlow.qll/predicate.DataFlow$DataFlow$Node$getALocalSource.0.html>`__ -- find the node that this came from - - `getTopLevel <https://help.semmle.com/qldoc/javascript/semmle/javascript/dataflow/DataFlow.qll/predicate.DataFlow$DataFlow$Node$getTopLevel.0.html>`__ -- top-level scope enclosing this node - - `getFile <https://help.semmle.com/qldoc/javascript/semmle/javascript/dataflow/DataFlow.qll/predicate.DataFlow$DataFlow$Node$getFile.0.html>`__ -- file containing this node - - `getIntValue <https://help.semmle.com/qldoc/javascript/semmle/javascript/dataflow/DataFlow.qll/predicate.DataFlow$DataFlow$Node$getIntValue.0.html>`__ -- value of this node if it's is an integer constant - - `getStringValue <https://help.semmle.com/qldoc/javascript/semmle/javascript/dataflow/DataFlow.qll/predicate.DataFlow$DataFlow$Node$getStringValue.0.html>`__ -- value of this node if it's is a string constant - - `mayHaveBooleanValue <https://help.semmle.com/qldoc/javascript/semmle/javascript/dataflow/DataFlow.qll/predicate.DataFlow$DataFlow$Node$mayHaveBooleanValue.1.html>`__ -- check if the value is ``true`` or ``false`` -- `SourceNode <https://help.semmle.com/qldoc/javascript/semmle/javascript/dataflow/Sources.qll/type.Sources$SourceNode.html>`__ extends `Node <https://help.semmle.com/qldoc/javascript/semmle/javascript/dataflow/DataFlow.qll/type.DataFlow$DataFlow$Node.html>`__ -- function call, parameter, object creation, or reference to a property or global variable - - `getACall <https://help.semmle.com/qldoc/javascript/semmle/javascript/dataflow/Sources.qll/predicate.Sources$SourceNode$getACall.0.html>`__ -- find calls with this as the callee - - `getAnInstantiation <https://help.semmle.com/qldoc/javascript/semmle/javascript/dataflow/Sources.qll/predicate.Sources$SourceNode$getAnInstantiation.0.html>`__ -- find ``new``-calls with this as the callee - - `getAnInvocation <https://help.semmle.com/qldoc/javascript/semmle/javascript/dataflow/Sources.qll/predicate.Sources$SourceNode$getAnInvocation.0.html>`__ -- find calls or ``new``-calls with this as the callee - - `getAMethodCall <https://help.semmle.com/qldoc/javascript/semmle/javascript/dataflow/Sources.qll/predicate.Sources$SourceNode$getAMethodCall.1.html>`__ -- find method calls with this as the receiver - - `getAMemberCall <https://help.semmle.com/qldoc/javascript/semmle/javascript/dataflow/Sources.qll/predicate.Sources$SourceNode$getAMemberCall.1.html>`__ -- find calls with a member of this as the receiver - - `getAPropertyRead <https://help.semmle.com/qldoc/javascript/semmle/javascript/dataflow/Sources.qll/predicate.Sources$SourceNode$getAPropertyRead.1.html>`__ -- find property reads with this as the base - - `getAPropertyWrite <https://help.semmle.com/qldoc/javascript/semmle/javascript/dataflow/Sources.qll/predicate.Sources$SourceNode$getAPropertyWrite.1.html>`__ -- find property writes with this as the base - - `getAPropertySource <https://help.semmle.com/qldoc/javascript/semmle/javascript/dataflow/Sources.qll/predicate.Sources$SourceNode$getAPropertySource.1.html>`__ -- find nodes flowing into a property of this node -- `InvokeNode <https://help.semmle.com/qldoc/javascript/semmle/javascript/dataflow/Nodes.qll/type.Nodes$InvokeNode.html>`__, `NewNode <https://help.semmle.com/qldoc/javascript/semmle/javascript/dataflow/Nodes.qll/type.Nodes$NewNode.html>`__, `CallNode <https://help.semmle.com/qldoc/javascript/semmle/javascript/dataflow/Nodes.qll/type.Nodes$CallNode.html>`__, `MethodCallNode <https://help.semmle.com/qldoc/javascript/semmle/javascript/dataflow/Nodes.qll/type.Nodes$MethodCallNode.html>`__ extends `SourceNode <https://help.semmle.com/qldoc/javascript/semmle/javascript/dataflow/Sources.qll/type.Sources$SourceNode.html>`__ -- call to a function or constructor - - `getArgument <https://help.semmle.com/qldoc/javascript/semmle/javascript/dataflow/Nodes.qll/predicate.Nodes$InvokeNode$getArgument.1.html>`__ -- an argument to the call - - `getCalleeNode <https://help.semmle.com/qldoc/javascript/semmle/javascript/dataflow/Nodes.qll/predicate.Nodes$InvokeNode$getCalleeNode.0.html>`__ -- node being invoked as a function - - `getCalleeName <https://help.semmle.com/qldoc/javascript/semmle/javascript/dataflow/Nodes.qll/predicate.Nodes$InvokeNode$getCalleeName.0.html>`__ -- name of the variable or property being called - - `getOptionArgument <https://help.semmle.com/qldoc/javascript/semmle/javascript/dataflow/Nodes.qll/predicate.Nodes$InvokeNode$getOptionArgument.2.html>`__ -- a "named argument" passed in through an object literal - - `getCallback <https://help.semmle.com/qldoc/javascript/semmle/javascript/dataflow/Nodes.qll/predicate.Nodes$InvokeNode$getCallback.1.html>`__ -- a function passed as a callback - - `getACallee <https://help.semmle.com/qldoc/javascript/semmle/javascript/dataflow/Nodes.qll/predicate.Nodes$InvokeNode$getACallee.0.html>`__ - a function being called here - - (MethodCallNode).\ `getMethodName <https://help.semmle.com/qldoc/javascript/semmle/javascript/dataflow/Nodes.qll/predicate.Nodes$MethodCallNode$getMethodName.0.html>`__ -- name of the method being invoked - - (MethodCallNode).\ `getReceiver <https://help.semmle.com/qldoc/javascript/semmle/javascript/dataflow/Nodes.qll/predicate.Nodes$CallNode$getReceiver.0.html>`__ -- receiver of the method call -- `FunctionNode <https://help.semmle.com/qldoc/javascript/semmle/javascript/dataflow/Nodes.qll/type.Nodes$FunctionNode.html>`__ extends `SourceNode <https://help.semmle.com/qldoc/javascript/semmle/javascript/dataflow/Sources.qll/type.Sources$SourceNode.html>`__ -- definition of a function, including closures, methods, and class constructors - - `getName <https://help.semmle.com/qldoc/javascript/semmle/javascript/dataflow/Nodes.qll/predicate.Nodes$FunctionNode$getName.0.html>`__ -- name of the function, derived from a variable or property name - - `getParameter <https://help.semmle.com/qldoc/javascript/semmle/javascript/dataflow/Nodes.qll/predicate.Nodes$FunctionNode$getParameter.1.html>`__ -- a parameter of the function - - `getReceiver <https://help.semmle.com/qldoc/javascript/semmle/javascript/dataflow/Nodes.qll/predicate.Nodes$FunctionNode$getReceiver.0.html>`__ -- the node representing the value of ``this`` - - `getAReturn <https://help.semmle.com/qldoc/javascript/semmle/javascript/dataflow/Nodes.qll/predicate.Nodes$FunctionNode$getAReturn.0.html>`__ -- get a returned expression -- `ParameterNode <https://help.semmle.com/qldoc/javascript/semmle/javascript/dataflow/Nodes.qll/type.Nodes$ParameterNode.html>`__ extends `SourceNode <https://help.semmle.com/qldoc/javascript/semmle/javascript/dataflow/Sources.qll/type.Sources$SourceNode.html>`__ -- parameter of a function - - `getName <https://help.semmle.com/qldoc/javascript/semmle/javascript/dataflow/Nodes.qll/predicate.Nodes$ParameterNode$getName.0.html>`__ -- the parameter name, if it has one -- `ClassNode <https://help.semmle.com/qldoc/javascript/semmle/javascript/dataflow/Nodes.qll/type.Nodes$ClassNode.html>`__ extends `SourceNode <https://help.semmle.com/qldoc/javascript/semmle/javascript/dataflow/Sources.qll/type.Sources$SourceNode.html>`__ -- class declaration or function that acts as a class - - `getName <https://help.semmle.com/qldoc/javascript/semmle/javascript/dataflow/Nodes.qll/predicate.Nodes$ClassNode$getName.0.html>`__ -- name of the class, derived from a variable or property name - - `getConstructor <https://help.semmle.com/qldoc/javascript/semmle/javascript/dataflow/Nodes.qll/predicate.Nodes$ClassNode$getConstructor.0.html>`__ -- the constructor function - - `getInstanceMethod <https://help.semmle.com/qldoc/javascript/semmle/javascript/dataflow/Nodes.qll/predicate.Nodes$ClassNode$getInstanceMethod.1.html>`__ -- get an instance method by name - - `getStaticMethod <https://help.semmle.com/qldoc/javascript/semmle/javascript/dataflow/Nodes.qll/predicate.Nodes$ClassNode$getStaticMethod.1.html>`__ -- get a static method by name - - `getAnInstanceReference <https://help.semmle.com/qldoc/javascript/semmle/javascript/dataflow/Nodes.qll/predicate.Nodes$ClassNode$getAnInstanceReference.0.html>`__ -- find references to an instance of the class - - `getAClassReference <https://help.semmle.com/qldoc/javascript/semmle/javascript/dataflow/Nodes.qll/predicate.Nodes$ClassNode$getAClassReference.0.html>`__ -- find references to the class itself -- `ObjectLiteralNode <https://help.semmle.com/qldoc/javascript/semmle/javascript/dataflow/Nodes.qll/type.Nodes$ObjectLiteralNode.html>`__ extends `SourceNode <https://help.semmle.com/qldoc/javascript/semmle/javascript/dataflow/Sources.qll/type.Sources$SourceNode.html>`__ -- object literal - - `getAPropertyWrite <https://help.semmle.com/qldoc/javascript/semmle/javascript/dataflow/Sources.qll/predicate.Sources$SourceNode$getAPropertyWrite.1.html>`__ -- a property in the object literal - - `getAPropertySource <https://help.semmle.com/qldoc/javascript/semmle/javascript/dataflow/Sources.qll/predicate.Sources$SourceNode$getAPropertySource.1.html>`__ -- value flowing into a property -- `ArrayCreationNode <https://help.semmle.com/qldoc/javascript/semmle/javascript/dataflow/Nodes.qll/type.Nodes$ArrayCreationNode.html>`__ extends `SourceNode <https://help.semmle.com/qldoc/javascript/semmle/javascript/dataflow/Sources.qll/type.Sources$SourceNode.html>`__ -- array literal or call to ``Array`` constructor - - `getElement <https://help.semmle.com/qldoc/javascript/semmle/javascript/dataflow/Nodes.qll/predicate.Nodes$ArrayCreationNode$getElement.1.html>`__ -- an element of the array -- `PropRef <https://help.semmle.com/qldoc/javascript/semmle/javascript/dataflow/DataFlow.qll/type.DataFlow$DataFlow$PropRef.html>`__, `PropRead <https://help.semmle.com/qldoc/javascript/semmle/javascript/dataflow/DataFlow.qll/type.DataFlow$DataFlow$PropRead.html>`__, `PropWrite <https://help.semmle.com/qldoc/javascript/semmle/javascript/dataflow/DataFlow.qll/type.DataFlow$DataFlow$PropWrite.html>`__ -- read or write of a property - - `getPropertyName <https://help.semmle.com/qldoc/javascript/semmle/javascript/dataflow/DataFlow.qll/predicate.DataFlow$DataFlow$PropRef$getPropertyName.0.html>`__ -- name of the property, if it is constant - - `getPropertyNameExpr <https://help.semmle.com/qldoc/javascript/semmle/javascript/dataflow/DataFlow.qll/predicate.DataFlow$DataFlow$PropRef$getPropertyNameExpr.0.html>`__ -- expression holding the name of the property - - `getBase <https://help.semmle.com/qldoc/javascript/semmle/javascript/dataflow/DataFlow.qll/predicate.DataFlow$DataFlow$PropRef$getBase.0.html>`__ -- object whose property is accessed - - (PropWrite).\ `getRhs <https://help.semmle.com/qldoc/javascript/semmle/javascript/dataflow/DataFlow.qll/predicate.DataFlow$DataFlow$PropWrite$getRhs.0.html>`__ -- right-hand side of the property assignment - - -StringOps module ----------------- - -- StringOps::`Concatenation <https://help.semmle.com/qldoc/javascript/semmle/javascript/StringOps.qll/type.StringOps$StringOps$Concatenation.html>`__ -- string concatenation, using a plus operator, template literal, or array join call -- StringOps::`StartsWith <https://help.semmle.com/qldoc/javascript/semmle/javascript/StringOps.qll/type.StringOps$StringOps$StartsWith.html>`__ -- check if a string starts with something -- StringOps::`EndsWith <https://help.semmle.com/qldoc/javascript/semmle/javascript/StringOps.qll/type.StringOps$StringOps$EndsWith.html>`__ -- check if a string ends with something -- StringOps::`Includes <https://help.semmle.com/qldoc/javascript/semmle/javascript/StringOps.qll/type.StringOps$StringOps$Includes.html>`__ -- check if a string contains something - -Utility --------- - -- `ExtendCall <https://help.semmle.com/qldoc/javascript/semmle/javascript/Extend.qll/type.Extend$ExtendCall.html>`__ -- call that copies properties from one object to another -- `JsonParserCall <https://help.semmle.com/qldoc/javascript/semmle/javascript/JsonParsers.qll/type.JsonParsers$JsonParserCall.html>`__ -- call that deserializes a JSON string -- `PropertyProjection <https://help.semmle.com/qldoc/javascript/semmle/javascript/frameworks/PropertyProjection.qll/type.PropertyProjection$PropertyProjection.html>`__ -- call that extracts nested properties by name - -System and Network ------------------- - -- `ClientRequest <https://help.semmle.com/qldoc/javascript/semmle/javascript/frameworks/ClientRequests.qll/type.ClientRequests$ClientRequest.html>`__ -- outgoing network request -- `DatabaseAccess <https://help.semmle.com/qldoc/javascript/semmle/javascript/Concepts.qll/type.Concepts$DatabaseAccess.html>`__ -- query being submitted to a database -- `FileNameSource <https://help.semmle.com/qldoc/javascript/semmle/javascript/Concepts.qll/type.Concepts$FileNameSource.html>`__ -- reference to a filename -- `FileSystemAccess <https://help.semmle.com/qldoc/javascript/semmle/javascript/Concepts.qll/type.Concepts$FileSystemAccess.html>`__ -- file system operation - - `FileSystemReadAccess <https://help.semmle.com/qldoc/javascript/semmle/javascript/Concepts.qll/type.Concepts$FileSystemReadAccess.html>`__ -- reading the contents of a file - - `FileSystemWriteAccess <https://help.semmle.com/qldoc/javascript/semmle/javascript/Concepts.qll/type.Concepts$FileSystemWriteAccess.html>`__ -- writing to the contents of a file -- `PersistentReadAccess <https://help.semmle.com/qldoc/javascript/semmle/javascript/Concepts.qll/type.Concepts$PersistentReadAccess.html>`__ -- reading from persistent storage, like cookies -- `PersistentWriteAccess <https://help.semmle.com/qldoc/javascript/semmle/javascript/Concepts.qll/type.Concepts$PersistentWriteAccess.html>`__ -- writing to persistent storage -- `RemoteFlowSource <https://help.semmle.com/qldoc/javascript/semmle/javascript/security/dataflow/RemoteFlowSources.qll/type.RemoteFlowSources$RemoteFlowSource.html>`__ -- source of untrusted user input -- `SystemCommandExecution <https://help.semmle.com/qldoc/javascript/semmle/javascript/Concepts.qll/type.Concepts$SystemCommandExecution.html>`__ -- execution of a system command - -Files ------ - -- `File <https://help.semmle.com/qldoc/javascript/semmle/javascript/Files.qll/type.Files$File.html>`__, - `Folder <https://help.semmle.com/qldoc/javascript/semmle/javascript/Files.qll/type.Files$Folder.html>`__ extends - `Container <https://help.semmle.com/qldoc/javascript/semmle/javascript/Files.qll/type.Files$Container.html>`__ -- file or folder in the database - - - `getBaseName <https://help.semmle.com/qldoc/javascript/semmle/javascript/Files.qll/predicate.Files$Container$getBaseName.0.html>`__ -- the name of the file or folder - - `getRelativePath <https://help.semmle.com/qldoc/javascript/semmle/javascript/Files.qll/predicate.Files$Container$getRelativePath.0.html>`__ -- path relative to the database root - -AST nodes ---------- - -See also: ":doc:`Abstract syntax tree classes for working with JavaScript and TypeScript programs <abstract-syntax-tree-classes-for-working-with-javascript-and-typescript-programs>`." - -Conversion between DataFlow and AST nodes: - -- `Node.asExpr() <https://help.semmle.com/qldoc/javascript/semmle/javascript/dataflow/DataFlow.qll/predicate.DataFlow$DataFlow$Node$asExpr.0.html>`__ -- convert node to an expression, if possible -- `Expr.flow() <https://help.semmle.com/qldoc/javascript/semmle/javascript/AST.qll/predicate.AST$AST$ValueNode$flow.0.html>`__ -- convert expression to a node (always possible) -- `DataFlow::valueNode <https://help.semmle.com/qldoc/javascript/semmle/javascript/dataflow/DataFlow.qll/predicate.DataFlow$DataFlow$valueNode.1.html>`__ -- convert expression or declaration to a node -- `DataFlow::parameterNode <https://help.semmle.com/qldoc/javascript/semmle/javascript/dataflow/DataFlow.qll/predicate.DataFlow$DataFlow$parameterNode.1.html>`__ -- convert a parameter to a node -- `DataFlow::thisNode <https://help.semmle.com/qldoc/javascript/semmle/javascript/dataflow/DataFlow.qll/predicate.DataFlow$DataFlow$thisNode.1.html>`__ -- get the receiver node of a function - -String matching ---------------- - -- x.\ `matches <https://help.semmle.com/qldoc/javascript/predicate.string$matches.1.html>`__\ ("escape%") -- holds if x starts with "escape" -- x.\ `regexpMatch <https://help.semmle.com/qldoc/javascript/predicate.string$regexpMatch.1.html>`__\ ("escape.*") -- holds if x starts with "escape" -- x.\ `regexpMatch <https://help.semmle.com/qldoc/javascript/predicate.string$regexpMatch.1.html>`__\ ("(?i).*escape.*") -- holds if x contains - "escape" (case insensitive) - -Type tracking -------------- - -See also: ":doc:`Using type tracking for API modeling <using-type-tracking-for-api-modeling>`." - -Use the following template to define forward type tracking predicates: - -.. code-block:: ql - - import DataFlow - - SourceNode myType(TypeTracker t) { - t.start() and - result = /* SourceNode to track */ - or - exists(TypeTracker t2 | - result = myType(t2).track(t2, t) - ) - } - - SourceNode myType() { - result = myType(TypeTracker::end()) - } - -Use the following template to define backward type tracking predicates: - -.. code-block:: ql - - import DataFlow - - SourceNode myType(TypeBackTracker t) { - t.start() and - result = (/* argument to track */).getALocalSource() - or - exists(TypeBackTracker t2 | - result = myType(t2).backtrack(t2, t) - ) - } - - SourceNode myType() { - result = myType(TypeBackTracker::end()) - } - -Troubleshooting ---------------- - -- Using a call node as as sink? Try using `getArgument <https://help.semmle.com/qldoc/javascript/semmle/javascript/dataflow/Nodes.qll/predicate.Nodes$InvokeNode$getArgument.1.html>`__ - to get an *argument* of the call node instead. -- Trying to use `moduleImport <https://help.semmle.com/qldoc/javascript/semmle/javascript/dataflow/Nodes.qll/predicate.Nodes$moduleImport.1.html>`__ - or `moduleMember <https://help.semmle.com/qldoc/javascript/semmle/javascript/dataflow/Nodes.qll/predicate.Nodes$moduleMember.2.html>`__ - as a call node? - Try using `getACall <https://help.semmle.com/qldoc/javascript/semmle/javascript/dataflow/Sources.qll/predicate.Sources$SourceNode$getACall.0.html>`__ - to get a *call* to the imported function, instead of the function itself. -- Compilation fails due to incompatible types? Make sure AST nodes and - DataFlow nodes are not mixed up. Use `asExpr() <https://help.semmle.com/qldoc/javascript/semmle/javascript/dataflow/DataFlow.qll/predicate.DataFlow$DataFlow$Node$asExpr.0.html>`__ or - `flow() <https://help.semmle.com/qldoc/javascript/semmle/javascript/AST.qll/predicate.AST$AST$ValueNode$flow.0.html>`__ to convert. - -Further reading ---------------- - -- ":ref:`Exploring data flow with path queries <exploring-data-flow-with-path-queries>`" - - -.. include:: ../../reusables/javascript-further-reading.rst -.. include:: ../../reusables/codeql-ref-tools-further-reading.rst \ No newline at end of file diff --git a/docs/codeql/codeql-language-guides/codeql-for-python/index.rst b/docs/codeql/codeql-language-guides/codeql-for-python.rst similarity index 100% rename from docs/codeql/codeql-language-guides/codeql-for-python/index.rst rename to docs/codeql/codeql-language-guides/codeql-for-python.rst diff --git a/docs/codeql/codeql-language-guides/codeql-library-for-cpp.rst b/docs/codeql/codeql-language-guides/codeql-library-for-cpp.rst new file mode 100644 index 00000000000..f7fa6751c3e --- /dev/null +++ b/docs/codeql/codeql-language-guides/codeql-library-for-cpp.rst @@ -0,0 +1,756 @@ +.. _codeql-library-for-cpp: + +CodeQL library for C and C++ +============================ + +When analyzing C or C++ code, you can use the large collection of classes in the CodeQL library for C and C++. + +About the CodeQL library for C and C++ +-------------------------------------- + +There is an extensive library for analyzing CodeQL databases extracted from C/C++ projects. The classes in this library present the data from a database in an object-oriented form and provide abstractions and predicates to help you with common analysis tasks. +The library is implemented as a set of QL modules, that is, files with the extension ``.qll``. The module ``cpp.qll`` imports all the core C/C++ library modules, so you can include the complete library by beginning your query with: + +.. code-block:: ql + + import cpp + +The rest of this topic summarizes the available CodeQL classes and corresponding C/C++ constructs. + +Commonly-used library classes +------------------------------ + +The most commonly used standard library classes are listed below. The listing is broken down by functionality. Each library class is annotated with a C/C++ construct it corresponds to. + +Declaration classes +~~~~~~~~~~~~~~~~~~~ + +This table lists Declaration_ classes representing C/C++ declarations. + ++-------------------------------------------------------------------------------+--------------------------------------+-------------------------------------+ +| Example syntax | CodeQL class | Remarks | ++===============================================================================+======================================+=====================================+ +| ``int`` *var* ``;`` | GlobalVariable_ | | ++-------------------------------------------------------------------------------+--------------------------------------+-------------------------------------+ +| ``namespace`` *N* ``{`` ... ``float`` *var* ``;`` ... ``}`` | NamespaceVariable_ | | ++-------------------------------------------------------------------------------+--------------------------------------+-------------------------------------+ +| ``int`` *func* ``( void ) {`` ... ``float`` *var* ``;`` ... ``}`` | LocalVariable_ | See also Initializer_ | ++-------------------------------------------------------------------------------+--------------------------------------+-------------------------------------+ +| ``class`` *C* ``{`` ... ``int`` *var* ``;`` ... ``}`` | MemberVariable_ | | ++-------------------------------------------------------------------------------+--------------------------------------+-------------------------------------+ +| ``int`` *func* ``(const char`` *param* ``);`` | Function_ | | ++-------------------------------------------------------------------------------+--------------------------------------+-------------------------------------+ +| | ``template < typename`` *T* ``>`` | TemplateFunction_ | | +| | ``void`` *func* ``(`` *T* ``param);`` | | | ++-------------------------------------------------------------------------------+--------------------------------------+-------------------------------------+ +| | ``int`` *func* ``(const char*`` *format* ``, ...)`` | FormattingFunction_ | | +| | ``{`` ... ``}`` | | | ++-------------------------------------------------------------------------------+--------------------------------------+-------------------------------------+ +| *func* ``< int, float > (`` ... ``);`` | FunctionTemplateInstantiation_ | | ++-------------------------------------------------------------------------------+--------------------------------------+-------------------------------------+ +| | ``template < typename`` *T* ``>`` | FunctionTemplateSpecialization_ | | +| | *func* ``< int,`` *T* ``> (`` ... ``) {`` ... ``}`` | | | ++-------------------------------------------------------------------------------+--------------------------------------+-------------------------------------+ +| | ``class`` *C* ``{`` ... | MemberFunction_ | | +| | ``int`` *func* ``( float`` *param* ``);`` ... ``};`` | | | ++-------------------------------------------------------------------------------+--------------------------------------+-------------------------------------+ +| | ``class`` *C* ``{`` ... | ConstMemberFunction_ | | +| | ``int`` *func* ``( float`` *param* ``) const;`` ... ``};`` | | | ++-------------------------------------------------------------------------------+--------------------------------------+-------------------------------------+ +| ``class`` *C* ``{`` ... ``virtual int`` *func* ``(`` ... ``) {`` ... ``} };`` | VirtualFunction_ | | ++-------------------------------------------------------------------------------+--------------------------------------+-------------------------------------+ +| ``class`` *C* ``{`` ... *C* ``(`` ... ``) {`` ... ``}`` ... ``};`` | Constructor_ | | ++-------------------------------------------------------------------------------+--------------------------------------+-------------------------------------+ +| ``C::operator float () const;`` | ConversionOperator_ | | ++-------------------------------------------------------------------------------+--------------------------------------+-------------------------------------+ +| ``class`` *C* ``{`` ... ``~`` *C* ``( void ) {`` ... ``}`` ... ``};`` | Destructor_ | | ++-------------------------------------------------------------------------------+--------------------------------------+-------------------------------------+ +| | ``class`` *C* ``{`` ... | ConversionConstructor_ | | +| | *C* ``( const`` *D* ``&`` *d* ``) {`` ... ``}`` ... ``};`` | | | ++-------------------------------------------------------------------------------+--------------------------------------+-------------------------------------+ +| *C* ``&`` *C* ``:: operator= (const`` *C* ``& );`` | CopyAssignmentOperator_ | | ++-------------------------------------------------------------------------------+--------------------------------------+-------------------------------------+ +| *C* ``&`` *C* ``:: operator= (`` *C* ``&& );`` | MoveAssignmentOperator_ | | ++-------------------------------------------------------------------------------+--------------------------------------+-------------------------------------+ +| *C* ``::`` *C* ``(const`` *C* ``& );`` | CopyConstructor_ | | ++-------------------------------------------------------------------------------+--------------------------------------+-------------------------------------+ +| *C* ``::`` *C* ``(`` *C* ``&& );`` | MoveConstructor_ | | ++-------------------------------------------------------------------------------+--------------------------------------+-------------------------------------+ +| *C* ``::`` *C* ``(void);`` | NoArgConstructor_ | Default constructor | ++-------------------------------------------------------------------------------+--------------------------------------+-------------------------------------+ +| ``enum`` *en* ``{`` *val1* ``,`` *val2* ... ``}`` | EnumConstant_ | | ++-------------------------------------------------------------------------------+--------------------------------------+-------------------------------------+ +| | ``friend void`` *func* ``( int );`` | FriendDecl_ | | +| | ``friend class`` *B* ``;`` | | | ++-------------------------------------------------------------------------------+--------------------------------------+-------------------------------------+ +| | ``int`` *func* ``( void ) {`` ... | LocalEnum_ | | +| | ``enum`` *en* ``{`` *val1* ``,`` *val2* ... ``};`` ... ``}`` | | | ++-------------------------------------------------------------------------------+--------------------------------------+-------------------------------------+ +| | ``class`` *C* ``{`` ... | NestedEnum_ | | +| | ``enum`` *en* ``{`` *val1* ``,`` *val2* ... ``}`` ... ``}`` | | | ++-------------------------------------------------------------------------------+--------------------------------------+-------------------------------------+ +| ``enum class`` *en* ``: short {`` *val1* ``,`` *val2* ... ``}`` | ScopedEnum_ | | ++-------------------------------------------------------------------------------+--------------------------------------+-------------------------------------+ +| | ``class`` *C* ``{`` ... | AbstractClass_ | | +| | ``virtual void`` *func* ``( int ) = 0;`` ... ``};`` | | | ++-------------------------------------------------------------------------------+--------------------------------------+-------------------------------------+ +| ``template < int , float > class`` *C* ``{`` ... ``};`` | ClassTemplateInstantiation_ | | ++-------------------------------------------------------------------------------+--------------------------------------+-------------------------------------+ +| ``template < > class`` *C* ``<`` Type_ ``> {`` ... ``};`` | FullClassTemplateSpecialization_ | | ++-------------------------------------------------------------------------------+--------------------------------------+-------------------------------------+ +| | ``template < typename`` *T* ``>`` | PartialClassTemplateSpecialization_ | | +| | ``class`` *C* ``<`` *T* ``,`` *5* ``> {`` ... ``};`` | | | ++-------------------------------------------------------------------------------+--------------------------------------+-------------------------------------+ +| ``int`` *func* ``( void ) {`` ... ``class`` *C* ``{`` ... ``};`` ... ``}`` | LocalClass_ | | ++-------------------------------------------------------------------------------+--------------------------------------+-------------------------------------+ +| ``class`` *C* ``{`` ... ``class`` *D* ``{`` ... ``};`` ... ``};`` | NestedClass_ | | ++-------------------------------------------------------------------------------+--------------------------------------+-------------------------------------+ +| | ``class`` *C* ``{`` | Class_ | | +| | Type_ *var* ``;`` | | | +| | Type_ *func* ``(`` Parameter_... ``) {`` ... ``}``... ``};`` | | | ++-------------------------------------------------------------------------------+--------------------------------------+-------------------------------------+ +| | ``struct`` *S* ``{`` ... | | Struct_ | | +| | Type_ *var* ``;`` | | Class_ | | +| | Type_ *func* ``(`` Parameter_... ``) {`` ... ``}``... ``};`` | | | | ++-------------------------------------------------------------------------------+--------------------------------------+-------------------------------------+ +| | ``union`` *U* ``{`` | | Union_ | | +| | Type_ *var1* ``;`` | | Struct_ | | +| | Type_ *var2* ``;`` ... ``};`` | | Class_ | | ++-------------------------------------------------------------------------------+--------------------------------------+-------------------------------------+ +| | ``template < typename`` *T* ``>`` | ProxyClass_ | Appears only in *uninstantiated* | +| | ``struct`` *C* ``:`` *T* ``{`` ... ``};`` | | templates | ++-------------------------------------------------------------------------------+--------------------------------------+-------------------------------------+ +| | ``int`` *func* ``( void ) {`` ... | LocalStruct_ | | +| | ``struct`` *S* ``{`` ... ``};`` ... ``}`` | | | ++-------------------------------------------------------------------------------+--------------------------------------+-------------------------------------+ +| | ``class`` *C* ``{`` ... | NestedStruct_ | | +| | ``struct`` *S* ``{`` ... ``};`` ... ``};`` | | | ++-------------------------------------------------------------------------------+--------------------------------------+-------------------------------------+ +| ``int *`` *func* ``( void ) {`` ... ``union`` *U* ``{`` ... ``};`` ... ``}`` | LocalUnion_ | | ++-------------------------------------------------------------------------------+--------------------------------------+-------------------------------------+ +| ``class`` *C* ``{`` ... ``union`` *U* ``{`` ... ``};`` ... ``};`` | NestedUnion_ | | ++-------------------------------------------------------------------------------+--------------------------------------+-------------------------------------+ +| ``typedef int`` *T* ``;`` | TypedefType_ | | ++-------------------------------------------------------------------------------+--------------------------------------+-------------------------------------+ +| | ``int`` *func* ``( void ) {`` ... | LocalTypedefType_ | | +| | ``typedef int`` *T* ``;`` ... ``}`` | | | ++-------------------------------------------------------------------------------+--------------------------------------+-------------------------------------+ +| | ``class`` *C* ``{`` ... | NestedTypedefType_ | | +| | ``typedef int`` *T* ``;`` ... ``};`` | | | ++-------------------------------------------------------------------------------+--------------------------------------+-------------------------------------+ +| ``class`` *V* ``:`` ... ``public`` *B* ... ``{`` ... ``};`` | ClassDerivation_ | | ++-------------------------------------------------------------------------------+--------------------------------------+-------------------------------------+ +| ``class`` *V* ``:`` ... ``virtual`` *B* ... ``{`` ... ``};`` | VirtualClassDerivation_ | | ++-------------------------------------------------------------------------------+--------------------------------------+-------------------------------------+ +| | ``template < typename`` *T* ``>`` | TemplateClass_ | | +| | ``class`` *C* ``{`` ... ``};`` | | | ++-------------------------------------------------------------------------------+--------------------------------------+-------------------------------------+ +| ``int`` *foo* ``(`` Type_ *param1* ``,`` Type_ *param2* ... ``);`` | Parameter_ | | ++-------------------------------------------------------------------------------+--------------------------------------+-------------------------------------+ +| ``template <typename`` *T* ``>`` *T* *t* ``;`` | TemplateVariable_ | Since C++14 | ++-------------------------------------------------------------------------------+--------------------------------------+-------------------------------------+ + +Statement classes +~~~~~~~~~~~~~~~~~ + +This table lists subclasses of Stmt_ representing C/C++ statements. + ++----------------------------------------------------------+--------------------------------+---------------------------------------------------+ +| Example syntax | CodeQL class | Remarks | ++==========================================================+================================+===================================================+ +| ``__asm__ ("`` *movb %bh, (%eax)* ``");`` | AsmStmt_ | Specific to a given CPU instruction set | ++----------------------------------------------------------+--------------------------------+---------------------------------------------------+ +| ``{`` Stmt_... ``}`` | BlockStmt_ | | ++----------------------------------------------------------+--------------------------------+---------------------------------------------------+ +| ``catch (`` Parameter_ ``)`` BlockStmt_ | CatchBlock_ | | ++----------------------------------------------------------+--------------------------------+---------------------------------------------------+ +| ``catch ( ... )`` BlockStmt_ | CatchAnyBlock_ | | ++----------------------------------------------------------+--------------------------------+---------------------------------------------------+ +| ``goto *`` *labelptr* ``;`` | ComputedGotoStmt_ | GNU extension; use with LabelLiteral_ | ++----------------------------------------------------------+--------------------------------+---------------------------------------------------+ +| Type_ *i* ``,`` *j* ``;`` | DeclStmt_ | | ++----------------------------------------------------------+--------------------------------+---------------------------------------------------+ +| ``if (`` Expr_ ``)`` Stmt_ ``else`` Stmt_ | IfStmt_ | | ++----------------------------------------------------------+--------------------------------+---------------------------------------------------+ +| ``switch (`` Expr_ ``) {`` SwitchCase_... ``}`` | SwitchStmt_ | | ++----------------------------------------------------------+--------------------------------+---------------------------------------------------+ +| ``do`` Stmt_ ``while (`` Expr_ ``)`` | DoStmt_ | | ++----------------------------------------------------------+--------------------------------+---------------------------------------------------+ +| ``for (`` DeclStmt_ ``;`` Expr_ ``;`` Expr_ ``)`` Stmt_ | ForStmt_ | | ++----------------------------------------------------------+--------------------------------+---------------------------------------------------+ +| ``for (`` DeclStmt_ ``:`` Expr_ ``)`` Stmt_ | RangeBasedForStmt_ | | ++----------------------------------------------------------+--------------------------------+---------------------------------------------------+ +| ``while (`` Expr_ ``)`` Stmt_ | WhileStmt_ | | ++----------------------------------------------------------+--------------------------------+---------------------------------------------------+ +| Expr_ ``;`` | ExprStmt_ | | ++----------------------------------------------------------+--------------------------------+---------------------------------------------------+ +| ``__try {`` ... ``} __except (`` Expr_ ``) {`` ... ``}`` | MicrosoftTryExceptStmt_ | Structured exception handling (SEH) under Windows | ++----------------------------------------------------------+--------------------------------+---------------------------------------------------+ +| ``__try {`` ... ``} __finally {`` ... ``}`` | MicrosoftTryFinallyStmt_ | Structured exception handling (SEH) under Windows | ++----------------------------------------------------------+--------------------------------+---------------------------------------------------+ +| ``return`` Expr_ ``;`` | ReturnStmt_ | | ++----------------------------------------------------------+--------------------------------+---------------------------------------------------+ +| ``case`` Expr_ ``:`` | SwitchCase_ | | ++----------------------------------------------------------+--------------------------------+---------------------------------------------------+ +| ``try {`` Stmt_... ``}`` CatchBlock_... CatchAnyBlock_ | TryStmt_ | | ++----------------------------------------------------------+--------------------------------+---------------------------------------------------+ +| | ``void`` *func* ``(void) try {`` Stmt_... ``}`` | FunctionTryStmt_ | | +| | CatchBlock_... CatchAnyBlock_ | | | ++----------------------------------------------------------+--------------------------------+---------------------------------------------------+ +| ``;`` | EmptyStmt_ | | ++----------------------------------------------------------+--------------------------------+---------------------------------------------------+ +| ``break;`` | BreakStmt_ | | ++----------------------------------------------------------+--------------------------------+---------------------------------------------------+ +| ``continue;`` | ContinueStmt_ | | ++----------------------------------------------------------+--------------------------------+---------------------------------------------------+ +| ``goto`` LabelStmt_ ``;`` | GotoStmt_ | | ++----------------------------------------------------------+--------------------------------+---------------------------------------------------+ +| *slabel* ``:`` | LabelStmt_ | | ++----------------------------------------------------------+--------------------------------+---------------------------------------------------+ +| ``float`` *arr* ``[`` Expr_ ``] [`` Expr_ ``];`` | VlaDeclStmt_ | C99 variable-length array | ++----------------------------------------------------------+--------------------------------+---------------------------------------------------+ + + +Expression classes +~~~~~~~~~~~~~~~~~~ + +This table lists subclasses of Expr_ representing C/C++ expressions. + ++-------------------------------------------------------+----------------------------------------------------+-------------------------------------------+ +| Example syntax | CodeQL class(es) | Remarks | ++=======================================================+====================================================+===========================================+ +| ``{`` Expr_... ``}`` | | ArrayAggregateLiteral_ | | +| | | ClassAggregateLiteral_ | | ++-------------------------------------------------------+----------------------------------------------------+-------------------------------------------+ +| ``alignof (`` Expr_ ``)`` | AlignofExprOperator_ | | ++-------------------------------------------------------+----------------------------------------------------+-------------------------------------------+ +| ``alignof (`` Type_ ``)`` | AlignofTypeOperator_ | | ++-------------------------------------------------------+----------------------------------------------------+-------------------------------------------+ +| Expr_ ``[`` Expr_ ``]`` | ArrayExpr_ | | ++-------------------------------------------------------+----------------------------------------------------+-------------------------------------------+ +| ``__assume (`` Expr_ ``)`` | AssumeExpr_ | Microsoft extension | ++-------------------------------------------------------+----------------------------------------------------+-------------------------------------------+ +| ``static_assert (`` Expr_ ``,`` StringLiteral_ ``)`` | StaticAssert_ | | C++11 | +| ``_Static_assert (`` Expr_ ``,`` StringLiteral_ ``)`` | | | C11 | ++-------------------------------------------------------+----------------------------------------------------+-------------------------------------------+ +| ``__noop;`` | BuiltInNoOp_ | Microsoft extension | ++-------------------------------------------------------+----------------------------------------------------+-------------------------------------------+ +| Expr_ ``(`` Expr_... ``)`` | ExprCall_ | | ++-------------------------------------------------------+----------------------------------------------------+-------------------------------------------+ +| | *func* ``(`` Expr_... ``)`` | FunctionCall_ | | +| | *instance* ``.`` *func* ``(`` Expr_... ``)`` | | | ++-------------------------------------------------------+----------------------------------------------------+-------------------------------------------+ +| Expr_ ``,`` Expr_ | CommaExpr_ | | ++-------------------------------------------------------+----------------------------------------------------+-------------------------------------------+ +| ``if (`` Type_ *arg* ``=`` Expr_ ``)`` | ConditionDeclExpr_ | | ++-------------------------------------------------------+----------------------------------------------------+-------------------------------------------+ +| ``(`` Type_ ``)`` Expr_ | CStyleCast_ | | ++-------------------------------------------------------+----------------------------------------------------+-------------------------------------------+ +| ``const_cast <`` Type_ ``> (`` Expr_ ``)`` | ConstCast_ | | ++-------------------------------------------------------+----------------------------------------------------+-------------------------------------------+ +| ``dynamic_cast <`` Type_ ``> (`` Expr_ ``)`` | DynamicCast_ | | ++-------------------------------------------------------+----------------------------------------------------+-------------------------------------------+ +| ``reinterpret_cast <`` Type_ ``> (`` Expr_ ``)`` | ReinterpretCast_ | | ++-------------------------------------------------------+----------------------------------------------------+-------------------------------------------+ +| ``static_cast <`` Type_ ``> (`` Expr_ ``)`` | StaticCast_ | | ++-------------------------------------------------------+----------------------------------------------------+-------------------------------------------+ +| | ``template < typename...`` *T* ``>`` | FoldExpr_ | Appears only in *uninstantiated* | +| | ``auto`` *sum* ``(`` *T* `...` *t* ``)`` | | templates | +| | ``{ return (`` *t* ``+ ... + 0 ); }`` | | | ++-------------------------------------------------------+----------------------------------------------------+-------------------------------------------+ +| ``int`` *func* ``(`` *format* ``, ... );`` | FormattingFunctionCall_ | | ++-------------------------------------------------------+----------------------------------------------------+-------------------------------------------+ +| | ``[ = ] ( float`` *b* ``) -> float`` | LambdaExpression_ | C++11 | +| | ``{ return`` *captured* ``*`` *b* ``; }`` | | | ++-------------------------------------------------------+----------------------------------------------------+-------------------------------------------+ +| | ``^ int ( int`` *x* ``, int`` *y* ``) {`` | BlockExpr_ | Apple extension | +| | ``{`` Stmt_... ``; return`` *x* ``+`` *y* ``; }``| | | ++-------------------------------------------------------+----------------------------------------------------+-------------------------------------------+ +| ``void *`` *labelptr* ``= &&`` *label* ``;`` | LabelLiteral_ | GNU extension; use with ComputedGotoStmt_ | ++-------------------------------------------------------+----------------------------------------------------+-------------------------------------------+ +| *"%3d %s\\n"* | FormatLiteral_ | | ++-------------------------------------------------------+----------------------------------------------------+-------------------------------------------+ +| *0xdbceffca* | HexLiteral_ | | ++-------------------------------------------------------+----------------------------------------------------+-------------------------------------------+ +| *0167* | OctalLiteral_ | | ++-------------------------------------------------------+----------------------------------------------------+-------------------------------------------+ +| *'c'* | CharLiteral_ | | ++-------------------------------------------------------+----------------------------------------------------+-------------------------------------------+ +| *"abcdefgh"*, *L"wide"* | StringLiteral_ | | ++-------------------------------------------------------+----------------------------------------------------+-------------------------------------------+ +| ``new`` Type_ ``[`` Expr_ ``]`` | NewArrayExpr_ | | ++-------------------------------------------------------+----------------------------------------------------+-------------------------------------------+ +| ``new`` Type_ | NewExpr_ | | ++-------------------------------------------------------+----------------------------------------------------+-------------------------------------------+ +| ``delete [ ]`` Expr_ ``;`` | DeleteArrayExpr_ | | ++-------------------------------------------------------+----------------------------------------------------+-------------------------------------------+ +| ``delete`` Expr_ ``;`` | DeleteExpr_ | | ++-------------------------------------------------------+----------------------------------------------------+-------------------------------------------+ +| ``noexcept (`` Expr_ ``)`` | NoExceptExpr_ | | ++-------------------------------------------------------+----------------------------------------------------+-------------------------------------------+ +| Expr_ ``=`` Expr_ | AssignExpr_ | See also Initializer_ | ++-------------------------------------------------------+----------------------------------------------------+-------------------------------------------+ +| Expr_ ``+=`` Expr_ | | AssignAddExpr_ | | +| | | AssignPointerAddExpr_ | | ++-------------------------------------------------------+----------------------------------------------------+-------------------------------------------+ +| Expr_ ``/=`` Expr_ | AssignDivExpr_ | | ++-------------------------------------------------------+----------------------------------------------------+-------------------------------------------+ +| Expr_ ``*=`` Expr_ | AssignMulExpr_ | | ++-------------------------------------------------------+----------------------------------------------------+-------------------------------------------+ +| Expr_ ``%=`` Expr_ | AssignRemExpr_ | | ++-------------------------------------------------------+----------------------------------------------------+-------------------------------------------+ +| Expr_ ``-=`` Expr_ | | AssignSubExpr_ | | +| | | AssignPointerSubExpr_ | | ++-------------------------------------------------------+----------------------------------------------------+-------------------------------------------+ +| Expr_ ``&=`` Expr_ | AssignAndExpr_ | | ++-------------------------------------------------------+----------------------------------------------------+-------------------------------------------+ +| Expr_ ``<<=`` Expr_ | AssignLShiftExpr_ | | ++-------------------------------------------------------+----------------------------------------------------+-------------------------------------------+ +| Expr_ `` | =`` Expr_ | AssignOrExpr_ | ++-------------------------------------------------------+----------------------------------------------------+-------------------------------------------+ +| Expr_ ``>>=`` Expr_ | AssignRShiftExpr_ | | ++-------------------------------------------------------+----------------------------------------------------+-------------------------------------------+ +| Expr_ ``^=`` Expr_ | AssignXorExpr_ | | ++-------------------------------------------------------+----------------------------------------------------+-------------------------------------------+ +| Expr_ ``+`` Expr_ | | AddExpr_ | | | +| | | PointerAddExpr_ | | | +| | | ImaginaryRealAddExpr_ | | C99 | +| | | RealImaginaryAddExpr_ | | C99 | ++-------------------------------------------------------+----------------------------------------------------+-------------------------------------------+ +| Expr_ ``/`` Expr_ | | DivExpr_ | | | +| | | ImaginaryDivExpr_ | | C99 | ++-------------------------------------------------------+----------------------------------------------------+-------------------------------------------+ +| Expr_ ``>?`` Expr_ | MaxExpr_ | GNU extension | ++-------------------------------------------------------+----------------------------------------------------+-------------------------------------------+ +| Expr_ ``<?`` Expr_ | MinExpr_ | GNU extension | ++-------------------------------------------------------+----------------------------------------------------+-------------------------------------------+ +| Expr_ ``*`` Expr_ | | MulExpr_ | | | +| | | ImaginaryMulExpr_ | | C99 | ++-------------------------------------------------------+----------------------------------------------------+-------------------------------------------+ +| Expr_ ``%`` Expr_ | RemExpr_ | | ++-------------------------------------------------------+----------------------------------------------------+-------------------------------------------+ +| Expr_ ``-`` Expr_ | | SubExpr_ | | | +| | | PointerDiffExpr_ | | | +| | | PointerSubExpr_ | | | +| | | ImaginaryRealSubExpr_ | | C99 | +| | | RealImaginarySubExpr_ | | C99 | ++-------------------------------------------------------+----------------------------------------------------+-------------------------------------------+ +| Expr_ ``&`` Expr_ | BitwiseAndExpr_ | | ++-------------------------------------------------------+----------------------------------------------------+-------------------------------------------+ +| Expr_ ``|`` Expr_ | BitwiseOrExpr_ | | ++-------------------------------------------------------+----------------------------------------------------+-------------------------------------------+ +| Expr_ ``^`` Expr_ | BitwiseXorExpr_ | | ++-------------------------------------------------------+----------------------------------------------------+-------------------------------------------+ +| Expr_ ``<<`` Expr_ | LShiftExpr_ | | ++-------------------------------------------------------+----------------------------------------------------+-------------------------------------------+ +| Expr_ ``>>`` Expr_ | RShiftExpr_ | | ++-------------------------------------------------------+----------------------------------------------------+-------------------------------------------+ +| Expr_ ``&&`` Expr_ | LogicalAndExpr_ | | ++-------------------------------------------------------+----------------------------------------------------+-------------------------------------------+ +| Expr_ ``||`` Expr_ | LogicalOrExpr_ | | ++-------------------------------------------------------+----------------------------------------------------+-------------------------------------------+ +| Expr_ ``==`` Expr_ | EQExpr_ | | ++-------------------------------------------------------+----------------------------------------------------+-------------------------------------------+ +| Expr_ ``!=`` Expr_ | NEExpr_ | | ++-------------------------------------------------------+----------------------------------------------------+-------------------------------------------+ +| Expr_ ``>=`` Expr_ | GEExpr_ | | ++-------------------------------------------------------+----------------------------------------------------+-------------------------------------------+ +| Expr_ ``>`` Expr_ | GTExpr_ | | ++-------------------------------------------------------+----------------------------------------------------+-------------------------------------------+ +| Expr_ ``<=`` Expr_ | LEExpr_ | | ++-------------------------------------------------------+----------------------------------------------------+-------------------------------------------+ +| Expr_ ``<`` Expr_ | LTExpr_ | | ++-------------------------------------------------------+----------------------------------------------------+-------------------------------------------+ +| Expr_ ``?`` Expr_ ``:`` Expr_ | ConditionalExpr_ | | ++-------------------------------------------------------+----------------------------------------------------+-------------------------------------------+ +| ``&`` Expr_ | AddressOfExpr_ | | ++-------------------------------------------------------+----------------------------------------------------+-------------------------------------------+ +| ``*`` Expr_ | PointerDereferenceExpr_ | | ++-------------------------------------------------------+----------------------------------------------------+-------------------------------------------+ +| Expr_ ``--`` | PostfixDecrExpr_ | | ++-------------------------------------------------------+----------------------------------------------------+-------------------------------------------+ +| ``--`` Expr_ | PrefixDecrExpr_ | | ++-------------------------------------------------------+----------------------------------------------------+-------------------------------------------+ +| Expr_ ``++`` | PostfixIncrExpr_ | | ++-------------------------------------------------------+----------------------------------------------------+-------------------------------------------+ +| ``++`` Expr_ | PrefixIncrExpr_ | | ++-------------------------------------------------------+----------------------------------------------------+-------------------------------------------+ +| ``__imag (`` Expr_ ``)`` | ImaginaryPartExpr_ | GNU extension | ++-------------------------------------------------------+----------------------------------------------------+-------------------------------------------+ +| ``__real (`` Expr_ ``)`` | RealPartExpr_ | GNU extension | ++-------------------------------------------------------+----------------------------------------------------+-------------------------------------------+ +| ``-`` Expr_ | UnaryMinusExpr_ | | ++-------------------------------------------------------+----------------------------------------------------+-------------------------------------------+ +| ``+`` Expr_ | UnaryPlusExpr_ | | ++-------------------------------------------------------+----------------------------------------------------+-------------------------------------------+ +| ``~`` Expr_ | | ComplementExpr_ | | | +| | | ConjugationExpr_ | | GNU extension | ++-------------------------------------------------------+----------------------------------------------------+-------------------------------------------+ +| ``!`` Expr_ | NotExpr_ | | ++-------------------------------------------------------+----------------------------------------------------+-------------------------------------------+ +| | ``int`` *vect* ``__attribute__`` | VectorFillOperation_ | GNU extension | +| | ``( ( vector_size (`` *16* ``) ) )`` | | | +| | ``= {`` *3* ``,`` *8* ``,`` *32* ``,`` | | | +| *33* ``};`` | | | ++-------------------------------------------------------+----------------------------------------------------+-------------------------------------------+ +| ``sizeof (`` Expr_ ``)`` | SizeofExprOperator_ | | ++-------------------------------------------------------+----------------------------------------------------+-------------------------------------------+ +| ``sizeof (`` Type_ ``)`` | SizeofTypeOperator_ | | ++-------------------------------------------------------+----------------------------------------------------+-------------------------------------------+ +| | ``template < typename...`` *T* ``>`` | SizeofPackOperator_ | | +| | ``int`` *count* ``(`` *T* ``&&...`` *t* ``)`` | | | +| | ``{ return sizeof... (`` *t* ``); }`` | | | ++-------------------------------------------------------+----------------------------------------------------+-------------------------------------------+ +| ``( {`` Stmt_... ``;`` Expr_ ``} )`` | StmtExpr_ | GNU/Clang extension | ++-------------------------------------------------------+----------------------------------------------------+-------------------------------------------+ +| ``this`` | ThisExpr_ | | ++-------------------------------------------------------+----------------------------------------------------+-------------------------------------------+ +| ``throw (`` Expr_ ``);`` | ThrowExpr_ | | ++-------------------------------------------------------+----------------------------------------------------+-------------------------------------------+ +| ``throw;`` | ReThrowExpr_ | | ++-------------------------------------------------------+----------------------------------------------------+-------------------------------------------+ +| | ``typeid (`` Expr_ ``)`` | TypeidOperator_ | | +| | ``typeid (`` Type_ ``)`` | | | ++-------------------------------------------------------+----------------------------------------------------+-------------------------------------------+ +| ``__uuidof (`` Expr_ ``)`` | UuidofOperator_ | Microsoft extension | ++-------------------------------------------------------+----------------------------------------------------+-------------------------------------------+ + +Type classes +~~~~~~~~~~~~ + +This table lists subclasses of Type_ representing C/C++ types. + ++-------------------------------------------------------------------+---------------------------------+-----------------+ +| Example syntax | CodeQL class | Remarks | ++===================================================================+=================================+=================+ +| ``void`` | VoidType_ | | ++-------------------------------------------------------------------+---------------------------------+-----------------+ +| ``_Bool`` or ``bool`` | BoolType_ | | ++-------------------------------------------------------------------+---------------------------------+-----------------+ +| ``char16_t`` | Char16Type_ | C11, C++11 | ++-------------------------------------------------------------------+---------------------------------+-----------------+ +| ``char32_t`` | Char32Type_ | C11, C++11 | ++-------------------------------------------------------------------+---------------------------------+-----------------+ +| ``char`` | PlainCharType_ | | ++-------------------------------------------------------------------+---------------------------------+-----------------+ +| ``signed char`` | SignedCharType_ | | ++-------------------------------------------------------------------+---------------------------------+-----------------+ +| ``unsigned char`` | UnsignedCharType_ | | ++-------------------------------------------------------------------+---------------------------------+-----------------+ +| ``int`` | IntType_ | | ++-------------------------------------------------------------------+---------------------------------+-----------------+ +| ``long long`` | LongLongType_ | | ++-------------------------------------------------------------------+---------------------------------+-----------------+ +| ``long`` | LongType_ | | ++-------------------------------------------------------------------+---------------------------------+-----------------+ +| ``short`` | ShortType_ | | ++-------------------------------------------------------------------+---------------------------------+-----------------+ +| ``wchar_t`` | WideCharType_ | | ++-------------------------------------------------------------------+---------------------------------+-----------------+ +| ``nullptr_t`` | NullPointerType_ | | ++-------------------------------------------------------------------+---------------------------------+-----------------+ +| ``double`` | DoubleType_ | | ++-------------------------------------------------------------------+---------------------------------+-----------------+ +| ``long double`` | LongDoubleType_ | | ++-------------------------------------------------------------------+---------------------------------+-----------------+ +| ``float`` | FloatType_ | | ++-------------------------------------------------------------------+---------------------------------+-----------------+ +| ``auto`` | AutoType_ | | ++-------------------------------------------------------------------+---------------------------------+-----------------+ +| ``decltype (`` Expr_ ``)`` | Decltype_ | | ++-------------------------------------------------------------------+---------------------------------+-----------------+ +| Type_ ``[`` *n* ``]`` | ArrayType_ | | ++-------------------------------------------------------------------+---------------------------------+-----------------+ +| Type_ ``( ^`` *blockptr* ``) (`` Parameter_... ``)`` | BlockType_ | Apple extension | ++-------------------------------------------------------------------+---------------------------------+-----------------+ +| Type_ ``( *`` *funcptr* ``) (`` Parameter_... ``)`` | FunctionPointerType_ | | ++-------------------------------------------------------------------+---------------------------------+-----------------+ +| Type_ ``( &`` *funcref* ``) (`` Parameter_... ``)`` | FunctionReferenceType_ | | ++-------------------------------------------------------------------+---------------------------------+-----------------+ +| Type_ ``__attribute__ ( ( vector_size (`` *n* ``) ) )`` | GNUVectorType_ | | ++-------------------------------------------------------------------+---------------------------------+-----------------+ +| Type_ ``*`` | PointerType_ | | ++-------------------------------------------------------------------+---------------------------------+-----------------+ +| Type_ ``&`` | LValueReferenceType_ | | ++-------------------------------------------------------------------+---------------------------------+-----------------+ +| Type_ ``&&`` | RValueReferenceType_ | | ++-------------------------------------------------------------------+---------------------------------+-----------------+ +| Type_ ``(`` Class_ ``*::`` *membptr* ``) (`` Parameter_... ``)`` | PointerToMemberType_ | | ++-------------------------------------------------------------------+---------------------------------+-----------------+ +| ``template < template < typename > class`` *C* ``>`` | TemplateTemplateParameter_ | | ++-------------------------------------------------------------------+---------------------------------+-----------------+ +| ``template < typename`` *T* ``>`` | TemplateParameter_ | | ++-------------------------------------------------------------------+---------------------------------+-----------------+ + + +Preprocessor classes +~~~~~~~~~~~~~~~~~~~~ + +This table lists Preprocessor_ classes representing C/C++ preprocessing directives. + ++-------------------------------------+----------------------+----------------------+ +| Example syntax | CodeQL class | Remarks | ++=====================================+======================+======================+ +| ``#elif`` *condition* | PreprocessorElif_ | | ++-------------------------------------+----------------------+----------------------+ +| ``#if`` *condition* | PreprocessorIf_ | | ++-------------------------------------+----------------------+----------------------+ +| ``#ifdef`` *macro* | PreprocessorIfdef_ | | ++-------------------------------------+----------------------+----------------------+ +| ``#ifndef`` *macro* | PreprocessorIfndef_ | | ++-------------------------------------+----------------------+----------------------+ +| ``#else`` | PreprocessorElse_ | | ++-------------------------------------+----------------------+----------------------+ +| ``#endif`` | PreprocessorEndif_ | | ++-------------------------------------+----------------------+----------------------+ +| ``#line`` *line_number* *file_name* | PreprocessorLine_ | | ++-------------------------------------+----------------------+----------------------+ +| ``#pragma`` *pragma_property* | PreprocessorPragma_ | | ++-------------------------------------+----------------------+----------------------+ +| ``#undef`` *macro* | PreprocessorUndef_ | | ++-------------------------------------+----------------------+----------------------+ +| ``#warning`` *message* | PreprocessorWarning_ | | ++-------------------------------------+----------------------+----------------------+ +| ``#error`` *message* | PreprocessorError_ | | ++-------------------------------------+----------------------+----------------------+ +| ``#include`` *file_name* | Include_ | | ++-------------------------------------+----------------------+----------------------+ +| ``#import`` *file_name* | Import_ | Apple/NeXT extension | ++-------------------------------------+----------------------+----------------------+ +| ``#include_next`` *file_name* | IncludeNext_ | Apple/NeXT extension | ++-------------------------------------+----------------------+----------------------+ +| ``#define`` *macro* ... | Macro_ | | ++-------------------------------------+----------------------+----------------------+ + +Further reading +--------------- + +.. include:: ../reusables/cpp-further-reading.rst +.. include:: ../reusables/codeql-ref-tools-further-reading.rst + +.. Links used in tables. For information about using these links, see + https://www.sphinx-doc.org/en/master/usage/restructuredtext/basics.html#hyperlinks. + +.. _Declaration: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/Declaration.qll/type.Declaration$Declaration.html +.. _GlobalVariable: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/Variable.qll/type.Variable$GlobalVariable.html +.. _NamespaceVariable: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/Variable.qll/type.Variable$NamespaceVariable.html +.. _LocalVariable: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/Variable.qll/type.Variable$LocalVariable.html +.. _Initializer: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/Initializer.qll/type.Initializer$Initializer.html +.. _MemberVariable: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/Variable.qll/type.Variable$MemberVariable.html +.. _Function: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/Function.qll/type.Function$Function.html +.. _TemplateFunction: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/Function.qll/type.Function$TemplateFunction.html +.. _FormattingFunction: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/models/interfaces/FormattingFunction.qll/type.FormattingFunction$FormattingFunction.html +.. _FunctionTemplateInstantiation: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/Function.qll/type.Function$FunctionTemplateInstantiation.html +.. _FunctionTemplateSpecialization: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/Function.qll/type.Function$FunctionTemplateSpecialization.html +.. _MemberFunction: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/MemberFunction.qll/type.MemberFunction$MemberFunction.html +.. _ConstMemberFunction: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/MemberFunction.qll/type.MemberFunction$ConstMemberFunction.html +.. _VirtualFunction: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/MemberFunction.qll/type.MemberFunction$VirtualFunction.html +.. _Constructor: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/MemberFunction.qll/type.MemberFunction$Constructor.html +.. _ConversionOperator: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/MemberFunction.qll/type.MemberFunction$ConversionOperator.html +.. _Destructor: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/MemberFunction.qll/type.MemberFunction$Destructor.html +.. _ConversionConstructor: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/MemberFunction.qll/type.MemberFunction$ConversionConstructor.html +.. _CopyAssignmentOperator: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/MemberFunction.qll/type.MemberFunction$CopyAssignmentOperator.html +.. _MoveAssignmentOperator: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/MemberFunction.qll/type.MemberFunction$MoveAssignmentOperator.html +.. _CopyConstructor: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/MemberFunction.qll/type.MemberFunction$CopyConstructor.html +.. _MoveConstructor: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/MemberFunction.qll/type.MemberFunction$MoveConstructor.html +.. _NoArgConstructor: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/MemberFunction.qll/type.MemberFunction$NoArgConstructor.html +.. _EnumConstant: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/Enum.qll/type.Enum$EnumConstant.html +.. _FriendDecl: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/FriendDecl.qll/type.FriendDecl$FriendDecl.html +.. _LocalEnum: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/Enum.qll/type.Enum$LocalEnum.html +.. _NestedEnum: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/Enum.qll/type.Enum$NestedEnum.html +.. _ScopedEnum: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/Enum.qll/type.Enum$ScopedEnum.html +.. _AbstractClass: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/Class.qll/type.Class$AbstractClass.html +.. _ClassTemplateInstantiation: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/Class.qll/type.Class$ClassTemplateInstantiation.html +.. _Type: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/Type.qll/type.Type$Type.html +.. _FullClassTemplateSpecialization: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/Class.qll/type.Class$FullClassTemplateSpecialization.html +.. _PartialClassTemplateSpecialization: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/Class.qll/type.Class$PartialClassTemplateSpecialization.html +.. _LocalClass: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/Class.qll/type.Class$LocalClass.html +.. _NestedClass: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/Class.qll/type.Class$NestedClass.html +.. _Class: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/Class.qll/type.Class$Class.html +.. _Parameter: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/Parameter.qll/type.Parameter$Parameter.html +.. _Struct: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/Struct.qll/type.Struct$Struct.html +.. _Union: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/Union.qll/type.Union$Union.html +.. _ProxyClass: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/Class.qll/type.Class$ProxyClass.html +.. _LocalStruct: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/Struct.qll/type.Struct$LocalStruct.html +.. _NestedStruct: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/Struct.qll/type.Struct$NestedStruct.html +.. _LocalUnion: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/Union.qll/type.Union$LocalUnion.html +.. _NestedUnion: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/Union.qll/type.Union$NestedUnion.html +.. _TypedefType: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/TypedefType.qll/type.TypedefType$TypedefType.html +.. _LocalTypedefType: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/TypedefType.qll/type.TypedefType$LocalTypedefType.html +.. _NestedTypedefType: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/TypedefType.qll/type.TypedefType$NestedTypedefType.html +.. _ClassDerivation: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/Class.qll/type.Class$ClassDerivation.html +.. _VirtualClassDerivation: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/Class.qll/type.Class$VirtualClassDerivation.html +.. _TemplateClass: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/Class.qll/type.Class$TemplateClass.html +.. _TemplateVariable: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/Variable.qll/type.Variable$TemplateVariable.html +.. _Stmt: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/stmts/Stmt.qll/type.Stmt$Stmt.html +.. _AsmStmt: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/stmts/Stmt.qll/type.Stmt$AsmStmt.html +.. _BlockStmt: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/stmts/Block.qll/type.Block$BlockStmt.html +.. _CatchBlock: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/stmts/Stmt.qll/type.Stmt$CatchBlock.html +.. _CatchAnyBlock: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/stmts/Stmt.qll/type.Stmt$CatchAnyBlock.html +.. _ComputedGotoStmt: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/stmts/Stmt.qll/type.Stmt$ComputedGotoStmt.html +.. _LabelLiteral: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/exprs/Literal.qll/type.Literal$LabelLiteral.html +.. _DeclStmt: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/stmts/Stmt.qll/type.Stmt$DeclStmt.html +.. _Expr: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/exprs/Expr.qll/type.Expr$Expr.html +.. _IfStmt: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/stmts/Stmt.qll/type.Stmt$IfStmt.html +.. _SwitchCase: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/stmts/Stmt.qll/type.Stmt$SwitchCase.html +.. _SwitchStmt: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/stmts/Stmt.qll/type.Stmt$SwitchStmt.html +.. _DoStmt: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/stmts/Stmt.qll/type.Stmt$DoStmt.html +.. _ForStmt: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/stmts/Stmt.qll/type.Stmt$ForStmt.html +.. _RangeBasedForStmt: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/stmts/Stmt.qll/type.Stmt$RangeBasedForStmt.html +.. _WhileStmt: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/stmts/Stmt.qll/type.Stmt$WhileStmt.html +.. _ExprStmt: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/stmts/Stmt.qll/type.Stmt$ExprStmt.html +.. _MicrosoftTryExceptStmt: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/stmts/Stmt.qll/type.Stmt$MicrosoftTryExceptStmt.html +.. _MicrosoftTryFinallyStmt: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/stmts/Stmt.qll/type.Stmt$MicrosoftTryFinallyStmt.html +.. _ReturnStmt: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/stmts/Stmt.qll/type.Stmt$ReturnStmt.html +.. _TryStmt: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/stmts/Stmt.qll/type.Stmt$TryStmt.html +.. _FunctionTryStmt: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/stmts/Stmt.qll/type.Stmt$FunctionTryStmt.html +.. _EmptyStmt: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/stmts/Stmt.qll/type.Stmt$EmptyStmt.html +.. _BreakStmt: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/stmts/Stmt.qll/type.Stmt$BreakStmt.html +.. _ContinueStmt: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/stmts/Stmt.qll/type.Stmt$ContinueStmt.html +.. _LabelStmt: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/stmts/Stmt.qll/type.Stmt$LabelStmt.html +.. _GotoStmt: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/stmts/Stmt.qll/type.Stmt$GotoStmt.html +.. _VlaDeclStmt: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/stmts/Stmt.qll/type.Stmt$VlaDeclStmt.html +.. _ArrayAggregateLiteral: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/exprs/Literal.qll/type.Literal$ArrayAggregateLiteral.html +.. _ClassAggregateLiteral: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/exprs/Literal.qll/type.Literal$ClassAggregateLiteral.html +.. _AlignofExprOperator: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/exprs/Cast.qll/type.Cast$AlignofExprOperator.html +.. _AlignofTypeOperator: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/exprs/Cast.qll/type.Cast$AlignofTypeOperator.html +.. _ArrayExpr: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/exprs/Access.qll/type.Access$ArrayExpr.html +.. _AssumeExpr: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/exprs/Expr.qll/type.Expr$AssumeExpr.html +.. _StringLiteral: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/exprs/Literal.qll/type.Literal$StringLiteral.html +.. _StaticAssert: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/Element.qll/type.Element$StaticAssert.html +.. _BuiltInNoOp: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/exprs/BuiltInOperations.qll/type.BuiltInOperations$BuiltInNoOp.html +.. _ExprCall: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/exprs/Call.qll/type.Call$ExprCall.html +.. _FunctionCall: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/exprs/Call.qll/type.Call$FunctionCall.html +.. _CommaExpr: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/exprs/Expr.qll/type.Expr$CommaExpr.html +.. _ConditionDeclExpr: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/exprs/Assignment.qll/type.Assignment$ConditionDeclExpr.html +.. _CStyleCast: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/exprs/Cast.qll/type.Cast$CStyleCast.html +.. _ConstCast: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/exprs/Cast.qll/type.Cast$ConstCast.html +.. _DynamicCast: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/exprs/Cast.qll/type.Cast$DynamicCast.html +.. _ReinterpretCast: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/exprs/Cast.qll/type.Cast$ReinterpretCast.html +.. _StaticCast: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/exprs/Cast.qll/type.Cast$StaticCast.html +.. _FoldExpr: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/exprs/Expr.qll/type.Expr$FoldExpr.html +.. _FormattingFunctionCall: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/commons/Printf.qll/type.Printf$FormattingFunctionCall.html +.. _LambdaExpression: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/exprs/Lambda.qll/type.Lambda$LambdaExpression.html +.. _BlockExpr: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/exprs/Expr.qll/type.Expr$BlockExpr.html +.. _FormatLiteral: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/commons/Printf.qll/type.Printf$FormatLiteral.html +.. _HexLiteral: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/exprs/Literal.qll/type.Literal$HexLiteral.html +.. _OctalLiteral: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/exprs/Literal.qll/type.Literal$OctalLiteral.html +.. _CharLiteral: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/exprs/Literal.qll/type.Literal$CharLiteral.html +.. _NewArrayExpr: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/exprs/Expr.qll/type.Expr$NewArrayExpr.html +.. _NewExpr: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/exprs/Expr.qll/type.Expr$NewExpr.html +.. _DeleteArrayExpr: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/exprs/Expr.qll/type.Expr$DeleteArrayExpr.html +.. _DeleteExpr: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/exprs/Expr.qll/type.Expr$DeleteExpr.html +.. _NoExceptExpr: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/exprs/Expr.qll/type.Expr$NoExceptExpr.html +.. _AssignExpr: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/exprs/Assignment.qll/type.Assignment$AssignExpr.html +.. _AssignAddExpr: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/exprs/Assignment.qll/type.Assignment$AssignAddExpr.html +.. _AssignPointerAddExpr: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/exprs/Assignment.qll/type.Assignment$AssignPointerAddExpr.html +.. _AssignDivExpr: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/exprs/Assignment.qll/type.Assignment$AssignDivExpr.html +.. _AssignMulExpr: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/exprs/Assignment.qll/type.Assignment$AssignMulExpr.html +.. _AssignRemExpr: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/exprs/Assignment.qll/type.Assignment$AssignRemExpr.html +.. _AssignSubExpr: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/exprs/Assignment.qll/type.Assignment$AssignSubExpr.html +.. _AssignPointerSubExpr: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/exprs/Assignment.qll/type.Assignment$AssignPointerSubExpr.html +.. _AssignAndExpr: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/exprs/Assignment.qll/type.Assignment$AssignAndExpr.html +.. _AssignLShiftExpr: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/exprs/Assignment.qll/type.Assignment$AssignLShiftExpr.html +.. _AssignOrExpr: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/exprs/Assignment.qll/type.Assignment$AssignOrExpr.html +.. _AssignRShiftExpr: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/exprs/Assignment.qll/type.Assignment$AssignRShiftExpr.html +.. _AssignXorExpr: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/exprs/Assignment.qll/type.Assignment$AssignXorExpr.html +.. _AddExpr: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/exprs/ArithmeticOperation.qll/type.ArithmeticOperation$AddExpr.html +.. _PointerAddExpr: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/exprs/ArithmeticOperation.qll/type.ArithmeticOperation$PointerAddExpr.html +.. _ImaginaryRealAddExpr: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/exprs/ArithmeticOperation.qll/type.ArithmeticOperation$ImaginaryRealAddExpr.html +.. _RealImaginaryAddExpr: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/exprs/ArithmeticOperation.qll/type.ArithmeticOperation$RealImaginaryAddExpr.html +.. _DivExpr: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/exprs/ArithmeticOperation.qll/type.ArithmeticOperation$DivExpr.html +.. _ImaginaryDivExpr: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/exprs/ArithmeticOperation.qll/type.ArithmeticOperation$ImaginaryDivExpr.html +.. _MaxExpr: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/exprs/ArithmeticOperation.qll/type.ArithmeticOperation$MaxExpr.html +.. _MinExpr: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/exprs/ArithmeticOperation.qll/type.ArithmeticOperation$MinExpr.html +.. _MulExpr: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/exprs/ArithmeticOperation.qll/type.ArithmeticOperation$MulExpr.html +.. _ImaginaryMulExpr: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/exprs/ArithmeticOperation.qll/type.ArithmeticOperation$ImaginaryMulExpr.html +.. _RemExpr: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/exprs/ArithmeticOperation.qll/type.ArithmeticOperation$RemExpr.html +.. _SubExpr: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/exprs/ArithmeticOperation.qll/type.ArithmeticOperation$SubExpr.html +.. _PointerDiffExpr: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/exprs/ArithmeticOperation.qll/type.ArithmeticOperation$PointerDiffExpr.html +.. _PointerSubExpr: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/exprs/ArithmeticOperation.qll/type.ArithmeticOperation$PointerSubExpr.html +.. _ImaginaryRealSubExpr: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/exprs/ArithmeticOperation.qll/type.ArithmeticOperation$ImaginaryRealSubExpr.html +.. _RealImaginarySubExpr: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/exprs/ArithmeticOperation.qll/type.ArithmeticOperation$RealImaginarySubExpr.html +.. _BitwiseAndExpr: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/exprs/BitwiseOperation.qll/type.BitwiseOperation$BitwiseAndExpr.html +.. _BitwiseOrExpr: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/exprs/BitwiseOperation.qll/type.BitwiseOperation$BitwiseOrExpr.html +.. _BitwiseXorExpr: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/exprs/BitwiseOperation.qll/type.BitwiseOperation$BitwiseXorExpr.html +.. _LShiftExpr: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/exprs/BitwiseOperation.qll/type.BitwiseOperation$LShiftExpr.html +.. _RShiftExpr: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/exprs/BitwiseOperation.qll/type.BitwiseOperation$RShiftExpr.html +.. _LogicalAndExpr: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/exprs/LogicalOperation.qll/type.LogicalOperation$LogicalAndExpr.html +.. _LogicalOrExpr: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/exprs/LogicalOperation.qll/type.LogicalOperation$LogicalOrExpr.html +.. _EQExpr: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/exprs/ComparisonOperation.qll/type.ComparisonOperation$EQExpr.html +.. _NEExpr: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/exprs/ComparisonOperation.qll/type.ComparisonOperation$NEExpr.html +.. _GEExpr: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/exprs/ComparisonOperation.qll/type.ComparisonOperation$GEExpr.html +.. _GTExpr: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/exprs/ComparisonOperation.qll/type.ComparisonOperation$GTExpr.html +.. _LEExpr: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/exprs/ComparisonOperation.qll/type.ComparisonOperation$LEExpr.html +.. _LTExpr: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/exprs/ComparisonOperation.qll/type.ComparisonOperation$LTExpr.html +.. _ConditionalExpr: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/exprs/LogicalOperation.qll/type.LogicalOperation$ConditionalExpr.html +.. _AddressOfExpr: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/exprs/Expr.qll/type.Expr$AddressOfExpr.html +.. _PointerDereferenceExpr: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/exprs/Expr.qll/type.Expr$PointerDereferenceExpr.html +.. _PostfixDecrExpr: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/exprs/ArithmeticOperation.qll/type.ArithmeticOperation$PostfixDecrExpr.html +.. _PrefixDecrExpr: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/exprs/ArithmeticOperation.qll/type.ArithmeticOperation$PrefixDecrExpr.html +.. _PostfixIncrExpr: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/exprs/ArithmeticOperation.qll/type.ArithmeticOperation$PostfixIncrExpr.html +.. _PrefixIncrExpr: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/exprs/ArithmeticOperation.qll/type.ArithmeticOperation$PrefixIncrExpr.html +.. _ImaginaryPartExpr: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/exprs/ArithmeticOperation.qll/type.ArithmeticOperation$ImaginaryPartExpr.html +.. _RealPartExpr: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/exprs/ArithmeticOperation.qll/type.ArithmeticOperation$RealPartExpr.html +.. _UnaryMinusExpr: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/exprs/ArithmeticOperation.qll/type.ArithmeticOperation$UnaryMinusExpr.html +.. _UnaryPlusExpr: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/exprs/ArithmeticOperation.qll/type.ArithmeticOperation$UnaryPlusExpr.html +.. _ComplementExpr: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/exprs/BitwiseOperation.qll/type.BitwiseOperation$ComplementExpr.html +.. _ConjugationExpr: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/exprs/ArithmeticOperation.qll/type.ArithmeticOperation$ConjugationExpr.html +.. _NotExpr: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/exprs/LogicalOperation.qll/type.LogicalOperation$NotExpr.html +.. _VectorFillOperation: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/exprs/BuiltInOperations.qll/type.BuiltInOperations$VectorFillOperation.html +.. _SizeofExprOperator: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/exprs/Cast.qll/type.Cast$SizeofExprOperator.html +.. _SizeofTypeOperator: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/exprs/Cast.qll/type.Cast$SizeofTypeOperator.html +.. _SizeofPackOperator: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/exprs/Cast.qll/type.Cast$SizeofPackOperator.html +.. _StmtExpr: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/exprs/Expr.qll/type.Expr$StmtExpr.html +.. _ThisExpr: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/exprs/Expr.qll/type.Expr$ThisExpr.html +.. _ThrowExpr: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/exprs/Expr.qll/type.Expr$ThrowExpr.html +.. _ReThrowExpr: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/exprs/Expr.qll/type.Expr$ReThrowExpr.html +.. _TypeidOperator: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/exprs/Cast.qll/type.Cast$TypeidOperator.html +.. _UuidofOperator: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/exprs/Cast.qll/type.Cast$UuidofOperator.html +.. _VoidType: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/Type.qll/type.Type$VoidType.html +.. _BoolType: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/Type.qll/type.Type$BoolType.html +.. _PlainCharType: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/Type.qll/type.Type$PlainCharType.html +.. _SignedCharType: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/Type.qll/type.Type$SignedCharType.html +.. _UnsignedCharType: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/Type.qll/type.Type$UnsignedCharType.html +.. _IntType: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/Type.qll/type.Type$IntType.html +.. _LongLongType: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/Type.qll/type.Type$LongLongType.html +.. _LongType: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/Type.qll/type.Type$LongType.html +.. _ShortType: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/Type.qll/type.Type$ShortType.html +.. _WideCharType: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/Type.qll/type.Type$WideCharType.html +.. _NullPointerType: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/Type.qll/type.Type$NullPointerType.html +.. _DoubleType: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/Type.qll/type.Type$DoubleType.html +.. _LongDoubleType: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/Type.qll/type.Type$LongDoubleType.html +.. _FloatType: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/Type.qll/type.Type$FloatType.html +.. _AutoType: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/Type.qll/type.Type$AutoType.html +.. _Decltype: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/Type.qll/type.Type$Decltype.html +.. _ArrayType: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/Type.qll/type.Type$ArrayType.html +.. _BlockType: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/Type.qll/type.Type$BlockType.html +.. _FunctionPointerType: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/Type.qll/type.Type$FunctionPointerType.html +.. _FunctionReferenceType: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/Type.qll/type.Type$FunctionReferenceType.html +.. _GNUVectorType: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/Type.qll/type.Type$GNUVectorType.html +.. _PointerType: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/Type.qll/type.Type$PointerType.html +.. _LValueReferenceType: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/Type.qll/type.Type$LValueReferenceType.html +.. _RValueReferenceType: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/Type.qll/type.Type$RValueReferenceType.html +.. _PointerToMemberType: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/Type.qll/type.Type$PointerToMemberType.html +.. _TemplateTemplateParameter: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/Type.qll/type.Type$TemplateTemplateParameter.html +.. _TemplateParameter: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/Type.qll/type.Type$TemplateParameter.html +.. _Preprocessor: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/Preprocessor.qll/module.Preprocessor.html +.. _PreprocessorElif: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/Preprocessor.qll/type.Preprocessor$PreprocessorElif.html +.. _PreprocessorIf: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/Preprocessor.qll/type.Preprocessor$PreprocessorIf.html +.. _PreprocessorIfdef: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/Preprocessor.qll/type.Preprocessor$PreprocessorIfdef.html +.. _PreprocessorIfndef: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/Preprocessor.qll/type.Preprocessor$PreprocessorIfndef.html +.. _PreprocessorElse: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/Preprocessor.qll/type.Preprocessor$PreprocessorElse.html +.. _PreprocessorEndif: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/Preprocessor.qll/type.Preprocessor$PreprocessorEndif.html +.. _PreprocessorLine: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/Preprocessor.qll/type.Preprocessor$PreprocessorLine.html +.. _PreprocessorPragma: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/Preprocessor.qll/type.Preprocessor$PreprocessorPragma.html +.. _PreprocessorUndef: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/Preprocessor.qll/type.Preprocessor$PreprocessorUndef.html +.. _PreprocessorWarning: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/Preprocessor.qll/type.Preprocessor$PreprocessorWarning.html +.. _PreprocessorError: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/Preprocessor.qll/type.Preprocessor$PreprocessorError.html +.. _Include: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/Include.qll/type.Include$Include.html +.. _Import: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/Include.qll/type.Include$Import.html +.. _IncludeNext: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/Include.qll/type.Include$IncludeNext.html +.. _Macro: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/Macro.qll/type.Macro$Macro.html +.. _Char16Type: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/Type.qll/type.Type$Char16Type.html +.. _Char32Type: https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/Type.qll/type.Type$Char32Type.html + + diff --git a/docs/codeql/codeql-language-guides/codeql-for-csharp/codeql-library-for-csharp.rst b/docs/codeql/codeql-language-guides/codeql-library-for-csharp.rst similarity index 88% rename from docs/codeql/codeql-language-guides/codeql-for-csharp/codeql-library-for-csharp.rst rename to docs/codeql/codeql-language-guides/codeql-library-for-csharp.rst index e3b2ee2fa27..03a1e449ea8 100644 --- a/docs/codeql/codeql-language-guides/codeql-for-csharp/codeql-library-for-csharp.rst +++ b/docs/codeql/codeql-language-guides/codeql-library-for-csharp.rst @@ -54,7 +54,7 @@ This overview omits some of the less important or intermediate classes from the Each class has predicates, which are logical propositions about that class. They also define navigable relationships between classes. Predicates are inherited, so for example the ``AddExpr`` class inherits the predicates ``getLeftOperand()`` and ``getRightOperand()`` from ``BinaryArithmeticOperation``, and ``getType()`` from class ``Expr``. This is similar to how methods are inherited in object-oriented programming languages. -In this overview, we present the most common and useful predicates. For the complete list of predicates available on each class, you can look in the CodeQL source code, use autocomplete in the editor, or see the `C# reference <https://help.semmle.com/qldoc/csharp>`__. +In this overview, we present the most common and useful predicates. For the complete list of predicates available on each class, you can look in the CodeQL source code, use autocomplete in the editor, or see the `C# reference <https://codeql.github.com/codeql-standard-libraries/csharp>`__. Exercises ~~~~~~~~~ @@ -74,7 +74,7 @@ Exercise 1: Simplify this query: Files ----- -Files are represented by the class `File <https://help.semmle.com/qldoc/csharp/semmle/code/csharp/File.qll/type.File$File.html>`__, and directories by the class `Folder <https://help.semmle.com/qldoc/csharp/semmle/code/csharp/File.qll/type.File$Folder.html>`__. The database contains all of the source files and assemblies used during the compilation. +Files are represented by the class `File <https://codeql.github.com/codeql-standard-libraries/csharp/semmle/code/csharp/File.qll/type.File$File.html>`__, and directories by the class `Folder <https://codeql.github.com/codeql-standard-libraries/csharp/semmle/code/csharp/File.qll/type.File$Folder.html>`__. The database contains all of the source files and assemblies used during the compilation. Class hierarchy ~~~~~~~~~~~~~~~ @@ -108,8 +108,8 @@ Count the number of lines of code, excluding the directory ``external``: .. code-block:: ql select sum(SourceFile f | - not exists(Folder external | external.getShortName() = "external" | - external.getAFolder*().getAFile() = f) | + not exists(Folder ext | ext.getShortName() = "external" | + ext.getAFolder*().getAFile() = f) | f.getNumberOfLines()) Exercises @@ -120,7 +120,7 @@ Exercise 2: Write a query to find the source file with the largest number of lin Elements -------- -The class `Element <https://help.semmle.com/qldoc/csharp/semmle/code/cil/Element.qll/type.Element$Element.html>`__ is the base class for all parts of a C# program, and it's the root of the element class hierarchy. All program elements (such as types, methods, statements, and expressions) ultimately derive from this common base class. +The class `Element <https://codeql.github.com/codeql-standard-libraries/csharp/semmle/code/cil/Element.qll/type.Element$Element.html>`__ is the base class for all parts of a C# program, and it's the root of the element class hierarchy. All program elements (such as types, methods, statements, and expressions) ultimately derive from this common base class. ``Element`` forms a hierarchical structure of the program, which can be navigated using the ``getParent()`` and ``getChild()`` predicates. This is much like an abstract syntax tree, and also applies to elements in assemblies. @@ -150,7 +150,7 @@ Note that ``getAQlClass()`` is available on all entities and is a useful way to Locations --------- -`Location <https://help.semmle.com/qldoc/csharp/semmle/code/csharp/Location.qll/type.Location$Location.html>`__ represents a section of text in the source code, or an assembly. All elements have a ``Location`` obtained by their ``getLocation()`` predicate. A ``SourceLocation`` represents a span of text in source code, whereas an ``Assembly`` location represents a referenced assembly. +`Location <https://codeql.github.com/codeql-standard-libraries/csharp/semmle/code/csharp/Location.qll/type.Location$Location.html>`__ represents a section of text in the source code, or an assembly. All elements have a ``Location`` obtained by their ``getLocation()`` predicate. A ``SourceLocation`` represents a span of text in source code, whereas an ``Assembly`` location represents a referenced assembly. Sometimes elements have several locations, for example if they occur in both source code and an assembly. In this case, only the ``SourceLocation`` is returned. @@ -189,7 +189,7 @@ Find all elements that are one character wide: Declarations ------------ -`Declaration <https://help.semmle.com/qldoc/csharp/semmle/code/cil/Declaration.qll/type.Declaration$Declaration.html>`__ is the common class of all entities defined in the program, such as types, methods, variables etc. The database contains all declarations from the source code and all referenced assemblies. +`Declaration <https://codeql.github.com/codeql-standard-libraries/csharp/semmle/code/cil/Declaration.qll/type.Declaration$Declaration.html>`__ is the common class of all entities defined in the program, such as types, methods, variables etc. The database contains all declarations from the source code and all referenced assemblies. Class hierarchy ~~~~~~~~~~~~~~~ @@ -236,7 +236,7 @@ Find declarations containing a username: Variables --------- -The class `Variable <https://help.semmle.com/qldoc/csharp/semmle/code/cil/Variable.qll/type.Variable$Variable.html>`__ represents C# variables, such as fields, parameters and local variables. The database contains all variables from the source code, as well as all fields and parameters from assemblies referenced by the program. +The class `Variable <https://codeql.github.com/codeql-standard-libraries/csharp/semmle/code/cil/Variable.qll/type.Variable$Variable.html>`__ represents C# variables, such as fields, parameters and local variables. The database contains all variables from the source code, as well as all fields and parameters from assemblies referenced by the program. Class hierarchy ~~~~~~~~~~~~~~~ @@ -285,7 +285,7 @@ Find all unused local variables: Types ----- -Types are represented by the CodeQL class `Type <https://help.semmle.com/qldoc/csharp/semmle/code/cil/Type.qll/type.Type$Type.html>`__ and consist of builtin types, interfaces, classes, structs, enums, and type parameters. The database contains types from the program and all referenced assemblies including mscorlib and the .NET framework. +Types are represented by the CodeQL class `Type <https://codeql.github.com/codeql-standard-libraries/csharp/semmle/code/cil/Type.qll/type.Type$Type.html>`__ and consist of builtin types, interfaces, classes, structs, enums, and type parameters. The database contains types from the program and all referenced assemblies including mscorlib and the .NET framework. The builtin types (``object``, ``int``, ``double`` etc.) have corresponding types (``System.Object``, ``System.Int32`` etc.) in mscorlib. @@ -440,7 +440,7 @@ Exercise 5: Write a query to find all classes starting with the letter ``A``. (` Callables --------- -Callables are represented by the class `Callable <https://help.semmle.com/qldoc/csharp/semmle/code/csharp/Callable.qll/type.Callable$Callable.html>`__ and are anything that can be called independently, such as methods, constructors, destructors, operators, anonymous functions, indexers, and property accessors. +Callables are represented by the class `Callable <https://codeql.github.com/codeql-standard-libraries/csharp/semmle/code/csharp/Callable.qll/type.Callable$Callable.html>`__ and are anything that can be called independently, such as methods, constructors, destructors, operators, anonymous functions, indexers, and property accessors. The database contains all of the callables in your program and in all referenced assemblies. @@ -566,7 +566,7 @@ Find ``Main`` methods which are not ``private``: Statements ---------- -Statements are represented by the class `Stmt <https://help.semmle.com/qldoc/csharp/semmle/code/csharp/Stmt.qll/type.Stmt$Stmt.html>`__ and make up the body of methods (and other callables). The database contains all statements in the source code, but does not contain any statements from referenced assemblies where the source code is not available. +Statements are represented by the class `Stmt <https://codeql.github.com/codeql-standard-libraries/csharp/semmle/code/csharp/Stmt.qll/type.Stmt$Stmt.html>`__ and make up the body of methods (and other callables). The database contains all statements in the source code, but does not contain any statements from referenced assemblies where the source code is not available. Class hierarchy ~~~~~~~~~~~~~~~ @@ -691,7 +691,7 @@ Exercise 8: Modify the last example to exclude chains of ``if`` statements, wher Expressions ----------- -The `Expr <https://help.semmle.com/qldoc/csharp/semmle/code/csharp/exprs/Expr.qll/type.Expr$Expr.html>`__ class represents all C# expressions in the program. An expression is something producing a value such as ``a+b`` or ``new List<int>()``. The database contains all expressions from the source code, but no expressions from referenced assemblies where the source code is not available. +The `Expr <https://codeql.github.com/codeql-standard-libraries/csharp/semmle/code/csharp/exprs/Expr.qll/type.Expr$Expr.html>`__ class represents all C# expressions in the program. An expression is something producing a value such as ``a+b`` or ``new List<int>()``. The database contains all expressions from the source code, but no expressions from referenced assemblies where the source code is not available. The ``Access`` class represents any use or cross-reference of another ``Declaration`` such a variable, property, method or field. The ``getTarget()`` predicate gets the declaration being accessed. @@ -924,7 +924,7 @@ Exercise 9: Limit the previous query to string types. Exclude empty passwords or Attributes ---------- -C# attributes are represented by the class `Attribute <https://help.semmle.com/qldoc/csharp/semmle/code/cil/Attribute.qll/type.Attribute$Attribute.html>`__. They can be present on many C# elements, such as classes, methods, fields, and parameters. The database contains attributes from the source code and all assembly references. +C# attributes are represented by the class `Attribute <https://codeql.github.com/codeql-standard-libraries/csharp/semmle/code/cil/Attribute.qll/type.Attribute$Attribute.html>`__. They can be present on many C# elements, such as classes, methods, fields, and parameters. The database contains attributes from the source code and all assembly references. The attribute of any ``Element`` can be obtained via ``getAnAttribute()``, whereas if you have an attribute, you can find its element via ``getTarget()``. These two query fragments are identical: @@ -961,7 +961,7 @@ Find all obsolete elements: Model NUnit test fixtures: -.. code-block:: csharp +.. code-block:: ql class TestFixture extends Class { @@ -1124,5 +1124,5 @@ Here is the fixed version: Further reading --------------- -.. include:: ../../reusables/csharp-further-reading.rst -.. include:: ../../reusables/codeql-ref-tools-further-reading.rst +.. include:: ../reusables/csharp-further-reading.rst +.. include:: ../reusables/codeql-ref-tools-further-reading.rst diff --git a/docs/codeql/codeql-language-guides/codeql-for-go/codeql-library-for-go.rst b/docs/codeql/codeql-language-guides/codeql-library-for-go.rst similarity index 96% rename from docs/codeql/codeql-language-guides/codeql-for-go/codeql-library-for-go.rst rename to docs/codeql/codeql-language-guides/codeql-library-for-go.rst index d51c2d3d249..f1f77c5150e 100644 --- a/docs/codeql/codeql-language-guides/codeql-for-go/codeql-library-for-go.rst +++ b/docs/codeql/codeql-language-guides/codeql-library-for-go.rst @@ -22,7 +22,7 @@ library by beginning your query with: Broadly speaking, the CodeQL library for Go provides two views of a Go code base: at the `syntactic level`, source code is represented as an `abstract syntax tree -<https://wikipedia.org/wiki/Abstract_syntax_tree>`__ (AST), while at the `data-flow level` it is +<https://en.wikipedia.org/wiki/Abstract_syntax_tree>`__ (AST), while at the `data-flow level` it is represented as a `data-flow graph <https://en.wikipedia.org/wiki/Data-flow_analysis>`__ (DFG). In between, there is also an intermediate representation of the program as a control-flow graph (CFG), though this representation is rarely useful on its own and mostly used to construct the higher-level @@ -44,7 +44,7 @@ analysis involving deeper semantic properties of the program should be done on t The rest of this tutorial briefly summarizes the most important classes and predicates provided by this library, including references to the `detailed API documentation -<https://help.semmle.com/qldoc/go/>`__ where applicable. We start by giving an overview of the AST +<https://codeql.github.com/codeql-standard-libraries/go/>`__ where applicable. We start by giving an overview of the AST representation, followed by an explanation of names and entities, which are used to represent name-binding information, and of types and type information. Then we move on to control flow and the data-flow graph, and finally the call graph and a few advanced topics. @@ -69,7 +69,7 @@ first child, reflecting their order in the program text. Similarly, ``x + y`` is ``(x + y)``, which is the zeroth child of ``(x + y) * z``, whose first child is ``z``. All AST nodes belong to class `AstNode -<https://help.semmle.com/qldoc/go/semmle/go/AST.qll/type.AST$AstNode.html>`__, which defines generic +<https://codeql.github.com/codeql-standard-libraries/go/semmle/go/AST.qll/type.AST$AstNode.html>`__, which defines generic tree traversal predicates: - ``getChild(i)``: returns the ``i``\ th child of this AST node. @@ -88,20 +88,20 @@ access to the source text corresponding to an AST node. The source text is not s dataset, and hence is not directly accessible to CodeQL queries. The predicate ``getLocation()`` in class ``AstNode`` returns a `Location -<https://help.semmle.com/qldoc/go/semmle/go/Locations.qll/type.Locations$Location.html>`__ entity +<https://codeql.github.com/codeql-standard-libraries/go/semmle/go/Locations.qll/type.Locations$Location.html>`__ entity describing the source location of the program element represented by the AST node. You can use its member predicates ``getFile()``, ``getStartLine()``, ``getStartColumn``, ``getEndLine()``, and ``getEndColumn()`` to obtain information about its file, start line and column, and end line and column. The most important subclasses of `AstNode -<https://help.semmle.com/qldoc/go/semmle/go/AST.qll/type.AST$AstNode.html>`__ are `Stmt -<https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$Stmt.html>`__ and `Expr -<https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html>`__, which represent +<https://codeql.github.com/codeql-standard-libraries/go/semmle/go/AST.qll/type.AST$AstNode.html>`__ are `Stmt +<https://codeql.github.com/codeql-standard-libraries/go/semmle/go/Stmt.qll/type.Stmt$Stmt.html>`__ and `Expr +<https://codeql.github.com/codeql-standard-libraries/go/semmle/go/Expr.qll/type.Expr$Expr.html>`__, which represent statements and expressions, respectively. This section briefly discusses some of their more important subclasses and predicates. For a full reference of all the subclasses of `Stmt -<https://help.semmle.com/qldoc/go/semmle/go/Stmt.qll/type.Stmt$Stmt.html>`__ and `Expr -<https://help.semmle.com/qldoc/go/semmle/go/Expr.qll/type.Expr$Expr.html>`__, see +<https://codeql.github.com/codeql-standard-libraries/go/semmle/go/Stmt.qll/type.Stmt$Stmt.html>`__ and `Expr +<https://codeql.github.com/codeql-standard-libraries/go/semmle/go/Expr.qll/type.Expr$Expr.html>`__, see :doc:`Abstract syntax tree classes for Go <abstract-syntax-tree-classes-for-working-with-go-programs>`. Statements @@ -612,11 +612,11 @@ is to compare them to each other to determine whether two data-flow nodes have t Further reading --------------- -.. include:: ../../reusables/go-further-reading.rst -.. include:: ../../reusables/codeql-ref-tools-further-reading.rst +.. include:: ../reusables/go-further-reading.rst +.. include:: ../reusables/codeql-ref-tools-further-reading.rst -.. |ast| image:: ast.png -.. |cfg| image:: cfg.png -.. |dfg| image:: dfg.png -.. |cfg2| image:: cfg2.png -.. |ssa| image:: ssa.png +.. |ast| image:: ../images/codeql-for-go/ast.png +.. |cfg| image:: ../images/codeql-for-go/cfg.png +.. |dfg| image:: ../images/codeql-for-go/dfg.png +.. |cfg2| image:: ../images/codeql-for-go/cfg2.png +.. |ssa| image:: ../images/codeql-for-go/ssa.png diff --git a/docs/codeql/codeql-language-guides/codeql-for-java/codeql-library-for-java.rst b/docs/codeql/codeql-language-guides/codeql-library-for-java.rst similarity index 99% rename from docs/codeql/codeql-language-guides/codeql-for-java/codeql-library-for-java.rst rename to docs/codeql/codeql-language-guides/codeql-library-for-java.rst index 242d00c3d08..c4072ad55b2 100644 --- a/docs/codeql/codeql-language-guides/codeql-for-java/codeql-library-for-java.rst +++ b/docs/codeql/codeql-language-guides/codeql-library-for-java.rst @@ -388,5 +388,5 @@ For more information about callables and calls, see the :doc:`article on the cal Further reading --------------- -.. include:: ../../reusables/java-further-reading.rst -.. include:: ../../reusables/codeql-ref-tools-further-reading.rst +.. include:: ../reusables/java-further-reading.rst +.. include:: ../reusables/codeql-ref-tools-further-reading.rst diff --git a/docs/codeql/codeql-language-guides/codeql-library-for-javascript.rst b/docs/codeql/codeql-language-guides/codeql-library-for-javascript.rst new file mode 100644 index 00000000000..d88b8b10d57 --- /dev/null +++ b/docs/codeql/codeql-language-guides/codeql-library-for-javascript.rst @@ -0,0 +1,1037 @@ +.. _codeql-library-for-javascript: + +CodeQL library for JavaScript +============================= + +When you're analyzing a JavaScript program, you can make use of the large collection of classes in the CodeQL library for JavaScript. + +Overview +-------- + +There is an extensive CodeQL library for analyzing JavaScript code. The classes in this library present the data from a CodeQL database in an object-oriented form and provide abstractions and predicates to help you with common analysis tasks. + +The library is implemented as a set of QL modules, that is, files with the extension ``.qll``. The module ``javascript.qll`` imports most other standard library modules, so you can include the complete library by beginning your query with: + +.. code-block:: ql + + import javascript + +The rest of this tutorial briefly summarizes the most important classes and predicates provided by this library, including references to the `detailed API documentation <https://codeql.github.com/codeql-standard-libraries/javascript/>`__ where applicable. + +Introducing the library +----------------------- + +The CodeQL library for JavaScript presents information about JavaScript source code at different levels: + +- **Textual** — classes that represent source code as unstructured text files +- **Lexical** — classes that represent source code as a series of tokens and comments +- **Syntactic** — classes that represent source code as an abstract syntax tree +- **Name binding** — classes that represent scopes and variables +- **Control flow** — classes that represent the flow of control during execution +- **Data flow** — classes that you can use to reason about data flow in JavaScript source code +- **Type inference** — classes that you can use to approximate types for JavaScript expressions and variables +- **Call graph** — classes that represent the caller-callee relationship between functions +- **Inter-procedural data flow** — classes that you can use to define inter-procedural data flow and taint tracking analyses +- **Frameworks** — classes that represent source code entities that have a special meaning to JavaScript tools and frameworks + +Note that representations above the textual level (for example the lexical representation or the flow graphs) are only available for JavaScript code that does not contain fatal syntax errors. For code with such errors, the only information available is at the textual level, as well as information about the errors themselves. + +Additionally, there is library support for working with HTML documents, JSON, and YAML data, JSDoc comments, and regular expressions. + +Textual level +~~~~~~~~~~~~~ + +At its most basic level, a JavaScript code base can simply be viewed as a collection of files organized into folders, where each file is composed of zero or more lines of text. + +Note that the textual content of a program is not included in the CodeQL database unless you specifically request it during extraction. In particular, databases on LGTM (also known as "snapshots") do not normally include textual information. + +Files and folders +^^^^^^^^^^^^^^^^^ + +In the CodeQL libraries, files are represented as entities of class `File <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Files.qll/type.Files$File.html>`__, and folders as entities of class `Folder <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Files.qll/type.Files$Folder.html>`__, both of which are subclasses of class `Container <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Files.qll/type.Files$Container.html>`__. + +Class `Container <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Files.qll/type.Files$Container.html>`__ provides the following member predicates: + +- ``Container.getParentContainer()`` returns the parent folder of the file or folder. +- ``Container.getAFile()`` returns a file within the folder. +- ``Container.getAFolder()`` returns a folder nested within the folder. + +Note that while ``getAFile`` and ``getAFolder`` are declared on class `Container <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Files.qll/type.Files$Container.html>`__, they currently only have results for `Folder <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Files.qll/type.Files$Folder.html>`__\ s. + +Both files and folders have paths, which can be accessed by the predicate ``Container.getAbsolutePath()``. For example, if ``f`` represents a file with the path ``/home/user/project/src/index.js``, then ``f.getAbsolutePath()`` evaluates to the string ``"/home/user/project/src/index.js"``, while ``f.getParentContainer().getAbsolutePath()`` returns ``"/home/user/project/src"``. + +These paths are absolute file system paths. If you want to obtain the path of a file relative to the source location in the CodeQL database, use ``Container.getRelativePath()`` instead. Note, however, that a database may contain files that are not located underneath the source location; for such files, ``getRelativePath()`` will not return anything. + +The following member predicates of class `Container <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Files.qll/type.Files$Container.html>`__ provide more information about the name of a file or folder: + +- ``Container.getBaseName()`` returns the base name of a file or folder, not including its parent folder, but including its extension. In the above example, ``f.getBaseName()`` would return the string ``"index.js"``. +- ``Container.getStem()`` is similar to ``Container.getBaseName()``, but it does *not* include the file extension; so ``f.getStem()`` returns ``"index"``. +- ``Container.getExtension()`` returns the file extension, not including the dot; so ``f.getExtension()`` returns ``"js"``. + +For example, the following query computes, for each folder, the number of JavaScript files (that is, files with extension ``js``) contained in the folder: + +.. code-block:: ql + + import javascript + + from Folder d + select d.getRelativePath(), count(File f | f = d.getAFile() and f.getExtension() = "js") + +➤ `See this in the query console on LGTM.com <https://lgtm.com/query/1506075865985/>`__. When you run the query on most projects, the results include folders that contain files with a ``js`` extension and folders that don't. + +Locations +^^^^^^^^^ + +Most entities in a CodeQL database have an associated source location. Locations are identified by four pieces of information: a file, a start line, a start column, an end line, and an end column. Line and column counts are 1-based (so the first character of a file is at line 1, column 1), and the end position is inclusive. + +All entities associated with a source location belong to the class `Locatable <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Locations.qll/type.Locations$Locatable.html>`__. The location itself is modeled by the class `Location <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Locations.qll/type.Locations$Location.html>`__ and can be accessed through the member predicate ``Locatable.getLocation()``. The `Location <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Locations.qll/type.Locations$Location.html>`__ class provides the following member predicates: + +- ``Location.getFile()``, ``Location.getStartLine()``, ``Location.getStartColumn()``, ``Location.getEndLine()``, ``Location.getEndColumn()`` return detailed information about the location. +- ``Location.getNumLines()`` returns the number of (whole or partial) lines covered by the location. +- ``Location.startsBefore(Location)`` and ``Location.endsAfter(Location)`` determine whether one location starts before or ends after another location. +- ``Location.contains(Location)`` indicates whether one location completely contains another location; ``l1.contains(l2)`` holds if, and only if, ``l1.startsBefore(l2)`` and ``l1.endsAfter(l2)``. + +Lines +^^^^^ + +Lines of text in files are represented by the class `Line <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Lines.qll/type.Lines$Line.html>`__. This class offers the following member predicates: + +- ``Line.getText()`` returns the text of the line, excluding any terminating newline characters. +- ``Line.getTerminator()`` returns the terminator character(s) of the line. The last line in a file may not have any terminator characters, in which case this predicate does not return anything; otherwise it returns either the two-character string ``"\r\n"`` (carriage-return followed by newline), or one of the one-character strings ``"\n"`` (newline), ``"\r"`` (carriage-return), ``"\u2028"`` (Unicode character LINE SEPARATOR), ``"\u2029"`` (Unicode character PARAGRAPH SEPARATOR). + +Note that, as mentioned above, the textual representation of the program is not included in the CodeQL database by default. + +Lexical level +~~~~~~~~~~~~~ + +A slightly more structured view of a JavaScript program is provided by the classes `Token <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Tokens.qll/type.Tokens$Token.html>`__ and `Comment <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Comments.qll/type.Comments$Comment.html>`__, which represent tokens and comments, respectively. + +Tokens +^^^^^^ + +The most important member predicates of class `Token <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Tokens.qll/type.Tokens$Token.html>`__ are as follows: + +- ``Token.getValue()`` returns the source text of the token. +- ``Token.getIndex()`` returns the index of the token within its enclosing script. +- ``Token.getNextToken()`` and ``Token.getPreviousToken()`` navigate between tokens. + +The `Token <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Tokens.qll/type.Tokens$Token.html>`__ class has nine subclasses, each representing a particular kind of token: + +- `EOFToken <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Tokens.qll/type.Tokens$EOFToken.html>`__: a marker token representing the end of a script +- `NullLiteralToken <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Tokens.qll/type.Tokens$NullLiteralToken.html>`__, `BooleanLiteralToken <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Tokens.qll/type.Tokens$BooleanLiteralToken.html>`__, `NumericLiteralToken <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Tokens.qll/type.Tokens$NumericLiteralToken.html>`__, `StringLiteralToken <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Tokens.qll/type.Tokens$StringLiteralToken.html>`__ and `RegularExpressionToken <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Tokens.qll/type.Tokens$RegularExpressionToken.html>`__: different kinds of literals +- `IdentifierToken <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Tokens.qll/type.Tokens$IdentifierToken.html>`__ and `KeywordToken <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Tokens.qll/type.Tokens$KeywordToken.html>`__: identifiers and keywords (including reserved words) respectively +- `PunctuatorToken <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Tokens.qll/type.Tokens$PunctuatorToken.html>`__: operators and other punctuation symbols + +As an example of a query operating entirely on the lexical level, consider the following query, which finds consecutive comma tokens arising from an omitted element in an array expression: + +.. code-block:: ql + + import javascript + + class CommaToken extends PunctuatorToken { + CommaToken() { + getValue() = "," + } + } + + from CommaToken comma + where comma.getNextToken() instanceof CommaToken + select comma, "Omitted array elements are bad style." + +➤ `See this in the query console on LGTM.com <https://lgtm.com/query/659662177/>`__. If the query returns no results, this pattern isn't used in the projects that you analyzed. + +You can use predicate ``Locatable.getFirstToken()`` and ``Locatable.getLastToken()`` to access the first and last token (if any) belonging to an element with a source location. + +Comments +^^^^^^^^ + +The class `Comment <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Comments.qll/type.Comments$Comment.html>`__ and its subclasses represent the different kinds of comments that can occur in JavaScript programs: + +- `Comment <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Comments.qll/type.Comments$Comment.html>`__: any comment + + - `LineComment <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Comments.qll/type.Comments$LineComment.html>`__: a single-line comment terminated by an end-of-line character + + - `SlashSlashComment <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Comments.qll/type.Comments$SlashSlashComment.html>`__: a plain JavaScript single-line comment starting with ``//`` + - `HtmlLineComment <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Comments.qll/type.Comments$HtmlLineComment.html>`__: a (non-standard) HTML comment + + - `HtmlCommentStart <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Comments.qll/type.Comments$HtmlCommentStart.html>`__: an HTML comment starting with ``<!--`` + + - `HtmlCommentEnd <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Comments.qll/type.Comments$HtmlCommentEnd.html>`__: an HTML comment ending with ``-->`` + + - `BlockComment <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Comments.qll/type.Comments$BlockComment.html>`__: a block comment potentially spanning multiple lines + + - `SlashStarComment <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Comments.qll/type.Comments$SlashStarComment.html>`__: a plain JavaScript block comment surrounded with ``/*...*/`` + - `DocComment <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Comments.qll/type.Comments$DocComment.html>`__: a documentation block comment surrounded with ``/**...*/`` + +The most important member predicates are as follows: + +- ``Comment.getText()`` returns the source text of the comment, not including delimiters. +- ``Comment.getLine(i)`` returns the ``i``\ th line of text within the comment (0-based). +- ``Comment.getNumLines()`` returns the number of lines in the comment. +- ``Comment.getNextToken()`` returns the token immediately following a comment. Note that such a token always exists: if a comment appears at the end of a file, its following token is an `EOFToken <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Tokens.qll/type.Tokens$EOFToken.html>`__. + +As an example of a query using only lexical information, consider the following query for finding HTML comments, which are not a standard ECMAScript feature and should be avoided: + +.. code-block:: ql + + import javascript + + from HtmlLineComment c + select c, "Do not use HTML comments." + +➤ `See this in the query console on LGTM.com <https://lgtm.com/query/686330023/>`__. When we ran this query on the *mozilla/pdf.js* project in LGTM.com, we found three HTML comments. + +Syntactic level +~~~~~~~~~~~~~~~ + +The majority of classes in the JavaScript library is concerned with representing a JavaScript program as a collection of `abstract syntax trees <https://en.wikipedia.org/wiki/Abstract_syntax_tree>`__ (ASTs). + +The class `ASTNode <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/AST.qll/type.AST$ASTNode.html>`__ contains all entities representing nodes in the abstract syntax trees and defines generic tree traversal predicates: + +- ``ASTNode.getChild(i)``: returns the ``i``\ th child of this AST node. +- ``ASTNode.getAChild()``: returns any child of this AST node. +- ``ASTNode.getParent()``: returns the parent node of this AST node, if any. + +.. pull-quote:: + + Note + + These predicates should only be used to perform generic AST traversal. To access children of specific AST node types, the specialized predicates introduced below should be used instead. In particular, queries should not rely on the numeric indices of child nodes relative to their parent nodes: these are considered an implementation detail that may change between versions of the library. + +Top-levels +^^^^^^^^^^ + +From a syntactic point of view, each JavaScript program is composed of one or more top-level code blocks (or *top-levels* for short), which are blocks of JavaScript code that do not belong to a larger code block. Top-levels are represented by the class `TopLevel <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/AST.qll/type.AST$TopLevel.html>`__ and its subclasses: + +- `TopLevel <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/AST.qll/type.AST$TopLevel.html>`__ + + - `Script <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/AST.qll/type.AST$Script.html>`__: a stand-alone file or HTML ``<script>`` element + + - `ExternalScript <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/AST.qll/type.AST$ExternalScript.html>`__: a stand-alone JavaScript file + - `InlineScript <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/AST.qll/type.AST$InlineScript.html>`__: code embedded inline in an HTML ``<script>`` tag + + - `CodeInAttribute <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/AST.qll/type.AST$CodeInAttribute.html>`__: a code block originating from an HTML attribute value + + - `EventHandlerCode <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/AST.qll/type.AST$EventHandlerCode.html>`__: code from an event handler attribute such as ``onload`` + - `JavaScriptURL <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/AST.qll/type.AST$JavaScriptURL.html>`__: code from a URL with the ``javascript:`` scheme + + - `Externs <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/AST.qll/type.AST$Externs.html>`__: a JavaScript file containing `externs <https://developers.google.com/closure/compiler/docs/externs-and-exports>`__ definitions + +Every `TopLevel <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/AST.qll/type.AST$TopLevel.html>`__ class is contained in a `File <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Files.qll/type.Files$File.html>`__ class, but a single `File <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Files.qll/type.Files$File.html>`__ may contain more than one `TopLevel <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/AST.qll/type.AST$TopLevel.html>`__. To go from a ``TopLevel tl`` to its `File <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Files.qll/type.Files$File.html>`__, use ``tl.getFile()``; conversely, for a ``File f``, predicate ``f.getATopLevel()`` returns a top-level contained in ``f``. For every AST node, predicate ``ASTNode.getTopLevel()`` can be used to find the top-level it belongs to. + +The `TopLevel <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/AST.qll/type.AST$TopLevel.html>`__ class additionally provides the following member predicates: + +- ``TopLevel.getNumberOfLines()`` returns the total number of lines (including code, comments and whitespace) in the top-level. +- ``TopLevel.getNumberOfLinesOfCode()`` returns the number of lines of code, that is, lines that contain at least one token. +- ``TopLevel.getNumberOfLinesOfComments()`` returns the number of lines containing or belonging to a comment. +- ``TopLevel.isMinified()`` determines whether the top-level contains minified code, using a heuristic based on the average number of statements per line. + +.. pull-quote:: + + Note + + By default, LGTM filters out alerts in minified top-levels, since they are often hard to interpret. When writing your own queries in the LGTM query console, this filtering is *not* done automatically, so you may want to explicitly add a condition of the form ``and not e.getTopLevel().isMinified()`` or similar to your query to exclude results in minified code. + +Statements and expressions +^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The most important subclasses of `ASTNode <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/AST.qll/type.AST$ASTNode.html>`__ besides `TopLevel <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/AST.qll/type.AST$TopLevel.html>`__ are `Stmt <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Stmt.qll/type.Stmt$Stmt.html>`__ and `Expr <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$Expr.html>`__, which, together with their subclasses, represent statements and expressions, respectively. This section briefly discusses some of the more important classes and predicates. For a full reference of all the subclasses of `Stmt <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Stmt.qll/type.Stmt$Stmt.html>`__ and `Expr <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$Expr.html>`__ and their API, see +`Stmt.qll <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Stmt.qll/module.Stmt.html>`__ and `Expr.qll <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/module.Expr.html>`__. + +- `Stmt <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Stmt.qll/type.Stmt$Stmt.html>`__: use ``Stmt.getContainer()`` to access the innermost function or top-level in which the statement is contained. + + - `ControlStmt <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Stmt.qll/type.Stmt$ControlStmt.html>`__: a statement that controls the execution of other statements, that is, a conditional, loop, ``try`` or ``with`` statement; use ``ControlStmt.getAControlledStmt()`` to access the statements that it controls. + + - `IfStmt <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Stmt.qll/type.Stmt$IfStmt.html>`__: an ``if`` statement; use ``IfStmt.getCondition()``, ``IfStmt.getThen()`` and ``IfStmt.getElse()`` to access its condition expression, "then" branch and "else" branch, respectively. + - `LoopStmt <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Stmt.qll/type.Stmt$LoopStmt.html>`__: a loop; use ``Loop.getBody()`` and ``Loop.getTest()`` to access its body and its test expression, respectively. + + - `WhileStmt <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Stmt.qll/type.Stmt$WhileStmt.html>`__, `DoWhileStmt <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Stmt.qll/type.Stmt$DoWhileStmt.html>`__: a "while" or "do-while" loop, respectively. + - `ForStmt <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Stmt.qll/type.Stmt$ForStmt.html>`__: a "for" statement; use ``ForStmt.getInit()`` and ``ForStmt.getUpdate()`` to access the init and update expressions, respectively. + - `EnhancedForLoop <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Stmt.qll/type.Stmt$EnhancedForLoop.html>`__: a "for-in" or "for-of" loop; use ``EnhancedForLoop.getIterator()`` to access the loop iterator (which may be a expression or variable declaration), and ``EnhancedForLoop.getIterationDomain()`` to access the expression being iterated over. + + - `ForInStmt <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Stmt.qll/type.Stmt$ForInStmt.html>`__, `ForOfStmt <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Stmt.qll/type.Stmt$ForOfStmt.html>`__: a "for-in" or "for-of" loop, respectively. + + - `WithStmt <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Stmt.qll/type.Stmt$WithStmt.html>`__: a "with" statement; use ``WithStmt.getExpr()`` and ``WithStmt.getBody()`` to access the controlling expression and the body of the with statement, respectively. + - `SwitchStmt <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Stmt.qll/type.Stmt$SwitchStmt.html>`__: a switch statement; use ``SwitchStmt.getExpr()`` to access the expression on which the statement switches; use ``SwitchStmt.getCase(int)`` and ``SwitchStmt.getACase()`` to access individual switch cases; each case is modeled by an entity of class `Case <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Stmt.qll/type.Stmt$Case.html>`__, whose member predicates ``Case.getExpr()`` and ``Case.getBodyStmt(int)`` provide access to the expression checked by the switch case (which is undefined for ``default``), and its body. + - `TryStmt <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Stmt.qll/type.Stmt$TryStmt.html>`__: a "try" statement; use ``TryStmt.getBody()``, ``TryStmt.getCatchClause()`` and ``TryStmt.getFinally`` to access its body, "catch" clause and "finally" block, respectively. + + - `BlockStmt <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Stmt.qll/type.Stmt$BlockStmt.html>`__: a block of statements; use ``BlockStmt.getStmt(int)`` to access the individual statements in the block. + - `ExprStmt <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Stmt.qll/type.Stmt$ExprStmt.html>`__: an expression statement; use ``ExprStmt.getExpr()`` to access the expression itself. + - `JumpStmt <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Stmt.qll/type.Stmt$JumpStmt.html>`__: a statement that disrupts structured control flow, that is, one of ``break``, ``continue``, ``return`` and ``throw``; use predicate ``JumpStmt.getTarget()`` to determine the target of the jump, which is either a statement or (for ``return`` and uncaught ``throw`` statements) the enclosing function. + + - `BreakStmt <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Stmt.qll/type.Stmt$BreakStmt.html>`__: a "break" statement; use ``BreakStmt.getLabel()`` to access its (optional) target label. + - `ContinueStmt <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Stmt.qll/type.Stmt$ContinueStmt.html>`__: a "continue" statement; use ``ContinueStmt.getLabel()`` to access its (optional) target label. + - `ReturnStmt <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Stmt.qll/type.Stmt$ReturnStmt.html>`__: a "return" statement; use ``ReturnStmt.getExpr()`` to access its (optional) result expression. + - `ThrowStmt <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Stmt.qll/type.Stmt$ThrowStmt.html>`__: a "throw" statement; use ``ThrowStmt.getExpr()`` to access its thrown expression. + + - `FunctionDeclStmt <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Stmt.qll/type.Stmt$FunctionDeclStmt.html>`__: a function declaration statement; see below for available member predicates. + - `ClassDeclStmt <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Classes.qll/type.Classes$ClassDeclStmt.html>`__: a class declaration statement; see below for available member predicates. + - `DeclStmt <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Stmt.qll/type.Stmt$DeclStmt.html>`__: a declaration statement containing one or more declarators which can be accessed by predicate ``DeclStmt.getDeclarator(int)``. + + - `VarDeclStmt <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Stmt.qll/type.Stmt$VarDeclStmt.html>`__, `ConstDeclStmt <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Stmt.qll/type.Stmt$ConstDeclStmt.html>`__, `LetStmt <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Stmt.qll/type.Stmt$LetStmt.html>`__: a ``var``, ``const`` or ``let`` declaration statement. + +- `Expr <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$Expr.html>`__: use ``Expr.getEnclosingStmt()`` to obtain the innermost statement to which this expression belongs; ``Expr.isPure()`` determines whether the expression is side-effect-free. + + - `Identifier <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$Identifier.html>`__: an identifier; use ``Identifier.getName()`` to obtain its name. + - `Literal <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$Literal.html>`__: a literal value; use ``Literal.getValue()`` to obtain a string representation of its value, and ``Literal.getRawValue()`` to obtain its raw source text (including surrounding quotes for string literals). + + - `NullLiteral <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$NullLiteral.html>`__, `BooleanLiteral <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$BooleanLiteral.html>`__, `NumberLiteral <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$NumberLiteral.html>`__, `StringLiteral <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$StringLiteral.html>`__, `RegExpLiteral <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$RegExpLiteral.html>`__: different kinds of literals. + + - `ThisExpr <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$ThisExpr.html>`__: a "this" expression. + - `SuperExpr <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Classes.qll/type.Classes$SuperExpr.html>`__: a "super" expression. + - `ArrayExpr <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$ArrayExpr.html>`__: an array expression; use ``ArrayExpr.getElement(i)`` to obtain the ``i``\ th element expression, and ``ArrayExpr.elementIsOmitted(i)`` to check whether the ``i``\ th element is omitted. + - `ObjectExpr <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$ObjectExpr.html>`__: an object expression; use ``ObjectExpr.getProperty(i)`` to obtain the ``i``\ th property in the object expression; properties are modeled by class `Property <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$Property.html>`__, which is described in more detail below. + - `FunctionExpr <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$FunctionExpr.html>`__: a function expression; see below for available member predicates. + - `ArrowFunctionExpr <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$ArrowFunctionExpr.html>`__: an ECMAScript 2015-style arrow function expression; see below for available member predicates. + - `ClassExpr <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Classes.qll/type.Classes$ClassExpr.html>`__: a class expression; see below for available member predicates. + - `ParExpr <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$ParExpr.html>`__: a parenthesized expression; use ``ParExpr.getExpression()`` to obtain the operand expression; for any expression, ``Expr.stripParens()`` can be used to recursively strip off any parentheses + - `SeqExpr <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$SeqExpr.html>`__: a sequence of two or more expressions connected by the comma operator; use ``SeqExpr.getOperand(i)`` to obtain the ``i``\ th sub-expression. + - `ConditionalExpr <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$ConditionalExpr.html>`__: a ternary conditional expression; member predicates ``ConditionalExpr.getCondition()``, ``ConditionalExpr.getConsequent()`` and ``ConditionalExpr.getAlternate()`` provide access to the condition expression, the "then" expression and the "else" expression, respectively. + - `InvokeExpr <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$InvokeExpr.html>`__: a function call or a "new" expression; use ``InvokeExpr.getCallee()`` to obtain the expression specifying the function to be called, and ``InvokeExpr.getArgument(i)`` to obtain the ``i``\ th argument expression. + + - `CallExpr <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$CallExpr.html>`__: a function call. + - `NewExpr <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$NewExpr.html>`__: a "new" expression. + - `MethodCallExpr <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$MethodCallExpr.html>`__: a function call whose callee expression is a property access; use ``MethodCallExpr.getReceiver`` to access the receiver expression of the method call, and ``MethodCallExpr.getMethodName()`` to get the method name (if it can be determined statically). + + - `PropAccess <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$PropAccess.html>`__: a property access, that is, either a "dot" expression of the form ``e.f`` or an index expression of the form ``e[p]``; use ``PropAccess.getBase()`` to obtain the base expression on which the property is accessed (``e`` in the example), and ``PropAccess.getPropertyName()`` to determine the name of the accessed property; if the name cannot be statically determined, ``getPropertyName()`` does not return any value. + + - `DotExpr <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$DotExpr.html>`__: a "dot" expression. + - `IndexExpr <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$IndexExpr.html>`__: an index expression (also known as computed property access). + + - `UnaryExpr <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$UnaryExpr.html>`__: a unary expression; use ``UnaryExpr.getOperand()`` to obtain the operand expression. + + - `NegExpr <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$NegExpr.html>`__ ("-"), `PlusExpr <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$PlusExpr.html>`__ ("+"), `LogNotExpr <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$LogNotExpr.html>`__ ("!"), `BitNotExpr <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$BitNotExpr.html>`__ ("~"), `TypeofExpr <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$TypeofExpr.html>`__, `VoidExpr <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$VoidExpr.html>`__, `DeleteExpr <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$DeleteExpr.html>`__, `SpreadElement <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$SpreadElement.html>`__ ("..."): various types of unary expressions. + + - `BinaryExpr <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$BinaryExpr.html>`__: a binary expression; use ``BinaryExpr.getLeftOperand()`` and ``BinaryExpr.getRightOperand()`` to access the operand expressions. + + - `Comparison <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$Comparison.html>`__: any comparison expression. + + - `EqualityTest <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$EqualityTest.html>`__: any equality or inequality test. + + - `EqExpr <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$EqExpr.html>`__ ("=="), `NEqExpr <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$NEqExpr.html>`__ ("!="): non-strict equality and inequality tests. + - `StrictEqExpr <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$StrictEqExpr.html>`__ ("==="), `StrictNEqExpr <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$StrictNEqExpr.html>`__ ("!=="): strict equality and inequality tests. + + - `LTExpr <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$LTExpr.html>`__ ("<"), `LEExpr <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$LEExpr.html>`__ ("<="), `GTExpr <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$GTExpr.html>`__ (">"), `GEExpr <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$GEExpr.html>`__ (">="): numeric comparisons. + + - `LShiftExpr <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$LShiftExpr.html>`__ ("<<"), `RShiftExpr <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$RShiftExpr.html>`__ (">>"), `URShiftExpr <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$URShiftExpr.html>`__ (">>>"): shift operators. + - `AddExpr <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$AddExpr.html>`__ ("+"), `SubExpr <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$SubExpr.html>`__ ("-"), `MulExpr <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$MulExpr.html>`__ ("*"), `DivExpr <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$DivExpr.html>`__ ("/"), `ModExpr <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$ModExpr.html>`__ ("%"), `ExpExpr <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$ExpExpr.html>`__ ("**"): arithmetic operators. + - `BitOrExpr <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$BitOrExpr.html>`__ ("|"), `XOrExpr <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$XOrExpr.html>`__ ("^"), `BitAndExpr <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$BitAndExpr.html>`__ ("&"): bitwise operators. + - `InExpr <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$InExpr.html>`__: an ``in`` test. + - `InstanceofExpr <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$InstanceofExpr.html>`__: an ``instanceof`` test. + - `LogAndExpr <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$LogAndExpr.html>`__ ("&&"), `LogOrExpr <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$LogOrExpr.html>`__ ("||"): short-circuiting logical operators. + + - `Assignment <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$Assignment.html>`__: assignment expressions, either simple or compound; use ``Assignment.getLhs()`` and ``Assignment.getRhs()`` to access the left- and right-hand side, respectively. + + - `AssignExpr <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$AssignExpr.html>`__: a simple assignment expression. + - `CompoundAssignExpr <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$CompoundAssignExpr.html>`__: a compound assignment expression. + + - `AssignAddExpr <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$AssignAddExpr.html>`__, `AssignSubExpr <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$AssignSubExpr.html>`__, `AssignMulExpr <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$AssignMulExpr.html>`__, `AssignDivExpr <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$AssignDivExpr.html>`__, `AssignModExpr <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$AssignModExpr.html>`__, `AssignLShiftExpr <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$AssignLShiftExpr.html>`__, `AssignRShiftExpr <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$AssignRShiftExpr.html>`__, + `AssignURShiftExpr <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$AssignURShiftExpr.html>`__, `AssignOrExpr <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$AssignOrExpr.html>`__, `AssignXOrExpr <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$AssignXOrExpr.html>`__, `AssignAndExpr <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$AssignAndExpr.html>`__, `AssignExpExpr <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$AssignExpExpr.html>`__: different kinds of compound assignment expressions. + + - `UpdateExpr <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$UpdateExpr.html>`__: an increment or decrement expression; use ``UpdateExpr.getOperand()`` to obtain the operand expression. + + - `PreIncExpr <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$PreIncExpr.html>`__, `PostIncExpr <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$PostIncExpr.html>`__: an increment expression. + - `PreDecExpr <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$PreDecExpr.html>`__, `PostDecExpr <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$PostDecExpr.html>`__: a decrement expression. + + - `YieldExpr <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$YieldExpr.html>`__: a "yield" expression; use ``YieldExpr.getOperand()`` to access the (optional) operand expression; use ``YieldExpr.isDelegating()`` to check whether this is a delegating ``yield*``. + - `TemplateLiteral <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Templates.qll/type.Templates$TemplateLiteral.html>`__: an ECMAScript 2015 template literal; ``TemplateLiteral.getElement(i)`` returns the ``i``\ th element of the template, which may either be an interpolated expression or a constant template element. + - `TaggedTemplateExpr <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Templates.qll/type.Templates$TaggedTemplateExpr.html>`__: an ECMAScript 2015 tagged template literal; use ``TaggedTemplateExpr.getTag()`` to access the tagging expression, and ``TaggedTemplateExpr.getTemplate()`` to access the template literal being tagged. + - `TemplateElement <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Templates.qll/type.Templates$TemplateElement.html>`__: a constant template element; as for literals, use ``TemplateElement.getValue()`` to obtain the value of the element, and ``TemplateElement.getRawValue()`` for its raw value + - `AwaitExpr <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$AwaitExpr.html>`__: an "await" expression; use ``AwaitExpr.getOperand()`` to access the operand expression. + +`Stmt <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Stmt.qll/type.Stmt$Stmt.html>`__ and `Expr <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$Expr.html>`__ share a common superclass `ExprOrStmt <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/AST.qll/type.AST$ExprOrStmt.html>`__ which is useful for queries that should operate either on statements or on expressions, but not on any other AST nodes. + +As an example of how to use expression AST nodes, here is a query that finds expressions of the form ``e + f >> g``; such expressions should be rewritten as ``(e + f) >> g`` to clarify operator precedence: + +.. code-block:: ql + + import javascript + + from ShiftExpr shift, AddExpr add + where add = shift.getAnOperand() + select add, "This expression should be bracketed to clarify precedence rules." + +➤ `See this in the query console on LGTM.com <https://lgtm.com/query/690010024/>`__. When we ran this query on the *meteor/meteor* project in LGTM.com, we found many results where precedence could be clarified using brackets. + +Functions +^^^^^^^^^ + +JavaScript provides several ways of defining functions: in ECMAScript 5, there are function declaration statements and function expressions, and ECMAScript 2015 adds arrow function expressions. These different syntactic forms are represented by the classes `FunctionDeclStmt <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Stmt.qll/type.Stmt$FunctionDeclStmt.html>`__ (a subclass of `Stmt <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Stmt.qll/type.Stmt$Stmt.html>`__), `FunctionExpr <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$FunctionExpr.html>`__ (a subclass of `Expr <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$Expr.html>`__) and `ArrowFunctionExpr <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$ArrowFunctionExpr.html>`__ (also a subclass of +`Expr <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$Expr.html>`__), respectively. All three are subclasses of `Function <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Functions.qll/type.Functions$Function.html>`__, which provides common member predicates for accessing function parameters or the function body: + +- ``Function.getId()`` returns the `Identifier <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$Identifier.html>`__ naming the function, which may not be defined for function expressions. +- ``Function.getParameter(i)`` and ``Function.getAParameter()`` access the ``i``\ th parameter or any parameter, respectively; parameters are modeled by the class `Parameter <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Variables.qll/type.Variables$Parameter.html>`__, which is a subclass of `BindingPattern <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Variables.qll/type.Variables$BindingPattern.html>`__ (see below). +- ``Function.getBody()`` returns the body of the function, which is usually a `Stmt <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Stmt.qll/type.Stmt$Stmt.html>`__, but may be an `Expr <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$Expr.html>`__ for arrow function expressions and legacy `expression closures <https://developer.mozilla.org/en-US/docs/Archive/Web/JavaScript/Expression_closures>`__. + +As an example, here is a query that finds all expression closures: + +.. code-block:: ql + + import javascript + + from FunctionExpr fe + where fe.getBody() instanceof Expr + select fe, "Use arrow expressions instead of expression closures." + +➤ `See this in the query console on LGTM.com <https://lgtm.com/query/668510056/>`__. None of the LGTM.com demo projects uses expression closures, but you may find this query gets results on other projects. + +As another example, this query finds functions that have two parameters that bind the same variable: + +.. code-block:: ql + + import javascript + + from Function fun, Parameter p, Parameter q, int i, int j + where p = fun.getParameter(i) and + q = fun.getParameter(j) and + i < j and + p.getAVariable() = q.getAVariable() + select fun, "This function has two parameters that bind the same variable." + +➤ `See this in the query console on LGTM.com <https://lgtm.com/query/673860037/>`__. None of the LGTM.com demo projects has functions where two parameters bind the same variable. + +Classes +^^^^^^^ + +Classes can be defined either by class declaration statements, represented by the CodeQL class `ClassDeclStmt <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Classes.qll/type.Classes$ClassDeclStmt.html>`__ (which is a subclass of `Stmt <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Stmt.qll/type.Stmt$Stmt.html>`__), or by class expressions, represented by the CodeQL class `ClassExpr <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Classes.qll/type.Classes$ClassExpr.html>`__ (which is a subclass of `Expr <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$Expr.html>`__). Both of these classes are also subclasses of `ClassDefinition <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Classes.qll/type.Classes$ClassDefinition.html>`__, which provides common member predicates for accessing the name of a class, its superclass, and its body: + +- ``ClassDefinition.getIdentifier()`` returns the `Identifier <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$Identifier.html>`__ naming the function, which may not be defined for class expressions. +- ``ClassDefinition.getSuperClass()`` returns the `Expr <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$Expr.html>`__ specifying the superclass, which may not be defined. +- ``ClassDefinition.getMember(n)`` returns the definition of member ``n`` of this class. +- ``ClassDefinition.getMethod(n)`` restricts ``ClassDefinition.getMember(n)`` to methods (as opposed to fields). +- ``ClassDefinition.getField(n)`` restricts ``ClassDefinition.getMember(n)`` to fields (as opposed to methods). +- ``ClassDefinition.getConstructor()`` gets the constructor of this class, possibly a synthetic default constructor. + +Note that class fields are not a standard language feature yet, so details of their representation may change. + +Method definitions are represented by the class `MethodDefinition <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Classes.qll/type.Classes$MethodDefinition.html>`__, which (like its counterpart `FieldDefinition <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Classes.qll/type.Classes$FieldDefinition.html>`__ for fields) is a subclass of `MemberDefinition <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Classes.qll/type.Classes$MemberDefinition.html>`__. That class provides the following important member predicates: + +- ``MemberDefinition.isStatic()``: holds if this is a static member. +- ``MemberDefinition.isComputed()``: holds if the name of this member is computed at runtime. +- ``MemberDefinition.getName()``: gets the name of this member if it can be determined statically. +- ``MemberDefinition.getInit()``: gets the initializer of this field; for methods, the initializer is a function expressions, for fields it may be an arbitrary expression, and may be undefined. + +There are three classes for modeling special methods: `ConstructorDefinition <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Classes.qll/type.Classes$ConstructorDefinition.html>`__ models constructors, while `GetterMethodDefinition <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Classes.qll/type.Classes$GetterMethodDefinition.html>`__ and `SetterMethodDefinition <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Classes.qll/type.Classes$SetterMethodDefinition.html>`__ model getter and setter methods, respectively. + +Declarations and binding patterns +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Variables are declared by declaration statements (class `DeclStmt <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Stmt.qll/type.Stmt$DeclStmt.html>`__), which come in three flavors: ``var`` statements (represented by class `VarDeclStmt <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Stmt.qll/type.Stmt$VarDeclStmt.html>`__), ``const`` statements (represented by class `ConstDeclStmt <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Stmt.qll/type.Stmt$ConstDeclStmt.html>`__), and ``let`` statements (represented by class `LetStmt <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Stmt.qll/type.Stmt$LetStmt.html>`__). Every declaration statement has one or more declarators, represented by class `VariableDeclarator <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Variables.qll/type.Variables$VariableDeclarator.html>`__. + +Each declarator consists of a binding pattern, returned by predicate ``VariableDeclarator.getBindingPattern()``, and an optional initializing expression, returned by ``VariableDeclarator.getInit()``. + +Often, the binding pattern is a simple identifier, as in ``var x = 42``. In ECMAScript 2015 and later, however, it can also be a more complex destructuring pattern, as in ``var [x, y] = arr``. + +The various kinds of binding patterns are represented by class `BindingPattern <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Variables.qll/type.Variables$BindingPattern.html>`__ and its subclasses: + +- `VarRef <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Variables.qll/type.Variables$VarRef.html>`__: a simple identifier in an l-value position, for example the ``x`` in ``var x`` or in ``x = 42`` +- `Parameter <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Variables.qll/type.Variables$Parameter.html>`__: a function or catch clause parameter +- `ArrayPattern <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Variables.qll/type.Variables$ArrayPattern.html>`__: an array pattern, for example, the left-hand side of ``[x, y] = arr`` +- `ObjectPattern <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Variables.qll/type.Variables$ObjectPattern.html>`__: an object pattern, for example, the left-hand side of ``{x, y: z} = o`` + +Here is an example of a query to find declaration statements that declare the same variable more than once, excluding results in minified code: + +.. code-block:: ql + + import javascript + + from DeclStmt ds, VariableDeclarator d1, VariableDeclarator d2, Variable v, int i, int j + where d1 = ds.getDecl(i) and + d2 = ds.getDecl(j) and + i < j and + v = d1.getBindingPattern().getAVariable() and + v = d2.getBindingPattern().getAVariable() and + not ds.getTopLevel().isMinified() + select ds, "Variable " + v.getName() + " is declared both $@ and $@.", d1, "here", d2, "here" + +➤ `See this in the query console on LGTM.com <https://lgtm.com/query/668700496/>`__. This is not a common problem, so you may not find any results in your own projects. The *angular/angular.js* project on LGTM.com has one instance of this problem at the time of writing. + + Notice the use of ``not ... isMinified()`` here and in the next few queries. This excludes any results found in minified code. If you delete ``and not ds.getTopLevel().isMinified()`` and re-run the query, two results in minified code in the *meteor/meteor* project are reported. + +Properties +^^^^^^^^^^ + +Properties in object literals are represented by class `Property <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$Property.html>`__, which is also a subclass of `ASTNode <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/AST.qll/type.AST$ASTNode.html>`__, but neither of `Expr <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$Expr.html>`__ nor of `Stmt <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Stmt.qll/type.Stmt$Stmt.html>`__. + +Class `Property <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$Property.html>`__ has two subclasses `ValueProperty <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$ValueProperty.html>`__ and `PropertyAccessor <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$PropertyAccessor.html>`__, which represent, respectively, normal value properties and getter/setter properties. Class `PropertyAccessor <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$PropertyAccessor.html>`__, in turn, has two subclasses `PropertyGetter <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$PropertyGetter.html>`__ and `PropertySetter <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$PropertySetter.html>`__ representing getters and setters, respectively. + +The predicates ``Property.getName()`` and ``Property.getInit()`` provide access to the defined property's name and its initial value. For `PropertyAccessor <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$PropertyAccessor.html>`__ and its subclasses, ``getInit()`` is overloaded to return the getter/setter function. + +As an example of a query involving properties, consider the following query that flags object expressions containing two identically named properties, excluding results in minified code: + +.. code-block:: ql + + import javascript + + from ObjectExpr oe, Property p1, Property p2, int i, int j + where p1 = oe.getProperty(i) and + p2 = oe.getProperty(j) and + i < j and + p1.getName() = p2.getName() and + not oe.getTopLevel().isMinified() + select oe, "Property " + p1.getName() + " is defined both $@ and $@.", p1, "here", p2, "here" + +➤ `See this in the query console on LGTM.com <https://lgtm.com/query/660700064/>`__. Many projects have a few instances of object expressions with two identically named properties. + +Modules +^^^^^^^ + +The JavaScript library has support for working with ECMAScript 2015 modules, as well as legacy CommonJS modules (still commonly employed by Node.js code bases) and AMD-style modules. The classes `ES2015Module <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/ES2015Modules.qll/type.ES2015Modules$ES2015Module.html>`__, `NodeModule <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/NodeJS.qll/type.NodeJS$NodeModule.html>`__, and `AMDModule <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/AMD.qll/type.AMD$AmdModule.html>`__ represent these three types of modules, and all three extend the common superclass `Module <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Modules.qll/type.Modules$Module.html>`__. + +The most important member predicates defined by `Module <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Modules.qll/type.Modules$Module.html>`__ are: + +- ``Module.getName()``: gets the name of the module, which is just the stem (that is, the basename without extension) of the enclosing file. +- ``Module.getAnImportedModule()``: gets another module that is imported (through ``import`` or ``require``) by this module. +- ``Module.getAnExportedSymbol()``: gets the name of a symbol that this module exports. + +Moreover, there is a class `Import <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Modules.qll/type.Modules$Import.html>`__ that models both ECMAScript 2015-style ``import`` declarations and CommonJS/AMD-style ``require`` calls; its member predicate ``Import.getImportedModule`` provides access to the module the import refers to, if it can be determined statically. + +Name binding +~~~~~~~~~~~~ + +Name binding is modeled in the JavaScript libraries using four concepts: *scopes*, *variables*, *variable declarations*, and *variable accesses*, represented by the classes `Scope <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Variables.qll/type.Variables$Scope.html>`__, `Variable <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Variables.qll/type.Variables$Variable.html>`__, `VarDecl <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Variables.qll/type.Variables$VarDecl.html>`__ and `VarAccess <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Variables.qll/type.Variables$VarAccess.html>`__, respectively. + +Scopes +^^^^^^ + +In ECMAScript 5, there are three kinds of scopes: the global scope (one per program), function scopes (one per function), and catch clause scopes (one per ``catch`` clause). These three kinds of scopes are represented by the classes `GlobalScope <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Variables.qll/type.Variables$GlobalScope.html>`__, `FunctionScope <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Variables.qll/type.Variables$FunctionScope.html>`__ and `CatchScope <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Variables.qll/type.Variables$CatchScope.html>`__. ECMAScript 2015 adds block scopes for ``let``-bound variables, which are also represented by class `Scope <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Variables.qll/type.Variables$Scope.html>`__, class expression scopes (`ClassExprScope <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Classes.qll/type.Classes$ClassExprScope.html>`__), +and module scopes (`ModuleScope <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Variables.qll/type.Variables$ModuleScope.html>`__). + +Class `Scope <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Variables.qll/type.Variables$Scope.html>`__ provides the following API: + +- ``Scope.getScopeElement()`` returns the AST node inducing this scope; undefined for `GlobalScope <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Variables.qll/type.Variables$GlobalScope.html>`__. +- ``Scope.getOuterScope()`` returns the lexically enclosing scope of this scope. +- ``Scope.getAnInnerScope()`` returns a scope lexically nested inside this scope. +- ``Scope.getVariable(name)``, ``Scope.getAVariable()`` return a variable declared (implicitly or explicitly) in this scope. + +Variables +^^^^^^^^^ + +The `Variable <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Variables.qll/type.Variables$Variable.html>`__ class models all variables in a JavaScript program, including global variables, local variables, and parameters (both of functions and ``catch`` clauses), whether explicitly declared or not. + +It is important not to confuse variables and their declarations: local variables may have more than one declaration, while global variables and the implicitly declared local ``arguments`` variable need not have a declaration at all. + +Variable declarations and accesses +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Variables may be declared by variable declarators, by function declaration statements and expressions, by class declaration statements or expressions, or by parameters of functions and ``catch`` clauses. While these declarations differ in their syntactic form, in each case there is an identifier naming the declared variable. We consider that identifier to be the declaration proper, and assign it the class `VarDecl <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Variables.qll/type.Variables$VarDecl.html>`__. Identifiers that reference a variable, on the other hand, are given the class `VarAccess <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Variables.qll/type.Variables$VarAccess.html>`__. + +The most important predicates involving variables, their declarations, and their accesses are as follows: + +- ``Variable.getName()``, ``VarDecl.getName()``, ``VarAccess.getName()`` return the name of the variable. +- ``Variable.getScope()`` returns the scope to which the variable belongs. +- ``Variable.isGlobal()``, ``Variable.isLocal()``, ``Variable.isParameter()`` determine whether the variable is a global variable, a local variable, or a parameter variable, respectively. +- ``Variable.getAnAccess()`` maps a `Variable <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Variables.qll/type.Variables$Variable.html>`__ to all `VarAccess <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Variables.qll/type.Variables$VarAccess.html>`__\ es that refer to it. +- ``Variable.getADeclaration()`` maps a `Variable <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Variables.qll/type.Variables$Variable.html>`__ to all `VarDecl <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Variables.qll/type.Variables$VarDecl.html>`__\ s that declare it (of which there may be none, one, or more than one). +- ``Variable.isCaptured()`` determines whether the variable is ever accessed in a scope that is lexically nested within the scope where it is declared. + +As an example, consider the following query which finds distinct function declarations that declare the same variable, that is, two conflicting function declarations within the same scope (again excluding minified code): + +.. code-block:: ql + + import javascript + + from FunctionDeclStmt f, FunctionDeclStmt g + where f != g and f.getVariable() = g.getVariable() and + not f.getTopLevel().isMinified() and + not g.getTopLevel().isMinified() + select f, g + +➤ `See this in the query console on LGTM.com <https://lgtm.com/query/667290067/>`__. Some projects declare conflicting functions of the same name and rely on platform-specific behavior to disambiguate the two declarations. + +Control flow +~~~~~~~~~~~~ + +A different program representation in terms of intraprocedural control flow graphs (CFGs) is provided by the classes in library `CFG.qll <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/CFG.qll/module.CFG.html>`__. + +Class `ControlFlowNode <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/CFG.qll/type.CFG$ControlFlowNode.html>`__ represents a single node in the control flow graph, which is either an expression, a statement, or a synthetic control flow node. Note that `Expr <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$Expr.html>`__ and `Stmt <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Stmt.qll/type.Stmt$Stmt.html>`__ do not inherit from `ControlFlowNode <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/CFG.qll/type.CFG$ControlFlowNode.html>`__ at the CodeQL level, although their entity types are compatible, so you can explicitly cast from one to the other if you need to map between the AST-based and the CFG-based program representations. + +There are two kinds of synthetic control flow nodes: entry nodes (class `ControlFlowEntryNode <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/CFG.qll/type.CFG$ControlFlowEntryNode.html>`__), which represent the beginning of a top-level or function, and exit nodes (class `ControlFlowExitNode <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/CFG.qll/type.CFG$ControlFlowExitNode.html>`__), which represent their end. They do not correspond to any AST nodes, but simply serve as the unique entry point and exit point of a control flow graph. Entry and exit nodes can be accessed through the predicates ``StmtContainer.getEntry()`` and ``StmtContainer.getExit()``. + +Most, but not all, top-levels and functions have another distinguished CFG node, the *start node*. This is the CFG node at which execution begins. Unlike the entry node, which is a synthetic construct, the start node corresponds to an actual program element: for top-levels, it is the first CFG node of the first statement; for functions, it is the CFG node corresponding to their first parameter or, if there are no parameters, the first CFG node of the body. Empty top-levels do not have a start node. + +For most purposes, using start nodes is preferable to using entry nodes. + +The structure of the control flow graph is reflected in the member predicates of `ControlFlowNode <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/CFG.qll/type.CFG$ControlFlowNode.html>`__: + +- ``ControlFlowNode.getASuccessor()`` returns a `ControlFlowNode <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/CFG.qll/type.CFG$ControlFlowNode.html>`__ that is a successor of this `ControlFlowNode <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/CFG.qll/type.CFG$ControlFlowNode.html>`__ in the control flow graph. +- ``ControlFlowNode.getAPredecessor()`` is the inverse of ``getASuccessor()``. +- ``ControlFlowNode.isBranch()`` determines whether this node has more than one successor. +- ``ControlFlowNode.isJoin()`` determines whether this node has more than one predecessor. +- ``ControlFlowNode.isStart()`` determines whether this node is a start node. + +Many control-flow-based analyses are phrased in terms of `basic blocks <https://en.wikipedia.org/wiki/Basic_block>`__ rather than single control flow nodes, where a basic block is a maximal sequence of control flow nodes without branches or joins. The class `BasicBlock <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/BasicBlocks.qll/type.BasicBlocks$BasicBlock.html>`__ from `BasicBlocks.qll <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/BasicBlocks.qll/module.BasicBlocks.html>`__ represents all such basic blocks. Similar to `ControlFlowNode <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/CFG.qll/type.CFG$ControlFlowNode.html>`__, it provides member predicates ``getASuccessor()`` and ``getAPredecessor()`` to navigate the control flow graph at the level of basic blocks, and member predicates ``getANode()``, ``getNode(int)``, ``getFirstNode()`` and ``getLastNode()`` to access individual control flow nodes within a basic block. The predicate +``Function.getEntryBB()`` returns the entry basic block in a function, that is, the basic block containing the function's entry node. Similarly, ``Function.getStartBB()`` provides access to the start basic block, which contains the function's start node. As for CFG nodes, ``getStartBB()`` should normally be preferred over ``getEntryBB()``. + +As an example of an analysis using basic blocks, ``BasicBlock.isLiveAtEntry(v, u)`` determines whether variable ``v`` is `live <https://en.wikipedia.org/wiki/Live_variable_analysis>`__ at the entry of the given basic block, and if so binds ``u`` to a use of ``v`` that refers to its value at the entry. We can use it to find global variables that are used in a function where they are not live (that is, every read of the variable is preceded by a write), suggesting that the variable was meant to be declared as a local variable instead: + +.. code-block:: ql + + import javascript + + from Function f, GlobalVariable gv + where gv.getAnAccess().getEnclosingFunction() = f and + not f.getStartBB().isLiveAtEntry(gv, _) + select f, "This function uses " + gv + " like a local variable." + +➤ `See this in the query console on LGTM.com <https://lgtm.com/query/686320048/>`__. Many projects have some variables which look as if they were intended to be local. + +Data flow +~~~~~~~~~ + +Definitions and uses +^^^^^^^^^^^^^^^^^^^^ + +Library `DefUse.qll <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/DefUse.qll/module.DefUse.html>`__ provides classes and predicates to determine `def-use <https://en.wikipedia.org/wiki/Use-define_chain>`__ relationships between definitions and uses of variables. + +Classes `VarDef <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/DefUse.qll/type.DefUse$VarDef.html>`__ and `VarUse <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/DefUse.qll/type.DefUse$VarUse.html>`__ contain all expressions that define and use a variable, respectively. For the former, you can use predicate ``VarDef.getAVariable()`` to find out which variables are defined by a given variable definition (recall that destructuring assignments in ECMAScript 2015 define several variables at the same time). Similarly, predicate ``VarUse.getVariable()`` returns the (single) variable being accessed by a variable use. + +The def-use information itself is provided by predicate ``VarUse.getADef()``, that connects a use of a variable to a definition of the same variable, where the definition may reach the use. + +As an example, the following query finds definitions of local variables that are not used anywhere; that is, the variable is either not referenced at all after the definition, or its value is overwritten: + +.. code-block:: ql + + import javascript + + from VarDef def, LocalVariable v + where v = def.getAVariable() and + not exists (VarUse use | def = use.getADef()) + select def, "Dead store of local variable." + +➤ `See this in the query console on LGTM.com <https://lgtm.com/query/2086440429/>`__. Many projects have some examples of useless assignments to local variables. + +SSA +^^^ + +A more fine-grained representation of a program's data flow based on `Static Simple Assignment Form (SSA) <https://en.wikipedia.org/wiki/Static_single_assignment_form>`__ is provided by the library ``semmle.javascript.SSA``. + +In SSA form, each use of a local variable has exactly one (SSA) definition that reaches it. SSA definitions are represented by class `SsaDefinition <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/SSA.qll/type.SSA$SsaDefinition.html>`__. They are not AST nodes, since not every SSA definition corresponds to an explicit element in the source code. + +Altogether, there are five kinds of SSA definitions: + +#. Explicit definitions (`SsaExplicitDefinition <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/SSA.qll/type.SSA$SsaExplicitDefinition.html>`__): these simply wrap a `VarDef <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/DefUse.qll/type.DefUse$VarDef.html>`__, that is, a definition like ``x = 1`` appearing explicitly in the source code. +#. Implicit initializations (`SsaImplicitInit <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/SSA.qll/type.SSA$SsaImplicitInit.html>`__): these represent the implicit initialization of local variables with ``undefined`` at the beginning of their scope. +#. Phi nodes (`SsaPhiNode <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/SSA.qll/type.SSA$SsaPhiNode.html>`__): these are pseudo-definitions that merge two or more SSA definitions where necessary; see the Wikipedia page linked to above for an explanation. +#. Variable captures (`SsaVariableCapture <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/SSA.qll/type.SSA$SsaVariableCapture.html>`__): these are pseudo-definitions appearing at places in the code where the value of a captured variable may change without there being an explicit assignment, for example due to a function call. +#. Refinement nodes (`SsaRefinementNode <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/SSA.qll/type.SSA$SsaRefinementNode.html>`__): these are pseudo-definitions appearing at places in the code where something becomes known about a variable; for example, a conditional ``if (x === null)`` induces a refinement node at the beginning of its "then" branch recording the fact that ``x`` is known to be ``null`` there. (In the literature, these are sometimes known as "pi nodes.") + +Data flow nodes +^^^^^^^^^^^^^^^ + +Moving beyond just variable definitions and uses, library ``semmle.javascript.dataflow.DataFlow`` provides a representation of the program as a data flow graph. Its nodes are values of class `DataFlow::Node <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/dataflow/DataFlow.qll/type.DataFlow$DataFlow$Node.html>`__, which has two subclasses ``ValueNode`` and ``SsaDefinitionNode``. Nodes of the former kind wrap an expression or a statement that is considered to produce a value (specifically, a function or class declaration statement, or a TypeScript namespace or enum declaration). Nodes of the latter kind wrap SSA definitions. + +You can use the predicate ``DataFlow::valueNode`` to convert an expression, function or class into its corresponding ``ValueNode``, and similarly ``DataFlow::ssaDefinitionNode`` to map an SSA definition to its corresponding ``SsaDefinitionNode``. + +There is also an auxiliary predicate ``DataFlow::parameterNode`` that maps a parameter to its corresponding data flow node. (This is really just a convenience wrapper around ``DataFlow::ssaDefinitionNode``, since parameters are also considered to be SSA definitions.) + +Going in the other direction, there is a predicate ``ValueNode.getAstNode()`` for mapping from ``ValueNode``\ s to ``ASTNode``\ s, and ``SsaDefinitionNode.getSsaVariable()`` for mapping from ``SsaDefinitionNode``\ s to ``SsaVariable``\ s. There is also a utility predicate ``Node.asExpr()`` that gets the underlying expression for a ``ValueNode``, and is undefined for all nodes that do not correspond to an expression. (Note in particular that this predicate is not defined for ``ValueNode``\ s wrapping function or class declaration statements!) + +You can use the predicate ``DataFlow::Node.getAPredecessor()`` to find other data flow nodes from which values may flow into this node, and ``getASuccessor`` for the other direction. + +For example, here is a query that finds all invocations of a method called ``send`` on a value that comes from a parameter named ``res``, indicating that it is perhaps sending an HTTP response: + +.. code-block:: ql + + import javascript + + from SimpleParameter res, DataFlow::Node resNode, MethodCallExpr send + where res.getName() = "res" and + resNode = DataFlow::parameterNode(res) and + resNode.getASuccessor+() = DataFlow::valueNode(send.getReceiver()) and + send.getMethodName() = "send" + select send + +➤ `See this in the query console on LGTM.com <https://lgtm.com/query/1506058347056/>`__. The query finds HTTP response sends in the `AMP HTML <https://lgtm.com/projects/g/ampproject/amphtml>`__ project. + +Note that the data flow modeling in this library is intraprocedural, that is, flow across function calls and returns is *not* modeled. Likewise, flow through object properties and global variables is not modeled. + +Type inference +~~~~~~~~~~~~~~ + +The library ``semmle.javascript.dataflow.TypeInference`` implements a simple type inference for JavaScript based on intraprocedural, heap-insensitive flow analysis. Basically, the inference algorithm approximates the possible concrete runtime values of variables and expressions as sets of abstract values (represented by the class `AbstractValue <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/dataflow/AbstractValues.qll/type.AbstractValues$AbstractValue.html>`__), each of which stands for a set of concrete values. + +For example, there is an abstract value representing all non-zero numbers, and another representing all non-empty strings except for those that can be converted to a number. Both of these abstract values are fairly coarse approximations that represent very large sets of concrete values. + +Other abstract values are more precise, to the point where they represent single concrete values: for example, there is an abstract value representing the concrete ``null`` value, and another representing the number zero. + +There is a special group of abstract values called *indefinite* abstract values that represent all concrete values. The analysis uses these to handle expressions for which it cannot infer a more precise value, such as function parameters (as mentioned above, the analysis is intraprocedural and hence does not model argument passing) or property reads (the analysis does not model property values either). + +Each indefinite abstract value is associated with a string value describing the cause of imprecision. In the above examples, the indefinite value for the parameter would have cause ``"call"``, while the indefinite value for the property would have cause ``"heap"``. + +To check whether an abstract value is indefinite, you can use the ``isIndefinite`` member predicate. Its single argument describes the cause of imprecision. + +Each abstract value has one or more associated types (CodeQL class `InferredType <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/dataflow/InferredTypes.qll/type.InferredTypes$InferredType.html>`__ corresponding roughly to the type tags computed by the ``typeof`` operator. The types are ``null``, ``undefined``, ``boolean``, ``number``, ``string``, ``function``, ``class``, ``date`` and ``object``. + +To access the results of the type inference, use class `DataFlow::AnalyzedNode <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/dataflow/TypeInference.qll/type.TypeInference$AnalyzedNode.html>`__: any `DataFlow::Node <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/dataflow/DataFlow.qll/type.DataFlow$DataFlow$Node.html>`__ can be cast to this class, and additionally there is a convenience predicate ``Expr::analyze`` that maps expressions directly to their corresponding ``AnalyzedNode``\ s. + +Once you have an ``AnalyzedNode``, you can use predicate ``AnalyzedNode.getAValue()`` to access the abstract values inferred for it, and ``getAType()`` to get the inferred types. + +For example, here is a query that looks for ``null`` checks on expressions that cannot, in fact, be null: + +.. code-block:: ql + + import javascript + + from StrictEqualityTest eq, DataFlow::AnalyzedNode nd, NullLiteral null + where eq.hasOperands(nd.asExpr(), null) and + not nd.getAValue().isIndefinite(_) and + not nd.getAValue() instanceof AbstractNull + select eq, "Spurious null check." + +To paraphrase, the query looks for equality tests ``eq`` where one operand is a ``null`` literal and the other some expression that we convert to an ``AnalyzedNode``. If the type inference results for that node are precise (that is, none of the inferred values is indefinite) and (the abstract representation of) ``null`` is not among them, we flag ``eq``. + +You can add custom type inference rules by defining new subclasses of ``DataFlow::AnalyzedNode`` and overriding ``getAValue``. You can also introduce new abstract values by extending the abstract class ``CustomAbstractValueTag``, which is a subclass of ``string``: each string belonging to that class induces a corresponding abstract value of type ``CustomAbstractValue``. You can use the predicate ``CustomAbstractValue.getTag()`` to map from the abstract value to its tag. By implementing the abstract predicates of class ``CustomAbstractValueTag`` you can define the semantics of your custom abstract values, such as what primitive value they coerce to and what type they have. + +Call graph +~~~~~~~~~~ + +The JavaScript library implements a simple `call graph <https://en.wikipedia.org/wiki/Call_graph>`__ construction algorithm to statically approximate the possible call targets of function calls and ``new`` expressions. Due to the dynamically typed nature of JavaScript and its support for higher-order functions and reflective language features, building static call graphs is quite difficult. Simple call graph algorithms tend to be incomplete, that is, they often fail to resolve all possible call targets. More sophisticated algorithms can suffer from the opposite problem of imprecision, that is, they may infer many spurious call targets. + +The call graph is represented by the member predicate ``getACallee()`` of class `DataFlow::InvokeNode <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/dataflow/Nodes.qll/type.Nodes$InvokeNode.html>`__, which computes possible callees of the given invocation, that is, functions that may at runtime be invoked by this expression. + +Furthermore, there are three member predicates that indicate the quality of the callee information for this invocation: + +- ``DataFlow::InvokeNode.isImprecise()``: holds for invocations where the call graph builder might infer spurious call targets. +- ``DataFlow::InvokeNode.isIncomplete()``: holds for invocations where the call graph builder might fail to infer possible call targets. +- ``DataFlow::InvokeNode.isUncertain()``: holds if either ``isImprecise()`` or ``isUncertain()`` holds. + +As an example of a call-graph-based query, here is a query to find invocations for which the call graph builder could not find any callees, despite the analysis being complete for this invocation: + +.. code-block:: ql + + import javascript + + from DataFlow::InvokeNode invk + where not invk.isIncomplete() and + not exists(invk.getACallee()) + select invk, "Unable to find a callee for this invocation." + +➤ `See this in the query console on LGTM.com <https://lgtm.com/query/3260345690335671362/>`__ + +Inter-procedural data flow +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The data flow graph-based analyses described so far are all intraprocedural: they do not take flow from function arguments to parameters or from a ``return`` to the function's caller into account. The data flow library also provides a framework for constructing custom inter-procedural analyses. + +We distinguish here between data flow proper, and *taint tracking*: the latter not only considers value-preserving flow (such as from variable definitions to uses), but also cases where one value influences ("taints") another without determining it entirely. For example, in the assignment ``s2 = s1.substring(i)``, the value of ``s1`` influences the value of ``s2``, because ``s2`` is assigned a substring of ``s1``. In general, ``s2`` will not be assigned ``s1`` itself, so there is no data flow from ``s1`` to ``s2``, but ``s1`` still taints ``s2``. + +The simplest way of implementing an interprocedural data flow analysis is to extend either class ``DataFlow::TrackedNode`` or ``DataFlow::TrackedExpr``. The former is a subclass of ``DataFlow::Node``, the latter of ``Expr``, and extending them ensures that the newly added values are tracked interprocedurally. You can use the predicate ``flowsTo`` to find out which nodes/expressions the tracked value flows to. + +For example, suppose that we are developing an analysis to find hard-coded passwords. We might start by writing a simple query that looks for string constants flowing into variables named ``"password"``. To do this, we can extend ``TrackedExpr`` to track all constant strings, ``flowsTo`` to find cases where such a string flows into a (SSA) definition of a password variable: + +.. code-block:: ql + + import javascript + + class TrackedStringLiteral extends DataFlow::TrackedNode { + TrackedStringLiteral() { + this.asExpr() instanceof ConstantString + } + } + + from TrackedStringLiteral source, DataFlow::Node sink, SsaExplicitDefinition def + where source.flowsTo(sink) and sink = DataFlow::ssaDefinitionNode(def) and + def.getSourceVariable().getName().toLowerCase() = "password" + select sink + +Note that ``TrackedNode`` and ``TrackedExpr`` do not restrict the set of "sinks" for the inter-procedural flow analysis, tracking flow into any expression that they might flow to. This can be expensive for large code bases, and is often unnecessary, since usually you are only interested in flow to a particular set of sinks. For example, the above query only looks for flow into assignments to password variables. + +This is a particular instance of a general pattern, whereby we want to specify a data flow or taint analysis in terms of its *sources* (where flow starts), *sinks* (where it should be tracked), and *barriers* or *sanitizers* (where flow is interrupted). The example does not include any sanitizers, but they are very common in security analyses: for example, an analysis that tracks the flow of untrusted user input into, say, a SQL query has to keep track of code that validates the input, thereby making it safe to use. Such a validation step is an example of a sanitizer. + +The classes ``DataFlow::Configuration`` and ``TaintTracking::Configuration`` allow specifying a data flow or taint analysis, respectively, by overriding the following predicates: + +- ``isSource(DataFlow::Node nd)`` selects all nodes ``nd`` from where flow tracking starts. +- ``isSink(DataFlow::Node nd)`` selects all nodes ``nd`` to which the flow is tracked. +- ``isBarrier(DataFlow::Node nd)`` selects all nodes ``nd`` that act as a barrier for data flow; ``isSanitizer`` is the corresponding predicate for taint tracking configurations. +- ``isBarrierEdge(DataFlow::Node src, DataFlow::Node trg)`` is a variant of ``isBarrier(nd)`` that allows specifying barrier *edges* in addition to barrier nodes; again, ``isSanitizerEdge`` is the corresponding predicate for taint tracking; +- ``isAdditionalFlowStep(DataFlow::Node src, DataFlow::Node trg)`` allows specifying custom additional flow steps for this analysis; ``isAdditionalTaintStep`` is the corresponding predicate for taint tracking configurations. + +Since for technical reasons both ``Configuration`` classes are subtypes of ``string``, you have to choose a unique name for each flow configuration and equate ``this`` with it in the characteristic predicate (as in the example below). + +The predicate ``Configuration.hasFlow`` performs the actual flow tracking, starting at a source and looking for flow to a sink that does not pass through a barrier node or edge. + +To continue with our above example, we can phrase it as a data flow configuration as follows: + +.. code-block:: ql + + class PasswordTracker extends DataFlow::Configuration { + PasswordTracker() { + // unique identifier for this configuration + this = "PasswordTracker" + } + + override predicate isSource(DataFlow::Node nd) { + nd.asExpr() instanceof StringLiteral + } + + override predicate isSink(DataFlow::Node nd) { + passwordVarAssign(_, nd) + } + + predicate passwordVarAssign(Variable v, DataFlow::Node nd) { + exists (SsaExplicitDefinition def | + nd = DataFlow::ssaDefinitionNode(def) and + def.getSourceVariable() = v and + v.getName().toLowerCase() = "password" + ) + } + } + +Now we can rephrase our query to use ``Configuration.hasFlow``: + +.. code-block:: ql + + from PasswordTracker pt, DataFlow::Node source, DataFlow::Node sink, Variable v + where pt.hasFlow(source, sink) and pt.passwordVarAssign(v, sink) + select sink, "Password variable " + v + " is assigned a constant string." + +Note that while analyses implemented in this way are inter-procedural in that they track flow and taint across function calls and returns, flow through global variables is not tracked. Flow through object properties is only tracked in limited cases, for example through properties of object literals or CommonJS ``module`` and ``exports`` objects. + +Syntax errors +~~~~~~~~~~~~~ + +JavaScript code that contains syntax errors cannot usually be analyzed. For such code, the lexical and syntactic representations are not available, and hence no name binding information, call graph or control and data flow. All that is available in this case is a value of class `JSParseError <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Errors.qll/type.Errors$JSParseError.html>`__ representing the syntax error. It provides information about the syntax error location (`JSParseError <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Errors.qll/type.Errors$JSParseError.html>`__ is a subclass of `Locatable <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Locations.qll/type.Locations$Locatable.html>`__) and the error message through predicate ``JSParseError.getMessage``. + +Note that for some very simple syntax errors the parser can recover and continue parsing. If this happens, lexical and syntactic information is available in addition to the `JSParseError <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Errors.qll/type.Errors$JSParseError.html>`__ values representing the (recoverable) syntax errors encountered during parsing. + +Frameworks +~~~~~~~~~~ + +AngularJS +^^^^^^^^^ + +The ``semmle.javascript.frameworks.AngularJS`` library provides support for working with `AngularJS (Angular 1.x) <https://angularjs.org/>`__ code. Its most important classes are: + +- `AngularJS::AngularModule <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/frameworks/AngularJS/AngularJSCore.qll/type.AngularJSCore$AngularModule.html>`__: an Angular module +- `AngularJS::DirectiveDefinition <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/frameworks/AngularJS/ServiceDefinitions.qll/type.ServiceDefinitions$DirectiveDefinition.html>`__, `AngularJS::FactoryRecipeDefinition <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/frameworks/AngularJS/ServiceDefinitions.qll/type.ServiceDefinitions$FactoryRecipeDefinition.html>`__, `AngularJS::FilterDefinition <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/frameworks/AngularJS/ServiceDefinitions.qll/type.ServiceDefinitions$FilterDefinition.html>`__, `AngularJS::ControllerDefinition <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/frameworks/AngularJS/ServiceDefinitions.qll/type.ServiceDefinitions$ControllerDefinition.html>`__: a definition of a directive, service, filter or controller, respectively +- `AngularJS::InjectableFunction <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/frameworks/AngularJS/DependencyInjections.qll/type.DependencyInjections$InjectableFunction.html>`__: a function that is subject to dependency injection + +HTTP framework libraries +^^^^^^^^^^^^^^^^^^^^^^^^ + +The library ``semmle.javacript.frameworks.HTTP`` provides classes modeling common concepts from various HTTP frameworks. + +Currently supported frameworks are `Express <https://expressjs.com/>`__, the standard Node.js ``http`` and ``https`` modules, `Connect <https://github.com/senchalabs/connect>`__, `Koa <https://koajs.com>`__, `Hapi <https://hapi.dev/>`__ and `Restify <http://restify.com/>`__. + +The most important classes include (all in module ``HTTP``): + +- ``ServerDefinition``: an expression that creates a new HTTP server. +- ``RouteHandler``: a callback for handling an HTTP request. +- ``RequestExpr``: an expression that may contain an HTTP request object. +- ``ResponseExpr``: an expression that may contain an HTTP response object. +- ``HeaderDefinition``: an expression that sets one or more HTTP response headers. +- ``CookieDefinition``: an expression that sets a cookie in an HTTP response. +- ``RequestInputAccess``: an expression that accesses user-controlled request data. + +For each framework library, there is a corresponding CodeQL library (for example ``semmle.javacript.frameworks.Express``) that instantiates the above classes for that framework and adds framework-specific classes. + +Node.js +^^^^^^^ + +The ``semmle.javascript.NodeJS`` library provides support for working with `Node.js <http://nodejs.org/>`__ modules through the following classes: + +- `NodeModule <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/NodeJS.qll/type.NodeJS$NodeModule.html>`__: a top-level that defines a Node.js module; see the section on `Modules <#modules>`__ for more information. +- `Require <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/NodeJS.qll/type.NodeJS$Require.html>`__: a call to the special ``require`` function that imports a module. + +As an example of the use of these classes, here is a query that counts for every module how many other modules it imports: + +.. code-block:: ql + + import javascript + + from NodeModule m + select m, count(m.getAnImportedModule()) + +➤ `See this in the query console on LGTM.com <https://lgtm.com/query/659662207/>`__. When you analyze a project, for each module you can see how many other modules it imports. + +NPM +^^^ + +The ``semmle.javascript.NPM`` library provides support for working with `NPM <https://www.npmjs.com/>`__ packages through the following classes: + +- `PackageJSON <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/NPM.qll/type.NPM$PackageJSON.html>`__: a ``package.json`` file describing an NPM package; various getter predicates are available for accessing detailed information about the package, which are described in the `online API documentation <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/NPM.qll/module.NPM.html>`__. +- `BugTrackerInfo <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/NPM.qll/type.NPM$BugTrackerInfo.html>`__, `ContributorInfo <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/NPM.qll/type.NPM$ContributorInfo.html>`__, `RepositoryInfo <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/NPM.qll/type.NPM$RepositoryInfo.html>`__: these classes model parts of the ``package.json`` file providing information on bug tracking systems, contributors and repositories. +- `PackageDependencies <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/NPM.qll/type.NPM$PackageDependencies.html>`__: models the dependencies of an NPM package; the predicate ``PackageDependencies.getADependency(pkg, v)`` binds ``pkg`` to the name and ``v`` to the version of a package required by a ``package.json`` file. +- `NPMPackage <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/NPM.qll/type.NPM$NPMPackage.html>`__: a subclass of `Folder <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Files.qll/type.Files$Folder.html>`__ that models an NPM package; important member predicates include: + + - ``NPMPackage.getPackageName()`` returns the name of this package. + - ``NPMPackage.getPackageJSON()`` returns the ``package.json`` file for this package. + - ``NPMPackage.getNodeModulesFolder()`` returns the ``node_modules`` folder for this package. + - ``NPMPackage.getAModule()`` returns a Node.js module belonging to this package (not including modules in the ``node_modules`` folder). + +As an example of the use of these classes, here is a query that identifies unused dependencies, that is, module dependencies that are listed in the ``package.json`` file, but which are not imported by any ``require`` call: + +.. code-block:: ql + + import javascript + + from NPMPackage pkg, PackageDependencies deps, string name + where deps = pkg.getPackageJSON().getDependencies() and + deps.getADependency(name, _) and + not exists (Require req | req.getTopLevel() = pkg.getAModule() | name = req.getImportedPath().getValue()) + select deps, "Unused dependency '" + name + "'." + +➤ `See this in the query console on LGTM.com <https://lgtm.com/query/666680077/>`__. It is not uncommon for projects to have some unused dependencies. + +React +^^^^^ + +The ``semmle.javascript.frameworks.React`` library provides support for working with `React <https://reactjs.org/>`__ code through the `ReactComponent <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/frameworks/React.qll/type.React$ReactComponent.html>`__ class, which models a React component defined either in the functional style or the class-based style (both ECMAScript 2015 classes and old-style ``React.createClass`` classes are supported). + +Databases +^^^^^^^^^ + +The class ``SQL::SqlString`` represents an expression that is interpreted as a SQL command. Currently, we model SQL commands issued through the following npm packages: +`mysql <https://www.npmjs.com/package/mysql>`__, `pg <https://www.npmjs.com/package/pg>`__, `pg-pool <https://www.npmjs.com/package/pg-pool>`__, `sqlite3 <https://www.npmjs.com/package/sqlite3>`__, `mssql <https://www.npmjs.com/package/mssql>`__ and `sequelize <https://www.npmjs.com/package/sequelize>`__. + +Similarly, the class ``NoSQL::Query`` represents an expression that is interpreted as a NoSQL query by the ``mongodb`` or ``mongoose`` package. + +Finally, the class ``DatabaseAccess`` contains all data flow nodes that perform a database access using any of the packages above. + +For example, here is a query to find SQL queries that use string concatenation (instead of a templating-based solution, which is usually safer): + +.. code-block:: ql + + import javascript + + from SQL::SqlString ss + where ss instanceof AddExpr + select ss, "Use templating instead of string concatenation." + +➤ `See this in the query console on LGTM.com <https://lgtm.com/query/1506076336224/>`__, showing two (benign) results on `strong-arc <https://lgtm.com/projects/g/strongloop/strong-arc/>`__. + +Miscellaneous +~~~~~~~~~~~~~ + +Externs +^^^^^^^ + +The ``semmle.javascript.Externs`` library provides support for working with `externs <https://developers.google.com/closure/compiler/docs/api-tutorial3>`__ through the following classes: + +- `ExternalDecl <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Externs.qll/type.Externs$ExternalDecl.html>`__: common superclass modeling all different kinds of externs declarations; it defines two member predicates: + + - ``ExternalDecl.getQualifiedName()`` returns the fully qualified name of the declared entity. + - ``ExternalDecl.getName()`` returns the unqualified name of the declared entity. + +- `ExternalTypedef <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Externs.qll/type.Externs$ExternalTypedef.html>`__: a subclass of `ExternalDecl <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Externs.qll/type.Externs$ExternalDecl.html>`__ representing type declarations; unlike other externs declarations, such declarations do not declare a function or object that is present at runtime, but simply introduce an alias for a type. +- `ExternalVarDecl <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Externs.qll/type.Externs$ExternalVarDecl.html>`__: a subclass of `ExternalDecl <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Externs.qll/type.Externs$ExternalDecl.html>`__ representing a variable or function declaration; it defines two member predicates: + + - ``ExternalVarDecl.getInit()`` returns the initializer associated with this declaration, if any; this can either be a `Function <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Functions.qll/type.Functions$Function.html>`__ or an `Expr <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$Expr.html>`__. + - ``ExternalVarDecl.getDocumentation()`` returns the JSDoc comment associated with this declaration. + +Variables and functions declared in an externs file are either globals (represented by class `ExternalGlobalDecl <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Externs.qll/type.Externs$ExternalGlobalDecl.html>`__), or members (represented by class `ExternalMemberDecl <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Externs.qll/type.Externs$ExternalMemberDecl.html>`__). + +Members are further subdivided into static members (class `ExternalStaticMemberDecl <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Externs.qll/type.Externs$ExternalStaticMemberDecl.html>`__) and instance members (class `ExternalInstanceMemberDecl <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Externs.qll/type.Externs$ExternalInstanceMemberDecl.html>`__). + +For more details on these and other classes representing externs, see `the API documentation <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Externs.qll/module.Externs.html>`__. + +HTML +^^^^ + +The ``semmle.javascript.HTML`` library provides support for working with HTML documents. They are represented as a tree of ``HTML::Element`` nodes, each of which may have zero or more attributes represented by class ``HTML::Attribute``. + +Similar to the abstract syntax tree representation, ``HTML::Element`` has member predicates ``getChild(i)`` and ``getParent()`` to navigate from an element to its ``i``\ th child element and its parent element, respectively. Use predicate ``HTML::Element.getAttribute(i)`` to get the ``i``\ th attribute of the element, and ``HTML::Element.getAttributeByName(n)`` to get the attribute with name ``n``. + +For ``HTML::Attribute``, predicates ``getName()`` and ``getValue()`` provide access to the attribute's name and value, respectively. + +Both ``HTML::Element`` and ``HTML::Attribute`` have a predicate ``getRoot()`` that gets the root ``HTML::Element`` of the document to which they belong. + +JSDoc +^^^^^ + +The ``semmle.javascript.JSDoc`` library provides support for working with `JSDoc comments <https://jsdoc.app/>`__. Documentation comments are parsed into an abstract syntax tree representation closely following the format employed by the `Doctrine <https://github.com/eslint/doctrine>`__ JSDoc parser. + +A JSDoc comment as a whole is represented by an entity of class `JSDoc <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/JSDoc.qll/type.JSDoc$JSDoc.html>`__, while individual tags are represented by class `JSDocTag <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/JSDoc.qll/type.JSDoc$JSDocTag.html>`__. Important member predicates of these two classes include: + +- ``JSDoc.getDescription()`` returns the descriptive header of the JSDoc comment, if any. +- ``JSDoc.getComment()`` maps the `JSDoc <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/JSDoc.qll/type.JSDoc$JSDoc.html>`__ entity to its underlying `Comment <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Comments.qll/type.Comments$Comment.html>`__ entity. +- ``JSDocTag.getATag()`` returns a tag in this JSDoc comment. +- ``JSDocTag.getTitle()`` returns the title of his tag; for instance, an ``@param`` tag has title ``"param"``. +- ``JSDocTag.getName()`` returns the name of the parameter or variable documented by this tag. +- ``JSDocTag.getType()`` returns the type of the parameter or variable documented by this tag. +- ``JSDocTag.getDescription()`` returns the description associated with this tag. + +Types in JSDoc comments are represented by the class `JSDocTypeExpr <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/JSDoc.qll/type.JSDoc$JSDocTypeExpr.html>`__ and its subclasses, which again represent type expressions as abstract syntax trees. Examples of type expressions are `JSDocAnyTypeExpr <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/JSDoc.qll/type.JSDoc$JSDocAnyTypeExpr.html>`__, representing the "any" type ``*``, or `JSDocNullTypeExpr <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/JSDoc.qll/type.JSDoc$JSDocNullTypeExpr.html>`__, representing the null type. + +As an example, here is a query that finds ``@param`` tags that do not specify the name of the documented parameter: + +.. code-block:: ql + + import javascript + + from JSDocTag t + where t.getTitle() = "param" and + not exists(t.getName()) + select t, "@param tag is missing name." + +➤ `See this in the query console on LGTM.com <https://lgtm.com/query/673060054/>`__. Of the LGTM.com demo projects analyzed, only *Semantic-Org/Semantic-UI* has an example where the ``@param`` tag omits the name. + +For full details on these and other classes representing JSDoc comments and type expressions, see `the API documentation <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/JSDoc.qll/module.JSDoc.html>`__. + +JSX +^^^ + +The ``semmle.javascript.JSX`` library provides support for working with `JSX code <https://reactjs.org/docs/jsx-in-depth.html>`__. + +Similar to the representation of HTML documents, JSX fragments are modeled as a tree of `JSXElement <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/JSX.qll/type.JSX$JSXElement.html>`__\ s, each of which may have zero or more `JSXAttribute <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/JSX.qll/type.JSX$JSXAttribute.html>`__\ s. + +However, unlike HTML, JSX is interleaved with JavaScript, hence `JSXElement <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/JSX.qll/type.JSX$JSXElement.html>`__ is a subclass of `Expr <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$Expr.html>`__. Like ``HTML::Element``, it has predicates ``getAttribute(i)`` and ``getAttributeByName(n)`` to look up attributes of a JSX element. Its body elements can be accessed by predicate ``getABodyElement()``; note that the results of this predicate are arbitrary expressions, which may either be further `JSXElement <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/JSX.qll/type.JSX$JSXElement.html>`__\ s, or other expressions that are interpolated into the body of the outer element. + +`JSXAttribute <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/JSX.qll/type.JSX$JSXAttribute.html>`__, again not unlike ``HTML::Attribute``, has predicates ``getName()`` and ``getValue()`` to access the attribute name and value. + +JSON +^^^^ + +The ``semmle.javascript.JSON`` library provides support for working with `JSON <http://json.org/>`__ files that were processed by the JavaScript extractor when building the CodeQL database. + +JSON files are modeled as trees of JSON values. Each JSON value is represented by an entity of class `JSONValue <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/JSON.qll/type.JSON$JSONValue.html>`__, which provides the following member predicates: + +- ``JSONValue.getParent()`` returns the JSON object or array in which this value occurs. +- ``JSONValue.getChild(i)`` returns the ``i``\ th child of this JSON object or array. + +Note that `JSONValue <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/JSON.qll/type.JSON$JSONValue.html>`__ is a subclass of `Locatable <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Locations.qll/type.Locations$Locatable.html>`__, so the usual member predicates of `Locatable <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Locations.qll/type.Locations$Locatable.html>`__ can be used to determine the file in which a JSON value appears, and its location within that file. + +Class `JSONValue <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/JSON.qll/type.JSON$JSONValue.html>`__ has the following subclasses: + +- `JSONPrimitiveValue <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/JSON.qll/type.JSON$JSONPrimitiveValue.html>`__: a JSON-encoded primitive value; use ``JSONPrimitiveValue.getValue()`` to obtain a string representation of the value. + + - `JSONNull <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/JSON.qll/type.JSON$JSONNull.html>`__, `JSONBoolean <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/JSON.qll/type.JSON$JSONBoolean.html>`__, `JSONNumber <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/JSON.qll/type.JSON$JSONNumber.html>`__, `JSONString <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/JSON.qll/type.JSON$JSONString.html>`__: subclasses of `JSONPrimitiveValue <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/JSON.qll/type.JSON$JSONPrimitiveValue.html>`__ representing the various kinds of primitive values. + +- `JSONArray <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/JSON.qll/type.JSON$JSONArray.html>`__: a JSON-encoded array; use ``JSONArray.getElementValue(i)`` to access the ``i``\ th element of the array. +- `JSONObject <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/JSON.qll/type.JSON$JSONObject.html>`__: a JSON-encoded object; use ``JSONObject.getValue(n)`` to access the value of property ``n`` of the object. + +Regular expressions +^^^^^^^^^^^^^^^^^^^ + +The ``semmle.javascript.Regexp`` library provides support for working with regular expression literals. The syntactic structure of regular expression literals is represented as an abstract syntax tree of regular expression terms, modeled by the class `RegExpTerm <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Regexp.qll/type.Regexp$RegExpTerm.html>`__. Similar to `ASTNode <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/AST.qll/type.AST$ASTNode.html>`__, class `RegExpTerm <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Regexp.qll/type.Regexp$RegExpTerm.html>`__ provides member predicates ``getParent()`` and ``getChild(i)`` to navigate the structure of the syntax tree. + +Various subclasses of `RegExpTerm <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Regexp.qll/type.Regexp$RegExpTerm.html>`__ model different kinds of regular expression constructs and operators; see `the API documentation <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Regexp.qll/module.Regexp.html>`__ for details. + +YAML +^^^^ + +The ``semmle.javascript.YAML`` library provides support for working with `YAML <https://yaml.org/>`__ files that were processed by the JavaScript extractor when building the CodeQL database. + +YAML files are modeled as trees of YAML nodes. Each YAML node is represented by an entity of class `YAMLNode <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/YAML.qll/type.YAML$YAMLNode.html>`__, which provides, among others, the following member predicates: + +- ``YAMLNode.getParentNode()`` returns the YAML collection in which this node is syntactically nested. +- ``YAMLNode.getChildNode(i)`` returns the ``i``\ th child node of this node, ``YAMLNode.getAChildNode()`` returns any child node of this node. +- ``YAMLNode.getTag()`` returns the tag of this YAML node. +- ``YAMLNode.getAnchor()`` returns the anchor associated with this YAML node, if any. +- ``YAMLNode.eval()`` returns the `YAMLValue <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/YAML.qll/type.YAML$YAMLValue.html>`__ this YAML node evaluates to after resolving aliases and includes. + +The various kinds of scalar values available in YAML are represented by classes `YAMLInteger <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/YAML.qll/type.YAML$YAMLInteger.html>`__, `YAMLFloat <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/YAML.qll/type.YAML$YAMLFloat.html>`__, `YAMLTimestamp <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/YAML.qll/type.YAML$YAMLTimestamp.html>`__, `YAMLBool <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/YAML.qll/type.YAML$YAMLBool.html>`__, `YAMLNull <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/YAML.qll/type.YAML$YAMLNull.html>`__ and `YAMLString <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/YAML.qll/type.YAML$YAMLString.html>`__. Their common superclass is `YAMLScalar <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/YAML.qll/type.YAML$YAMLScalar.html>`__, which has a member predicate ``getValue()`` to obtain the value of a scalar as a +string. + +`YAMLMapping <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/YAML.qll/type.YAML$YAMLMapping.html>`__ and `YAMLSequence <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/YAML.qll/type.YAML$YAMLSequence.html>`__ represent mappings and sequences, respectively, and are subclasses of `YAMLCollection <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/YAML.qll/type.YAML$YAMLCollection.html>`__. + +Alias nodes are represented by class `YAMLAliasNode <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/YAML.qll/type.YAML$YAMLAliasNode.html>`__, while `YAMLMergeKey <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/YAML.qll/type.YAML$YAMLMergeKey.html>`__ and `YAMLInclude <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/YAML.qll/type.YAML$YAMLInclude.html>`__ represent merge keys and ``!include`` directives, respectively. + +Predicate ``YAMLMapping.maps(key, value)`` models the key-value relation represented by a mapping, taking merge keys into account. + +Further reading +--------------- + +.. include:: ../reusables/javascript-further-reading.rst +.. include:: ../reusables/codeql-ref-tools-further-reading.rst diff --git a/docs/codeql/codeql-language-guides/codeql-for-python/codeql-library-for-python.rst b/docs/codeql/codeql-language-guides/codeql-library-for-python.rst similarity index 78% rename from docs/codeql/codeql-language-guides/codeql-for-python/codeql-library-for-python.rst rename to docs/codeql/codeql-language-guides/codeql-library-for-python.rst index 50101f405e6..466e100b146 100644 --- a/docs/codeql/codeql-language-guides/codeql-for-python/codeql-library-for-python.rst +++ b/docs/codeql/codeql-language-guides/codeql-library-for-python.rst @@ -26,12 +26,12 @@ The CodeQL library for Python incorporates a large number of classes. Each class Syntactic classes ----------------- -This part of the library represents the Python source code. The ``Module``, ``Class``, and ``Function`` classes correspond to Python modules, classes, and functions respectively, collectively these are known as ``Scope`` classes. Each ``Scope`` contains a list of statements each of which is represented by a subclass of the class ``Stmt``. Statements themselves can contain other statements or expressions which are represented by subclasses of ``Expr``. Finally, there are a few additional classes for the parts of more complex expressions such as list comprehensions. Collectively these classes are subclasses of ``AstNode`` and form an Abstract syntax tree (AST). The root of each AST is a ``Module``. Symbolic information is attached to the AST in the form of variables (represented by the class ``Variable``). For more information, see `Abstract syntax tree <http://en.wikipedia.org/wiki/Abstract_syntax_tree>`__ and `Symbolic information <http://en.wikipedia.org/wiki/Symbol_table>`__ on Wikipedia. +This part of the library represents the Python source code. The ``Module``, ``Class``, and ``Function`` classes correspond to Python modules, classes, and functions respectively, collectively these are known as ``Scope`` classes. Each ``Scope`` contains a list of statements each of which is represented by a subclass of the class ``Stmt``. Statements themselves can contain other statements or expressions which are represented by subclasses of ``Expr``. Finally, there are a few additional classes for the parts of more complex expressions such as list comprehensions. Collectively these classes are subclasses of ``AstNode`` and form an Abstract syntax tree (AST). The root of each AST is a ``Module``. Symbolic information is attached to the AST in the form of variables (represented by the class ``Variable``). For more information, see `Abstract syntax tree <https://en.wikipedia.org/wiki/Abstract_syntax_tree>`__ and `Symbolic information <https://en.wikipedia.org/wiki/Symbol_table>`__ on Wikipedia. Scope ^^^^^ -A Python program is a group of modules. Technically a module is just a list of statements, but we often think of it as composed of classes and functions. These top-level entities, the module, class, and function are represented by the three CodeQL classes `Module <https://help.semmle.com/qldoc/python/semmle/python/Module.qll/type.Module$Module.html>`__, `Class <https://help.semmle.com/qldoc/python/semmle/python/Class.qll/type.Class$Class.html>`__ and `Function <https://help.semmle.com/qldoc/python/semmle/python/Function.qll/type.Function$Function.html>`__ which are all subclasses of ``Scope``. +A Python program is a group of modules. Technically a module is just a list of statements, but we often think of it as composed of classes and functions. These top-level entities, the module, class, and function are represented by the three CodeQL classes `Module <https://codeql.github.com/codeql-standard-libraries/python/semmle/python/Module.qll/type.Module$Module.html>`__, `Class <https://codeql.github.com/codeql-standard-libraries/python/semmle/python/Class.qll/type.Class$Class.html>`__ and `Function <https://codeql.github.com/codeql-standard-libraries/python/semmle/python/Function.qll/type.Function$Function.html>`__ which are all subclasses of ``Scope``. - ``Scope`` @@ -54,7 +54,7 @@ All scopes are basically a list of statements, although ``Scope`` classes have a Statement ^^^^^^^^^ -A statement is represented by the `Stmt <https://help.semmle.com/qldoc/python/semmle/python/Stmts.qll/type.Stmts$Stmt.html>`__ class which has about 20 subclasses representing the various kinds of statements, such as the ``Pass`` statement, the ``Return`` statement or the ``For`` statement. Statements are usually made up of parts. The most common of these is the expression, represented by the ``Expr`` class. For example, take the following Python ``for`` statement: +A statement is represented by the `Stmt <https://codeql.github.com/codeql-standard-libraries/python/semmle/python/Stmts.qll/type.Stmts$Stmt.html>`__ class which has about 20 subclasses representing the various kinds of statements, such as the ``Pass`` statement, the ``Return`` statement or the ``For`` statement. Statements are usually made up of parts. The most common of these is the expression, represented by the ``Expr`` class. For example, take the following Python ``for`` statement: .. code-block:: python @@ -63,7 +63,7 @@ A statement is represented by the `Stmt <https://help.semmle.com/qldoc/python/se else: return 0 -The `For <https://help.semmle.com/qldoc/python/semmle/python/Stmts.qll/type.Stmts$For.html>`__ class representing the ``for`` statement has a number of member predicates to access its parts: +The `For <https://codeql.github.com/codeql-standard-libraries/python/semmle/python/Stmts.qll/type.Stmts$For.html>`__ class representing the ``for`` statement has a number of member predicates to access its parts: - ``getTarget()`` returns the ``Expr`` representing the variable ``var``. - ``getIter()`` returns the ``Expr`` resenting the variable ``seq``. @@ -74,7 +74,7 @@ The `For <https://help.semmle.com/qldoc/python/semmle/python/Stmts.qll/type.Stmt Expression ^^^^^^^^^^ -Most statements are made up of expressions. The `Expr <https://help.semmle.com/qldoc/python/semmle/python/Exprs.qll/type.Exprs$Expr.html>`__ class is the superclass of all expression classes, of which there are about 30 including calls, comprehensions, tuples, lists and arithmetic operations. For example, the Python expression ``a+2`` is represented by the ``BinaryExpr`` class: +Most statements are made up of expressions. The `Expr <https://codeql.github.com/codeql-standard-libraries/python/semmle/python/Exprs.qll/type.Exprs$Expr.html>`__ class is the superclass of all expression classes, of which there are about 30 including calls, comprehensions, tuples, lists and arithmetic operations. For example, the Python expression ``a+2`` is represented by the ``BinaryExpr`` class: - ``getLeft()`` returns the ``Expr`` representing the ``a``. - ``getRight()`` returns the ``Expr`` representing the ``2``. @@ -96,12 +96,12 @@ As an example, to find expressions of the form ``a+2`` where the left is a simpl Variable ^^^^^^^^ -Variables are represented by the `Variable <https://help.semmle.com/qldoc/python/semmle/python/Variables.qll/type.Variables$Variable.html>`__ class in the CodeQL library. There are two subclasses, ``LocalVariable`` for function-level and class-level variables and ``GlobalVariable`` for module-level variables. +Variables are represented by the `Variable <https://codeql.github.com/codeql-standard-libraries/python/semmle/python/Variables.qll/type.Variables$Variable.html>`__ class in the CodeQL library. There are two subclasses, ``LocalVariable`` for function-level and class-level variables and ``GlobalVariable`` for module-level variables. Other source code elements ^^^^^^^^^^^^^^^^^^^^^^^^^^ -Although the meaning of the program is encoded by the syntactic elements, ``Scope``, ``Stmt`` and ``Expr`` there are some parts of the source code not covered by the abstract syntax tree. The most useful of these is the `Comment <https://help.semmle.com/qldoc/python/semmle/python/Comment.qll/type.Comment$Comment.html>`__ class which describes comments in the source code. +Although the meaning of the program is encoded by the syntactic elements, ``Scope``, ``Stmt`` and ``Expr`` there are some parts of the source code not covered by the abstract syntax tree. The most useful of these is the `Comment <https://codeql.github.com/codeql-standard-libraries/python/semmle/python/Comment.qll/type.Comment$Comment.html>`__ class which describes comments in the source code. Examples ^^^^^^^^ @@ -160,7 +160,7 @@ Summary The most commonly used standard classes in the syntactic part of the library are organized as follows: -``Module``, ``Class``, ``Function``, ``Stmt``, and ``Expr`` - they are all subclasses of `AstNode <https://help.semmle.com/qldoc/python/semmle/python/AstExtended.qll/type.AstExtended$AstNode.html>`__. +``Module``, ``Class``, ``Function``, ``Stmt``, and ``Expr`` - they are all subclasses of `AstNode <https://codeql.github.com/codeql-standard-libraries/python/semmle/python/AstExtended.qll/type.AstExtended$AstNode.html>`__. Abstract syntax tree '''''''''''''''''''' @@ -241,7 +241,7 @@ Other Control flow classes -------------------- -This part of the library represents the control flow graph of each ``Scope`` (classes, functions, and modules). Each ``Scope`` contains a graph of ``ControlFlowNode`` elements. Each scope has a single entry point and at least one (potentially many) exit points. To speed up control and data flow analysis, control flow nodes are grouped into basic blocks. For more information, see `Basic block <http://en.wikipedia.org/wiki/Basic_block>`__ on Wikipedia. +This part of the library represents the control flow graph of each ``Scope`` (classes, functions, and modules). Each ``Scope`` contains a graph of ``ControlFlowNode`` elements. Each scope has a single entry point and at least one (potentially many) exit points. To speed up control and data flow analysis, control flow nodes are grouped into basic blocks. For more information, see `Basic block <https://en.wikipedia.org/wiki/Basic_block>`__ on Wikipedia. Example ^^^^^^^ @@ -287,8 +287,8 @@ Summary The classes in the control-flow part of the library are: -- `ControlFlowNode <https://help.semmle.com/qldoc/python/semmle/python/Flow.qll/type.Flow$ControlFlowNode.html>`__ – A control-flow node. There is a one-to-many relation between AST nodes and control-flow nodes. -- `BasicBlock <https://help.semmle.com/qldoc/python/semmle/python/Flow.qll/type.Flow$BasicBlock.html>`__ – A non branching list of control-flow nodes. +- `ControlFlowNode <https://codeql.github.com/codeql-standard-libraries/python/semmle/python/Flow.qll/type.Flow$ControlFlowNode.html>`__ – A control-flow node. There is a one-to-many relation between AST nodes and control-flow nodes. +- `BasicBlock <https://codeql.github.com/codeql-standard-libraries/python/semmle/python/Flow.qll/type.Flow$BasicBlock.html>`__ – A non branching list of control-flow nodes. Type-inference classes @@ -311,12 +311,12 @@ For example, which ``ClassValue``\ s are iterable can be determined using the qu where cls.hasAttribute("__iter__") select cls -➤ `See this in the query console on LGTM.com <https://lgtm.com/query/5151030165280978402/>`__ This query returns a list of classes for the projects analyzed. If you want to include the results for ``builtin`` classes, which do not have any Python source code, show the non-source results. For more information, see `builtin classes <http://docs.python.org/library/stdtypes.html>`__ in the Python documentation. +➤ `See this in the query console on LGTM.com <https://lgtm.com/query/5151030165280978402/>`__ This query returns a list of classes for the projects analyzed. If you want to include the results for ``builtin`` classes, which do not have any Python source code, show the non-source results. For more information, see `builtin classes <https://docs.python.org/3/library/stdtypes.html>`__ in the Python documentation. Summary ^^^^^^^ -- `Value <https://help.semmle.com/qldoc/python/semmle/python/objects/ObjectAPI.qll/type.ObjectAPI$Value.html>`__ +- `Value <https://codeql.github.com/codeql-standard-libraries/python/semmle/python/objects/ObjectAPI.qll/type.ObjectAPI$Value.html>`__ - ``ClassValue`` - ``CallableValue`` @@ -333,8 +333,8 @@ The CodeQL library for Python also supplies classes to specify taint-tracking an Summary ^^^^^^^ -- `TaintKind <https://help.semmle.com/qldoc/python/semmle/python/dataflow/TaintTracking.qll/type.TaintTracking$TaintKind.html>`__ -- `Configuration <https://help.semmle.com/qldoc/python/semmle/python/dataflow/Configuration.qll/type.Configuration$TaintTracking$Configuration.html>`__ +- `TaintKind <https://codeql.github.com/codeql-standard-libraries/python/semmle/python/dataflow/old/TaintTracking.qll/type.TaintTracking$TaintKind.html>`__ +- `Configuration <https://codeql.github.com/codeql-standard-libraries/python/semmle/python/dataflow/old/Configuration.qll/type.Configuration$TaintTracking$Configuration.html>`__ For more information about these classes, see ":doc:`Analyzing data flow and tracking tainted data in Python <analyzing-data-flow-and-tracking-tainted-data-in-python>`." @@ -342,6 +342,6 @@ For more information about these classes, see ":doc:`Analyzing data flow and tra Further reading --------------- -.. include:: ../../reusables/python-further-reading.rst -.. include:: ../../reusables/codeql-ref-tools-further-reading.rst +.. include:: ../reusables/python-further-reading.rst +.. include:: ../reusables/codeql-ref-tools-further-reading.rst diff --git a/docs/codeql/codeql-language-guides/codeql-for-javascript/codeql-library-for-typescript.rst b/docs/codeql/codeql-language-guides/codeql-library-for-typescript.rst similarity index 50% rename from docs/codeql/codeql-language-guides/codeql-for-javascript/codeql-library-for-typescript.rst rename to docs/codeql/codeql-language-guides/codeql-library-for-typescript.rst index 9cb71916897..e729011a3e9 100644 --- a/docs/codeql/codeql-language-guides/codeql-for-javascript/codeql-library-for-typescript.rst +++ b/docs/codeql/codeql-language-guides/codeql-library-for-typescript.rst @@ -19,12 +19,12 @@ Support for analyzing TypeScript code is bundled with the CodeQL libraries for J Syntax ------ -Most syntax in TypeScript is represented in the same way as its JavaScript counterpart. For example, ``a+b`` is represented by an `AddExpr <https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/type.Expr$AddExpr.html>`__; the same as it would be in JavaScript. On the other hand, ``x as number`` is represented by `TypeAssertion <https://help.semmle.com/qldoc/javascript/semmle/javascript/TypeScript.qll/type.TypeScript$TypeAssertion.html>`__, a class that is specific to TypeScript. +Most syntax in TypeScript is represented in the same way as its JavaScript counterpart. For example, ``a+b`` is represented by an `AddExpr <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Expr.qll/type.Expr$AddExpr.html>`__; the same as it would be in JavaScript. On the other hand, ``x as number`` is represented by `TypeAssertion <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/TypeScript.qll/type.TypeScript$TypeAssertion.html>`__, a class that is specific to TypeScript. Type annotations ~~~~~~~~~~~~~~~~ -The `TypeExpr <https://help.semmle.com/qldoc/javascript/semmle/javascript/TypeScript.qll/type.TypeScript$TypeExpr.html>`__ class represents anything that is part of a type annotation. +The `TypeExpr <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/TypeScript.qll/type.TypeScript$TypeExpr.html>`__ class represents anything that is part of a type annotation. Only type annotations that are explicit in the source code occur as a ``TypeExpr``. Types inferred by the TypeScript compiler are ``Type`` entities; for details about this, see the section on `static type information <#static-type-information>`__. @@ -37,48 +37,48 @@ There are several ways to access type annotations, for example: - ``VarDecl.getTypeAnnotation()`` (special case of ``BindingPattern.getTypeAnnotation()``) - ``FieldDeclaration.getTypeAnnotation()`` -The `TypeExpr <https://help.semmle.com/qldoc/javascript/semmle/javascript/TypeScript.qll/type.TypeScript$TypeExpr.html>`__ class provides some convenient member predicates such as ``isString()`` and ``isVoid()`` to recognize commonly used types. +The `TypeExpr <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/TypeScript.qll/type.TypeScript$TypeExpr.html>`__ class provides some convenient member predicates such as ``isString()`` and ``isVoid()`` to recognize commonly used types. The subclasses that represent type annotations are: -- `TypeAccess <https://help.semmle.com/qldoc/javascript/semmle/javascript/TypeScript.qll/type.TypeScript$TypeAccess.html>`__: a name referring to a type, such as ``Date`` or ``http.ServerRequest``. +- `TypeAccess <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/TypeScript.qll/type.TypeScript$TypeAccess.html>`__: a name referring to a type, such as ``Date`` or ``http.ServerRequest``. - - `LocalTypeAccess <https://help.semmle.com/qldoc/javascript/semmle/javascript/TypeScript.qll/type.TypeScript$LocalTypeAccess.html>`__: an unqualified name, such as ``Date``. - - `QualifiedTypeAccess <https://help.semmle.com/qldoc/javascript/semmle/javascript/TypeScript.qll/type.TypeScript$QualifiedTypeAccess.html>`__: a name prefixed by a namespace, such as ``http.ServerRequest``. - - `ImportTypeAccess <https://help.semmle.com/qldoc/javascript/semmle/javascript/TypeScript.qll/type.TypeScript$ImportTypeAccess.html>`__: an ``import`` used as a type, such as ``import("./foo")``. + - `LocalTypeAccess <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/TypeScript.qll/type.TypeScript$LocalTypeAccess.html>`__: an unqualified name, such as ``Date``. + - `QualifiedTypeAccess <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/TypeScript.qll/type.TypeScript$QualifiedTypeAccess.html>`__: a name prefixed by a namespace, such as ``http.ServerRequest``. + - `ImportTypeAccess <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/TypeScript.qll/type.TypeScript$ImportTypeAccess.html>`__: an ``import`` used as a type, such as ``import("./foo")``. -- `PredefinedTypeExpr <https://help.semmle.com/qldoc/javascript/semmle/javascript/TypeScript.qll/type.TypeScript$PredefinedTypeExpr.html>`__: a predefined type, such as ``number``, ``string``, ``void``, or ``any``. -- `ThisTypeExpr <https://help.semmle.com/qldoc/javascript/semmle/javascript/TypeScript.qll/type.TypeScript$ThisTypeExpr.html>`__: the ``this`` type. -- `InterfaceTypeExpr <https://help.semmle.com/qldoc/javascript/semmle/javascript/TypeScript.qll/type.TypeScript$InterfaceTypeExpr.html>`__, also known as a literal type, such as ``{x: number}``. -- `FunctionTypeExpr <https://help.semmle.com/qldoc/javascript/semmle/javascript/TypeScript.qll/type.TypeScript$FunctionTypeExpr.html>`__: a type such as ``(x: number) => string``. -- `GenericTypeExpr <https://help.semmle.com/qldoc/javascript/semmle/javascript/TypeScript.qll/type.TypeScript$GenericTypeExpr.html>`__: a named type with type arguments, such as ``Array<string>``. -- `LiteralTypeExpr <https://help.semmle.com/qldoc/javascript/semmle/javascript/TypeScript.qll/type.TypeScript$LiteralTypeExpr.html>`__: a string, number, or boolean constant used as a type, such as ``'foo'``. -- `ArrayTypeExpr <https://help.semmle.com/qldoc/javascript/semmle/javascript/TypeScript.qll/type.TypeScript$ArrayTypeExpr.html>`__: a type such as ``string[]``. -- `UnionTypeExpr <https://help.semmle.com/qldoc/javascript/semmle/javascript/TypeScript.qll/type.TypeScript$UnionTypeExpr.html>`__: a type such as ``string | number``. -- `IntersectionTypeExpr <https://help.semmle.com/qldoc/javascript/semmle/javascript/TypeScript.qll/type.TypeScript$IntersectionTypeExpr.html>`__: a type such as ``S & T``. -- `IndexedAccessTypeExpr <https://help.semmle.com/qldoc/javascript/semmle/javascript/TypeScript.qll/type.TypeScript$IndexedAccessTypeExpr.html>`__: a type such as ``T[K]``. -- `ParenthesizedTypeExpr <https://help.semmle.com/qldoc/javascript/semmle/javascript/TypeScript.qll/type.TypeScript$ParenthesizedTypeExpr.html>`__: a type such as ``(string)``. -- `TupleTypeExpr <https://help.semmle.com/qldoc/javascript/semmle/javascript/TypeScript.qll/type.TypeScript$TupleTypeExpr.html>`__: a type such as ``[string, number]``. -- `KeyofTypeExpr <https://help.semmle.com/qldoc/javascript/semmle/javascript/TypeScript.qll/type.TypeScript$KeyofTypeExpr.html>`__: a type such as ``keyof T``. -- `TypeofTypeExpr <https://help.semmle.com/qldoc/javascript/semmle/javascript/TypeScript.qll/type.TypeScript$TypeofTypeExpr.html>`__: a type such as ``typeof x``. -- `IsTypeExpr <https://help.semmle.com/qldoc/javascript/semmle/javascript/TypeScript.qll/type.TypeScript$IsTypeExpr.html>`__: a type such as ``x is string``. -- `MappedTypeExpr <https://help.semmle.com/qldoc/javascript/semmle/javascript/TypeScript.qll/type.TypeScript$MappedTypeExpr.html>`__: a type such as ``{ [K in C]: T }``. +- `PredefinedTypeExpr <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/TypeScript.qll/type.TypeScript$PredefinedTypeExpr.html>`__: a predefined type, such as ``number``, ``string``, ``void``, or ``any``. +- `ThisTypeExpr <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/TypeScript.qll/type.TypeScript$ThisTypeExpr.html>`__: the ``this`` type. +- `InterfaceTypeExpr <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/TypeScript.qll/type.TypeScript$InterfaceTypeExpr.html>`__, also known as a literal type, such as ``{x: number}``. +- `FunctionTypeExpr <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/TypeScript.qll/type.TypeScript$FunctionTypeExpr.html>`__: a type such as ``(x: number) => string``. +- `GenericTypeExpr <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/TypeScript.qll/type.TypeScript$GenericTypeExpr.html>`__: a named type with type arguments, such as ``Array<string>``. +- `LiteralTypeExpr <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/TypeScript.qll/type.TypeScript$LiteralTypeExpr.html>`__: a string, number, or boolean constant used as a type, such as ``'foo'``. +- `ArrayTypeExpr <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/TypeScript.qll/type.TypeScript$ArrayTypeExpr.html>`__: a type such as ``string[]``. +- `UnionTypeExpr <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/TypeScript.qll/type.TypeScript$UnionTypeExpr.html>`__: a type such as ``string | number``. +- `IntersectionTypeExpr <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/TypeScript.qll/type.TypeScript$IntersectionTypeExpr.html>`__: a type such as ``S & T``. +- `IndexedAccessTypeExpr <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/TypeScript.qll/type.TypeScript$IndexedAccessTypeExpr.html>`__: a type such as ``T[K]``. +- `ParenthesizedTypeExpr <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/TypeScript.qll/type.TypeScript$ParenthesizedTypeExpr.html>`__: a type such as ``(string)``. +- `TupleTypeExpr <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/TypeScript.qll/type.TypeScript$TupleTypeExpr.html>`__: a type such as ``[string, number]``. +- `KeyofTypeExpr <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/TypeScript.qll/type.TypeScript$KeyofTypeExpr.html>`__: a type such as ``keyof T``. +- `TypeofTypeExpr <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/TypeScript.qll/type.TypeScript$TypeofTypeExpr.html>`__: a type such as ``typeof x``. +- `IsTypeExpr <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/TypeScript.qll/type.TypeScript$IsTypeExpr.html>`__: a type such as ``x is string``. +- `MappedTypeExpr <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/TypeScript.qll/type.TypeScript$MappedTypeExpr.html>`__: a type such as ``{ [K in C]: T }``. There are some subclasses that may be part of a type annotation, but are not themselves types: -- `TypeParameter <https://help.semmle.com/qldoc/javascript/semmle/javascript/TypeScript.qll/type.TypeScript$TypeParameter.html>`__: a type parameter declared on a type or function, such as ``T`` in ``class C<T> {}``. -- `NamespaceAccess <https://help.semmle.com/qldoc/javascript/semmle/javascript/TypeScript.qll/type.TypeScript$NamespaceAccess.html>`__: a name referring to a namespace from inside a type, such as ``http`` in ``http.ServerRequest``. +- `TypeParameter <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/TypeScript.qll/type.TypeScript$TypeParameter.html>`__: a type parameter declared on a type or function, such as ``T`` in ``class C<T> {}``. +- `NamespaceAccess <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/TypeScript.qll/type.TypeScript$NamespaceAccess.html>`__: a name referring to a namespace from inside a type, such as ``http`` in ``http.ServerRequest``. - - `LocalNamespaceAccess <https://help.semmle.com/qldoc/javascript/semmle/javascript/TypeScript.qll/type.TypeScript$LocalNamespaceAccess.html>`__: the initial identifier in a prefix, such as ``http`` in ``http.ServerRequest``. - - `QualifiedNamespaceAccess <https://help.semmle.com/qldoc/javascript/semmle/javascript/TypeScript.qll/type.TypeScript$QualifiedNamespaceAccess.html>`__: a qualified name in a prefix, such as ``net.client`` in ``net.client.Connection``. - - `ImportNamespaceAccess <https://help.semmle.com/qldoc/javascript/semmle/javascript/TypeScript.qll/type.TypeScript$ImportNamespaceAccess.html>`__: an ``import`` used as a namespace in a type, such as in ``import("http").ServerRequest``. + - `LocalNamespaceAccess <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/TypeScript.qll/type.TypeScript$LocalNamespaceAccess.html>`__: the initial identifier in a prefix, such as ``http`` in ``http.ServerRequest``. + - `QualifiedNamespaceAccess <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/TypeScript.qll/type.TypeScript$QualifiedNamespaceAccess.html>`__: a qualified name in a prefix, such as ``net.client`` in ``net.client.Connection``. + - `ImportNamespaceAccess <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/TypeScript.qll/type.TypeScript$ImportNamespaceAccess.html>`__: an ``import`` used as a namespace in a type, such as in ``import("http").ServerRequest``. -- `VarTypeAccess <https://help.semmle.com/qldoc/javascript/semmle/javascript/TypeScript.qll/type.TypeScript$VarTypeAccess.html>`__: a reference to a value from inside a type, such as ``x`` in ``typeof x`` or ``x is string``. +- `VarTypeAccess <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/TypeScript.qll/type.TypeScript$VarTypeAccess.html>`__: a reference to a value from inside a type, such as ``x`` in ``typeof x`` or ``x is string``. Function signatures ~~~~~~~~~~~~~~~~~~~ -The `Function <https://help.semmle.com/qldoc/javascript/semmle/javascript/Functions.qll/type.Functions$Function.html>`__ class is a broad class that includes both concrete functions and function signatures. +The `Function <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Functions.qll/type.Functions$Function.html>`__ class is a broad class that includes both concrete functions and function signatures. Function signatures can take several forms: @@ -94,7 +94,7 @@ We recommend that you use the predicate ``Function.hasBody()`` to distinguish co Type parameters ~~~~~~~~~~~~~~~ -The `TypeParameter <https://help.semmle.com/qldoc/javascript/semmle/javascript/TypeScript.qll/type.TypeScript$TypeParameter.html>`__ class represents type parameters, and the `TypeParameterized <https://help.semmle.com/qldoc/javascript/semmle/javascript/TypeScript.qll/type.TypeScript$TypeParameterized.html>`__ class represents entities that can declare type parameters. Classes, interfaces, type aliases, functions, and mapped type expressions are all ``TypeParameterized``. +The `TypeParameter <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/TypeScript.qll/type.TypeScript$TypeParameter.html>`__ class represents type parameters, and the `TypeParameterized <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/TypeScript.qll/type.TypeScript$TypeParameterized.html>`__ class represents entities that can declare type parameters. Classes, interfaces, type aliases, functions, and mapped type expressions are all ``TypeParameterized``. You can access type parameters using the following predicates: @@ -104,7 +104,7 @@ You can access type parameters using the following predicates: You can access type arguments using the following predicates: - ``GenericTypeExpr.getTypeArgument(n)`` gets the ``n``\ th type argument of a type. -- ``TypeAccess.getTypeArgument(n)`` is a convenient alternative for the above (a `TypeAccess <https://help.semmle.com/qldoc/javascript/semmle/javascript/TypeScript.qll/type.TypeScript$TypeAccess.html>`__ with type arguments is wrapped in a `GenericTypeExpr <https://help.semmle.com/qldoc/javascript/semmle/javascript/TypeScript.qll/type.TypeScript$GenericTypeExpr.html>`__). +- ``TypeAccess.getTypeArgument(n)`` is a convenient alternative for the above (a `TypeAccess <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/TypeScript.qll/type.TypeScript$TypeAccess.html>`__ with type arguments is wrapped in a `GenericTypeExpr <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/TypeScript.qll/type.TypeScript$GenericTypeExpr.html>`__). - ``InvokeExpr.getTypeArgument(n)`` gets the ``n``\ th type argument of a call. - ``ExpressionWithTypeArguments.getTypeArgument(n)`` gets the ``n``\ th type argument of a generic superclass expression. @@ -128,7 +128,7 @@ Select expressions that cast a value to a type parameter: Classes and interfaces ~~~~~~~~~~~~~~~~~~~~~~ -The CodeQL class `ClassOrInterface <https://help.semmle.com/qldoc/javascript/semmle/javascript/Classes.qll/type.Classes$ClassOrInterface.html>`__ is a common supertype of classes and interfaces, and provides some TypeScript-specific member predicates: +The CodeQL class `ClassOrInterface <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Classes.qll/type.Classes$ClassOrInterface.html>`__ is a common supertype of classes and interfaces, and provides some TypeScript-specific member predicates: - ``ClassOrInterface.isAbstract()`` holds if this is an interface or a class with the ``abstract`` modifier. - ``ClassOrInterface.getASuperInterface()`` gets a type from the ``implements`` clause of a class or from the ``extends`` clause of an interface. @@ -136,9 +136,9 @@ The CodeQL class `ClassOrInterface <https://help.semmle.com/qldoc/javascript/sem - ``ClassOrInterface.getAnIndexSignature()`` gets an index signature, such as in ``{ [key: string]: number }``. - ``ClassOrInterface.getATypeParameter()`` gets a declared type parameter (special case of ``TypeParameterized.getATypeParameter()``). -Note that the superclass of a class is an expression, not a type annotation. If the superclass has type arguments, it will be an expression of kind `ExpressionWithTypeArguments <https://help.semmle.com/qldoc/javascript/semmle/javascript/TypeScript.qll/type.TypeScript$ExpressionWithTypeArguments.html>`__. +Note that the superclass of a class is an expression, not a type annotation. If the superclass has type arguments, it will be an expression of kind `ExpressionWithTypeArguments <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/TypeScript.qll/type.TypeScript$ExpressionWithTypeArguments.html>`__. -Also see the documentation for classes in the "`CodeQL libraries for JavaScript <introduce-libraries-js#classes>`__." +Also see the documentation for classes in the "`CodeQL libraries for JavaScript <https://codeql.github.com/docs/codeql-language-guides/codeql-library-for-javascript/#classes>`__." To select the type references to a class or an interface, use ``getTypeName()``. @@ -147,25 +147,25 @@ Statements The following are TypeScript-specific statements: -- `NamespaceDeclaration <https://help.semmle.com/qldoc/javascript/semmle/javascript/TypeScript.qll/type.TypeScript$NamespaceDeclaration.html>`__: a statement such as ``namespace M {}``. -- `EnumDeclaration <https://help.semmle.com/qldoc/javascript/semmle/javascript/TypeScript.qll/type.TypeScript$EnumDeclaration.html>`__: a statement such as ``enum Color { red, green, blue }``. -- `TypeAliasDeclaration <https://help.semmle.com/qldoc/javascript/semmle/javascript/TypeScript.qll/type.TypeScript$TypeAliasDeclaration.html>`__: a statement such as ``type A = number``. -- `InterfaceDeclaration <https://help.semmle.com/qldoc/javascript/semmle/javascript/TypeScript.qll/type.TypeScript$InterfaceDeclaration.html>`__: a statement such as ``interface Point { x: number; y: number; }``. -- `ImportEqualsDeclaration <https://help.semmle.com/qldoc/javascript/semmle/javascript/TypeScript.qll/type.TypeScript$ImportEqualsDeclaration.html>`__: a statement such as ``import fs = require("fs")``. -- `ExportAssignDeclaration <https://help.semmle.com/qldoc/javascript/semmle/javascript/TypeScript.qll/type.TypeScript$ExportAssignDeclaration.html>`__: a statement such as ``export = M``. -- `ExportAsNamespaceDeclaration <https://help.semmle.com/qldoc/javascript/semmle/javascript/TypeScript.qll/type.TypeScript$ExportAsNamespaceDeclaration.html>`__: a statement such as ``export as namespace M``. -- `ExternalModuleDeclaration <https://help.semmle.com/qldoc/javascript/semmle/javascript/TypeScript.qll/type.TypeScript$ExternalModuleDeclaration.html>`__: a statement such as ``module "foo" {}``. -- `GlobalAugmentationDeclaration <https://help.semmle.com/qldoc/javascript/semmle/javascript/TypeScript.qll/type.TypeScript$GlobalAugmentationDeclaration.html>`__: a statement such as ``global {}`` +- `NamespaceDeclaration <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/TypeScript.qll/type.TypeScript$NamespaceDeclaration.html>`__: a statement such as ``namespace M {}``. +- `EnumDeclaration <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/TypeScript.qll/type.TypeScript$EnumDeclaration.html>`__: a statement such as ``enum Color { red, green, blue }``. +- `TypeAliasDeclaration <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/TypeScript.qll/type.TypeScript$TypeAliasDeclaration.html>`__: a statement such as ``type A = number``. +- `InterfaceDeclaration <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/TypeScript.qll/type.TypeScript$InterfaceDeclaration.html>`__: a statement such as ``interface Point { x: number; y: number; }``. +- `ImportEqualsDeclaration <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/TypeScript.qll/type.TypeScript$ImportEqualsDeclaration.html>`__: a statement such as ``import fs = require("fs")``. +- `ExportAssignDeclaration <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/TypeScript.qll/type.TypeScript$ExportAssignDeclaration.html>`__: a statement such as ``export = M``. +- `ExportAsNamespaceDeclaration <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/TypeScript.qll/type.TypeScript$ExportAsNamespaceDeclaration.html>`__: a statement such as ``export as namespace M``. +- `ExternalModuleDeclaration <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/TypeScript.qll/type.TypeScript$ExternalModuleDeclaration.html>`__: a statement such as ``module "foo" {}``. +- `GlobalAugmentationDeclaration <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/TypeScript.qll/type.TypeScript$GlobalAugmentationDeclaration.html>`__: a statement such as ``global {}`` Expressions ~~~~~~~~~~~ The following are TypeScript-specific expressions: -- `ExpressionWithTypeArguments <https://help.semmle.com/qldoc/javascript/semmle/javascript/TypeScript.qll/type.TypeScript$ExpressionWithTypeArguments.html>`__: occurs when the ``extends`` clause of a class has type arguments, such as in ``class C extends D<string>``. -- `TypeAssertion <https://help.semmle.com/qldoc/javascript/semmle/javascript/TypeScript.qll/type.TypeScript$TypeAssertion.html>`__: asserts that a value has a given type, such as ``x as number`` or ``<number> x``. -- `NonNullAssertion <https://help.semmle.com/qldoc/javascript/semmle/javascript/TypeScript.qll/type.TypeScript$NonNullAssertion.html>`__: asserts that a value is not null or undefined, such as ``x!``. -- `ExternalModuleReference <https://help.semmle.com/qldoc/javascript/semmle/javascript/TypeScript.qll/type.TypeScript$ExternalModuleReference.html>`__: a ``require`` call on the right-hand side of an import-assign, such as ``import fs = require("fs")``. +- `ExpressionWithTypeArguments <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/TypeScript.qll/type.TypeScript$ExpressionWithTypeArguments.html>`__: occurs when the ``extends`` clause of a class has type arguments, such as in ``class C extends D<string>``. +- `TypeAssertion <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/TypeScript.qll/type.TypeScript$TypeAssertion.html>`__: asserts that a value has a given type, such as ``x as number`` or ``<number> x``. +- `NonNullAssertion <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/TypeScript.qll/type.TypeScript$NonNullAssertion.html>`__: asserts that a value is not null or undefined, such as ``x!``. +- `ExternalModuleReference <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/TypeScript.qll/type.TypeScript$ExternalModuleReference.html>`__: a ``require`` call on the right-hand side of an import-assign, such as ``import fs = require("fs")``. Ambient declarations ~~~~~~~~~~~~~~~~~~~~ @@ -181,16 +181,10 @@ Static type information Static type information and global name binding is available for projects with "full" TypeScript extraction enabled. This option is enabled by default for projects on LGTM.com and when you create databases with the :ref:`CodeQL CLI <codeql-cli>`. -.. pull-quote:: Note - - If you are using the `legacy QL command-line tools <https://help.semmle.com/wiki/display/SD/QL+command-line+tools>`__, you must enable full TypeScript extraction by passing ``--typescript-full`` to the JavaScript extractor. For further information on customizing calls to the extractor, see `Customizing JavaScript extraction <https://help.semmle.com/wiki/display/SD/Customizing+JavaScript+extraction>`__. - - Without full extraction, the classes and predicates described in this section are empty. - Basic usage ~~~~~~~~~~~ -The `Type <https://help.semmle.com/qldoc/javascript/semmle/javascript/TypeScript.qll/type.TypeScript$Type.html>`__ class represents a static type, such as ``number`` or ``string``. The type of an expression can be obtained with ``Expr.getType()``. +The `Type <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/TypeScript.qll/type.TypeScript$Type.html>`__ class represents a static type, such as ``number`` or ``string``. The type of an expression can be obtained with ``Expr.getType()``. Types that refer to a specific named type can be recognized in various ways: @@ -343,7 +337,7 @@ Name binding In TypeScript, names can refer to variables, types, and namespaces, or a combination of these. -These concepts are modeled as distinct entities: `Variable <https://help.semmle.com/qldoc/javascript/semmle/javascript/Variables.qll/type.Variables$Variable.html>`__, `TypeName <https://help.semmle.com/qldoc/javascript/semmle/javascript/CanonicalNames.qll/type.CanonicalNames$TypeName.html>`__, and `Namespace <https://help.semmle.com/qldoc/javascript/semmle/javascript/CanonicalNames.qll/type.CanonicalNames$Namespace.html>`__. For example, the class ``C`` below introduces both a variable and a type: +These concepts are modeled as distinct entities: `Variable <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Variables.qll/type.Variables$Variable.html>`__, `TypeName <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/CanonicalNames.qll/type.CanonicalNames$TypeName.html>`__, and `Namespace <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/CanonicalNames.qll/type.CanonicalNames$Namespace.html>`__. For example, the class ``C`` below introduces both a variable and a type: .. code-block:: typescript @@ -351,7 +345,7 @@ These concepts are modeled as distinct entities: `Variable <https://help.semmle. let x = C; // refers to the variable C let y: C; // refers to the type C -The variable ``C`` and the type ``C`` are modeled as distinct entities. One is a `Variable <https://help.semmle.com/qldoc/javascript/semmle/javascript/Variables.qll/type.Variables$Variable.html>`__, the other is a `TypeName <https://help.semmle.com/qldoc/javascript/semmle/javascript/CanonicalNames.qll/type.CanonicalNames$TypeName.html>`__. +The variable ``C`` and the type ``C`` are modeled as distinct entities. One is a `Variable <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Variables.qll/type.Variables$Variable.html>`__, the other is a `TypeName <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/CanonicalNames.qll/type.CanonicalNames$TypeName.html>`__. TypeScript also allows you to import types and namespaces, and give them local names in different scopes. For example, the import below introduces a local type name ``B``: @@ -359,33 +353,33 @@ TypeScript also allows you to import types and namespaces, and give them local n import {C as B} from "./foo" -The local name ``B`` is represented as a `LocalTypeName <https://help.semmle.com/qldoc/javascript/semmle/javascript/TypeScript.qll/type.TypeScript$LocalTypeName.html>`__ named ``B``, restricted to just the file containing the import. An import statement can also introduce a `Variable <https://help.semmle.com/qldoc/javascript/semmle/javascript/Variables.qll/type.Variables$Variable.html>`__ and a `LocalNamespaceName <https://help.semmle.com/qldoc/javascript/semmle/javascript/TypeScript.qll/type.TypeScript$LocalNamespaceName.html>`__. +The local name ``B`` is represented as a `LocalTypeName <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/TypeScript.qll/type.TypeScript$LocalTypeName.html>`__ named ``B``, restricted to just the file containing the import. An import statement can also introduce a `Variable <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Variables.qll/type.Variables$Variable.html>`__ and a `LocalNamespaceName <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/TypeScript.qll/type.TypeScript$LocalNamespaceName.html>`__. The following table shows the relevant classes for working with each kind of name. The classes are described in more detail below. -+-----------+------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------+ -| Kind | Local alias | Canonical name | Definition | Access | -+===========+================================================================================================================================================+======================================================================================================================================+===================================================================================================================================================+==========================================================================================================================================+ -| Value | `Variable <https://help.semmle.com/qldoc/javascript/semmle/javascript/Variables.qll/type.Variables$Variable.html>`__ | | | `VarAccess <https://help.semmle.com/qldoc/javascript/semmle/javascript/Variables.qll/type.Variables$VarAccess.html>`__ | -+-----------+------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------+ -| Type | `LocalTypeName <https://help.semmle.com/qldoc/javascript/semmle/javascript/TypeScript.qll/type.TypeScript$LocalTypeName.html>`__ | `TypeName <https://help.semmle.com/qldoc/javascript/semmle/javascript/CanonicalNames.qll/type.CanonicalNames$TypeName.html>`__ | `TypeDefinition <https://help.semmle.com/qldoc/javascript/semmle/javascript/TypeScript.qll/type.TypeScript$TypeDefinition.html>`__ | `TypeAccess <https://help.semmle.com/qldoc/javascript/semmle/javascript/TypeScript.qll/type.TypeScript$TypeAccess.html>`__ | -+-----------+------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------+ -| Namespace | `LocalNamespaceName <https://help.semmle.com/qldoc/javascript/semmle/javascript/TypeScript.qll/type.TypeScript$LocalNamespaceName.html>`__ | `Namespace <https://help.semmle.com/qldoc/javascript/semmle/javascript/CanonicalNames.qll/type.CanonicalNames$Namespace.html>`__ | `NamespaceDefinition <https://help.semmle.com/qldoc/javascript/semmle/javascript/TypeScript.qll/type.TypeScript$NamespaceDeclaration.html>`__ | `NamespaceAccess <https://help.semmle.com/qldoc/javascript/semmle/javascript/TypeScript.qll/type.TypeScript$NamespaceAccess.html>`__ | -+-----------+------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------+ ++-----------+------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| Kind | Local alias | Canonical name | Definition | Access | ++===========+==================================================================================================================================================================+========================================================================================================================================================+=====================================================================================================================================================================+============================================================================================================================================================+ +| Value | `Variable <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Variables.qll/type.Variables$Variable.html>`__ | | | `VarAccess <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Variables.qll/type.Variables$VarAccess.html>`__ | ++-----------+------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| Type | `LocalTypeName <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/TypeScript.qll/type.TypeScript$LocalTypeName.html>`__ | `TypeName <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/CanonicalNames.qll/type.CanonicalNames$TypeName.html>`__ | `TypeDefinition <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/TypeScript.qll/type.TypeScript$TypeDefinition.html>`__ | `TypeAccess <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/TypeScript.qll/type.TypeScript$TypeAccess.html>`__ | ++-----------+------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| Namespace | `LocalNamespaceName <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/TypeScript.qll/type.TypeScript$LocalNamespaceName.html>`__ | `Namespace <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/CanonicalNames.qll/type.CanonicalNames$Namespace.html>`__ | `NamespaceDefinition <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/TypeScript.qll/type.TypeScript$NamespaceDeclaration.html>`__ | `NamespaceAccess <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/TypeScript.qll/type.TypeScript$NamespaceAccess.html>`__ | ++-----------+------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------+ **Note:** ``TypeName`` and ``Namespace`` are only populated if the database is generated using full TypeScript extraction. ``LocalTypeName`` and ``LocalNamespaceName`` are always populated. Type names ~~~~~~~~~~ -A `TypeName <https://help.semmle.com/qldoc/javascript/semmle/javascript/CanonicalNames.qll/type.CanonicalNames$TypeName.html>`__ is a qualified name for a type and is not bound to a specific lexical scope. The `TypeDefinition <https://help.semmle.com/qldoc/javascript/semmle/javascript/TypeScript.qll/type.TypeScript$TypeDefinition.html>`__ class represents an entity that defines a type, namely a class, interface, type alias, enum, or enum member. The relevant predicates for working with type names are: +A `TypeName <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/CanonicalNames.qll/type.CanonicalNames$TypeName.html>`__ is a qualified name for a type and is not bound to a specific lexical scope. The `TypeDefinition <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/TypeScript.qll/type.TypeScript$TypeDefinition.html>`__ class represents an entity that defines a type, namely a class, interface, type alias, enum, or enum member. The relevant predicates for working with type names are: - ``TypeAccess.getTypeName()`` gets the qualified name being referenced (if any). - ``TypeDefinition.getTypeName()`` gets the qualified name of a class, interface, type alias, enum, or enum member. - ``TypeName.getAnAccess()``, gets an access to a given type. - ``TypeName.getADefinition()``, get a definition of a given type. Note that interfaces can have multiple definitions. -A `LocalTypeName <https://help.semmle.com/qldoc/javascript/semmle/javascript/TypeScript.qll/type.TypeScript$LocalTypeName.html>`__ behaves like a block-scoped variable, that is, it has an unqualified name and is restricted to a specific scope. The relevant predicates are: +A `LocalTypeName <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/TypeScript.qll/type.TypeScript$LocalTypeName.html>`__ behaves like a block-scoped variable, that is, it has an unqualified name and is restricted to a specific scope. The relevant predicates are: - ``LocalTypeAccess.getLocalTypeName()`` gets the local name referenced by an unqualified type access. - ``LocalTypeName.getAnAccess()`` gets an access to a local type name. @@ -397,7 +391,7 @@ Examples Find references that omit type arguments to a generic type. -It is best to use `TypeName <https://help.semmle.com/qldoc/javascript/semmle/javascript/CanonicalNames.qll/type.CanonicalNames$TypeName.html>`__ to resolve through imports and qualified names: +It is best to use `TypeName <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/CanonicalNames.qll/type.CanonicalNames$TypeName.html>`__ to resolve through imports and qualified names: .. code-block:: ql @@ -427,11 +421,11 @@ Find imported names that are used as both a type and a value: Namespace names ~~~~~~~~~~~~~~~ -Namespaces are represented by the classes `Namespace <https://help.semmle.com/qldoc/javascript/semmle/javascript/CanonicalNames.qll/type.CanonicalNames$Namespace.html>`__ and `LocalNamespaceName <https://help.semmle.com/qldoc/javascript/semmle/javascript/TypeScript.qll/type.TypeScript$LocalNamespaceName.html>`__. The `NamespaceDefinition <https://help.semmle.com/qldoc/javascript/semmle/javascript/TypeScript.qll/type.TypeScript$NamespaceDefinition.html>`__ class represents a syntactic definition of a namespace, which includes ordinary namespace declarations as well as enum declarations. +Namespaces are represented by the classes `Namespace <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/CanonicalNames.qll/type.CanonicalNames$Namespace.html>`__ and `LocalNamespaceName <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/TypeScript.qll/type.TypeScript$LocalNamespaceName.html>`__. The `NamespaceDefinition <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/TypeScript.qll/type.TypeScript$NamespaceDefinition.html>`__ class represents a syntactic definition of a namespace, which includes ordinary namespace declarations as well as enum declarations. Note that these classes deal exclusively with namespaces referenced from inside type annotations, not through expressions. -A `Namespace <https://help.semmle.com/qldoc/javascript/semmle/javascript/CanonicalNames.qll/type.CanonicalNames$Namespace.html>`__ is a qualified name for a namespace, and is not bound to a specific scope. The relevant predicates for working with namespaces are: +A `Namespace <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/CanonicalNames.qll/type.CanonicalNames$Namespace.html>`__ is a qualified name for a namespace, and is not bound to a specific scope. The relevant predicates for working with namespaces are: - ``NamespaceAccess.getNamespace()`` gets the namespace being referenced by a namespace access. - ``NamespaceDefinition.getNamespace()`` gets the namespace defined by a namespace or enum declaration. @@ -439,9 +433,9 @@ A `Namespace <https://help.semmle.com/qldoc/javascript/semmle/javascript/Canonic - ``Namespace.getADefinition()`` gets a definition of this namespace. Note that namespaces can have multiple definitions. - ``Namespace.getNamespaceMember(name)`` gets an inner namespace with a given name. - ``Namespace.getTypeMember(name)`` gets a type exported under a given name. -- ``Namespace.getAnExportingContainer()`` gets a `StmtContainer <https://help.semmle.com/qldoc/javascript/semmle/javascript/AST.qll/type.AST$StmtContainer.html>`__ whose exports contribute to this namespace. This can be a the body of a namespace declaration or the top-level of a module. Enums have no exporting containers. +- ``Namespace.getAnExportingContainer()`` gets a `StmtContainer <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/AST.qll/type.AST$StmtContainer.html>`__ whose exports contribute to this namespace. This can be a the body of a namespace declaration or the top-level of a module. Enums have no exporting containers. -A `LocalNamespaceName <https://help.semmle.com/qldoc/javascript/semmle/javascript/TypeScript.qll/type.TypeScript$LocalNamespaceName.html>`__ behaves like a block-scoped variable, that is, it has an unqualified name and is restricted to a specific scope. The relevant predicates are: +A `LocalNamespaceName <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/TypeScript.qll/type.TypeScript$LocalNamespaceName.html>`__ behaves like a block-scoped variable, that is, it has an unqualified name and is restricted to a specific scope. The relevant predicates are: - ``LocalNamespaceAccess.getLocalNamespaceName()`` gets the local name referenced by an identifier. - ``LocalNamespaceName.getAnAccess()`` gets an identifier that refers to this local name. @@ -451,5 +445,5 @@ A `LocalNamespaceName <https://help.semmle.com/qldoc/javascript/semmle/javascrip Further reading --------------- -.. include:: ../../reusables/javascript-further-reading.rst -.. include:: ../../reusables/codeql-ref-tools-further-reading.rst +.. include:: ../reusables/javascript-further-reading.rst +.. include:: ../reusables/codeql-ref-tools-further-reading.rst diff --git a/docs/codeql/codeql-language-guides/codeql-for-cpp/conversions-and-classes-in-cpp.rst b/docs/codeql/codeql-language-guides/conversions-and-classes-in-cpp.rst similarity index 96% rename from docs/codeql/codeql-language-guides/codeql-for-cpp/conversions-and-classes-in-cpp.rst rename to docs/codeql/codeql-language-guides/conversions-and-classes-in-cpp.rst index ea08d7620d9..9bd057412f6 100644 --- a/docs/codeql/codeql-language-guides/codeql-for-cpp/conversions-and-classes-in-cpp.rst +++ b/docs/codeql/codeql-language-guides/conversions-and-classes-in-cpp.rst @@ -10,7 +10,7 @@ Conversions In C and C++, conversions change the type of an expression. They may be implicit conversions generated by the compiler, or explicit conversions requested by the user. -Let's take a look at the `Conversion <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/Cast.qll/type.Cast$Conversion.html>`__ class in the standard library: +Let's take a look at the `Conversion <https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/exprs/Cast.qll/type.Cast$Conversion.html>`__ class in the standard library: - ``Expr`` @@ -225,5 +225,5 @@ There is a similar built-in `query <https://lgtm.com/rules/2158670642/>`__ on LG Further reading --------------- -.. include:: ../../reusables/cpp-further-reading.rst -.. include:: ../../reusables/codeql-ref-tools-further-reading.rst +.. include:: ../reusables/cpp-further-reading.rst +.. include:: ../reusables/codeql-ref-tools-further-reading.rst diff --git a/docs/codeql/codeql-language-guides/data-flow-cheat-sheet-for-javascript.rst b/docs/codeql/codeql-language-guides/data-flow-cheat-sheet-for-javascript.rst new file mode 100644 index 00000000000..92eb35d4d2e --- /dev/null +++ b/docs/codeql/codeql-language-guides/data-flow-cheat-sheet-for-javascript.rst @@ -0,0 +1,229 @@ +.. _data-flow-cheat-sheet-for-javascript: + +Data flow cheat sheet for JavaScript +==================================== + +This article describes parts of the JavaScript libraries commonly used for variant analysis and in data flow queries. + +Taint tracking path queries +--------------------------- + +Use the following template to create a taint tracking path query: + +.. code-block:: ql + + /** + * @kind path-problem + */ + import javascript + import DataFlow + import DataFlow::PathGraph + + class MyConfig extends TaintTracking::Configuration { + MyConfig() { this = "MyConfig" } + override predicate isSource(Node node) { ... } + override predicate isSink(Node node) { ... } + override predicate isAdditionalTaintStep(Node pred, Node succ) { ... } + } + + from MyConfig cfg, PathNode source, PathNode sink + where cfg.hasFlowPath(source, sink) + select sink.getNode(), source, sink, "taint from $@.", source.getNode(), "here" + +This query reports flow paths which: + +- Begin at a node matched by `isSource <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/dataflow/Configuration.qll/predicate.Configuration$Configuration$isSource.1.html>`__. +- Step through variables, function calls, properties, strings, arrays, promises, exceptions, and steps added by `isAdditionalTaintStep <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/dataflow/TaintTracking.qll/predicate.TaintTracking$TaintTracking$Configuration$isAdditionalTaintStep.2.html>`__. +- End at a node matched by `isSink <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/dataflow/Configuration.qll/predicate.Configuration$Configuration$isSink.1.html>`__. + +See also: "`Global data flow <https://codeql.github.com/docs/codeql-language-guides/analyzing-data-flow-in-javascript-and-typescript/#global-data-flow>`__" and ":ref:`Creating path queries <creating-path-queries>`." + +DataFlow module +--------------- + +Use data flow nodes to match program elements independently of syntax. See also: ":doc:`Analyzing data flow in JavaScript and TypeScript <analyzing-data-flow-in-javascript-and-typescript>`." + +Predicates in the ``DataFlow::`` module: + +- `moduleImport <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/dataflow/Nodes.qll/predicate.Nodes$moduleImport.1.html>`__ -- finds uses of a module +- `moduleMember <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/dataflow/Nodes.qll/predicate.Nodes$moduleMember.2.html>`__ -- finds uses of a module member +- `globalVarRef <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/dataflow/Nodes.qll/predicate.Nodes$globalVarRef.1.html>`__ -- finds uses of a global variable + +Classes and member predicates in the ``DataFlow::`` module: + +- `Node <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/dataflow/DataFlow.qll/type.DataFlow$DataFlow$Node.html>`__ -- something that can have a value, such as an expression, declaration, or SSA variable + - `getALocalSource <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/dataflow/DataFlow.qll/predicate.DataFlow$DataFlow$Node$getALocalSource.0.html>`__ -- find the node that this came from + - `getTopLevel <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/dataflow/DataFlow.qll/predicate.DataFlow$DataFlow$Node$getTopLevel.0.html>`__ -- top-level scope enclosing this node + - `getFile <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/dataflow/DataFlow.qll/predicate.DataFlow$DataFlow$Node$getFile.0.html>`__ -- file containing this node + - `getIntValue <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/dataflow/DataFlow.qll/predicate.DataFlow$DataFlow$Node$getIntValue.0.html>`__ -- value of this node if it's is an integer constant + - `getStringValue <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/dataflow/DataFlow.qll/predicate.DataFlow$DataFlow$Node$getStringValue.0.html>`__ -- value of this node if it's is a string constant + - `mayHaveBooleanValue <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/dataflow/DataFlow.qll/predicate.DataFlow$DataFlow$Node$mayHaveBooleanValue.1.html>`__ -- check if the value is ``true`` or ``false`` +- `SourceNode <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/dataflow/Sources.qll/type.Sources$SourceNode.html>`__ extends `Node <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/dataflow/DataFlow.qll/type.DataFlow$DataFlow$Node.html>`__ -- function call, parameter, object creation, or reference to a property or global variable + - `getACall <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/dataflow/Sources.qll/predicate.Sources$SourceNode$getACall.0.html>`__ -- find calls with this as the callee + - `getAnInstantiation <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/dataflow/Sources.qll/predicate.Sources$SourceNode$getAnInstantiation.0.html>`__ -- find ``new``-calls with this as the callee + - `getAnInvocation <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/dataflow/Sources.qll/predicate.Sources$SourceNode$getAnInvocation.0.html>`__ -- find calls or ``new``-calls with this as the callee + - `getAMethodCall <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/dataflow/Sources.qll/predicate.Sources$SourceNode$getAMethodCall.1.html>`__ -- find method calls with this as the receiver + - `getAMemberCall <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/dataflow/Sources.qll/predicate.Sources$SourceNode$getAMemberCall.1.html>`__ -- find calls with a member of this as the receiver + - `getAPropertyRead <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/dataflow/Sources.qll/predicate.Sources$SourceNode$getAPropertyRead.1.html>`__ -- find property reads with this as the base + - `getAPropertyWrite <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/dataflow/Sources.qll/predicate.Sources$SourceNode$getAPropertyWrite.1.html>`__ -- find property writes with this as the base + - `getAPropertySource <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/dataflow/Sources.qll/predicate.Sources$SourceNode$getAPropertySource.1.html>`__ -- find nodes flowing into a property of this node +- `InvokeNode <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/dataflow/Nodes.qll/type.Nodes$InvokeNode.html>`__, `NewNode <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/dataflow/Nodes.qll/type.Nodes$NewNode.html>`__, `CallNode <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/dataflow/Nodes.qll/type.Nodes$CallNode.html>`__, `MethodCallNode <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/dataflow/Nodes.qll/type.Nodes$MethodCallNode.html>`__ extends `SourceNode <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/dataflow/Sources.qll/type.Sources$SourceNode.html>`__ -- call to a function or constructor + - `getArgument <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/dataflow/Nodes.qll/predicate.Nodes$InvokeNode$getArgument.1.html>`__ -- an argument to the call + - `getCalleeNode <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/dataflow/Nodes.qll/predicate.Nodes$InvokeNode$getCalleeNode.0.html>`__ -- node being invoked as a function + - `getCalleeName <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/dataflow/Nodes.qll/predicate.Nodes$InvokeNode$getCalleeName.0.html>`__ -- name of the variable or property being called + - `getOptionArgument <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/dataflow/Nodes.qll/predicate.Nodes$InvokeNode$getOptionArgument.2.html>`__ -- a "named argument" passed in through an object literal + - `getCallback <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/dataflow/Nodes.qll/predicate.Nodes$InvokeNode$getCallback.1.html>`__ -- a function passed as a callback + - `getACallee <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/dataflow/Nodes.qll/predicate.Nodes$InvokeNode$getACallee.0.html>`__ - a function being called here + - (MethodCallNode).\ `getMethodName <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/dataflow/Nodes.qll/predicate.Nodes$MethodCallNode$getMethodName.0.html>`__ -- name of the method being invoked + - (MethodCallNode).\ `getReceiver <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/dataflow/Nodes.qll/predicate.Nodes$CallNode$getReceiver.0.html>`__ -- receiver of the method call +- `FunctionNode <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/dataflow/Nodes.qll/type.Nodes$FunctionNode.html>`__ extends `SourceNode <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/dataflow/Sources.qll/type.Sources$SourceNode.html>`__ -- definition of a function, including closures, methods, and class constructors + - `getName <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/dataflow/Nodes.qll/predicate.Nodes$FunctionNode$getName.0.html>`__ -- name of the function, derived from a variable or property name + - `getParameter <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/dataflow/Nodes.qll/predicate.Nodes$FunctionNode$getParameter.1.html>`__ -- a parameter of the function + - `getReceiver <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/dataflow/Nodes.qll/predicate.Nodes$FunctionNode$getReceiver.0.html>`__ -- the node representing the value of ``this`` + - `getAReturn <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/dataflow/Nodes.qll/predicate.Nodes$FunctionNode$getAReturn.0.html>`__ -- get a returned expression +- `ParameterNode <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/dataflow/Nodes.qll/type.Nodes$ParameterNode.html>`__ extends `SourceNode <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/dataflow/Sources.qll/type.Sources$SourceNode.html>`__ -- parameter of a function + - `getName <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/dataflow/Nodes.qll/predicate.Nodes$ParameterNode$getName.0.html>`__ -- the parameter name, if it has one +- `ClassNode <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/dataflow/Nodes.qll/type.Nodes$ClassNode.html>`__ extends `SourceNode <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/dataflow/Sources.qll/type.Sources$SourceNode.html>`__ -- class declaration or function that acts as a class + - `getName <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/dataflow/Nodes.qll/predicate.Nodes$ClassNode$getName.0.html>`__ -- name of the class, derived from a variable or property name + - `getConstructor <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/dataflow/Nodes.qll/predicate.Nodes$ClassNode$getConstructor.0.html>`__ -- the constructor function + - `getInstanceMethod <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/dataflow/Nodes.qll/predicate.Nodes$ClassNode$getInstanceMethod.1.html>`__ -- get an instance method by name + - `getStaticMethod <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/dataflow/Nodes.qll/predicate.Nodes$ClassNode$getStaticMethod.1.html>`__ -- get a static method by name + - `getAnInstanceReference <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/dataflow/Nodes.qll/predicate.Nodes$ClassNode$getAnInstanceReference.0.html>`__ -- find references to an instance of the class + - `getAClassReference <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/dataflow/Nodes.qll/predicate.Nodes$ClassNode$getAClassReference.0.html>`__ -- find references to the class itself +- `ObjectLiteralNode <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/dataflow/Nodes.qll/type.Nodes$ObjectLiteralNode.html>`__ extends `SourceNode <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/dataflow/Sources.qll/type.Sources$SourceNode.html>`__ -- object literal + - `getAPropertyWrite <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/dataflow/Sources.qll/predicate.Sources$SourceNode$getAPropertyWrite.1.html>`__ -- a property in the object literal + - `getAPropertySource <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/dataflow/Sources.qll/predicate.Sources$SourceNode$getAPropertySource.1.html>`__ -- value flowing into a property +- `ArrayCreationNode <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/dataflow/Nodes.qll/type.Nodes$ArrayCreationNode.html>`__ extends `SourceNode <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/dataflow/Sources.qll/type.Sources$SourceNode.html>`__ -- array literal or call to ``Array`` constructor + - `getElement <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/dataflow/Nodes.qll/predicate.Nodes$ArrayCreationNode$getElement.1.html>`__ -- an element of the array +- `PropRef <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/dataflow/DataFlow.qll/type.DataFlow$DataFlow$PropRef.html>`__, `PropRead <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/dataflow/DataFlow.qll/type.DataFlow$DataFlow$PropRead.html>`__, `PropWrite <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/dataflow/DataFlow.qll/type.DataFlow$DataFlow$PropWrite.html>`__ -- read or write of a property + - `getPropertyName <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/dataflow/DataFlow.qll/predicate.DataFlow$DataFlow$PropRef$getPropertyName.0.html>`__ -- name of the property, if it is constant + - `getPropertyNameExpr <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/dataflow/DataFlow.qll/predicate.DataFlow$DataFlow$PropRef$getPropertyNameExpr.0.html>`__ -- expression holding the name of the property + - `getBase <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/dataflow/DataFlow.qll/predicate.DataFlow$DataFlow$PropRef$getBase.0.html>`__ -- object whose property is accessed + - (PropWrite).\ `getRhs <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/dataflow/DataFlow.qll/predicate.DataFlow$DataFlow$PropWrite$getRhs.0.html>`__ -- right-hand side of the property assignment + + +StringOps module +---------------- + +- StringOps::`Concatenation <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/StringOps.qll/type.StringOps$StringOps$Concatenation.html>`__ -- string concatenation, using a plus operator, template literal, or array join call +- StringOps::`StartsWith <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/StringOps.qll/type.StringOps$StringOps$StartsWith.html>`__ -- check if a string starts with something +- StringOps::`EndsWith <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/StringOps.qll/type.StringOps$StringOps$EndsWith.html>`__ -- check if a string ends with something +- StringOps::`Includes <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/StringOps.qll/type.StringOps$StringOps$Includes.html>`__ -- check if a string contains something + +Utility +-------- + +- `ExtendCall <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Extend.qll/type.Extend$ExtendCall.html>`__ -- call that copies properties from one object to another +- `JsonParserCall <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/JsonParsers.qll/type.JsonParsers$JsonParserCall.html>`__ -- call that deserializes a JSON string +- `PropertyProjection <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/frameworks/PropertyProjection.qll/type.PropertyProjection$PropertyProjection.html>`__ -- call that extracts nested properties by name + +System and Network +------------------ + +- `ClientRequest <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/frameworks/ClientRequests.qll/type.ClientRequests$ClientRequest.html>`__ -- outgoing network request +- `DatabaseAccess <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Concepts.qll/type.Concepts$DatabaseAccess.html>`__ -- query being submitted to a database +- `FileNameSource <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Concepts.qll/type.Concepts$FileNameSource.html>`__ -- reference to a filename +- `FileSystemAccess <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Concepts.qll/type.Concepts$FileSystemAccess.html>`__ -- file system operation + - `FileSystemReadAccess <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Concepts.qll/type.Concepts$FileSystemReadAccess.html>`__ -- reading the contents of a file + - `FileSystemWriteAccess <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Concepts.qll/type.Concepts$FileSystemWriteAccess.html>`__ -- writing to the contents of a file +- `PersistentReadAccess <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Concepts.qll/type.Concepts$PersistentReadAccess.html>`__ -- reading from persistent storage, like cookies +- `PersistentWriteAccess <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Concepts.qll/type.Concepts$PersistentWriteAccess.html>`__ -- writing to persistent storage +- `RemoteFlowSource <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/security/dataflow/RemoteFlowSources.qll/type.RemoteFlowSources$RemoteFlowSource.html>`__ -- source of untrusted user input +- `SystemCommandExecution <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Concepts.qll/type.Concepts$SystemCommandExecution.html>`__ -- execution of a system command + +Files +----- + +- `File <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Files.qll/type.Files$File.html>`__, + `Folder <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Files.qll/type.Files$Folder.html>`__ extends + `Container <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Files.qll/type.Files$Container.html>`__ -- file or folder in the database + + - `getBaseName <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Files.qll/predicate.Files$Container$getBaseName.0.html>`__ -- the name of the file or folder + - `getRelativePath <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/Files.qll/predicate.Files$Container$getRelativePath.0.html>`__ -- path relative to the database root + +AST nodes +--------- + +See also: ":doc:`Abstract syntax tree classes for working with JavaScript and TypeScript programs <abstract-syntax-tree-classes-for-working-with-javascript-and-typescript-programs>`." + +Conversion between DataFlow and AST nodes: + +- `Node.asExpr() <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/dataflow/DataFlow.qll/predicate.DataFlow$DataFlow$Node$asExpr.0.html>`__ -- convert node to an expression, if possible +- `Expr.flow() <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/AST.qll/predicate.AST$AST$ValueNode$flow.0.html>`__ -- convert expression to a node (always possible) +- `DataFlow::valueNode <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/dataflow/DataFlow.qll/predicate.DataFlow$DataFlow$valueNode.1.html>`__ -- convert expression or declaration to a node +- `DataFlow::parameterNode <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/dataflow/DataFlow.qll/predicate.DataFlow$DataFlow$parameterNode.1.html>`__ -- convert a parameter to a node +- `DataFlow::thisNode <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/dataflow/DataFlow.qll/predicate.DataFlow$DataFlow$thisNode.1.html>`__ -- get the receiver node of a function + +String matching +--------------- + +- x.\ `matches <https://codeql.github.com/codeql-standard-libraries/javascript/predicate.string$matches.1.html>`__\ ("escape%") -- holds if x starts with "escape" +- x.\ `regexpMatch <https://codeql.github.com/codeql-standard-libraries/javascript/predicate.string$regexpMatch.1.html>`__\ ("escape.*") -- holds if x starts with "escape" +- x.\ `regexpMatch <https://codeql.github.com/codeql-standard-libraries/javascript/predicate.string$regexpMatch.1.html>`__\ ("(?i).*escape.*") -- holds if x contains + "escape" (case insensitive) + +Type tracking +------------- + +See also: ":doc:`Using type tracking for API modeling <using-type-tracking-for-api-modeling>`." + +Use the following template to define forward type tracking predicates: + +.. code-block:: ql + + import DataFlow + + SourceNode myType(TypeTracker t) { + t.start() and + result = /* SourceNode to track */ + or + exists(TypeTracker t2 | + result = myType(t2).track(t2, t) + ) + } + + SourceNode myType() { + result = myType(TypeTracker::end()) + } + +Use the following template to define backward type tracking predicates: + +.. code-block:: ql + + import DataFlow + + SourceNode myType(TypeBackTracker t) { + t.start() and + result = (/* argument to track */).getALocalSource() + or + exists(TypeBackTracker t2 | + result = myType(t2).backtrack(t2, t) + ) + } + + SourceNode myType() { + result = myType(TypeBackTracker::end()) + } + +Troubleshooting +--------------- + +- Using a call node as as sink? Try using `getArgument <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/dataflow/Nodes.qll/predicate.Nodes$InvokeNode$getArgument.1.html>`__ + to get an *argument* of the call node instead. +- Trying to use `moduleImport <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/dataflow/Nodes.qll/predicate.Nodes$moduleImport.1.html>`__ + or `moduleMember <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/dataflow/Nodes.qll/predicate.Nodes$moduleMember.2.html>`__ + as a call node? + Try using `getACall <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/dataflow/Sources.qll/predicate.Sources$SourceNode$getACall.0.html>`__ + to get a *call* to the imported function, instead of the function itself. +- Compilation fails due to incompatible types? Make sure AST nodes and + DataFlow nodes are not mixed up. Use `asExpr() <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/dataflow/DataFlow.qll/predicate.DataFlow$DataFlow$Node$asExpr.0.html>`__ or + `flow() <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/AST.qll/predicate.AST$AST$ValueNode$flow.0.html>`__ to convert. + +Further reading +--------------- + +- ":ref:`Exploring data flow with path queries <exploring-data-flow-with-path-queries>`" + + +.. include:: ../reusables/javascript-further-reading.rst +.. include:: ../reusables/codeql-ref-tools-further-reading.rst \ No newline at end of file diff --git a/docs/codeql/codeql-language-guides/codeql-for-cpp/detecting-a-potential-buffer-overflow.rst b/docs/codeql/codeql-language-guides/detecting-a-potential-buffer-overflow.rst similarity index 93% rename from docs/codeql/codeql-language-guides/codeql-for-cpp/detecting-a-potential-buffer-overflow.rst rename to docs/codeql/codeql-language-guides/detecting-a-potential-buffer-overflow.rst index b3471128049..ca52df98f73 100644 --- a/docs/codeql/codeql-language-guides/codeql-for-cpp/detecting-a-potential-buffer-overflow.rst +++ b/docs/codeql/codeql-language-guides/detecting-a-potential-buffer-overflow.rst @@ -31,7 +31,7 @@ Defining the entities of interest You could approach this problem either by searching for code similar to the call to ``malloc`` in line 3 or the call to ``strcpy`` in line 5 (see example above). For our basic query, we start with a simple assumption: any call to ``malloc`` with only a ``strlen`` to define the memory size is likely to cause an error when the memory is populated. -Calls to ``strlen`` can be identified using the library `StrlenCall <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/commons/StringAnalysis.qll/type.StringAnalysis$StrlenCall.html>`__ class, but we need to define a new class to identify calls to ``malloc``. Both the library class and the new class need to extend the standard class ``FunctionCall``, with the added restriction of the function name that they apply to: +Calls to ``strlen`` can be identified using the library `StrlenCall <https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/commons/StringAnalysis.qll/type.StringAnalysis$StrlenCall.html>`__ class, but we need to define a new class to identify calls to ``malloc``. Both the library class and the new class need to extend the standard class ``FunctionCall``, with the added restriction of the function name that they apply to: .. code-block:: ql @@ -97,7 +97,7 @@ When you have defined the basic query then you can refine the query to include f Improving the query using the 'SSA' library ------------------------------------------- -The ``SSA`` library represents variables in static single assignment (SSA) form. In this form, each variable is assigned exactly once and every variable is defined before it is used. The use of SSA variables simplifies queries considerably as much of the local data flow analysis has been done for us. For more information, see `Static single assignment <http://en.wikipedia.org/wiki/Static_single_assignment_form>`__ on Wikipedia. +The ``SSA`` library represents variables in static single assignment (SSA) form. In this form, each variable is assigned exactly once and every variable is defined before it is used. The use of SSA variables simplifies queries considerably as much of the local data flow analysis has been done for us. For more information, see `Static single assignment <https://en.wikipedia.org/wiki/Static_single_assignment_form>`__ on Wikipedia. Including examples where the string size is stored before use ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -226,5 +226,5 @@ The completed query will now identify cases where the result of ``strlen`` is st Further reading --------------- -.. include:: ../../reusables/cpp-further-reading.rst -.. include:: ../../reusables/codeql-ref-tools-further-reading.rst +.. include:: ../reusables/cpp-further-reading.rst +.. include:: ../reusables/codeql-ref-tools-further-reading.rst diff --git a/docs/codeql/codeql-language-guides/codeql-for-python/expressions-and-statements-in-python.rst b/docs/codeql/codeql-language-guides/expressions-and-statements-in-python.rst similarity index 98% rename from docs/codeql/codeql-language-guides/codeql-for-python/expressions-and-statements-in-python.rst rename to docs/codeql/codeql-language-guides/expressions-and-statements-in-python.rst index 7c856ee8506..48cca630660 100644 --- a/docs/codeql/codeql-language-guides/codeql-for-python/expressions-and-statements-in-python.rst +++ b/docs/codeql/codeql-language-guides/expressions-and-statements-in-python.rst @@ -258,6 +258,6 @@ Here is the relevant part of the class hierarchy: Further reading --------------- -.. include:: ../../reusables/python-further-reading.rst -.. include:: ../../reusables/codeql-ref-tools-further-reading.rst +.. include:: ../reusables/python-further-reading.rst +.. include:: ../reusables/codeql-ref-tools-further-reading.rst diff --git a/docs/codeql/codeql-language-guides/codeql-for-cpp/expressions-types-and-statements-in-cpp.rst b/docs/codeql/codeql-language-guides/expressions-types-and-statements-in-cpp.rst similarity index 98% rename from docs/codeql/codeql-language-guides/codeql-for-cpp/expressions-types-and-statements-in-cpp.rst rename to docs/codeql/codeql-language-guides/expressions-types-and-statements-in-cpp.rst index fcd35768698..d7adc22c2cd 100644 --- a/docs/codeql/codeql-language-guides/codeql-for-cpp/expressions-types-and-statements-in-cpp.rst +++ b/docs/codeql/codeql-language-guides/expressions-types-and-statements-in-cpp.rst @@ -134,5 +134,5 @@ Note that we replaced ``e.getEnclosingStmt()`` with ``e.getEnclosingStmt().getPa Further reading --------------- -.. include:: ../../reusables/cpp-further-reading.rst -.. include:: ../../reusables/codeql-ref-tools-further-reading.rst +.. include:: ../reusables/cpp-further-reading.rst +.. include:: ../reusables/codeql-ref-tools-further-reading.rst diff --git a/docs/codeql/codeql-language-guides/codeql-for-cpp/functions-in-cpp.rst b/docs/codeql/codeql-language-guides/functions-in-cpp.rst similarity index 97% rename from docs/codeql/codeql-language-guides/codeql-for-cpp/functions-in-cpp.rst rename to docs/codeql/codeql-language-guides/functions-in-cpp.rst index abf04311873..84d72e5376a 100644 --- a/docs/codeql/codeql-language-guides/codeql-for-cpp/functions-in-cpp.rst +++ b/docs/codeql/codeql-language-guides/functions-in-cpp.rst @@ -94,5 +94,5 @@ The LGTM version of this query is considerably more complicated, but if you look Further reading --------------- -.. include:: ../../reusables/cpp-further-reading.rst -.. include:: ../../reusables/codeql-ref-tools-further-reading.rst +.. include:: ../reusables/cpp-further-reading.rst +.. include:: ../reusables/codeql-ref-tools-further-reading.rst diff --git a/docs/codeql/codeql-language-guides/codeql-for-python/functions-in-python.rst b/docs/codeql/codeql-language-guides/functions-in-python.rst similarity index 92% rename from docs/codeql/codeql-language-guides/codeql-for-python/functions-in-python.rst rename to docs/codeql/codeql-language-guides/functions-in-python.rst index 3314bb7494c..ab401f6c5e5 100644 --- a/docs/codeql/codeql-language-guides/codeql-for-python/functions-in-python.rst +++ b/docs/codeql/codeql-language-guides/functions-in-python.rst @@ -5,7 +5,7 @@ Functions in Python You can use syntactic classes from the standard CodeQL library to find Python functions and identify calls to them. -These examples use the standard CodeQL class `Function <https://help.semmle.com/qldoc/python/semmle/python/Function.qll/type.Function$Function.html>`__. For more information, see ":doc:`CodeQL library for Python <codeql-library-for-python>`." +These examples use the standard CodeQL class `Function <https://codeql.github.com/codeql-standard-libraries/python/semmle/python/Function.qll/type.Function$Function.html>`__. For more information, see ":doc:`CodeQL library for Python <codeql-library-for-python>`." Finding all functions called "get..." ------------------------------------- @@ -83,6 +83,6 @@ In a later tutorial we will see how to use the type-inference library to find ca Further reading --------------- -.. include:: ../../reusables/python-further-reading.rst -.. include:: ../../reusables/codeql-ref-tools-further-reading.rst +.. include:: ../reusables/python-further-reading.rst +.. include:: ../reusables/codeql-ref-tools-further-reading.rst diff --git a/docs/codeql/codeql-language-guides/codeql-for-cpp/hash-consing-and-value-numbering.rst b/docs/codeql/codeql-language-guides/hash-consing-and-value-numbering.rst similarity index 97% rename from docs/codeql/codeql-language-guides/codeql-for-cpp/hash-consing-and-value-numbering.rst rename to docs/codeql/codeql-language-guides/hash-consing-and-value-numbering.rst index 1a064d9f27b..8afa51e3e53 100644 --- a/docs/codeql/codeql-language-guides/codeql-for-cpp/hash-consing-and-value-numbering.rst +++ b/docs/codeql/codeql-language-guides/hash-consing-and-value-numbering.rst @@ -54,7 +54,7 @@ The value numbering library exposes its interface primarily through the ``GVN`` To get the ``GVN`` of an ``Expr``, use the ``globalValueNumber`` predicate. -.. note:: +.. pull-quote:: Note While the ``GVN`` class has ``toString`` and ``getLocation`` methods, these are only provided as debugging aids. They give the ``toString`` and ``getLocation`` of an arbitrary ``Expr`` within the set. @@ -90,7 +90,7 @@ The hash consing API The hash consing library exposes its interface primarily through the ``HashCons`` class. Each instance of ``HashCons`` represents a set of expressions within one function that have the same syntax (including referring to the same variables). To get an expression in the set represented by a particular ``HashCons``, use the ``getAnExpr()`` member predicate. -.. note:: +.. pull-quote:: Note While the ``HashCons`` class has ``toString`` and ``getLocation`` methods, these are only provided as debugging aids. They give the ``toString`` and ``getLocation`` of an arbitrary ``Expr`` within the set. @@ -116,5 +116,5 @@ Example query Further reading --------------- -.. include:: ../../reusables/cpp-further-reading.rst -.. include:: ../../reusables/codeql-ref-tools-further-reading.rst \ No newline at end of file +.. include:: ../reusables/cpp-further-reading.rst +.. include:: ../reusables/codeql-ref-tools-further-reading.rst \ No newline at end of file diff --git a/docs/codeql/codeql-language-guides/index.rst b/docs/codeql/codeql-language-guides/index.rst index 760f6871a2d..440b706a02a 100644 --- a/docs/codeql/codeql-language-guides/index.rst +++ b/docs/codeql/codeql-language-guides/index.rst @@ -3,12 +3,14 @@ CodeQL language guides ====================== +Experiment and learn how to write effective and efficient queries for CodeQL databases generated from the languages supported in CodeQL analysis. + .. toctree:: - codeql-for-cpp/index - codeql-for-csharp/index - codeql-for-go/index - codeql-for-java/index - codeql-for-javascript/index - codeql-for-python/index + codeql-for-cpp + codeql-for-csharp + codeql-for-go + codeql-for-java + codeql-for-javascript + codeql-for-python \ No newline at end of file diff --git a/docs/codeql/codeql-language-guides/codeql-for-java/javadoc.rst b/docs/codeql/codeql-language-guides/javadoc.rst similarity index 98% rename from docs/codeql/codeql-language-guides/codeql-for-java/javadoc.rst rename to docs/codeql/codeql-language-guides/javadoc.rst index bed07e015e0..7e16cc6ce36 100644 --- a/docs/codeql/codeql-language-guides/codeql-for-java/javadoc.rst +++ b/docs/codeql/codeql-language-guides/javadoc.rst @@ -223,5 +223,5 @@ Currently, ``visibleIn`` only considers single-type imports, but you could exten Further reading --------------- -.. include:: ../../reusables/java-further-reading.rst -.. include:: ../../reusables/codeql-ref-tools-further-reading.rst +.. include:: ../reusables/java-further-reading.rst +.. include:: ../reusables/codeql-ref-tools-further-reading.rst diff --git a/docs/codeql/codeql-language-guides/codeql-for-go/modeling-data-flow-in-go-libraries.rst b/docs/codeql/codeql-language-guides/modeling-data-flow-in-go-libraries.rst similarity index 98% rename from docs/codeql/codeql-language-guides/codeql-for-go/modeling-data-flow-in-go-libraries.rst rename to docs/codeql/codeql-language-guides/modeling-data-flow-in-go-libraries.rst index b57b57820a6..9e3c068701e 100644 --- a/docs/codeql/codeql-language-guides/codeql-for-go/modeling-data-flow-in-go-libraries.rst +++ b/docs/codeql/codeql-language-guides/modeling-data-flow-in-go-libraries.rst @@ -27,7 +27,7 @@ example from ``Mux.qll``. } This has the effect that all calls to `the function Vars from the -package mux <http://www.gorillatoolkit.org/pkg/mux#Vars>`__ are +package mux <https://github.com/gorilla/mux>`__ are treated as sources of untrusted data. Flow propagation diff --git a/docs/codeql/codeql-language-guides/codeql-for-java/navigating-the-call-graph.rst b/docs/codeql/codeql-language-guides/navigating-the-call-graph.rst similarity index 98% rename from docs/codeql/codeql-language-guides/codeql-for-java/navigating-the-call-graph.rst rename to docs/codeql/codeql-language-guides/navigating-the-call-graph.rst index f2490e58a6e..8b73b49153b 100644 --- a/docs/codeql/codeql-language-guides/codeql-for-java/navigating-the-call-graph.rst +++ b/docs/codeql/codeql-language-guides/navigating-the-call-graph.rst @@ -166,5 +166,5 @@ Finally, on many Java projects there are methods that are invoked indirectly by Further reading --------------- -.. include:: ../../reusables/java-further-reading.rst -.. include:: ../../reusables/codeql-ref-tools-further-reading.rst +.. include:: ../reusables/java-further-reading.rst +.. include:: ../reusables/codeql-ref-tools-further-reading.rst diff --git a/docs/codeql/codeql-language-guides/codeql-for-java/overflow-prone-comparisons-in-java.rst b/docs/codeql/codeql-language-guides/overflow-prone-comparisons-in-java.rst similarity index 98% rename from docs/codeql/codeql-language-guides/codeql-for-java/overflow-prone-comparisons-in-java.rst rename to docs/codeql/codeql-language-guides/overflow-prone-comparisons-in-java.rst index cd73cd1512a..b0762a5c139 100644 --- a/docs/codeql/codeql-language-guides/codeql-for-java/overflow-prone-comparisons-in-java.rst +++ b/docs/codeql/codeql-language-guides/overflow-prone-comparisons-in-java.rst @@ -127,5 +127,5 @@ Now we rewrite our query to make use of these new classes: Further reading --------------- -.. include:: ../../reusables/java-further-reading.rst -.. include:: ../../reusables/codeql-ref-tools-further-reading.rst +.. include:: ../reusables/java-further-reading.rst +.. include:: ../reusables/codeql-ref-tools-further-reading.rst diff --git a/docs/codeql/codeql-language-guides/codeql-for-python/pointer-analysis-and-type-inference-in-python.rst b/docs/codeql/codeql-language-guides/pointer-analysis-and-type-inference-in-python.rst similarity index 95% rename from docs/codeql/codeql-language-guides/codeql-for-python/pointer-analysis-and-type-inference-in-python.rst rename to docs/codeql/codeql-language-guides/pointer-analysis-and-type-inference-in-python.rst index 7ff754483b4..85896bc5479 100644 --- a/docs/codeql/codeql-language-guides/codeql-for-python/pointer-analysis-and-type-inference-in-python.rst +++ b/docs/codeql/codeql-language-guides/pointer-analysis-and-type-inference-in-python.rst @@ -15,7 +15,7 @@ Summary Class hierarchy for ``Value``: -- `Value <https://help.semmle.com/qldoc/python/semmle/python/objects/ObjectAPI.qll/type.ObjectAPI$Value.html>`__ +- `Value <https://codeql.github.com/codeql-standard-libraries/python/semmle/python/objects/ObjectAPI.qll/type.ObjectAPI$Value.html>`__ - ``ClassValue`` - ``FunctionValue`` @@ -24,7 +24,7 @@ Class hierarchy for ``Value``: Points-to analysis and type inference ------------------------------------- -Points-to analysis, sometimes known as pointer analysis, allows us to determine which objects an expression may "point to" at runtime. Type inference allows us to infer what the types (classes) of an expression may be at runtime. For more information, see `Pointer analysis <http://en.wikipedia.org/wiki/Pointer_analysis>`__ and `Type inference <http://en.wikipedia.org/wiki/Type_inference>`__ on Wikipedia. +Points-to analysis, sometimes known as pointer analysis, allows us to determine which objects an expression may "point to" at runtime. Type inference allows us to infer what the types (classes) of an expression may be at runtime. For more information, see `Pointer analysis <https://en.wikipedia.org/wiki/Pointer_analysis>`__ and `Type inference <https://en.wikipedia.org/wiki/Type_inference>`__ on Wikipedia. The predicate ``ControlFlowNode.pointsTo(...)`` shows which object a control flow node may "point to" at runtime. @@ -228,6 +228,6 @@ Then we can use ``Value.getACall()`` to identify calls to the ``eval`` function, Further reading --------------- -.. include:: ../../reusables/python-further-reading.rst -.. include:: ../../reusables/codeql-ref-tools-further-reading.rst +.. include:: ../reusables/python-further-reading.rst +.. include:: ../reusables/codeql-ref-tools-further-reading.rst diff --git a/docs/codeql/codeql-language-guides/codeql-for-cpp/refining-a-query-to-account-for-edge-cases.rst b/docs/codeql/codeql-language-guides/refining-a-query-to-account-for-edge-cases.rst similarity index 98% rename from docs/codeql/codeql-language-guides/codeql-for-cpp/refining-a-query-to-account-for-edge-cases.rst rename to docs/codeql/codeql-language-guides/refining-a-query-to-account-for-edge-cases.rst index cabefa4388f..d2a6cee326a 100644 --- a/docs/codeql/codeql-language-guides/codeql-for-cpp/refining-a-query-to-account-for-edge-cases.rst +++ b/docs/codeql/codeql-language-guides/refining-a-query-to-account-for-edge-cases.rst @@ -151,5 +151,5 @@ Finally we can simplify the query by using the transitive closure operator. In t Further reading --------------- -.. include:: ../../reusables/cpp-further-reading.rst -.. include:: ../../reusables/codeql-ref-tools-further-reading.rst +.. include:: ../reusables/cpp-further-reading.rst +.. include:: ../reusables/codeql-ref-tools-further-reading.rst diff --git a/docs/codeql/codeql-language-guides/specifying-additional-remote-flow-sources-for-javascript.rst b/docs/codeql/codeql-language-guides/specifying-additional-remote-flow-sources-for-javascript.rst new file mode 100644 index 00000000000..fabe58bf5c9 --- /dev/null +++ b/docs/codeql/codeql-language-guides/specifying-additional-remote-flow-sources-for-javascript.rst @@ -0,0 +1,51 @@ +.. _specifying-additional-remote-flow-sources-for-javascript: + +Specifying additional remote flow sources for JavaScript +======================================================== + +You can model potential sources of untrusted user input in your code without making changes to the CodeQL standard library by specifying extra remote flow sources in an external file. + +.. pull-quote:: + + Note + + Specifying remote flow sources in external files is currently in beta and subject to change. + +As mentioned in the :doc:`Data flow cheat sheet for JavaScript <data-flow-cheat-sheet-for-javascript>`, the CodeQL libraries for JavaScript +provide a class `RemoteFlowSource <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/security/dataflow/RemoteFlowSources.qll/type.RemoteFlowSources$RemoteFlowSource.html>`__ to represent sources of untrusted user input, sometimes also referred to as remote flow +sources. + +To model a new source of untrusted input, such as a previously unmodelled library API, you can +define a subclass of ``RemoteFlowSource`` that covers all uses of that API. All standard analyses +will then automatically pick up this new source of remote flow. + +However, this approach requires writing QL code and adding it to the standard library, which is not +always easy to do. Instead, you can also add a JSON file describing custom sources of untrusted +input to your code base and have it picked up without needing to modify the standard library. This +JSON file can be hand-written or generated by another tool. The custom remote flow sources are only available to the code base containing the JSON file. This means that you need to copy the JSON file into each code base that requires the customizations. + +Specification format +-------------------- + +The JSON file must be called ``codeql-javascript-remote-flow-sources.json`` and +can be located anywhere in your code base. It should consist of a single JSON object. The property +names of this object are interpreted as `source types`. The values they map to should be arrays of +strings. Each string should be of the form ``window.props``, where ``props`` is a sequence of one +or more property names separated by dots. This notation specifies that any value reachable from the global window +object by this sequence of property names should be considered as untrusted user input of the +associated source type. + +Example +------- + +Consider the following specification: + +.. code-block:: json + + { + "user input": [ "window.user.name", "window.user.address", "window.dob" ] + } + +It declares that the contents of global variable ``dob``, as well as the contents of properties +``name`` and ``address`` of global variable ``user``, should be considered as remote flow sources, +with source type "user input". diff --git a/docs/codeql/codeql-language-guides/codeql-for-java/types-in-java.rst b/docs/codeql/codeql-language-guides/types-in-java.rst similarity index 99% rename from docs/codeql/codeql-language-guides/codeql-for-java/types-in-java.rst rename to docs/codeql/codeql-language-guides/types-in-java.rst index 515bb2e7080..04cc716b961 100644 --- a/docs/codeql/codeql-language-guides/codeql-for-java/types-in-java.rst +++ b/docs/codeql/codeql-language-guides/types-in-java.rst @@ -301,5 +301,5 @@ Adding these three improvements, our final query becomes: Further reading --------------- -.. include:: ../../reusables/java-further-reading.rst -.. include:: ../../reusables/codeql-ref-tools-further-reading.rst +.. include:: ../reusables/java-further-reading.rst +.. include:: ../reusables/codeql-ref-tools-further-reading.rst diff --git a/docs/codeql/codeql-language-guides/codeql-for-javascript/using-flow-labels-for-precise-data-flow-analysis.rst b/docs/codeql/codeql-language-guides/using-flow-labels-for-precise-data-flow-analysis.rst similarity index 98% rename from docs/codeql/codeql-language-guides/codeql-for-javascript/using-flow-labels-for-precise-data-flow-analysis.rst rename to docs/codeql/codeql-language-guides/using-flow-labels-for-precise-data-flow-analysis.rst index 357b4638805..c2f93525341 100644 --- a/docs/codeql/codeql-language-guides/codeql-for-javascript/using-flow-labels-for-precise-data-flow-analysis.rst +++ b/docs/codeql/codeql-language-guides/using-flow-labels-for-precise-data-flow-analysis.rst @@ -9,7 +9,7 @@ Overview -------- You can use basic inter-procedural data-flow analysis and taint tracking as described in -":doc:`Analyzing data flow in JavaScript and TypeScript <analyzing-data-flow-in-javascript>`" to check whether there is a path in +":doc:`Analyzing data flow in JavaScript and TypeScript <analyzing-data-flow-in-javascript-and-typescript>`" to check whether there is a path in the data-flow graph from some source node to a sink node that does not pass through any sanitizer nodes. Another way of thinking about this is that it statically models the flow of data through the program, and associates a flag with every data value telling us whether it might have come from a @@ -403,5 +403,5 @@ Further reading - ":ref:`Exploring data flow with path queries <exploring-data-flow-with-path-queries>`" -.. include:: ../../reusables/javascript-further-reading.rst -.. include:: ../../reusables/codeql-ref-tools-further-reading.rst +.. include:: ../reusables/javascript-further-reading.rst +.. include:: ../reusables/codeql-ref-tools-further-reading.rst diff --git a/docs/codeql/codeql-language-guides/codeql-for-cpp/using-range-analsis-in-cpp.rst b/docs/codeql/codeql-language-guides/using-range-analsis-in-cpp.rst similarity index 94% rename from docs/codeql/codeql-language-guides/codeql-for-cpp/using-range-analsis-in-cpp.rst rename to docs/codeql/codeql-language-guides/using-range-analsis-in-cpp.rst index e8f8ce156f1..11f1da1259c 100644 --- a/docs/codeql/codeql-language-guides/codeql-for-cpp/using-range-analsis-in-cpp.rst +++ b/docs/codeql/codeql-language-guides/using-range-analsis-in-cpp.rst @@ -47,5 +47,5 @@ This query uses ``upperBound`` to determine whether the result of ``snprintf`` i Further reading --------------- -.. include:: ../../reusables/cpp-further-reading.rst -.. include:: ../../reusables/codeql-ref-tools-further-reading.rst +.. include:: ../reusables/cpp-further-reading.rst +.. include:: ../reusables/codeql-ref-tools-further-reading.rst diff --git a/docs/codeql/codeql-language-guides/codeql-for-cpp/using-the-guards-library-in-cpp.rst b/docs/codeql/codeql-language-guides/using-the-guards-library-in-cpp.rst similarity index 91% rename from docs/codeql/codeql-language-guides/codeql-for-cpp/using-the-guards-library-in-cpp.rst rename to docs/codeql/codeql-language-guides/using-the-guards-library-in-cpp.rst index b3cf98b96c2..792cbcd4703 100644 --- a/docs/codeql/codeql-language-guides/codeql-for-cpp/using-the-guards-library-in-cpp.rst +++ b/docs/codeql/codeql-language-guides/using-the-guards-library-in-cpp.rst @@ -8,7 +8,7 @@ You can use the CodeQL guards library to identify conditional expressions that c About the guards library ------------------------ -The guards library (defined in ``semmle.code.cpp.controlflow.Guards``) provides a class `GuardCondition <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/controlflow/Guards.qll/type.Guards$GuardCondition.html>`__ representing Boolean values that are used to make control flow decisions. +The guards library (defined in ``semmle.code.cpp.controlflow.Guards``) provides a class `GuardCondition <https://codeql.github.com/codeql-standard-libraries/cpp/semmle/code/cpp/controlflow/Guards.qll/type.Guards$GuardCondition.html>`__ representing Boolean values that are used to make control flow decisions. A ``GuardCondition`` is considered to guard a basic block if the block can only be reached if the ``GuardCondition`` is evaluated a certain way. For instance, in the following code, ``x < 10`` is a ``GuardCondition``, and it guards all the code before the return statement. .. code-block:: cpp @@ -98,6 +98,6 @@ The ``comparesLt`` predicate Further reading --------------- -.. include:: ../../reusables/cpp-further-reading.rst -.. include:: ../../reusables/codeql-ref-tools-further-reading.rst +.. include:: ../reusables/cpp-further-reading.rst +.. include:: ../reusables/codeql-ref-tools-further-reading.rst diff --git a/docs/codeql/codeql-language-guides/codeql-for-javascript/using-type-tracking-for-api-modeling.rst b/docs/codeql/codeql-language-guides/using-type-tracking-for-api-modeling.rst similarity index 85% rename from docs/codeql/codeql-language-guides/codeql-for-javascript/using-type-tracking-for-api-modeling.rst rename to docs/codeql/codeql-language-guides/using-type-tracking-for-api-modeling.rst index fa52ce3d00b..e1690397e63 100644 --- a/docs/codeql/codeql-language-guides/codeql-for-javascript/using-type-tracking-for-api-modeling.rst +++ b/docs/codeql/codeql-language-guides/using-type-tracking-for-api-modeling.rst @@ -11,9 +11,9 @@ The type-tracking library makes it possible to track values through properties a usually to recognize method calls and properties accessed on a specific type of object. This is an advanced topic and is intended for readers already familiar with the -`SourceNode <analyzing-data-flow-in-javascript.html#source-nodes>`__ class as well as -`taint tracking <analyzing-data-flow-in-javascript.html#using-global-analyzing-data-flow-and-tracking-tainted-data-in-python>`__. -For TypeScript analysis also consider reading about `static type information <codeql-library-for-typescript.html.html#static-type-information>`__ first. +`SourceNode <https://codeql.github.com/docs/codeql-language-guides/analyzing-data-flow-in-javascript-and-typescript/#source-nodes>`__ class as well as +`taint tracking <https://codeql.github.com/docs/codeql-language-guides/analyzing-data-flow-in-javascript-and-typescript/#using-global-taint-tracking>`__. +For TypeScript analysis also consider reading about `static type information <https://codeql.github.com/docs/codeql-language-guides/codeql-library-for-typescript/#static-type-information>`__ first. The problem of recognizing method calls @@ -120,9 +120,9 @@ Type tracking is a generalization of the above pattern, where a predicate matche and has a recursive clause that tracks the flow of that value. But instead of us having to deal with function calls/returns and property reads/writes, all of these steps are included in a single predicate, -`SourceNode.track <https://help.semmle.com/qldoc/javascript/semmle/javascript/dataflow/Sources.qll/predicate.Sources$SourceNode$track.2.html>`__, +`SourceNode.track <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/dataflow/Sources.qll/predicate.Sources$SourceNode$track.2.html>`__, to be used with the companion class -`TypeTracker <https://help.semmle.com/qldoc/javascript/semmle/javascript/dataflow/TypeTracking.qll/type.TypeTracking$TypeTracker.html>`__. +`TypeTracker <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/dataflow/TypeTracking.qll/type.TypeTracking$TypeTracker.html>`__. Predicates that use type tracking usually conform to the following general pattern, which we explain below: @@ -435,7 +435,7 @@ Note that these predicates all return ``SourceNode``, so attempts to track a non-source node, such as an identifier or string literal, will not work. If this becomes an issue, see -`TypeTracker.smallstep <https://help.semmle.com/qldoc/javascript/semmle/javascript/dataflow/TypeTracking.qll/predicate.TypeTracking$TypeTracker$smallstep.2.html>`__. +`TypeTracker.smallstep <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/dataflow/TypeTracking.qll/predicate.TypeTracking$TypeTracker$smallstep.2.html>`__. Also note that the predicates taking a ``TypeTracker`` or ``TypeBackTracker`` can often be made ``private``, as they are typically only used as an intermediate result to compute the other predicate. @@ -458,7 +458,7 @@ Here's an example that the model from this tutorial won't find: let wrapper = wrapDB(firebase.database()) wrapper.db.ref("forecast"); // <-- not found -This is an example of where `data-flow configurations <analyzing-data-flow-in-javascript.html#global-data-flow>`__ are more powerful. +This is an example of where `data-flow configurations <https://codeql.github.com/docs/codeql-language-guides/analyzing-data-flow-in-javascript-and-typescript/#global-data-flow>`__ are more powerful. When to use type tracking ------------------------- @@ -491,7 +491,7 @@ Prefer type tracking when: Prefer data-flow configurations when: -- Tracking user-controlled data -- use `taint tracking <analyzing-data-flow-in-javascript.html#using-global-analyzing-data-flow-and-tracking-tainted-data-in-python>`__. +- Tracking user-controlled data -- use `taint tracking <https://codeql.github.com/docs/codeql-language-guides/analyzing-data-flow-in-javascript-and-typescript/#using-global-taint-tracking>`__. - Differentiating between different kinds of user-controlled data -- see ":doc:`Using flow labels for precise data flow analysis <using-flow-labels-for-precise-data-flow-analysis>`." - Tracking transformations of a value through generic utility functions. - Tracking values through string manipulation. @@ -499,7 +499,7 @@ Prefer data-flow configurations when: Lastly, depending on the code base being analyzed, some alternatives to consider are: -- Using `static type information <codeql-library-for-typescript.html.html#static-type-information>`__, +- Using `static type information <https://codeql.github.com/docs/codeql-language-guides/codeql-library-for-typescript/#static-type-information>`__, if analyzing TypeScript code. - Relying on local data flow. @@ -511,17 +511,17 @@ Type tracking in the standard libraries Type tracking is used in a few places in the standard libraries: -- The `DOM <https://help.semmle.com/qldoc/javascript/semmle/javascript/DOM.qll/module.DOM$DOM.html>`__ predicates, - `documentRef <https://help.semmle.com/qldoc/javascript/semmle/javascript/DOM.qll/predicate.DOM$DOM$documentRef.0.html>`__, - `locationRef <https://help.semmle.com/qldoc/javascript/semmle/javascript/DOM.qll/predicate.DOM$DOM$locationRef.0.html>`__, and - `domValueRef <https://help.semmle.com/qldoc/javascript/semmle/javascript/DOM.qll/predicate.DOM$DOM$domValueRef.0.html>`__, +- The `DOM <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/DOM.qll/module.DOM$DOM.html>`__ predicates, + `documentRef <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/DOM.qll/predicate.DOM$DOM$documentRef.0.html>`__, + `locationRef <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/DOM.qll/predicate.DOM$DOM$locationRef.0.html>`__, and + `domValueRef <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/DOM.qll/predicate.DOM$DOM$domValueRef.0.html>`__, are implemented with type tracking. -- The `HTTP <https://help.semmle.com/qldoc/javascript/semmle/javascript/frameworks/HTTP.qll/module.HTTP$HTTP.html>`__ server models, such as `Express <https://help.semmle.com/qldoc/javascript/semmle/javascript/frameworks/Express.qll/module.Express$Express.html>`__, use type tracking to track the installation of router handler functions. -- The `Firebase <https://help.semmle.com/qldoc/javascript/semmle/javascript/frameworks/Firebase.qll/module.Firebase$Firebase.html>`__ and - `Socket.io <https://help.semmle.com/qldoc/javascript/semmle/javascript/frameworks/SocketIO.qll/module.SocketIO$SocketIO.html>`__ models use type tracking to track objects coming from their respective APIs. +- The `HTTP <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/frameworks/HTTP.qll/module.HTTP$HTTP.html>`__ server models, such as `Express <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/frameworks/Express.qll/module.Express$Express.html>`__, use type tracking to track the installation of router handler functions. +- The `Firebase <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/frameworks/Firebase.qll/module.Firebase$Firebase.html>`__ and + `Socket.io <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/frameworks/SocketIO.qll/module.SocketIO$SocketIO.html>`__ models use type tracking to track objects coming from their respective APIs. Further reading --------------- -.. include:: ../../reusables/javascript-further-reading.rst -.. include:: ../../reusables/codeql-ref-tools-further-reading.rst +.. include:: ../reusables/javascript-further-reading.rst +.. include:: ../reusables/codeql-ref-tools-further-reading.rst diff --git a/docs/codeql/codeql-language-guides/codeql-for-java/working-with-source-locations.rst b/docs/codeql/codeql-language-guides/working-with-source-locations.rst similarity index 98% rename from docs/codeql/codeql-language-guides/codeql-for-java/working-with-source-locations.rst rename to docs/codeql/codeql-language-guides/working-with-source-locations.rst index 7b570ce7d0e..9b55b95df52 100644 --- a/docs/codeql/codeql-language-guides/codeql-for-java/working-with-source-locations.rst +++ b/docs/codeql/codeql-language-guides/working-with-source-locations.rst @@ -188,5 +188,5 @@ Whitespace suggests that the programmer meant to toggle ``i`` between zero and o Further reading --------------- -.. include:: ../../reusables/java-further-reading.rst -.. include:: ../../reusables/codeql-ref-tools-further-reading.rst +.. include:: ../reusables/java-further-reading.rst +.. include:: ../reusables/codeql-ref-tools-further-reading.rst diff --git a/docs/codeql/codeql-overview/about-codeql.rst b/docs/codeql/codeql-overview/about-codeql.rst index 7278f609d0a..a05282bf494 100644 --- a/docs/codeql/codeql-overview/about-codeql.rst +++ b/docs/codeql/codeql-overview/about-codeql.rst @@ -1,3 +1,5 @@ +:tocdepth: 1 + .. _about-codeql: About CodeQL diff --git a/docs/codeql/codeql-overview/codeql-glossary.rst b/docs/codeql/codeql-overview/codeql-glossary.rst index 05039eafa43..0acc7bd25f1 100644 --- a/docs/codeql/codeql-overview/codeql-glossary.rst +++ b/docs/codeql/codeql-overview/codeql-glossary.rst @@ -1,9 +1,11 @@ +:tocdepth: 1 + .. _codeql-glossary: CodeQL glossary =============== -An overview of the technical terms and concepts in coCodeQL. +An overview of the technical terms and concepts in CodeQL. .. _bqrs-file: diff --git a/docs/codeql/codeql-overview/codeql-tools.rst b/docs/codeql/codeql-overview/codeql-tools.rst index 3a57cd98b46..c51a5286cb0 100644 --- a/docs/codeql/codeql-overview/codeql-tools.rst +++ b/docs/codeql/codeql-overview/codeql-tools.rst @@ -1,3 +1,5 @@ +:tocdepth: 1 + .. _codeql-tools: CodeQL tools diff --git a/docs/codeql/codeql-overview/index.rst b/docs/codeql/codeql-overview/index.rst index 02313631d80..aacb209cf4c 100644 --- a/docs/codeql/codeql-overview/index.rst +++ b/docs/codeql/codeql-overview/index.rst @@ -3,8 +3,19 @@ CodeQL overview =============== +Learn more about how CodeQL works, the languages and libraries supported by CodeQL analysis, and the tools you can use to run CodeQL on open source projects. + +- :doc:`About CodeQL <about-codeql>`: CodeQL is the analysis engine used by developers to automate security checks, and by security researchers to perform variant analysis. + +- :doc:`Supported languages and frameworks <supported-languages-and-frameworks>`: View the languages, libraries, and frameworks supported in the latest version of CodeQL. + +- :doc:`CodeQL tools <codeql-tools>`: GitHub provides the CodeQL command-line interface and CodeQL for Visual Studio Code for performing CodeQL analysis on open source codebases. + +- :doc:`CodeQL glossary <codeql-glossary>`: An overview of the technical terms and concepts in CodeQL. + .. toctree:: :maxdepth: 1 + :hidden: about-codeql supported-languages-and-frameworks diff --git a/docs/codeql/codeql-overview/supported-languages-and-frameworks.rst b/docs/codeql/codeql-overview/supported-languages-and-frameworks.rst index 22885fcd745..4353f9402b7 100644 --- a/docs/codeql/codeql-overview/supported-languages-and-frameworks.rst +++ b/docs/codeql/codeql-overview/supported-languages-and-frameworks.rst @@ -1,3 +1,5 @@ +:tocdepth: 1 + .. _supported-languages-and-frameworks: Supported languages and frameworks diff --git a/docs/codeql/conf.py b/docs/codeql/conf.py index 6372c6968b6..68d0a012610 100644 --- a/docs/codeql/conf.py +++ b/docs/codeql/conf.py @@ -1,33 +1,24 @@ # -*- coding: utf-8 -*- # -# Global configuration file, created on 29th April 2019. -# -# The config values below are used across all of the sphinx projects +# The Sphinx config values used in the CodeQL documentation that is published +# at codeql.github.com/docs # # Note that not all possible configuration values are present in this file. # # All configuration values have a default; values that are commented out # serve to show the default. - +# # For details of all possible config values, # see https://www.sphinx-doc.org/en/master/usage/configuration.html - -################################################################################## # -# Project-specific values are configured in the relevant conf.py file. -# See individual projects for details -# -################################################################################## - -# -- GLOBAL GENERAL CONFIG VALUES ------------------------------------------------ +# -- GENERAL CONFIG VALUES ------------------------------------------------ # The suffix(es) of source filenames. # You can specify multiple suffix as a list of string: -# source_suffix = ['.rst', '.md'] source_suffix = '.rst' # The master toctree document. -master_doc = 'index' +master_doc = 'contents' # General information about the project. project = u'CodeQL documentation' @@ -42,16 +33,18 @@ htmlhelp_basename = 'CodeQL' # If your documentation needs a minimal Sphinx version, state it here. #needs_sphinx = '1.0' -# Add any Sphinx extension module names here, as strings. They can be -# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom -# ones. - # The encoding of source files. source_encoding = 'utf-8-sig' # The name of the Pygments (syntax highlighting) style to use. pygments_style = 'sphinx' +# The default language for syntax highlighting. We need to explicitly set this to "none", +# otherwise Sphinx tries to highlight any unlabeled code samples as "python3". +# See https://www.sphinx-doc.org/en/master/usage/configuration.html#confval-highlight_language. + +highlight_language = "none" + # Import the QL Lexer to use for syntax highlighting import os import sys @@ -61,10 +54,9 @@ def setup(sphinx): from qllexer import QLLexer sphinx.add_lexer("ql", QLLexer()) -# The Semmle version info for the current release you're documenting, acts as replacement for -# |version| and |release|, also used in various other places throughout the -# built documents. -# +# The version of CodeQL for the current release you're documenting, acts as replacement for +# |version| and |release| + # The short X.Y version. version = u'3.0' # The full version, including alpha/beta/rc tags. @@ -85,13 +77,11 @@ html_show_sphinx = False # -- Global HTML configuration ------------------------------------- -# The theme to use for HTML and HTML Help pages. See the documentation for -# a list of builtin themes. +# The theme to use for HTML pages. See https://github.com/bitprophet/alabaster/blob/master/alabaster/static/alabaster.css_t +# Many of the built-in theme styles are overridden by the static stylesheets in html_static_path. html_theme = 'alabaster' -# Theme options are theme-specific and customize the look and feel of a theme -# further. For a list of options available for each theme, see the -# documentation. +# HTML theme options used to customize the look and feel of the docs. html_theme_options = {'font_size': '16px', 'body_text': '#333', 'link': '#2F1695', @@ -101,13 +91,16 @@ html_theme_options = {'font_size': '16px', 'head_font_family': '-apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"', } -# Add any paths that contain templates here, relative to this directory. +# Path to the folder that contains the project's HTML template templates_path = ['_templates'] -# Add any paths that contain custom static files (such as style sheets) here, -# relative to this directory. They are copied after the builtin static files, -# so a file named "default.css" will overwrite the builtin "default.css". +# Path to the folder that contains static stylesheets html_static_path = ['_static'] -exclude_patterns = ['vale*', '_static', '_templates', 'codeql', 'learn-ql', 'reusables', 'images', 'support', 'ql-training', '_build', '*.py*', 'README.rst'] -############################################################################## \ No newline at end of file +# Copy the static landing page for codeql.github.com/docs when building this sphinx project +html_extra_path = ['index.html'] + +html_favicon = 'images/site/favicon.ico' + +# Exclude these paths from being built by Sphinx +exclude_patterns = ['vale*', '_static', '_templates', 'reusables', 'images', 'support', 'ql-training', 'query-help', '_build', '*.py*', 'README.rst'] diff --git a/docs/codeql/index.rst b/docs/codeql/contents.rst similarity index 87% rename from docs/codeql/index.rst rename to docs/codeql/contents.rst index 79f3e9d3921..1a772c7263c 100644 --- a/docs/codeql/index.rst +++ b/docs/codeql/contents.rst @@ -2,7 +2,8 @@ CodeQL documentation ==================== .. toctree:: - :hidden: + :includehidden: + :maxdepth: 3 codeql-overview/index codeql-for-visual-studio-code/index diff --git a/docs/codeql/codeql-language-guides/codeql-for-go/ast.dot b/docs/codeql/images/codeql-for-go/ast.dot similarity index 100% rename from docs/codeql/codeql-language-guides/codeql-for-go/ast.dot rename to docs/codeql/images/codeql-for-go/ast.dot diff --git a/docs/codeql/codeql-language-guides/codeql-for-go/ast.png b/docs/codeql/images/codeql-for-go/ast.png similarity index 100% rename from docs/codeql/codeql-language-guides/codeql-for-go/ast.png rename to docs/codeql/images/codeql-for-go/ast.png diff --git a/docs/codeql/codeql-language-guides/codeql-for-go/cfg.dot b/docs/codeql/images/codeql-for-go/cfg.dot similarity index 100% rename from docs/codeql/codeql-language-guides/codeql-for-go/cfg.dot rename to docs/codeql/images/codeql-for-go/cfg.dot diff --git a/docs/codeql/codeql-language-guides/codeql-for-go/cfg.png b/docs/codeql/images/codeql-for-go/cfg.png similarity index 100% rename from docs/codeql/codeql-language-guides/codeql-for-go/cfg.png rename to docs/codeql/images/codeql-for-go/cfg.png diff --git a/docs/codeql/codeql-language-guides/codeql-for-go/cfg2.dot b/docs/codeql/images/codeql-for-go/cfg2.dot similarity index 100% rename from docs/codeql/codeql-language-guides/codeql-for-go/cfg2.dot rename to docs/codeql/images/codeql-for-go/cfg2.dot diff --git a/docs/codeql/codeql-language-guides/codeql-for-go/cfg2.png b/docs/codeql/images/codeql-for-go/cfg2.png similarity index 100% rename from docs/codeql/codeql-language-guides/codeql-for-go/cfg2.png rename to docs/codeql/images/codeql-for-go/cfg2.png diff --git a/docs/codeql/codeql-language-guides/codeql-for-go/dfg.dot b/docs/codeql/images/codeql-for-go/dfg.dot similarity index 100% rename from docs/codeql/codeql-language-guides/codeql-for-go/dfg.dot rename to docs/codeql/images/codeql-for-go/dfg.dot diff --git a/docs/codeql/codeql-language-guides/codeql-for-go/dfg.png b/docs/codeql/images/codeql-for-go/dfg.png similarity index 100% rename from docs/codeql/codeql-language-guides/codeql-for-go/dfg.png rename to docs/codeql/images/codeql-for-go/dfg.png diff --git a/docs/codeql/codeql-language-guides/codeql-for-go/ssa.dot b/docs/codeql/images/codeql-for-go/ssa.dot similarity index 100% rename from docs/codeql/codeql-language-guides/codeql-for-go/ssa.dot rename to docs/codeql/images/codeql-for-go/ssa.dot diff --git a/docs/codeql/codeql-language-guides/codeql-for-go/ssa.png b/docs/codeql/images/codeql-for-go/ssa.png similarity index 100% rename from docs/codeql/codeql-language-guides/codeql-for-go/ssa.png rename to docs/codeql/images/codeql-for-go/ssa.png diff --git a/docs/codeql/images/site/favicon.ico b/docs/codeql/images/site/favicon.ico new file mode 100644 index 00000000000..cedb6140f45 Binary files /dev/null and b/docs/codeql/images/site/favicon.ico differ diff --git a/docs/codeql/index.html b/docs/codeql/index.html new file mode 100644 index 00000000000..1173d5a68c4 --- /dev/null +++ b/docs/codeql/index.html @@ -0,0 +1,364 @@ +<!DOCTYPE html> +<html lang="en"> + +<head> + <title>CodeQL documentation + + + + + + +
    + +
    + +
    +
    + +
    +
    +
    +
    + +

    CodeQL documentation

    +

    Discover vulnerabilities across a codebase with CodeQL, our industry-leading semantic code + analysis + engine. CodeQL lets you query code as though it were data. Write a query to find all variants of a + vulnerability, eradicating it forever. Then share your query to help others do the same.

    +
    +
    +
    + +
    +

    + BACKGROUND INFORMATION +

    +
    +
    +
    + +
    About CodeQL
    +
    +
    Learn more about how CodeQL works...
    +
    +
    + +
    Supported languages and frameworks
    +
    +
    View the languages, libraries, and frameworks supported in the + latest version of CodeQL...
    +
    +
    + +
    Academic publications
    +
    +
    Read academic articles published by the team behind CodeQL... +
    +
    + +
    +
    +
    +
    +

    + CODEQL TOOLS +

    +
    +
    +
    + +
    CodeQL CLI
    +
    +
    The CodeQL command-line interface (CLI) is used + to create + databases for security research....
    +
    +
    + +
    CodeQL for Visual Studio Code
    +
    +
    CodeQL for Visual Studio Code adds rich language + support for CodeQL...
    +
    +
    + +
    Code scanning with CodeQL
    +
    +
    Use code scanning with CodeQL to analyze the code in a GitHub + repository to find + security + vulnerabilities...
    +
    + +
    +
    + + + + +
    + + + + +
    + +
    +
    +

    + CODEQL GUIDES +

    +
    +
    +
    + +
    Writing CodeQL queries
    +
    +
    Get to know more about queries and learn some key + query-writing skills by solving puzzles.....
    +
    +
    + +
    CodeQL language guides
    +
    +
    Experiment and learn how to write effective and efficient + queries for CodeQL databases generated from the languages supported in CodeQL + analysis...
    +
    +
    +
    +
    +
    +

    + CODEQL REFERENCE DOCS +

    +
    +
    +
    +
    + +
    QL language reference
    +
    +
    Learn all about QL, the powerful query language that + underlies the code scanning tool CodeQL... +
    +
    + +
    CodeQL standard libraries
    +
    +
    Find details of the predicates, modules, and classes + included with CodeQL...
    +
    +
    + +
    CodeQL query help
    +
    +
    View the query help for the queries included in the code + scanning query suites...
    +
    + +
    +
    + +
    +
    + + + + \ No newline at end of file diff --git a/docs/codeql/ql-language-reference/about-the-ql-language.rst b/docs/codeql/ql-language-reference/about-the-ql-language.rst index 73943dc8e12..c24a29aea96 100644 --- a/docs/codeql/ql-language-reference/about-the-ql-language.rst +++ b/docs/codeql/ql-language-reference/about-the-ql-language.rst @@ -1,3 +1,5 @@ +:tocdepth: 1 + .. _about-the-ql-language: About the QL language @@ -42,7 +44,7 @@ When you write this process in QL, it closely resembles the above structure. Not For more information about the important concepts and syntactic constructs of QL, see the individual reference topics such as ":doc:`Expressions `" and ":doc:`Recursion `." The explanations and examples help you understand how the language works, and how to write more advanced QL code. -For formal specifications of the QL language and QLDoc comments, see the ":doc:`QL language specification `" and ":doc:`QLDoc comment specification `." +For a formal specification of the QL language, see the ":doc:`QL language specification `." QL and object orientation ------------------------- @@ -62,9 +64,9 @@ Here are a few prominent conceptual and functional differences between general p Further reading --------------- -`Academic references `__ also provide an overview of QL and its semantics. Other useful references on database query languages and Datalog: +`Academic references `__ also provide an overview of QL and its semantics. Other useful references on database query languages and Datalog: -- `Database theory: Query languages `__ -- `Logic Programming and Databases book - Amazon page `__ +- `Database theory: Query languages `__ +- `Logic Programming and Databases book `__ - `Foundations of Databases `__ - `Datalog `__ diff --git a/docs/codeql/ql-language-reference/aliases.rst b/docs/codeql/ql-language-reference/aliases.rst index 33fd63ca7e3..4a9c2cb8886 100644 --- a/docs/codeql/ql-language-reference/aliases.rst +++ b/docs/codeql/ql-language-reference/aliases.rst @@ -1,4 +1,7 @@ +:tocdepth: 1 + .. index:: alias + .. _aliases: Aliases @@ -30,7 +33,9 @@ to the name that it aliases. Module aliases ============== -Use the following syntax to define an alias for a :ref:`module `:: +Use the following syntax to define an alias for a :ref:`module `: + +.. code-block:: ql module ModAlias = ModuleName; @@ -49,14 +54,18 @@ a deprecation warning is displayed. Type aliases ============ -Use the following syntax to define an alias for a :ref:`type `:: +Use the following syntax to define an alias for a :ref:`type `: + +.. code-block:: ql class TypeAlias = TypeName; Note that ``class`` is just a keyword. You can define an alias for any type—namely, :ref:`primitive types `, :ref:`database types ` and user-defined :ref:`classes `. -For example, you can use an alias to abbreviate the name of the primitive type ``boolean`` to ``bool``:: +For example, you can use an alias to abbreviate the name of the primitive type ``boolean`` to ``bool``: + +.. code-block:: ql class bool = boolean; @@ -77,21 +86,27 @@ Or, to use a class ``OneTwo`` defined in a :ref:`module ` ``M` Predicate aliases ================= -Use the following syntax to define an alias for a :ref:`non-member predicate `:: +Use the following syntax to define an alias for a :ref:`non-member predicate `: + +.. code-block:: ql predicate PredAlias = PredicateName/Arity; This works for predicates :ref:`with ` or :ref:`without ` result. For example, suppose you frequently use the following predicate, which calculates the successor of a positive integer -less than ten:: +less than ten: + +.. code-block:: ql int getSuccessor(int i) { result = i + 1 and i in [1 .. 9] } -You can use an alias to abbreviate the name to ``succ``:: +You can use an alias to abbreviate the name to ``succ``: + +.. code-block:: ql predicate succ = getSuccessor/1; diff --git a/docs/codeql/ql-language-reference/annotations.rst b/docs/codeql/ql-language-reference/annotations.rst index 7def4c3afea..b3dabb42bfb 100644 --- a/docs/codeql/ql-language-reference/annotations.rst +++ b/docs/codeql/ql-language-reference/annotations.rst @@ -1,3 +1,5 @@ +:tocdepth: 1 + .. _annotations: Annotations @@ -45,7 +47,7 @@ Overview of annotations This section describes what the different annotations do, and when you can use them. You can also find a summary table in the Annotations section of the -`QL language specification `_. +`QL language specification `_. .. index:: abstract .. _abstract: @@ -81,7 +83,9 @@ to describe specific configurations. Any non-abstract subtypes must override it indirectly) to describe what sources of data they each track. In other words, all non-abstract classes that extend ``Configuration`` must override ``isSource`` in their -own body, or they must inherit from another class that overrides ``isSource``:: +own body, or they must inherit from another class that overrides ``isSource``: + +.. code-block:: ql class ConfigA extends Configuration { ... @@ -201,7 +205,8 @@ change this definition. In this case, ``hasName`` should be final: **Available for**: |classes| -.. important:: +.. pull-quote:: Important + This annotation is deprecated. Instead of annotating a name with ``library``, put it in a private (or privately imported) module. @@ -326,8 +331,10 @@ When you use this annotation, be aware of the following issues: In particular, you can't chain predicate :ref:`calls ` or call predicates on a :ref:`cast `. You must write them as multiple conjuncts and explicitly order them. - For example, suppose you have the following definitions:: - + For example, suppose you have the following definitions: + + .. code-block:: ql + class Small extends int { Small() { this in [1 .. 10] } Small getSucc() { result = this + 1} @@ -341,8 +348,10 @@ When you use this annotation, be aware of the following issues: s.getSucc().getSucc() = 3 } - If you add ``noopt`` pragmas, you must rewrite the predicates. For example:: - + If you add ``noopt`` pragmas, you must rewrite the predicates. For example: + + .. code-block:: ql + pragma[noopt] predicate p(int i) { exists(Small s | s = i and s.getSucc() = 2) diff --git a/docs/codeql/ql-language-reference/evaluation-of-ql-programs.rst b/docs/codeql/ql-language-reference/evaluation-of-ql-programs.rst index 2a8ce7c20ed..4b94a957a04 100644 --- a/docs/codeql/ql-language-reference/evaluation-of-ql-programs.rst +++ b/docs/codeql/ql-language-reference/evaluation-of-ql-programs.rst @@ -1,3 +1,5 @@ +:tocdepth: 1 + .. _evaluation-of-ql-programs: Evaluation of QL programs @@ -21,7 +23,7 @@ A QL program is evaluated from the bottom up, so a predicate is usually only eva all the predicates it depends on are evaluated. The database includes sets of ordered tuples for the `built-in predicates -`_ and :ref:`external predicates `. +`_ and :ref:`external predicates `. Each evaluation starts from these sets of tuples. The remaining predicates and types in the program are organized into a number of layers, based on the dependencies between them. @@ -33,7 +35,7 @@ results of the program. The results are sorted according to any ordering directi (``order by``) in the queries. For more details about each step of the evaluation process, see the "`QL language specification -`_." +`_." Validity of programs ******************** @@ -46,21 +48,27 @@ Here are some common ways that you might define infinite predicates. These all g compilation errors: - The following query conceptually selects all values of type ``int``, without restricting them. - The QL compiler returns the error ``'i' is not bound to a value``:: + The QL compiler returns the error ``'i' is not bound to a value``: + + .. code-block:: ql from int i select i - The following predicate generates two errors: ``'n' is not bound to a value`` and ``'result' is - not bound to a value``:: + not bound to a value``: + .. code-block:: ql + int timesTwo(int n) { result = n * 2 } - The following class ``Person`` contains all strings that start with ``"Peter"``. There are infinitely many such strings, so this is another invalid definition. The QL compiler gives the - error message ``'this' is not bound to a value``:: + error message ``'this' is not bound to a value``: + + .. code-block:: ql class Person extends string { Person() { @@ -94,7 +102,9 @@ To do this, you can use the following mechanisms: :ref:`binds ` all its arguments. Therefore, if you :ref:`call ` a predicate on a variable, the variable becomes bound. - .. important:: If a predicate uses non-standard binding sets, then it does **not** always bind + .. pull-quote:: Important + + If a predicate uses non-standard binding sets, then it does **not** always bind all its arguments. In such a case, whether the predicate call binds a specific argument depends on which other arguments are bound, and what the binding sets say about the argument in question. For more information, see ":ref:`binding-sets`." diff --git a/docs/codeql/ql-language-reference/expressions.rst b/docs/codeql/ql-language-reference/expressions.rst index 0415538a831..a9facb0dec1 100644 --- a/docs/codeql/ql-language-reference/expressions.rst +++ b/docs/codeql/ql-language-reference/expressions.rst @@ -1,3 +1,5 @@ +:tocdepth: 1 + .. _expressions: Expressions @@ -35,7 +37,7 @@ You can express certain values directly in QL, such as numbers, booleans, and st possibly starting with a minus sign (``-``). For example: -.. code-block:: ql + .. code-block:: ql 0 42 @@ -43,7 +45,9 @@ You can express certain values directly in QL, such as numbers, booleans, and st - :ref:`Float ` literals: These are sequences of decimal digits separated by a dot (``.``), possibly starting with a minus sign (``-``). - For example:: + For example: + + .. code-block:: ql 2.0 123.456 @@ -54,12 +58,12 @@ You can express certain values directly in QL, such as numbers, booleans, and st characters represent themselves, but there are a few characters that you need to "escape" with a backslash. The following are examples of string literals: -.. code-block:: ql + .. code-block:: ql "hello" "They said, \"Please escape quotation marks!\"" - See `String literals `_ + See `String literals `__ in the QL language specification for more details. Note: there is no "date literal" in QL. Instead, to specify a :ref:`date `, you should @@ -133,7 +137,7 @@ In the following example, the class ``C`` inherits two definitions of the predic ``getANumber()``—one from ``A`` and one from ``B``. Instead of overriding both definitions, it uses the definition from ``B``. -:: +.. code-block:: ql class A extends int { A() { this = 1 } @@ -211,7 +215,7 @@ The following aggregates are available in QL: For example, the following aggregation returns the number of files that have more than ``500`` lines: -.. code-block:: ql + .. code-block:: ql count(File f | f.getTotalNumberOfLines() > 500 | f) @@ -227,7 +231,7 @@ The following aggregates are available in QL: For example, the following aggregation returns the name of the ``.js`` file (or files) with the largest number of lines: -.. code-block:: ql + .. code-block:: ql max(File f | f.getExtension() = "js" | f.getBaseName() order by f.getTotalNumberOfLines()) @@ -235,7 +239,7 @@ The following aggregates are available in QL: below, that is, the string that comes first in the lexicographic ordering of all the possible values of ``s``. (In this case, it returns ``"De Morgan"``.) - :: + .. code-block:: ql min(string s | s = "Tarski" or s = "Dedekind" or s = "De Morgan" | s) @@ -247,7 +251,9 @@ The following aggregates are available in QL: returns no values. In other words, it evaluates to the empty set. For example, the following aggregation returns the average of the integers ``0``, ``1``, - ``2``, and ``3``:: + ``2``, and ``3``: + + .. code-block:: ql avg(int i | i = [0 .. 3] | i) @@ -258,7 +264,9 @@ The following aggregates are available in QL: If there are no possible assignments to the aggregation variables that satisfy the formula, then the sum is ``0``. For example, the following aggregation returns the sum of ``i * j`` for all possible values - of ``i`` and ``j``:: + of ``i`` and ``j``: + + .. code-block:: ql sum(int i, int j | i = [0 .. 2] and j = [3 .. 5] | i * j) @@ -272,14 +280,16 @@ The following aggregates are available in QL: For example, the following aggregation returns the string ``"3210"``, that is, the concatenation of the strings ``"0"``, ``"1"``, ``"2"``, and ``"3"`` in descending order: -.. code-block:: ql + .. code-block:: ql concat(int i | i = [0 .. 3] | i.toString() order by i desc) The ``concat`` aggregate can also take a second expression, separated from the first one by a comma. This second expression is inserted as a separator between each concatenated value. - For example, the following aggregation returns ``"0|1|2|3"``:: + For example, the following aggregation returns ``"0|1|2|3"``: + + .. code-block:: ql concat(int i | i = [0 .. 3] | i.toString(), "|") @@ -292,7 +302,9 @@ The following aggregates are available in QL: For example, the following aggregation returns the value that is ranked 4th out of all the possible values. In this case, ``8`` is the 4th integer in the range from ``5`` through - ``15``:: + ``15``: + + .. code-block:: ql rank[4](int i | i = [5 .. 15] | i) @@ -315,7 +327,9 @@ The following aggregates are available in QL: For example, the following query returns the positive integers ``1``, ``2``, ``3``, ``4``, ``5``. For negative integers ``x``, the expressions ``x`` and ``x.abs()`` have different values, so the - value for ``y`` in the aggregate expression is not uniquely determined. :: + value for ``y`` in the aggregate expression is not uniquely determined. + + .. code-block:: ql from int x where x in [-5 .. 5] and x != 0 @@ -392,48 +406,54 @@ aggregation in a simpler form: then you can omit the ```` and ```` parts and write it as follows: -.. code-block:: ql + .. code-block:: ql () For example, the following aggregations determine how many times the letter ``l`` occurs in - string ``"hello"``. These forms are equivalent:: + string ``"hello"``. These forms are equivalent: + + .. code-block:: ql count(int i | i = "hello".indexOf("l") | i) count("hello".indexOf("l")) -#. If there only one aggregation variable, you can omit the ```` part instead. +#. If there is only one aggregation variable, you can omit the ```` part instead. In this case, the expression is considered to be the aggregation variable itself. - For example, the following aggregations are equivalent:: - + For example, the following aggregations are equivalent: + + .. code-block:: ql + avg(int i | i = [0 .. 3] | i) avg(int i | i = [0 .. 3]) #. As a special case, you can omit the ```` part from ``count`` even if there is more than one aggregation variable. In such a case, it counts the number of distinct tuples of aggregation variables that satisfy the formula. In other words, the expression part is - considered to be the constant ``1``. For example, the following aggregations are equivalent:: - + considered to be the constant ``1``. For example, the following aggregations are equivalent: + + .. code-block:: ql + count(int i, int j | i in [1 .. 3] and j in [1 .. 3] | 1) count(int i, int j | i in [1 .. 3] and j in [1 .. 3]) #. You can omit the ```` part, but in that case you should include two vertical bars: -.. code-block:: ql + .. code-block:: ql ( | | ) This is useful if you don't want to restrict the aggregation variables any further. For example, the following aggregation returns the maximum number of lines across all files: -.. code-block:: ql + .. code-block:: ql max(File f | | f.getTotalNumberOfLines()) #. Finally, you can also omit both the ```` and ```` parts. For example, the following aggregations are equivalent ways to count the number of files in a database: -.. code-block:: ql + .. code-block:: ql count(File f | any() | 1) count(File f | | 1) @@ -550,8 +570,9 @@ The following table lists some examples of different forms of ``any`` expression | ``any(int i | i = [0 .. 3] | i * i)`` | the integers ``0``, ``1``, ``4``, and ``9`` | +------------------------------------------+-------------------------------------------------+ -.. note:: - There is also a `built-in predicate `_ +.. pull-quote:: Note + + There is also a `built-in predicate `_ ``any()``. This is a predicate that always holds. Unary operations @@ -634,8 +655,10 @@ is exactly equivalent to ``((Foo)x)``. Casts are useful if you want to call a :ref:`member predicate ` that is only defined for a more specific type. For example, the following query selects Java -`classes `_ -that have a direct supertype called "List":: +`classes `_ +that have a direct supertype called "List": + +.. code-block:: ql import java @@ -666,7 +689,9 @@ Unlike other expressions, a don't-care expression does not have a type. In pract means that ``_`` doesn't have any :ref:`member predicates `, so you can't call ``_.somePredicate()``. -For example, the following query selects all the characters in the string ``"hello"``:: +For example, the following query selects all the characters in the string ``"hello"``: + +.. code-block:: ql from string s where s = "hello".charAt(_) diff --git a/docs/codeql/ql-language-reference/formulas.rst b/docs/codeql/ql-language-reference/formulas.rst index a5adeaf4de8..b4bc7481aeb 100644 --- a/docs/codeql/ql-language-reference/formulas.rst +++ b/docs/codeql/ql-language-reference/formulas.rst @@ -1,3 +1,5 @@ +:tocdepth: 1 + .. _formulas: Formulas @@ -35,7 +37,7 @@ Order To compare two expressions using one of these order operators, each expression must have a type and those types must be :ref:`compatible ` and -`orderable `_. +`orderable `_. +--------------------------+--------+ | Name | Symbol | @@ -316,7 +318,8 @@ The following query selects files that are not HTML files. where not f.getFileType().isHtml() select f -.. note:: +.. pull-quote:: Note + You should be careful when using ``not`` in a recursive definition, as this could lead to non-monotonic recursion. For more information, ":ref:`non-monotonic-recursion`." @@ -379,13 +382,14 @@ disjunction. **Example** With the following definition, an integer is in the class ``OneTwoThree`` if it is equal to -``1``, ``2``, or ``3``:: +``1``, ``2``, or ``3``: + +.. code-block:: ql class OneTwoThree extends int { OneTwoThree() { this = 1 or this = 2 or this = 3 } - ... } .. index:: implies @@ -416,15 +420,15 @@ The following query selects any ``SmallInt`` that is odd, or a multiple of ``4`` .. [#] The difference between ``A != B`` and ``not A = B`` is due to the underlying quantifiers. If you think of ``A`` and ``B`` as sets of values, then ``A != B`` means: -.. code-block:: ql + .. code-block:: ql - exists( a, b | a in A and b in B | a != b ) + exists( a, b | a in A and b in B | a != b ) On the other hand, ``not A = B`` means: -.. code-block:: ql + .. code-block:: ql not exists( a, b | a in A and b in B | a = b ) This is equivalent to ``forall( a, b | a in A and b in B | a != b )``, which is very - different from the first formula. \ No newline at end of file + different from the first formula. diff --git a/docs/codeql/ql-language-reference/index.rst b/docs/codeql/ql-language-reference/index.rst index e5661ddc4a1..5a971259cf7 100644 --- a/docs/codeql/ql-language-reference/index.rst +++ b/docs/codeql/ql-language-reference/index.rst @@ -5,8 +5,39 @@ QL language reference Learn all about QL, the powerful query language that underlies the code scanning tool CodeQL. +- :doc:`About the QL language `: QL is the powerful query language that underlies CodeQL, which is used to analyze code. + +- :doc:`Predicates `: Predicates are used to describe the logical relations that make up a QL program. + +- :doc:`Queries `: Queries are the output of a QL program. They evaluate to sets of results. + +- :doc:`Types `: QL is a statically typed language, so each variable must have a declared type. + +- :doc:`Modules `: Modules provide a way of organizing QL code by grouping together related types, predicates, and other modules. + +- :doc:`Aliases `: An alias is an alternative name for an existing QL entity. + +- :doc:`Variables `: Variables in QL are used in a similar way to variables in algebra or logic. They represent sets of values, and those values are usually restricted by a formula. + +- :doc:`Expressions `: An expression evaluates to a set of values and has a type. + +- :doc:`Formulas `: Formulas define logical relations between the free variables used in expressions. + +- :doc:`Annotations `: An annotation is a string that you can place directly before the declaration of a QL entity or name. + +- :doc:`Recursion `: QL provides strong support for recursion. A predicate in QL is said to be recursive if it depends, directly or indirectly, on itself. + +- :doc:`Lexical syntax `: The QL syntax includes different kinds of keywords, identifiers, and comments. + +- :doc:`Name resolution `: The QL compiler resolves names to program elements. + +- :doc:`Evaluation of QL programs `: A QL program is evaluated in a number of different steps. + +- :doc:`QL language specification `: A formal specification for the QL language. It provides a comprehensive reference for terminology, syntax, and other technical details about QL. + .. toctree:: :maxdepth: 1 + :hidden: about-the-ql-language predicates @@ -23,4 +54,3 @@ Learn all about QL, the powerful query language that underlies the code scanning name-resolution evaluation-of-ql-programs ql-language-specification - qldoc-comment-specification \ No newline at end of file diff --git a/docs/codeql/ql-language-reference/lexical-syntax.rst b/docs/codeql/ql-language-reference/lexical-syntax.rst index 736784740cf..9051e4cd5fb 100644 --- a/docs/codeql/ql-language-reference/lexical-syntax.rst +++ b/docs/codeql/ql-language-reference/lexical-syntax.rst @@ -1,3 +1,5 @@ +:tocdepth: 1 + .. _lexical-syntax: Lexical syntax @@ -6,7 +8,7 @@ Lexical syntax The QL syntax includes different kinds of keywords, identifiers, and comments. For an overview of the lexical syntax, see "`Lexical syntax -`_" in the QL language specification. +`_" in the QL language specification. .. index:: comment, QLDoc .. _comments: @@ -14,12 +16,10 @@ For an overview of the lexical syntax, see "`Lexical syntax Comments ******** -All standard one-line and multiline comments, as described in the "`QL language specification -`_," are ignored by the QL +All standard one-line and multiline comments are ignored by the QL compiler and are only visible in the source code. You can also write another kind of comment, namely **QLDoc comments**. These comments describe -QL entities and are displayed as pop-up information in QL editors. For information about QLDoc -comments, see the ":doc:`QLDoc comment specification `." +QL entities and are displayed as pop-up information in QL editors. The following example uses these three different kinds of comments: diff --git a/docs/codeql/ql-language-reference/modules.rst b/docs/codeql/ql-language-reference/modules.rst index 984e0ff35ec..b9998b63248 100644 --- a/docs/codeql/ql-language-reference/modules.rst +++ b/docs/codeql/ql-language-reference/modules.rst @@ -1,3 +1,5 @@ +:tocdepth: 1 + .. _modules: Modules @@ -15,7 +17,9 @@ Defining a module There are various ways to define modules—here is an example of the simplest way, declaring an :ref:`explicit module ` named ``Example`` containing -a class ``OneTwoThree``:: +a class ``OneTwoThree``: + +.. code-block:: ql module Example { class OneTwoThree extends int { @@ -25,7 +29,7 @@ a class ``OneTwoThree``:: } } -The name of a module can be any `identifier `_ +The name of a module can be any `identifier `_ that starts with an uppercase or lowercase letter. ``.ql`` or ``.qll`` files also implicitly define modules. @@ -113,7 +117,9 @@ the module name, and then the module body enclosed in braces. It can contain any of the elements listed in ":ref:`module-bodies`" below, apart from select clauses. For example, you could add the following QL snippet to the library file **OneTwoThreeLib.qll** -defined :ref:`above `:: +defined :ref:`above `: + +.. code-block:: ql ... module M { @@ -180,5 +186,5 @@ for example ``import javascript as js``. The ```` itself can be a module name, a selection, or a qualified reference. For more information, see ":ref:`name-resolution`." -For information about how import statements are looked up, see "`Module resolution `__" +For information about how import statements are looked up, see "`Module resolution `__" in the QL language specification. \ No newline at end of file diff --git a/docs/codeql/ql-language-reference/name-resolution.rst b/docs/codeql/ql-language-reference/name-resolution.rst index 5908f3ff7a9..c8fc351cffb 100644 --- a/docs/codeql/ql-language-reference/name-resolution.rst +++ b/docs/codeql/ql-language-reference/name-resolution.rst @@ -1,3 +1,5 @@ +:tocdepth: 1 + .. _name-resolution: Name resolution @@ -78,7 +80,7 @@ statement as follows: #. If the compiler can't find the library file using the above two checks, it looks up ``examples/security/MyLibrary.qll`` relative to each library path entry. The library path is usually specified using the ``libraryPathDependencies`` of the ``qlpack.yml`` file, though it may also depend on the tools you use to run your query, and whether you have specified any extra settings. - For more information, see "`Library path `__" in the QL language specification. + For more information, see "`Library path `__" in the QL language specification. If the compiler cannot resolve an import statement, then it gives a compilation error. @@ -104,7 +106,7 @@ Consider the following :ref:`library module `: **CountriesLib.qll** -:: +.. code-block:: ql class Countries extends string { Countries() { @@ -127,7 +129,9 @@ Consider the following :ref:`library module `: } You could write a query that imports ``CountriesLib`` and then uses ``M::EuropeanCountries`` -to refer to the class ``EuropeanCountries``:: +to refer to the class ``EuropeanCountries``: + +.. code-block:: ql import CountriesLib @@ -135,7 +139,9 @@ to refer to the class ``EuropeanCountries``:: select ec Alternatively, you could import the contents of ``M`` directly by using the selection -``CountriesLib::M`` in the import statement:: +``CountriesLib::M`` in the import statement: + +.. code-block:: ql import CountriesLib::M @@ -152,7 +158,7 @@ Namespaces ********** When writing QL, it's useful to understand how namespaces (also known as -`environments `_) work. +`environments `_) work. As in many other programming languages, a namespace is a mapping from **keys** to **entities**. A key is a kind of identifier, for example a name, and a QL entity is @@ -179,7 +185,7 @@ In particular: - The **global module namespace** is empty. - The **global type namespace** has entries for the :ref:`primitive types ` ``int``, ``float``, ``string``, ``boolean``, and ``date``, as well as any :ref:`database types ` defined in the database schema. - - The **global predicate namespace** includes all the `built-in predicates `_, + - The **global predicate namespace** includes all the `built-in predicates `_, as well as any :ref:`database predicates `. In practice, this means that you can use the built-in types and predicates directly in a QL module (without @@ -244,7 +250,7 @@ were defined in the :ref:`QL tutorials `: **Villagers.qll** -:: +.. code-block:: ql import tutorial @@ -295,7 +301,7 @@ The type namespace of ``S`` has entries for: The predicate namespace of ``Villagers`` has entries for: - The predicate ``isBald``, with arity 1. - Any predicates (and their arities) exported by ``tutorial``. - - The `built-in predicates `_. + - The `built-in predicates `_. The predicate namespace of ``S`` has entries for: - All the above predicates. diff --git a/docs/codeql/ql-language-reference/predicates.rst b/docs/codeql/ql-language-reference/predicates.rst index db37d56128c..1850b0a1ee0 100644 --- a/docs/codeql/ql-language-reference/predicates.rst +++ b/docs/codeql/ql-language-reference/predicates.rst @@ -1,3 +1,5 @@ +:tocdepth: 1 + .. _predicates: Predicates @@ -6,7 +8,9 @@ Predicates Predicates are used to describe the logical relations that make up a QL program. Strictly speaking, a predicate evaluates to a set of tuples. For example, consider the -following two predicate definitions:: +following two predicate definitions: + +.. code-block:: ql predicate isCountry(string country) { country = "Germany" @@ -33,7 +37,7 @@ The `arity `_ of these predicates is one an In general, all tuples in a predicate have the same number of elements. The **arity** of a predicate is that number of elements, not including a possible ``result`` variable. For more information, see ":ref:`predicates-with-result`." -There are a number of `built-in predicates `_ +There are a number of `built-in predicates `_ in QL. You can use these in any queries without needing to :ref:`import ` any additional modules. In addition to these built-in predicates, you can also define your own: @@ -47,13 +51,14 @@ When defining a predicate, you should specify: #. The keyword ``predicate`` (for a :ref:`predicate without result `), or the type of the result (for a :ref:`predicate with result `). -#. The name of the predicate. This is an `identifier `_ +#. The name of the predicate. This is an `identifier `_ starting with a lowercase letter. #. The arguments to the predicate, if any, separated by commas. For each argument, specify the argument type and an identifier for the argument variable. #. The predicate body itself. This is a logical formula enclosed in braces. -.. note:: +.. pull-quote:: Note + An :ref:`abstract` or :ref:`external` predicate has no body. To define such a predicate, end the predicate definition with a semicolon (``;``) instead. @@ -140,7 +145,9 @@ on itself. For example, you could use recursion to refine the above example. As it stands, the relation defined in ``getANeighbor`` is not symmetric—it does not capture the fact that if x is a neighbor of y, then y is a neighbor of x. A simple way to capture this is to call this -predicate recursively, as shown below:: +predicate recursively, as shown below: + +.. code-block:: ql string getANeighbor(string country) { country = "France" and result = "Belgium" @@ -219,14 +226,16 @@ Here are a few examples of infinite predicates: Compilation errors: ERROR: "i" is not bound to a value. ERROR: "result" is not bound to a value. + ERROR: expression "i * 4" is not bound to a value. */ int multiplyBy4(int i) { result = i * 4 } /* - Compilation error: + Compilation errors: ERROR: "str" is not bound to a value. + ERROR: expression "str.length()" is not bound to a value. */ predicate shortString(string str) { str.length() < 10 diff --git a/docs/codeql/ql-language-reference/ql-language-specification.rst b/docs/codeql/ql-language-reference/ql-language-specification.rst index 45a2385f1f3..0fe54210504 100644 --- a/docs/codeql/ql-language-reference/ql-language-specification.rst +++ b/docs/codeql/ql-language-reference/ql-language-specification.rst @@ -1,3 +1,5 @@ +:tocdepth: 1 + .. _ql-language-specification: QL language specification @@ -5,10 +7,6 @@ QL language specification This is a formal specification for the QL language. It provides a comprehensive reference for terminology, syntax, and other technical details about QL. -.. This ``highlight`` directive prevents code blocks in this file being highlighted as QL (the default language for this Sphinx project). - -.. highlight:: none - Introduction ------------ @@ -376,7 +374,7 @@ A *variable declaration list* provides a sequence of variables and a type for ea :: - var_decls ::= var_decl ("," var_decl)* + var_decls ::= (var_decl ("," var_decl)*)? var_decl ::= type simpleId A valid variable declaration list must not include two declarations with the same variable name. Moreover, if the declaration has a typing environment that applies, it must not use a variable name that is already present in that typing environment. @@ -388,27 +386,30 @@ The store QL programs evaluate in the context of a *store*. This section specifies several definitions related to the store. -A *fact* is a predicate or type along with an ordered tuple. A fact is written as the predicate name or type name followed immediately by the tuple. Here are some examples of facts: +A *fact* is a predicate or type along with a named tuple. A fact is written as the predicate name or type name followed immediately by the tuple. Here are some examples of facts: :: - successor(0, 1) - Tree.toString(@method_tree(12), "def println") - Location.class(@location(43)) - Location.getURL(@location(43), "file:///etc/hosts:2:0:2:12") + successor(fst: 0, snd:1) + Tree.toString(this:@method_tree(12), result:"def println") + Location.class(this:@location(43)) + Location.getURL(this: @location(43), result:"file:///etc/hosts:2:0:2:12") A *store* is a mutable set of facts. The store can be mutated by adding more facts to it. -An ordered tuple *directly satisfies* a predicate or type with a given if there is a fact in the store with the given tuple and predicate or type. +An named tuple *directly satisfies* a predicate or type with a given tuple if there is a fact in the store with the given tuple and predicate or type. A value ``v`` is in a type ``t`` under any of the following conditions: - The type of ``v`` is ``t`` and ``t`` is a primitive type. -- The tuple ``(v)`` directly satisfies ``t``. +- There is a tuple with ``this`` component ``v`` that directly satisfies ``t``. -An ordered tuple *satisfies a predicate* ``p`` under the following circumstances. If ``p`` is not a member predicate, then the tuple satisfies the predicate whenever it directly satisfies the predicate. +An ordered tuple ``v`` *directly satisfies* a predicate with a given tuple if there is a fact in the store with the given predicate and a named tuple ``v'`` +such that taking the ordered tuple formed by the ``this`` component of ``v'`` followed by the component for each argument equals the ordered tuple. -Otherwise, the tuple must be the tuple of a fact in the store with predicate ``q``, where ``q`` shares a root definition with ``p``. The first element of the tuple must be in the type before the dot in ``q``, and there must be no other predicate that overrides ``q`` such that this is true (see "`Classes <#classes>`__" for details on overriding and root definitions). +An ordered tuple *satisfies a predicate* ``p`` under the following circumstances. If ``p`` is not a member predicate, then the tuple satisfies the predicate whenever the named tuple satisfies the tuple. + +Otherwise, the tuple must be the tuple of a fact in the store with predicate ``q``, where ``q`` shares a root definition with ``p``. The `first` element of the tuple must be in the type before the dot in ``q``, and there must be no other predicate that overrides ``q`` such that this is true (see "`Classes <#classes>`__" for details on overriding and root definitions). An ordered tuple ``(a0, an)`` satisfies the ``+`` closure of a predicate if there is a sequence of binary tuples ``(a0, a1)``, ``(a1, a2)``, ..., ``(an-1, an)`` that all satisfy the predicate. An ordered tuple ``(a, b)`` satisfies the ``*`` closure of a predicate if it either satisfies the ``+`` closure, or if ``a`` and ``b`` are the same, and if moreover they are in each argument type of the predicate. @@ -444,7 +445,7 @@ A one-line comment is two slash characters (``/``, U+002F) followed by any seque // This is a comment -A multiline comment is a *comment start*, followed by a *comment body*, followed by a *comment end*. A comment start is a slash (``/``, U+002F) followed by an asterisk (``*``, U+002A), and a comment end is an asterisk followed by a slash. A comment body is any sequence of characters that does not include a comment end. Here is an example multiline comment: +A multiline comment is a *comment start*, followed by a *comment body*, followed by a *comment end*. A comment start is a slash (``/``, U+002F) followed by an asterisk (``*``, U+002A), and a comment end is an asterisk followed by a slash. A comment body is any sequence of characters that does not include a comment end and does not start with an asterisk. Here is an example multiline comment: :: @@ -454,6 +455,23 @@ A multiline comment is a *comment start*, followed by a *comment body*, followed It had a multiline comment. */ +QLDoc (qldoc) +~~~~~~~~~~~~~ + +A QLDoc comment is a *qldoc comment start*, followed by a *qldoc comment body*, followed by a *qldoc comment end*. A comment start is a slash (``/``, U+002F) followed by two asterisks (``*``, U+002A), and a qldoc comment end is an asterisk followed by a slash. A qldoc comment body is any sequence of characters that does not include a comment end. Here is an example QLDoc comment: + +:: + + /** + It was the best of code. + It was the worst of code. + It had a qldoc comment. + */ + +The "content" of a QLDoc comment is the comment body of the comment, omitting the initial ``/**``, the trailing ``*/``, and the leading whitespace followed by ``*`` on each internal line. + +For more information about how the content is interpreted, see "`QLDoc <#qldoc>`__" below. + Keywords ~~~~~~~~ @@ -736,6 +754,48 @@ A predicate may have several different binding sets, which can be stated by usin | ``bindingset`` | | yes | yes | yes | | | | | +----------------+---------+------------+-------------------+-----------------------+---------+--------+---------+---------+ +QLDoc +----- + +QLDoc is used for documenting QL entities and bindings. QLDoc that is used as part of the +declaration is said to be declared. + +Ambiguous QLDoc +~~~~~~~~~~~~~~~ + +If QLDoc can be parsed as part of a file module or as part of the first declaration in the file then +it is parsed as part of the first declaration. + +Inheriting QLDoc +~~~~~~~~~~~~~~~~ + +If no QLDoc is provided then it may be inherited. + +In the case of an alias then it may be inherited from the right-hand side of the alias. + +In the case of a member predicate we collect all member predicates that it overrides with declared QLDoc. If there is a member predicate in that collection that +overrides every other member predicate in that collection, then the QLDoc of that member predicate is used as the QLDoc. + +In the case of a field we collect all fields that it overrides with declared QLDoc. If there is a field in that collection that +overrides every other field in that collection, then the QLDoc of that field is used as the QLDoc. + +Content +~~~~~~~ + +The content of a QLDoc comment is interpreted as `CommonMark `__, with the following extensions: + +- Automatic interpretation of links and email addresses. +- Use of appropriate characters for ellipses, dashes, apostrophes, and quotes. + +The content of a QLDoc comment may contain metadata tags as follows: + +The tag begins with any number of whitespace characters, followed by an ``@`` sign. At this point there may be any number of non-whitespace characters, which form the key of the tag. Then, a single whitespace character which separates the key from the value. The value of the tag is formed by the remainder of the line, and any subsequent lines until another ``@`` tag is seen, or the end of the content is reached. Any sequence of consecutive whitespace characters in the value are replaced by a single space. + +Metadata +~~~~~~~~ + +If the query file starts with whitespace followed by a QLDoc comment, then the tags from that QLDoc comment form the query metadata. + Top-level entities ------------------ @@ -748,7 +808,7 @@ A *predicate* is declared as a sequence of annotations, a head, and an optional :: - predicate ::= annotations head optbody + predicate ::= qldoc? annotations head optbody A predicate definition adds a mapping from the predicate name and arity to the predicate declaration to the current module's declared predicate environment. @@ -760,7 +820,7 @@ The head of the predicate gives a name, an optional *result type*, and a sequenc :: - head ::= ("predicate" | type) predicateName "(" (var_decls)? ")" + head ::= ("predicate" | type) predicateName "(" var_decls ")" The body of a predicate is of one of three forms: @@ -783,7 +843,7 @@ A class definition has the following syntax: :: - class ::= annotations "class" classname "extends" type ("," type)* "{" member* "}" + class ::= qldoc? annotations "class" classname "extends" type ("," type)* "{" member* "}" The identifier following the ``class`` keyword is the name of the class. @@ -800,20 +860,20 @@ A valid class may not inherit from a final class, from itself, or from more than Class environments ~~~~~~~~~~~~~~~~~~ -For each of modules, types, predicates, and fields a class *inherits*, *declares*, and *exports* an environment. These are defined as follows (with X denoting the type of entity we are currently considering): +For each of member predicates and fields a class *inherits* and *declares*, and *exports* an environment. These are defined as follows (with X denoting the type of entity we are currently considering): -- The *inherited X environment* of a class is the union of the exported X environments of its base types. +- The *inherited X environment* of a class is the union of the exported X environments of types it inherits from, excluding any elements that are ``overridden`` by another element. - The *declared X environment* of a class is the multimap of X declarations in the class itself. - The *exported X environment* of a class is the overriding union of its declared X environment (excluding ``private`` declaration entries) with its inherited X environment. -- The *external X environment* of a class is the visible X environment of the enclosing module. - -- The *visible X environment* is the overriding union of the declared X environment and the inherited X environment; overriding unioned with the external X environment. +- The *visible X environment* is the overriding union of the declared X environment and the inherited X environment. The program is invalid if any of these environments is not definite. +For each of member predicates and fields a domain type *exports* an environment. This is the union of the exported ``X`` environments of types the class inherits from, excluding any elements that are ``overridden`` by another element. + Members ~~~~~~~ @@ -822,8 +882,8 @@ Each member of a class is either a *character*, a predicate, or a field: :: member ::= character | predicate | field - character ::= annotations classname "(" ")" "{" formula "}" - field ::= annotations var_decl ";" + character ::= qldoc? annotations classname "(" ")" "{" formula "}" + field ::= qldoc? annotations var_decl ";" Characters ^^^^^^^^^^ @@ -837,7 +897,7 @@ Member predicates A predicate that is a member of a class is called a *member predicate*. The name of the predicate is the identifier just before the open parenthesis. -A member predicate adds a mapping from the predicate name and arity to the predicate declaration in the class's declared predicate environment. +A member predicate adds a mapping from the predicate name and arity to the predicate declaration in the class's declared member predicate environment. A valid member predicate can be annotated with ``abstract``, ``cached``, ``final``, ``private``, ``deprecated``, and ``override``. @@ -859,13 +919,22 @@ A valid class must include a non-private predicate named ``toString`` with no ar A valid class may not inherit from two different classes that include a predicate with the same name and number of arguments, unless either one of the predicates overrides the other, or the class defines a predicate that overrides both of them. -The typing environment for a member predicate or character is the same as if it were a non-member predicate, except that it additionally maps ``this`` to a type. If the member is a character, then the typing environment maps ``this`` to the class domain type of the class. Otherwise, it maps ``this`` to the class type of the class itself. +The typing environment for a member predicate or character is the same as if it were a non-member predicate, except that it additionally maps ``this`` to a type and also maps any fields on a class to a type. If the member is a character, then the typing environment maps ``this`` to the class domain type of the class. Otherwise, it maps ``this`` to the class type of the class itself. +The typing environment also maps any field to the type of the field. Fields ^^^^^^ A field declaration introduces a mapping from the field name to the field declaration in the class's declared field environment. +A field ``f`` with enclosing class ``C`` *overrides* a field ``f'`` with enclosing class ``D`` when ``f`` is annotated ``override``, ``C`` inherits from ``D``, ``p'`` is visible in ``C``, and both ``p`` and ``p'`` have the same name. + +A valid class may not inherit from two different classes that include a field with the same name, unless either one of the fields overrides the other, or the class defines a field that overrides both of them. + +A valid field must override another field if it is annotated ``override``. + +When field ``f`` overrides field ``g`` the type of ``f`` must be a subtype of the type of ``g``. ``f`` may not be a final field. + Select clauses ~~~~~~~~~~~~~~ @@ -1092,13 +1161,24 @@ The expressions in parentheses are the *arguments* of the call. The expression b The type environment for the arguments is the same as for the call. -A valid call with results must *resolve* to exactly one predicate. The ways a call can resolve are as follows: +A valid call with results *resolves* to a set of predicates. The ways a call can resolve are as follows: -- If the call has no receiver, then it can resolve to a non-member predicate. If the predicate name is a simple identifier, then the predicate is resolved by looking up its name and arity in the visible predicate environment of the enclosing class or module. +- If the call has no receiver and the predicate name is a simple identifier, then the predicate is resolved by looking up its name and arity in the visible member-predicate environment of the enclosing class. - If the predicate name is a selection identifier, then the qualifier is resolved as a module (see "`Module resolution <#module-resolution>`__"). The identifier is then resolved in the exported predicate environment of the qualifier module. +- If the call has no receiver and the predicate name is a simple identifier, then the predicate is resolved by looking up its name and arity in the visible predicate environment of the enclosing module. -- If the call has a super expression as the receiver, then it resolves to a member predicate in a class the enclosing class inherits from. If the super expression is unqualified, then the super-class is the single class that the current class inherits from. If there is not exactly one such class, then the program is invalid. Otherwise the super-class is the class named by the qualifier of the super expression. The predicate is resolved by looking up its name and arity in the exported predicate environment of the super-class. If there is more than one such predicate, then the predicate call is not valid. +- If the call has no receiver and the predicate name is a selection identifier, then the qualifier is resolved as a module (see "`Module resolution <#module-resolution>`__"). The identifier is then resolved in the exported predicate environment of the qualifier module. + +- If the call has a super expression as the receiver, then it resolves to a member predicate in a class the enclosing class inherits from. If the super expression is unqualified, then the super-class is the single class that the current class inherits from. If there is not exactly one such class, then the program is invalid. Otherwise the super-class is the class named by the qualifier of the super expression. The predicate is resolved by looking up its name and arity in the exported predicate environment of the super-class. + +- If the type of the receiver is the same as the enclosing class, the predicate is resolved by looking up its name and arity in the visible predicate environment of the class. + +- If the type of the receiver is not the same as the enclosing class, the predicate is resolved by looking up its name and arity in the exported predicate environment of the class or domain type. + +If all the predicates that the call resolves to are declared on a primitive type, we then restrict to the set of predicates where each argument of the call is a subtype of the corresponding predicate argument type. +Then we find all predicates ``p`` from this new set such that there is not another predicate ``p'`` where each argument of ``p'`` is a subtype of the corresponding argument in ``p``. We then say the call resolves to this set instead. + +A valid call must only resolve to a single predicate. For each argument other than a don't-care expression, the type of the argument must be compatible with the type of the corresponding argument type of the predicate, otherwise the call is invalid. @@ -1112,6 +1192,8 @@ If the resolved predicate is built in, then the call may not include a closure. - The number 1 if the predicate has a result, otherwise 0. +If the call includes a closure, then all declared predicate arguments, the enclosing type of the declaration (if it exists), and the result type of the declaration (if it exists) must be compatible. If one of those types is a subtype of ``int``, then all the other arguments must be a subtype of ``int``. + If the call resolves to a member predicate, then the *receiver values* are as follows. If the call has a receiver, then the receiver values are the values of that receiver. If the call does not have a receiver, then the single receiver value is the value of ``this`` in the contextual named tuple. The *tuple prefixes* of a call with results include one value from each of the argument expressions' values, in the same order as the order of the arguments. If the call resolves to a non-member predicate, then those values are exactly the tuple prefixes of the call. If the call instead resolves to a member predicate, then the tuple prefixes additionally include a receiver value, ordered before the argument values. @@ -1127,7 +1209,7 @@ An aggregation can be written in one of two forms: :: - aggregation ::= aggid ("[" expr "]")? "(" (var_decls)? ("|" (formula)? ("|" as_exprs ("order" "by" aggorderbys)?)?)? ")" + aggregation ::= aggid ("[" expr "]")? "(" var_decls ("|" (formula)? ("|" as_exprs ("order" "by" aggorderbys)?)?)? ")" | aggid ("[" expr "]")? "(" as_exprs ("order" "by" aggorderbys)? ")" | "unique" "(" var_decls "|" (formula)? ("|" as_exprs)? ")" @@ -1137,7 +1219,7 @@ An aggregation can be written in one of two forms: aggorderby ::= expr ("asc" | "desc")? -The expression enclosed in square brackets (``[`` and ``]``, U+005B and U+005D), if present, is called the *rank expression*. It must have type ``int`` in the enclosing environment. +The expression enclosed in square brackets (``[`` and ``]``, U+005B and U+005D), if present, is called the *rank expression*. It must have type ``int``. The ``as_exprs``, if present, are called the *aggregation expressions*. If an aggregation expression is of the form ``expr as v`` then the expression is said to be *named* v. @@ -1267,7 +1349,9 @@ The grammar given in this section is disambiguated first by precedence, and seco - binary ``*`` , ``/`` and ``%`` - binary ``+`` and ``-`` -Additionally, whenever a sequence of tokens can be interpreted either as a call to a predicate with result (with specified closure), or as a binary operation with operator ``+`` or ``*``, the syntax is interpreted as a call to a predicate with result. +Whenever a sequence of tokens can be interpreted either as a call to a predicate with result (with specified closure), or as a binary operation with operator ``+`` or ``*``, the syntax is interpreted as a call to a predicate with result. + +Whenever a sequence of tokens can be interpreted either as arithmetic with a parenthesized variable or as a prefix cast of a unary operation, the syntax is interpreted as a cast. Formulas -------- @@ -1474,9 +1558,9 @@ Aliases define new names for existing QL entities. :: - alias ::= annotations "predicate" literalId "=" predicateRef "/" int ";" - | annotations "class" classname "=" type ";" - | annotations "module" modulename "=" moduleId ";" + alias ::= qldoc? annotations "predicate" literalId "=" predicateRef "/" int ";" + | qldoc? annotations "class" classname "=" type ";" + | qldoc? annotations "module" modulename "=" moduleId ";" An alias introduces a binding from the new name to the entity referred to by the right-hand side in the current module's declared predicate, type, or module environment respectively. @@ -1830,7 +1914,7 @@ Predicates, and types can *depend* and *strictly depend* on each other. Such dep - If a predicate contains a variable declaration with negative or zero polarity of a variable whose declared type is a class type ``C``, then the predicate strictly depends on ``C.class``. -- If a predicate contains an expression whose type is a class type ``C``, then the predicate depends on ``C.class``. If the expression has negative or zero polarity then the dependency is strict. +- If a predicate contains an expression whose type is a class type ``C`` which is not a variable reference, then the predicate depends on ``C.class``. If the expression has negative or zero polarity then the dependency is strict. - A predicate containing a predicate call depends on the predicate to which the call resolves. If the call has negative or zero polarity then the dependency is strict. @@ -1863,29 +1947,53 @@ The store is first initialized with the *database content* of all built-in predi Each layer of the stratification is *populated* in order. To populate a layer, each predicate in the layer is repeatedly populated until the store stops changing. The way that a predicate is populated is as follows: -- To populate a predicate that has a formula as a body, find all named tuples with the variables of the predicate's arguments that match the body formula and the types of the variables. If the predicate has a result, then the matching named tuples should additionally have a value for ``result`` that is in the result type of the predicate. If the predicate is a member predicate, then the tuples should additionally have a value for ``this`` that is of the type assigned to ``this`` by the typing environment. For each such tuple, convert the named tuple to an ordered tuple by sequencing the values of the tuple, starting with ``this`` if present, followed by the predicate's arguments, followed by ``result`` if present. Add each such converted tuple to the predicate in the store. +- To populate a predicate that has a formula as a body, find each named tuple ``t`` that has the following properties: + + - The tuple matches the body formula. + - The variables should be the predicate's arguments. + - If the predicate has a result, then the tuples should additionally have a value for ``result``. + - If the predicate is a member predicate or characteristic predicate of a class ``C`` then the tuples should additionally have a value for ``this`` and each visible field on the class. + - The values corresponding to the arguments should all be a member of the declared types of the arguments. + - The values corresponding to ``result`` should all be a member of the result type. + - The values corresponding to the fields should all be a member of the declared types of the fields. + - If the predicate is a member predicate of a class ``C`` and not a characteristic predicate, then the tuples should additionally extend some tuple in ``C.class``. + - If the predicate is a characteristic predicate of a class ``C``, then there should be a tuple ``t'`` in ``C.extends`` such that for each visible field in ``C``, any field that is equal to or overrides a field in ``t'`` should have the same value in ``t``. ``this`` should also map to the same value in ``t`` and ``t'``. + + For each such tuple remove any components that correspond to fields and add it to the predicate in the store. - To populate an abstract predicate, do nothing. - The population of predicates with a higher-order body is left only partially specified. A number of tuples are added to the given predicate in the store. The tuples that are added must be fully determined by the QL program and by the state of the store. -- To populate the type ``C.extends`` for a class ``C``, identify each value ``v`` that has the following properties: It is in all non-class base types of ``C``, and for each class base type ``B`` of ``C`` it is in ``B.B``. For each such ``v``, add ``(v)`` to ``C.extends``. +- To populate the type ``C.extends`` for a class ``C``, identify each named tuple that has the following properties: -- To populate the type ``C.C`` for a class ``C``, if ``C`` has a characteristic predicate, then add all tuples from that predicate to the store. Otherwise add each tuple in ``C.extends`` into the store. + - The value of ``this`` is in all non-class base types of ``C``. + - The keys of the tuple are ``this`` and the union of the public fields from each base type. + - For each class base type ``B`` of ``C`` there is a named tuple with variables from the public fields of ``B`` and ``this`` that the given tuple and some tuple in ``B.B`` both extend. + + For each such tuple add it to ``C.extends``. + +- To populate the type ``C.C`` for a class ``C``, if ``C`` has a characteristic predicate, then add all tuples from that predicate to the store. Otherwise add all tuples ``t`` such that: + + - The variables of ``t`` should be ``this`` and the visible fields of ``C``. + - The values corresponding to the fields should all be a member of the declared types of the fields. + - If the predicate is a characteristic predicate of a class ``C``, then there should be a tuple ``t'`` in ``C.extends`` such that for each visible field in ``C``, any field that is equal to or overrides a field in ``t'`` should have the same value in ``t``. ``this`` should also map to the same value in ``t`` and ``t'``. - To populate the type ``C.class`` for a non-abstract class type ``C``, add each tuple in ``C.C`` to ``C.class``. -- To populate the type ``C.class`` for an abstract class type ``C``, for each class ``D`` that has ``C`` as a base type add all tuples in ``D.class`` to ``C.class``. +- To populate the type ``C.class`` for an abstract class type ``C``, identify each named tuple that has the following properties: + - It is a member of ``C.C``. + - For each class ``D`` that has ``C`` as a base type then there is a named tuple with variables from the public fields of ``C`` and ``this`` that the given tuple and a tuple in ``D.class`` both extend. -- To populate a select clause, find all named tuples with the variables declared in the ``from`` clause that match the formula given in the ``where`` clause, if there is one. For each named tuple, convert it to a set of ordered tuples where each element of the ordered tuple is, in the context of the named tuple, a value of one of the corresponding select expressions. Collect all ordered tuples that can be produced from all of the restricted named tuples in this way. Add each such converted tuple to the select clause in the store. Query evaluation ~~~~~~~~~~~~~~~~ A query is evaluated as follows: -#. Identify all named tuples in the predicate targeted by the query. -#. Sequence the ordered tuples lexicographically. The first elements of the lexicographic order are the tuple elements specified by the ordering directives of the predicate targeted by the query, if it has any. Each such element is ordered either ascending (``asc``) or descending (``desc``) as specified by the ordering directive, or ascending if the ordering directive does not specify. This lexicographic order is only a partial order, if there are fewer ordering directives than elements of the tuples. An implementation may produce any sequence of the ordered tuples that satisfies this partial order. +#. Identify all facts about query predicates. +#. If there is a select clause then find all named tuples with the variables declared in the ``from`` clause that match the formula given in the ``where`` clause, if there is one. For each named tuple, convert it to a set of ordered tuples where each element of the ordered tuple is, in the context of the named tuple, a value of one of the corresponding select expressions. Then sequence the ordered tuples lexicographically. The first elements of the lexicographic order are the tuple elements specified by the ordering directives of the predicate targeted by the query, if it has any. Each such element is ordered either ascending (``asc``) or descending (``desc``) as specified by the ordering directive, or ascending if the ordering directive does not specify. This lexicographic order is only a partial order, if there are fewer ordering directives than elements of the tuples. An implementation may produce any sequence of the ordered tuples that satisfies this partial order. +#. The result is the facts from the query predicates plus the list of ordered tuples from the select clause if it exists. Summary of syntax ----------------- @@ -1894,7 +2002,7 @@ The complete grammar for QL is as follows: :: - ql ::= moduleBody + ql ::= qldoc? moduleBody module ::= annotation* "module" modulename "{" moduleBody "}" @@ -1917,7 +2025,7 @@ The complete grammar for QL is as follows: orderby ::= simpleId ("asc" | "desc")? - predicate ::= annotations head optbody + predicate ::= qldoc? annotations head optbody annotations ::= annotation* @@ -1938,19 +2046,19 @@ The complete grammar for QL is as follows: | "language" "[" "monotonicAggregates" "]" | "bindingset" "[" (variable ( "," variable)*)? "]" - head ::= ("predicate" | type) predicateName "(" (var_decls)? ")" + head ::= ("predicate" | type) predicateName "(" var_decls ")" optbody ::= ";" | "{" formula "}" | "=" literalId "(" (predicateRef "/" int ("," predicateRef "/" int)*)? ")" "(" (exprs)? ")" - class ::= annotations "class" classname "extends" type ("," type)* "{" member* "}" + class ::= qldoc? annotations "class" classname "extends" type ("," type)* "{" member* "}" member ::= character | predicate | field - character ::= annotations classname "(" ")" "{" formula "}" + character ::= qldoc? annotations classname "(" ")" "{" formula "}" - field ::= annotations var_decl ";" + field ::= qldoc? annotations var_decl ";" moduleId ::= simpleId | moduleId "::" simpleId @@ -1958,11 +2066,11 @@ The complete grammar for QL is as follows: exprs ::= expr ("," expr)* - alias := annotations "predicate" literalId "=" predicateRef "/" int ";" - | annotations "class" classname "=" type ";" - | annotations "module" modulename "=" moduleId ";" + alias := qldoc? annotations "predicate" literalId "=" predicateRef "/" int ";" + | qldoc? annotations "class" classname "=" type ";" + | qldoc? annotations "module" modulename "=" moduleId ";" - var_decls ::= var_decl ("," var_decl)* + var_decls ::= (var_decl ("," var_decl)*)? var_decl ::= type simpleId @@ -2049,7 +2157,7 @@ The complete grammar for QL is as follows: postfix_cast ::= primary "." "(" type ")" - aggregation ::= aggid ("[" expr "]")? "(" (var_decls)? ("|" (formula)? ("|" as_exprs ("order" "by" aggorderbys)?)?)? ")" + aggregation ::= aggid ("[" expr "]")? "(" var_decls ("|" (formula)? ("|" as_exprs ("order" "by" aggorderbys)?)?)? ")" | aggid ("[" expr "]")? "(" as_exprs ("order" "by" aggorderbys)? ")" | "unique" "(" var_decls "|" (formula)? ("|" as_exprs)? ")" diff --git a/docs/codeql/ql-language-reference/qldoc-comment-specification.rst b/docs/codeql/ql-language-reference/qldoc-comment-specification.rst deleted file mode 100644 index cb84d281c93..00000000000 --- a/docs/codeql/ql-language-reference/qldoc-comment-specification.rst +++ /dev/null @@ -1,52 +0,0 @@ -.. _qldoc-comment-specification: - -QLDoc comment specification -=========================== - -This document is a formal specification for QLDoc comments. - -About QLDoc comments --------------------- - -You can provide documentation for a QL entity by adding a QLDoc comment in the source file. The QLDoc comment is displayed as pop-up information in QL editors, for example when you hover over a predicate name. - -Notation --------- - -A 'QLDoc comment' is a valid QL comment that begins with ``/**`` and ends with ``*/``. - -The 'content' of a QLDoc comment is the textual body of the comment, omitting the initial ``/**``, the trailing ``*/``, and the leading whitespace followed by ``*`` on each internal line. - -A QLDoc comment 'precedes' the next QL syntax element after it in the file. - -Association ------------ - -A QLDoc comment may be 'associated with' any of the following QL syntax elements: - -- Class declarations -- Non-member predicate declarations -- Member predicate declarations -- Modules - -For class and predicate declarations, the associated QLDoc comment (if any) is the closest preceding QLDoc comment. - -For modules, the associated QLDoc comment (if any) is the QLDoc comment which is the first element in the file, and moreover is not associated with any other QL element. - -Inheritance ------------ - -If a member predicate has no directly associated QLDoc and overrides a set of member predicates which all have the same QLDoc, then the member predicate inherits that QLDoc. - -Content -------- - -The content of a QLDoc comment is interpreted as standard Markdown, with the following extensions: - -- Fenced code blocks using backticks. -- Automatic interpretation of links and email addresses. -- Use of appropriate characters for ellipses, dashes, apostrophes, and quotes. - -The content of a QLDoc comment may contain metadata tags as follows: - -The tag begins with any number of whitespace characters, followed by an ``@`` sign. At this point there may be any number of non-whitespace characters, which form the key of the tag. Then, a single whitespace character which separates the key from the value. The value of the tag is formed by the remainder of the line, and any subsequent lines until another ``@`` tag is seen, or the end of the content is reached. diff --git a/docs/codeql/ql-language-reference/queries.rst b/docs/codeql/ql-language-reference/queries.rst index 2bdf9d9bb0a..8cba04942b6 100644 --- a/docs/codeql/ql-language-reference/queries.rst +++ b/docs/codeql/ql-language-reference/queries.rst @@ -1,4 +1,7 @@ +:tocdepth: 1 + .. index:: query + .. _queries: Queries @@ -21,7 +24,9 @@ Select clauses ************** When writing a query module, you can include a **select clause** (usually at the end of the -file) of the following form:: +file) of the following form: + +.. code-block:: ql from /* ... variable declarations ... */ where /* ... logical formula ... */ @@ -102,7 +107,9 @@ This predicate returns the following results: A benefit of writing a query predicate instead of a select clause is that you can call the predicate in other parts of the code too. For example, you can call ``getProduct`` inside -the body of a :ref:`class `:: +the body of a :ref:`class `: + +.. code-block:: ql class MultipleOfThree extends int { MultipleOfThree() { this = getProduct(_, _) } diff --git a/docs/codeql/ql-language-reference/recursion.rst b/docs/codeql/ql-language-reference/recursion.rst index 4188a5be4a1..9f89955795c 100644 --- a/docs/codeql/ql-language-reference/recursion.rst +++ b/docs/codeql/ql-language-reference/recursion.rst @@ -1,3 +1,5 @@ +:tocdepth: 1 + .. index:: recursion .. _recursion: @@ -27,7 +29,9 @@ Counting from 0 to 100 ====================== The following query uses the predicate ``getANumber()`` to list all integers from 0 to 100 -(inclusive):: +(inclusive): + +.. code-block:: ql int getANumber() { result = 0 @@ -44,7 +48,9 @@ Mutual recursion ================ Predicates can be mutually recursive, that is, you can have a cycle of predicates that -depend on each other. For example, here is a QL query that counts to 100 using even numbers:: +depend on each other. For example, here is a QL query that counts to 100 using even numbers: + +.. code-block:: ql int getAnEven() { result = 0 @@ -87,7 +93,9 @@ helpful abbreviations: ``p``, and so on. Using this ``+`` notation is often simpler than defining the recursive predicate explicitly. - In this case, an explicit definition could look like this:: + In this case, an explicit definition could look like this: + + .. code-block:: ql Person getAnAncestor() { result = this.getAParent() @@ -105,7 +113,9 @@ helpful abbreviations: For example, the result of ``p.getAParent*()`` is an ancestor of ``p`` (as above), or ``p`` itself. - In this case, the explicit definition looks like this:: + In this case, the explicit definition looks like this: + + .. code-block:: ql Person getAnAncestor2() { result = this @@ -174,7 +184,9 @@ According to this definition, the predicate ``isParadox()`` holds precisely when This is impossible, so there is no fixed point solution to the recursion. If the recursion appears under an even number of negations, then this isn't a problem. -For example, consider the following (slightly macabre) member predicate of class ``Person``:: +For example, consider the following (slightly macabre) member predicate of class ``Person``: + +.. code-block:: ql predicate isExtinct() { this.isDead() and diff --git a/docs/codeql/ql-language-reference/types.rst b/docs/codeql/ql-language-reference/types.rst index 21ecf83490e..ae37230f05c 100644 --- a/docs/codeql/ql-language-reference/types.rst +++ b/docs/codeql/ql-language-reference/types.rst @@ -1,3 +1,5 @@ +:tocdepth: 1 + .. index:: type .. _types: @@ -48,7 +50,7 @@ independent of the database that you are querying. QL has a range of built-in operations defined on primitive types. These are available by using dispatch on expressions of the appropriate type. For example, ``1.toString()`` is the string representation of the integer constant ``1``. For a full list of built-in operations available in QL, see the -section on `built-ins `__ in the QL language specification. +section on `built-ins `__ in the QL language specification. .. index:: class .. _classes: @@ -74,7 +76,7 @@ Defining a class To define a class, you write: #. The keyword ``class``. -#. The name of the class. This is an `identifier `_ +#. The name of the class. This is an `identifier `_ starting with an uppercase letter. #. The types to extend. #. The :ref:`body of the class `, enclosed in braces. @@ -161,7 +163,9 @@ The expression ``(OneTwoThree)`` is a :ref:`cast `. It ensures that ``1`` ``getAString()``. Member predicates are especially useful because you can chain them together. For example, you -can use ``toUpperCase()``, a built-in function defined for ``string``:: +can use ``toUpperCase()``, a built-in function defined for ``string``: + +.. code-block:: ql 1.(OneTwoThree).getAString().toUpperCase() @@ -170,9 +174,7 @@ This call returns ``"ONE, TWO OR THREE: 1"``. .. index:: this .. _this: -.. note: - -.. code-block:: ql +.. pull-quote:: Note Characteristic predicates and member predicates often use the variable ``this``. This variable always refers to a member of the class—in this case a value belonging to the @@ -193,7 +195,9 @@ declarations (that is, variable declarations) within its body. You can use these predicate declarations inside the class. Much like the :ref:`variable ` ``this``, fields must be constrained in the :ref:`characteristic predicate `. -For example:: +For example: + +.. code-block:: ql class SmallInt extends int { SmallInt() { this = [1 .. 10] } @@ -281,7 +285,9 @@ inherited predicate, and by adding the ``override`` :ref:`annotation ` This is useful if you want to refine the predicate to give a more specific result for the values in the subclass. -For example, extending the class from the :ref:`first example `:: +For example, extending the class from the :ref:`first example `: + +.. code-block:: ql class OneTwo extends OneTwoThree { OneTwo() { @@ -296,7 +302,9 @@ For example, extending the class from the :ref:`first example The member predicate ``getAString()`` overrides the original definition of ``getAString()`` from ``OneTwoThree``. -Now, consider the following query:: +Now, consider the following query: + +.. code-block:: ql from OneTwoThree o select o, o.getAString() @@ -316,7 +324,9 @@ look like this: In QL, unlike other object-oriented languages, different subtypes of the same types don't need to be disjoint. For example, you could define another subclass of ``OneTwoThree``, which overlaps -with ``OneTwo``:: +with ``OneTwo``: + +.. code-block:: ql class TwoThree extends OneTwoThree { TwoThree() { @@ -364,7 +374,9 @@ value, namely 2. It inherits member predicates from ``OneTwo`` and ``TwoThree``. It also (indirectly) inherits from ``OneTwoThree`` and ``int``. -.. note:: If a subclass inherits multiple definitions for the same predicate name, then it +.. pull-quote:: Note + + If a subclass inherits multiple definitions for the same predicate name, then it must :ref:`override ` those definitions to avoid ambiguity. :ref:`Super expressions ` are often useful in this situation. @@ -395,7 +407,9 @@ in the characteristic predicate of a class. Algebraic datatypes ******************* -.. note:: The syntax for algebraic datatypes is considered experimental and is subject to +.. pull-quote:: Note + + The syntax for algebraic datatypes is considered experimental and is subject to change. However, they appear in the `standard QL libraries `_ so the following sections should help you understand those examples. @@ -423,7 +437,9 @@ It also means that a unique ``NoCall`` value is produced. Defining an algebraic datatype ============================== -To define an algebraic datatype, use the following general syntax:: +To define an algebraic datatype, use the following general syntax: + +.. code-block:: ql newtype = @@ -433,7 +449,7 @@ The branch definitions have the following form: () { } -- The type name and the branch names must be `identifiers `_ +- The type name and the branch names must be `identifiers `_ starting with an uppercase letter. Conventionally, they start with ``T``. - The different branches of an algebraic datatype are separated by ``or``. - The arguments to a branch, if any, are :ref:`variable declarations ` @@ -472,7 +488,9 @@ In the standard QL language libraries, this is usually done as follows: For example, the following code snippet from the CodeQL data-flow library for C# defines classes for dealing with tainted or untainted values. In this case, it doesn't make sense for ``TaintType`` to extend a database type. It is part of the taint analysis, not the underlying -program, so it's helpful to extend a new type (namely ``TTaintType``):: +program, so it's helpful to extend a new type (namely ``TTaintType``): + +.. code-block:: ql private newtype TTaintType = TExactValue() @@ -529,7 +547,9 @@ For example, the following construction is legal: } However, a similar implementation that restricts ``InitialValueSource`` in a class extension is not valid. -If we had implemented ``DefiniteInitialization`` as a class extension instead, it would trigger a type test for ``InitialValueSource``. This results in an illegal recursion ``DefiniteInitialization -> InitialValueSource -> UnknownInitialGarbage -> ¬DefiniteInitialization`` since ``UnknownInitialGarbage`` relies on ``DefiniteInitialization``:: +If we had implemented ``DefiniteInitialization`` as a class extension instead, it would trigger a type test for ``InitialValueSource``. This results in an illegal recursion ``DefiniteInitialization -> InitialValueSource -> UnknownInitialGarbage -> ¬DefiniteInitialization`` since ``UnknownInitialGarbage`` relies on ``DefiniteInitialization``: + +.. code-block:: ql // THIS WON'T WORK: The implicit type check for InitialValueSource involves an illegal recursion // DefiniteInitialization -> InitialValueSource -> UnknownInitialGarbage -> ¬DefiniteInitialization! diff --git a/docs/codeql/ql-language-reference/variables.rst b/docs/codeql/ql-language-reference/variables.rst index da7ccd1e7ea..7f151a362e9 100644 --- a/docs/codeql/ql-language-reference/variables.rst +++ b/docs/codeql/ql-language-reference/variables.rst @@ -1,4 +1,7 @@ +:tocdepth: 1 + .. index:: variable + .. _variables: Variables @@ -20,7 +23,7 @@ Declaring a variable ******************** All variable declarations consist of a :ref:`type ` and a name for the variable. -The name can be any `identifier `_ +The name can be any `identifier `_ that starts with an uppercase or lowercase letter. For example, ``int i``, ``SsaDefinitionNode node``, and ``LocalScopeVariable lsv`` declare diff --git a/docs/codeql/ql-training/cpp/bad-overflow-guard.rst b/docs/codeql/ql-training/cpp/bad-overflow-guard.rst index 0630bdcb039..b0d892a3a48 100644 --- a/docs/codeql/ql-training/cpp/bad-overflow-guard.rst +++ b/docs/codeql/ql-training/cpp/bad-overflow-guard.rst @@ -149,7 +149,7 @@ Let’s look for overflow guards of the form ``v + b < v``, using the classes - a ``RelationalOperation``: the overflow comparison check. - a ``Variable``: used as an argument to both the addition and comparison. - - The ``where`` part of the query ties these three variables together using `predicates `__ defined in the `standard CodeQL for C/C++ library `__. + - The ``where`` part of the query ties these three variables together using `predicates `__ defined in the `standard CodeQL for C/C++ library `__. CodeQL query: bad overflow guards ================================= diff --git a/docs/codeql/ql-training/cpp/control-flow-cpp.rst b/docs/codeql/ql-training/cpp/control-flow-cpp.rst index 64c34b46328..fe478bd4edc 100644 --- a/docs/codeql/ql-training/cpp/control-flow-cpp.rst +++ b/docs/codeql/ql-training/cpp/control-flow-cpp.rst @@ -223,7 +223,7 @@ Further materials ================= - CodeQL for C/C++: https://help.semmle.com/QL/learn-ql/ql/cpp/ql-for-cpp.html -- API reference: https://help.semmle.com/qldoc/cpp +- API reference: https://codeql.github.com/codeql-standard-libraries/cpp .. rst-class:: end-slide diff --git a/docs/codeql/ql-training/cpp/data-flow-cpp.rst b/docs/codeql/ql-training/cpp/data-flow-cpp.rst index 9d2f29863c9..855ccb40ccb 100644 --- a/docs/codeql/ql-training/cpp/data-flow-cpp.rst +++ b/docs/codeql/ql-training/cpp/data-flow-cpp.rst @@ -84,7 +84,7 @@ Write a query that flags ``printf`` calls where the format argument is not a ``S This first query is about finding places where the format specifier is not a constant string. In the CodeQL libraries for C/C++, constant strings are modeled as ``StringLiteral`` nodes, so we are looking for calls to format functions where the format specifier argument is not a string literal. - The `C/C++ standard libraries `__ include many different formatting functions that may be vulnerable to this particular attack–including ``printf``, ``snprintf``, and others. Furthermore, each of these different formatting functions may include the format string in a different position in the argument list. Instead of laboriously listing all these different variants, we can make use of the standard CodeQL class ``FormattingFunction``, which provides an interface that models common formatting functions in C/C++. + The `C/C++ standard libraries `__ include many different formatting functions that may be vulnerable to this particular attack–including ``printf``, ``snprintf``, and others. Furthermore, each of these different formatting functions may include the format string in a different position in the argument list. Instead of laboriously listing all these different variants, we can make use of the standard CodeQL class ``FormattingFunction``, which provides an interface that models common formatting functions in C/C++. Meh... ====== diff --git a/docs/codeql/ql-training/cpp/intro-ql-cpp.rst b/docs/codeql/ql-training/cpp/intro-ql-cpp.rst index aa8e8cfa72b..4753aa4a493 100644 --- a/docs/codeql/ql-training/cpp/intro-ql-cpp.rst +++ b/docs/codeql/ql-training/cpp/intro-ql-cpp.rst @@ -70,7 +70,7 @@ A simple CodeQL query A `query `__ consists of a “select” clause that indicates what results should be returned. Typically it will also provide a “from” clause to declare some variables, and a “where” clause to state conditions over those variables. For more information on the structure of query files (including links to useful topics in the `QL language reference `__), see `About CodeQL queries `__. - In our example here, the first line of the query imports the `CodeQL library for C/C++ `__, which defines concepts like ``IfStmt`` and ``Block``. + In our example here, the first line of the query imports the `CodeQL library for C/C++ `__, which defines concepts like ``IfStmt`` and ``Block``. The query proper starts by declaring two variables–ifStmt and block. These variables represent sets of values in the database, according to the type of each of the variables. For example, ifStmt has the type IfStmt, which means it represents the set of all if statements in the program. If we simply selected these two variables:: diff --git a/docs/codeql/ql-training/java/intro-ql-java.rst b/docs/codeql/ql-training/java/intro-ql-java.rst index 0398ffe205d..fb415d078bc 100644 --- a/docs/codeql/ql-training/java/intro-ql-java.rst +++ b/docs/codeql/ql-training/java/intro-ql-java.rst @@ -70,7 +70,7 @@ A simple CodeQL query A `query `__ consists of a “select” clause that indicates what results should be returned. Typically it will also provide a “from” clause to declare some variables, and a “where” clause to state conditions over those variables. For more information on the structure of query files (including links to useful topics in the `QL language reference `__), see `About CodeQL queries `__. - In our example here, the first line of the query imports the `CodeQL library for Java `__, which defines concepts like ``IfStmt`` and ``Block``. + In our example here, the first line of the query imports the `CodeQL library for Java `__, which defines concepts like ``IfStmt`` and ``Block``. The query proper starts by declaring two variables–ifStmt and block. These variables represent sets of values in the database, according to the type of each of the variables. For example, ``ifStmt`` has the type ``IfStmt``, which means it represents the set of all if statements in the program. If we simply selected these two variables:: diff --git a/docs/codeql/ql-training/java/query-injection-java.rst b/docs/codeql/ql-training/java/query-injection-java.rst index ce215069b8d..92e0930d9bf 100644 --- a/docs/codeql/ql-training/java/query-injection-java.rst +++ b/docs/codeql/ql-training/java/query-injection-java.rst @@ -84,7 +84,7 @@ Let’s start by looking for calls to methods with names of the form ``sparql*Qu - a ``MethodAccess``: the call to a SPARQL query method - a ``Method``: the SPARQL query method. - - The ``where`` part of the query ties these variables together using `predicates `__ defined in the `standard CodeQL library for Java `__. + - The ``where`` part of the query ties these variables together using `predicates `__ defined in the `standard CodeQL library for Java `__. CodeQL query: find string concatenation ======================================= diff --git a/docs/codeql/ql-training/slide-snippets/local-data-flow.rst b/docs/codeql/ql-training/slide-snippets/local-data-flow.rst index c660d83d21a..f0d1dfa546f 100644 --- a/docs/codeql/ql-training/slide-snippets/local-data-flow.rst +++ b/docs/codeql/ql-training/slide-snippets/local-data-flow.rst @@ -105,9 +105,9 @@ So all references will need to be qualified (that is, ``DataFlow::Node``) A **query library** is file with the extension ``.qll``. Query libraries do not contain a query clause, but may contain modules, classes, and predicates. For further information on the data flow libraries, see the following links: - - `Java data flow library `__ - - `C/C++ data flow library `__ - - `C# data flow library `__ + - `Java data flow library `__ + - `C/C++ data flow library `__ + - `C# data flow library `__ A **module** is a way of organizing QL code by grouping together related predicates, classes, and (sub-)modules. They can be either explicitly declared or implicit. A query library implicitly declares a module with the same name as the QLL file. @@ -155,6 +155,6 @@ Taint tracking The taint-tracking API is almost identical to that of the local data flow. All we need to do to switch to taint tracking is ``import semmle.code..dataflow.TaintTracking`` instead of ``semmle.code..dataflow.DataFlow``, and instead of using ``localFlow``, we use ``localTaint``. - - `Java taint-tracking library `__ - - `C/C++ taint-tracking library `__ - - `C# taint-tracking library `__ + - `Java taint-tracking library `__ + - `C/C++ taint-tracking library `__ + - `C# taint-tracking library `__ diff --git a/docs/codeql/query-help-markdown.py b/docs/codeql/query-help-markdown.py new file mode 100644 index 00000000000..350c9aefce2 --- /dev/null +++ b/docs/codeql/query-help-markdown.py @@ -0,0 +1,256 @@ +import re +import subprocess +import json +import csv +import sys +import os + +""" +This script collects CodeQL queries that are part of code scanning query packs, +renders the accompanying query help as markdown, inserts some useful metadata +into the help, and adds a link to the query in the CodeQL repo. + +This script requires that 'git' and 'codeql' commands +are on the PATH. It'll try to automatically set the CodeQL search path correctly, +as long as you run the script from one of the following locations: + - anywhere from within a clone of the CodeQL Git repo + - from the parent directory of a clone of the CodeQL Git repo (assuming 'codeql' + and 'codeql-go' directories both exist) +""" + +# Define which languages and query packs to consider +languages = [ "cpp", "csharp", "go", "java", "javascript", "python"] + +# Query suites to generate help for - lgtm suite should cover the queries that users are interested in +packs = ["lgtm"] + +def prefix_repo_nwo(filename): + """ + Replaces an absolute path prefix with a GitHub repository name with owner (NWO). + This function relies on `git` being available. + For example: + /home/alice/git/ql/java/ql/src/MyQuery.ql + becomes: + github/codeql/java/ql/src/MyQuery.ql + + If we can't detect a known NWO (e.g. github/codeql, github/codeql-go), the + path will be truncated to the root of the git repo: + ql/java/ql/src/MyQuery.ql + + If the filename is not part of a Git repo, the return value is the + same as the input value: the whole path. + """ + dirname = os.path.dirname(filename) + + try: + git_toplevel_dir_subp = subprocess_run( + ["git", "-C", dirname, "rev-parse", "--show-toplevel"]) + except: + # Not a Git repo + return filename + + git_toplevel_dir = git_toplevel_dir_subp.stdout.strip() + + # Detect 'github/codeql' and 'github/codeql-go' repositories by checking the remote (it's a bit + # of a hack but will work in most cases, as long as the remotes have 'codeql' and 'codeql-go' + # in the URL + git_remotes = subprocess_run( + ["git", "-C", dirname, "remote", "-v"]).stdout.strip() + + if "codeql-go" in git_remotes: + prefix = "github/codeql-go" + elif "codeql" in git_remotes: + prefix = "github/codeql" + else: + prefix = os.path.basename(git_toplevel_dir) + + return os.path.join(prefix, filename[len(git_toplevel_dir)+1:]) + + +def single_spaces(input): + """ + Workaround for https://github.com/github/codeql-coreql-team/issues/470 which causes + some metadata strings to contain newlines and spaces without a good reason. + """ + return " ".join(input.split()) + + +def get_query_metadata(key, metadata, queryfile): + """Returns query metadata or prints a warning to stderr if a particular piece of metadata is not available.""" + if key in metadata: + return single_spaces(metadata[key]) + query_id = metadata['id'] if 'id' in metadata else 'unknown' + print("Warning: no '%s' metadata for query with ID '%s' (%s)" % + (key, query_id, queryfile), file=sys.stderr) + return "" + + +def subprocess_run(cmd): + """Runs a command through subprocess.run, with a few tweaks. Raises an Exception if exit code != 0.""" + return subprocess.run(cmd, capture_output=True, text=True, env=os.environ.copy(), check=True) + + +try: # Check for `git` on path + subprocess_run(["git", "--version"]) +except Exception as e: + print("Error: couldn't invoke 'git'. Is it on the path? Aborting.", file=sys.stderr) + raise e + +try: # Check for `codeql` on path + subprocess_run(["codeql", "--version"]) +except Exception as e: + print("Error: couldn't invoke CodeQL CLI 'codeql'. Is it on the path? Aborting.", file=sys.stderr) + raise e + +# Define CodeQL search path so it'll find the CodeQL repositories: +# - anywhere in the current Git clone (including current working directory) +# - the 'codeql' subdirectory of the cwd +# +# (and assumes the codeql-go repo is in a similar location) + +codeql_search_path = "./codeql:./codeql-go" # will be extended further down +# Extend CodeQL search path by detecting root of the current Git repo (if any). This means that you +# can run this script from any location within the CodeQL git repository. +try: + git_toplevel_dir = subprocess_run(["git", "rev-parse", "--show-toplevel"]) + + # Current working directory is in a Git repo. Add it to the search path, just in case it's the CodeQL repo + #git_toplevel_dir = git_toplevel_dir.stdout.strip() + codeql_search_path += ":" + git_toplevel_dir + ":" + git_toplevel_dir + "/../codeql-go" + codeql_search_path = git_toplevel_dir = git_toplevel_dir.stdout.strip() +except: + # git rev-parse --show-toplevel exited with non-zero exit code. We're not in a Git repo + pass + +# Iterate over all languages and packs, and resolve which queries are part of those packs +for lang in languages: + + code_scanning_queries = subprocess_run( + ["codeql", "resolve", "queries", "--search-path", codeql_search_path, "%s-code-scanning.qls" % (lang)]).stdout.strip() + security_extended_queries = subprocess_run( + ["codeql", "resolve", "queries", "--search-path", codeql_search_path, "%s-security-extended.qls" % (lang)]).stdout.strip() + security_and_quality_queries = subprocess_run( + ["codeql", "resolve", "queries", "--search-path", codeql_search_path, "%s-security-and-quality.qls" % (lang)]).stdout.strip() + # Define empty dictionary to store @name:filename pairs to generate alphabetically sorted Sphinx toctree + index_file_dictionary = {} + for pack in packs: + # Get absolute paths to queries in this pack by using 'codeql resolve queries' + try: + + queries_subp = subprocess_run( + ["codeql", "resolve", "queries", "--search-path", codeql_search_path, "%s-%s.qls" % (lang, pack)]) + except Exception as e: + # Resolving queries might go wrong if the github/codeql and github/codeql-go repositories are not + # on the search path. + print( + "Warning: couldn't find query pack '%s' for language '%s'. Do you have the right repositories in the right places (search path: '%s')?" % ( + pack, lang, codeql_search_path), + file=sys.stderr + ) + continue + + # Define empty dictionary to store @name:filename pairs to generate alphabetically sorted Sphinx toctree later + index_file_dictionary = {} + + # Investigate metadata for every query by using 'codeql resolve metadata' + for queryfile in queries_subp.stdout.strip().split("\n"): + query_metadata_json = subprocess_run( + ["codeql", "resolve", "metadata", queryfile]).stdout.strip() + meta = json.loads(query_metadata_json) + + # Turn an absolute path to a query file into an nwo-prefixed path (e.g. github/codeql/java/ql/src/....) + queryfile_nwo = prefix_repo_nwo(queryfile) + + # Generate the query help for each query + try: + query_help = subprocess_run( + ["codeql", "generate", "query-help", "--format=markdown", "--warnings=error", queryfile]).stdout.strip() + except: + # Print a message if generate query help fails + print("Failed to generate query help for '%s'" % (queryfile_nwo)) + continue + + # Pull out relevant query metadata properties that we want to display in the query help + query_name_meta = get_query_metadata('name', meta, queryfile) + query_description = get_query_metadata( + 'description', meta, queryfile) + query_id = "ID: " + \ + get_query_metadata('id', meta, queryfile) + "\n" + query_kind = "Kind: " + \ + get_query_metadata('kind', meta, queryfile) + "\n" + query_severity = "Severity: " + \ + get_query_metadata('problem.severity', meta, queryfile) + "\n" + query_precision = "Precision: " + \ + get_query_metadata('precision', meta, queryfile) + "\n" + query_tags = "Tags:\n - " + \ + get_query_metadata('tags', meta, queryfile).replace(" ", "\n - ") + "\n" + + # Build a link to the query source file for display in the query help + if "go" in prefix_repo_nwo(queryfile): + transform_link = prefix_repo_nwo(queryfile).replace( + "codeql-go", "codeql-go/blob/main").replace(" ", "%20").replace("\\", "/") + else: + transform_link = prefix_repo_nwo(queryfile).replace( + "codeql", "codeql/blob/main").replace(" ", "%20").replace("\\", "/") + query_link = "[Click to see the query in the CodeQL repository](https://github.com/" + \ + transform_link + ")\n" + + if queryfile in code_scanning_queries: + cs_suites = ' - ' + lang +'-code-scanning.qls\n' + else: + cs_suites = "" + if queryfile in security_extended_queries: + se_suites = ' - ' + lang + '-security-extended.qls\n' + else: + se_suites = "" + if queryfile in security_and_quality_queries: + sq_suites = ' - ' +lang + '-security-and-quality.qls\n' + else: + sq_Suites = "" + + if queryfile in code_scanning_queries or queryfile in security_extended_queries or queryfile in security_and_quality_queries: + suites_list = "Query suites:\n" + cs_suites + se_suites + sq_suites + else: + suites_list = "" + + # Join metadata into a literal block and add query link below + meta_string = "\n"*2 + "```\n" + query_id + query_kind + query_severity + \ + query_precision + query_tags + suites_list + "```\n\n" + query_link + "\n" + + # Insert metadata block into query help directly under title + full_help = query_help.replace("\n", meta_string, 1) + + # Use id property to make name for markdown file, replacing any "/" characters with "-" + query_name = query_id[4:-1].replace("/", "-") + + # Populate index_file_dictionary with @name extracted from metadata and corresponding query filename + index_file_dictionary[query_name_meta] = lang + "/" + query_name + + # Make paths for output of the form: query-help-markdown//.md + docs_dir = 'query-help' + md_dir_path = os.path.join(docs_dir, lang) + md_file_path = os.path.join(md_dir_path, query_name + ".md") + + # Make directories for output paths they don't already exist + if not os.path.isdir(md_dir_path): + os.makedirs(md_dir_path) + + # Generate query help at chosen path if output file doesn't already exist + if not os.path.exists(md_file_path): + file = open(md_file_path, "x") + file.write(full_help) + file.close() + + # Sort index_file_dictionary alphabetically by @name key, and create column of filename values + sorted_index = dict(sorted(index_file_dictionary.items())) + sorted_index = ("\n" + " ").join(sorted_index.values()) + + # Add directives to make sorted_index a valid toctree for sphinx source files + toc_directive = ".. toctree::\n :titlesonly:\n\n " + toc_include = toc_directive + sorted_index + + # Write toctree to rst + toc_file = os.path.join(docs_dir, "toc-" + lang + ".rst") + file = open(toc_file, "x") + file.write(toc_include) + file.close() diff --git a/docs/codeql/query-help/codeql-cwe-coverage.md b/docs/codeql/query-help/codeql-cwe-coverage.md new file mode 100644 index 00000000000..245318a5258 --- /dev/null +++ b/docs/codeql/query-help/codeql-cwe-coverage.md @@ -0,0 +1,25 @@ +# CodeQL CWE coverage + +An overview of the coverage of MITRE's Common Weakness Enumeration (CWE) for the latest release of CodeQL. + +## About CWEs + +The CWE categorization contains several types of entity, collectively known as CWEs. The CWEs that we consider in this report are only those of the types: + +- Weakness Class +- Weakness Base +- Weakness Variant +- Compound Element + +Other types of CWE do not correspond directly to weaknesses, so are omitted. + +The CWE categorization includes relationships between entities, in particular a parent-child relationship. +These relationships are associated with Views (another kind of CWE entity). For the purposes of coverage claims, we use the "[Research View](https://cwe.mitre.org/data/definitions/1000.html)." + +Every security query is associated with one or more CWEs, which are the most precise CWEs that are covered by that query. +Overall coverage is claimed for the most-precise CWEs, as well as for any of their ancestors in the View. + +## Overview + + + diff --git a/docs/codeql/query-help/conf.py b/docs/codeql/query-help/conf.py new file mode 100644 index 00000000000..f3d4090f952 --- /dev/null +++ b/docs/codeql/query-help/conf.py @@ -0,0 +1,65 @@ +# -*- coding: utf-8 -*- +# +# CodeQL query help configuration file +# +# This file is execfile()d with the current directory set to its +# containing dir. +# +# Note that not all possible configuration values are present in this +# autogenerated file. +# +# All configuration values have a default; values that are commented out +# serve to show the default. + +# For details of all possible config values, +# see https://www.sphinx-doc.org/en/master/usage/configuration.html + +# -- Project-specific configuration ----------------------------------- + +# The master toctree document. +master_doc = 'index' + +# General information about the project. +project = u'CodeQL query help' + +# Add md parser to process query help markdown files +extensions = [ + 'recommonmark', + 'sphinx_markdown_tables', +] + +source_suffix = { + '.rst': 'restructuredtext', + '.md': 'markdown', +} + +# -- Project-specific options for HTML output ---------------------------------------------- + +# Theme options are theme-specific and customize the look and feel of a theme +# further. For a list of options available for each theme, see the +# documentation. +html_theme_options = {'font_size': '16px', + 'body_text': '#333', + 'link': '#2F1695', + 'link_hover': '#2F1695', + 'show_powered_by': False, + 'nosidebar':True, + 'head_font_family': '-apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"', + } + +highlight_language = "none" + +# Add any paths that contain templates here, relative to this directory. +templates_path = ['../_templates'] + +# Add any paths that contain custom static files (such as style sheets) here, +# relative to this directory. They are copied after the builtin static files, +# so a file named "default.css" will overwrite the builtin "default.css". +html_static_path = ['../_static'] + +html_favicon = '../images/site/favicon.ico' + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. + +exclude_patterns = ['toc-*', 'readme.md'] # ignore toc-.rst files as they are 'included' in index pages diff --git a/docs/codeql/query-help/cpp.rst b/docs/codeql/query-help/cpp.rst new file mode 100644 index 00000000000..7c3cbe304d7 --- /dev/null +++ b/docs/codeql/query-help/cpp.rst @@ -0,0 +1,9 @@ +CodeQL query help for C and C++ +=============================== + +.. include:: ../reusables/query-help-overview.rst + +For shorter queries that you can use as building blocks when writing your own queries, see the `example queries in the CodeQL repository `__. + +.. include:: toc-cpp.rst + \ No newline at end of file diff --git a/docs/codeql/query-help/csharp.rst b/docs/codeql/query-help/csharp.rst new file mode 100644 index 00000000000..9c5c6351ce3 --- /dev/null +++ b/docs/codeql/query-help/csharp.rst @@ -0,0 +1,8 @@ +CodeQL query help for C# +======================== + +.. include:: ../reusables/query-help-overview.rst + +For shorter queries that you can use as building blocks when writing your own queries, see the `example queries in the CodeQL repository `__. + +.. include:: toc-csharp.rst \ No newline at end of file diff --git a/docs/codeql/query-help/go.rst b/docs/codeql/query-help/go.rst new file mode 100644 index 00000000000..e81d759f807 --- /dev/null +++ b/docs/codeql/query-help/go.rst @@ -0,0 +1,8 @@ +CodeQL query help for Go +======================== + +.. include:: ../reusables/query-help-overview.rst + +For shorter queries that you can use as building blocks when writing your own queries, see the `example queries in the CodeQL for Go repository `__. + +.. include:: toc-go.rst diff --git a/docs/codeql/query-help/index.rst b/docs/codeql/query-help/index.rst new file mode 100644 index 00000000000..10e4b0dff20 --- /dev/null +++ b/docs/codeql/query-help/index.rst @@ -0,0 +1,37 @@ +CodeQL query help +----------------- + +View the query help for the queries included in the ``code-scanning``, ``security-extended``, and ``security-and-quality`` query suites for the languages supported by CodeQL. + +- :doc:`CodeQL query help for C and C++ ` +- :doc:`CodeQL query help for C# ` +- :doc:`CodeQL query help for Go ` +- :doc:`CodeQL query help for Java ` +- :doc:`CodeQL query help for JavaScript ` +- :doc:`CodeQL query help for Python ` + + +.. pull-quote:: Information + + Each query help article includes: + + - A summary of key metadata for the query. + - Information about which query suites the query is included in. + - A link to the query in the `CodeQL repository `__. + - A description of the potential vulnerability that the query identifies and a recommendation for how to avoid introducing the problem to your code. + + +For a full list of the CWEs covered by these queries, see ":doc:`CodeQL CWE coverage `." + +.. toctree:: + :hidden: + :titlesonly: + + cpp + csharp + go + java + javascript + python + codeql-cwe-coverage + diff --git a/docs/codeql/query-help/java.rst b/docs/codeql/query-help/java.rst new file mode 100644 index 00000000000..8af2ee52890 --- /dev/null +++ b/docs/codeql/query-help/java.rst @@ -0,0 +1,8 @@ +CodeQL query help for Java +========================== + +.. include:: ../reusables/query-help-overview.rst + +For shorter queries that you can use as building blocks when writing your own queries, see the `example queries in the CodeQL repository `__. + +.. include:: toc-java.rst diff --git a/docs/codeql/query-help/javascript.rst b/docs/codeql/query-help/javascript.rst new file mode 100644 index 00000000000..d7cf6797852 --- /dev/null +++ b/docs/codeql/query-help/javascript.rst @@ -0,0 +1,8 @@ +CodeQL query help for JavaScript +================================ + +.. include:: ../reusables/query-help-overview.rst + +For shorter queries that you can use as building blocks when writing your own queries, see the `example queries in the CodeQL repository `__. + +.. include:: toc-javascript.rst \ No newline at end of file diff --git a/docs/codeql/query-help/python.rst b/docs/codeql/query-help/python.rst new file mode 100644 index 00000000000..da68c1caa9b --- /dev/null +++ b/docs/codeql/query-help/python.rst @@ -0,0 +1,8 @@ +CodeQL query help for Python +============================ + +.. include:: ../reusables/query-help-overview.rst + +For shorter queries that you can use as building blocks when writing your own queries, see the `example queries in the CodeQL repository `__. + +.. include:: toc-python.rst \ No newline at end of file diff --git a/docs/codeql/query-help/readme.md b/docs/codeql/query-help/readme.md new file mode 100644 index 00000000000..4e98220f759 --- /dev/null +++ b/docs/codeql/query-help/readme.md @@ -0,0 +1,8 @@ +CodeQL query help Sphinx documentation +-------------------------------------- + +This project supplies the configuration and some boiler plate +index files for the CodeQL query help documentation. + +The query help itself is automatically generated by the +"Generate CodeQL query help documentation using Sphinx" workflow. \ No newline at end of file diff --git a/docs/codeql/reusables/advanced-query-execution.rst b/docs/codeql/reusables/advanced-query-execution.rst index 0519939f0d9..7162b2042e6 100644 --- a/docs/codeql/reusables/advanced-query-execution.rst +++ b/docs/codeql/reusables/advanced-query-execution.rst @@ -4,15 +4,15 @@ `. You can also execute queries using the following plumbing-level subcommands: - - `database run-queries <../codeql-cli-manual/database-run-queries.html>`__, which + - `database run-queries <../manual/database-run-queries>`__, which outputs non-interpreted results in an intermediate binary format called :ref:`BQRS `. - - `query run <../codeql-cli-manual/query-run.html>`__, which will output BQRS files, or print + - `query run <../manual/query-run>`__, which will output BQRS files, or print results tables directly to the command line. Viewing results directly in the command line may be useful for iterative query development using the CLI. Queries run with these commands don't have the same metadata requirements. However, to save human-readable data you have to process each BQRS results - file using the `bqrs decode <../codeql-cli-manual/bqrs-decode.html>`__ plumbing + file using the `bqrs decode <../manual/bqrs-decode>`__ plumbing subcommand. Therefore, for most use cases it's easiest to use ``database analyze`` to directly generate interpreted results. \ No newline at end of file diff --git a/docs/codeql/reusables/cpp-further-reading.rst b/docs/codeql/reusables/cpp-further-reading.rst index 5cd69858578..a288bc710cf 100644 --- a/docs/codeql/reusables/cpp-further-reading.rst +++ b/docs/codeql/reusables/cpp-further-reading.rst @@ -1,4 +1,4 @@ - `CodeQL queries for C and C++ `__ - `Example queries for C and C++ `__ -- `CodeQL library reference for C and C++ `__ +- `CodeQL library reference for C and C++ `__ diff --git a/docs/codeql/reusables/csharp-further-reading.rst b/docs/codeql/reusables/csharp-further-reading.rst index 1b5cb7754c0..40c1bced4c7 100644 --- a/docs/codeql/reusables/csharp-further-reading.rst +++ b/docs/codeql/reusables/csharp-further-reading.rst @@ -1,4 +1,4 @@ - `CodeQL queries for C# `__ - `Example queries for C# `__ -- `CodeQL library reference for C# `__ +- `CodeQL library reference for C# `__ diff --git a/docs/codeql/reusables/go-further-reading.rst b/docs/codeql/reusables/go-further-reading.rst index 59f3625bc42..275d3c85c3e 100644 --- a/docs/codeql/reusables/go-further-reading.rst +++ b/docs/codeql/reusables/go-further-reading.rst @@ -1,3 +1,3 @@ - `CodeQL queries for Go `__ - `Example queries for Go `__ -- `CodeQL library reference for Go `__ +- `CodeQL library reference for Go `__ diff --git a/docs/codeql/reusables/java-further-reading.rst b/docs/codeql/reusables/java-further-reading.rst index 4f94a78099b..cde17dbfa1c 100644 --- a/docs/codeql/reusables/java-further-reading.rst +++ b/docs/codeql/reusables/java-further-reading.rst @@ -1,4 +1,4 @@ - `CodeQL queries for Java `__ - `Example queries for Java `__ -- `CodeQL library reference for Java `__ +- `CodeQL library reference for Java `__ diff --git a/docs/codeql/reusables/javascript-further-reading.rst b/docs/codeql/reusables/javascript-further-reading.rst index bda3e058a1b..1e09d193648 100644 --- a/docs/codeql/reusables/javascript-further-reading.rst +++ b/docs/codeql/reusables/javascript-further-reading.rst @@ -1,3 +1,3 @@ - `CodeQL queries for JavaScript `__ - `Example queries for JavaScript `__ -- `CodeQL library reference for JavaScript `__ +- `CodeQL library reference for JavaScript `__ diff --git a/docs/codeql/reusables/python-further-reading.rst b/docs/codeql/reusables/python-further-reading.rst index 7ff521c4abf..eab9644d555 100644 --- a/docs/codeql/reusables/python-further-reading.rst +++ b/docs/codeql/reusables/python-further-reading.rst @@ -1,4 +1,4 @@ - `CodeQL queries for Python `__ - `Example queries for Python `__ -- `CodeQL library reference for Python `__ +- `CodeQL library reference for Python `__ diff --git a/docs/codeql/reusables/query-help-overview.rst b/docs/codeql/reusables/query-help-overview.rst new file mode 100644 index 00000000000..52bc65fef5b --- /dev/null +++ b/docs/codeql/reusables/query-help-overview.rst @@ -0,0 +1,5 @@ +Visit the articles below to see the documentation for the queries included in the following query suites: + +- ``code-scanning``: queries run by default in CodeQL code scanning on GitHub. +- ``security-extended``: queries from ``code-scanning``, plus extra security queries with slightly lower precision and severity. +- ``security-and-quality``: queries from ``code-scanning``, ``security-extended``, plus extra maintainability and reliability queries. diff --git a/docs/codeql/support/conf.py b/docs/codeql/support/conf.py index 1647b35eb35..45a8456ce9a 100644 --- a/docs/codeql/support/conf.py +++ b/docs/codeql/support/conf.py @@ -71,6 +71,8 @@ html_theme_options = {'font_size': '16px', 'nosidebar':True, } +html_favicon = '../images/site/favicon.ico' + # -- Currently unused, but potentially useful, configs-------------------------------------- # Add any paths that contain custom themes here, relative to this directory. diff --git a/docs/codeql/support/index.rst b/docs/codeql/support/index.rst index 6236b4c1543..f9cdf40e227 100644 --- a/docs/codeql/support/index.rst +++ b/docs/codeql/support/index.rst @@ -11,4 +11,10 @@ For details see: language-support.rst framework-support.rst -For details of the CodeQL libraries, see `CodeQL standard libraries `_. \ No newline at end of file +For details of the CodeQL libraries, see `CodeQL standard libraries `_. + +.. toctree:: + :hidden: + + notes-ql-users + ql-training \ No newline at end of file diff --git a/docs/codeql/support/notes-ql-users.rst b/docs/codeql/support/notes-ql-users.rst new file mode 100644 index 00000000000..7e5f032279e --- /dev/null +++ b/docs/codeql/support/notes-ql-users.rst @@ -0,0 +1,91 @@ +Notes for legacy QL CLI users +============================= + +If you've previously used the QL command-line tools (``odasa``), you'll notice a +few key differences when you use the new CodeQL products: + +* "QL snapshots" are now called `CodeQL databases `__. +* The process of creating a CodeQL database is much simpler and more streamlined. + There's no need to create ``projects`` or ``snapshots``---just check out the + code and build it using the CodeQL CLI ``codeql database create`` command. +* Queries are run against CodeQL databases using the CodeQL CLI ``codeql + database analyze`` command. + +For more information, see `Creating CodeQL databases +`__ and +`Analyzing databases with the CodeQL CLI `__. +For detailed guidance about equivalent commands, see `Overview of common commands +<#overview-of-common-commands>`__ below. + +.. _database-compatibiilty-notes: + +Database compatibility notes +---------------------------- + +A CodeQL database created by the CodeQL CLI serves the same purpose as a QL +snapshot created using ``odasa``. They both contain a code database to query and +usually a source reference for results display. However, they are not identical +formats and, if you use the legacy QL tools alongside the CodeQL tools, you need +to be aware of the following: + +* Existing QL snapshots, exported using the legacy CLI, can be used with the new + CodeQL tools. Unzip the snapshot and treat the directory as a database. If it + was built with an earlier version of the legacy CLI, you may need to upgrade + the database using ``codeql database upgrade``. For more information, see the + `database upgrade reference documentation + `__. + +* CodeQL databases are not directly compatible with CodeQL for Eclipse. + However, you can "bundle" a CodeQL database into the equivalent of a QL + exported snapshot by running:: + + codeql database bundle --include-uncompressed-source -o + + The resulting database can be imported into CodeQL for Eclipse. For more + information, see the `database bundle reference documentation `__. + +* .. include:: ../reusables/index-files-note.rst + +* CodeQL databases cannot be directly uploaded to an LGTM Enterprise instance. + For more information, see `Preparing CodeQL databases to upload to LGTM + `__ + in the LGTM admin help. + +Query suites +------------ + +CodeQL includes a new, more flexible, format for query suites. Legacy query +suite definitions are not compatible with the new CodeQL tools. For more +information about CodeQL query suites, see `Creating CodeQL query suites +`__. + +Overview of common commands +--------------------------- + +If you're switching from the legacy ODASA CLI to the new CodeQL CLI, +the table below shows which commands replace the most +common ODASA processes. + ++------------------------------------------+---------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| ``odasa`` command | Corresponding ``codeql`` command | Notes | ++==========================================+===================================================================================================+=========================================================================================================================================================================================================================================================================================================================================================================================================================================================================+ +| ``bootstrap`` | n/a | CodeQL analysis does not use ``project`` files during database creation. For more information about creating databases, see `Creating CodeQL databases `__. | ++------------------------------------------+---------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| ``addSnapshot``, ``addLatestSnapshot`` | n/a | To obtain the version of the code you want to analyze, just run your normal check-out commands. | ++------------------------------------------+---------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| ``buildSnapshot`` | `database create `__ | When creating a CodeQL database, you specfiy build commands in the command line, rather than in a project file. For more information, see `Creating CodeQL databases `__. | ++------------------------------------------+---------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| ``analyzeSnapshot`` | `database analyze `__ | For more information, see `Analyzing databases with the CodeQL CLI `__. | ++------------------------------------------+---------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| ``archiveSnapshot`` | `database cleanup `__ | Use ``database cleanup`` to reduce the size of a CodeQL database by deleting temporary data. | ++------------------------------------------+---------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| ``export`` | `database bundle `__ | You don't need to export databases before adding them to VS Code. However, you should "bundle" CodeQL databases before using them with LGTM Enterprise, CodeQL for Eclipse, or CodeQL for Visual Studio. For more information, see `Preparing CodeQL databases to upload to LGTM `__ in the LGTM admin help and the `Database compatibility notes <#database-compatibility-notes>`__. | ++------------------------------------------+---------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| ``prepareQueries`` | `query compile `__ | Queries are compiled when you run ``database analyze`` and other query-running commands. You can speed up compilation by running ``query compile`` separately using more threads. | ++------------------------------------------+---------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| ``qltest`` | `test run `__ | For more information about running regression tests, see `Testing custom queries `__. | ++------------------------------------------+---------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| ``runQuery`` | `query run `__ | Use ``query run`` to quickly view results in your terminal. To generate interpreted results that can be viewed in source code, use ``database analyze``. | ++------------------------------------------+---------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| ``upgrade`` | `database upgrade `__ | For more information, see `Upgrading CodeQL databases `__. | ++------------------------------------------+---------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ \ No newline at end of file diff --git a/docs/codeql/support/ql-training.rst b/docs/codeql/support/ql-training.rst new file mode 100644 index 00000000000..bb4dc9a3f2e --- /dev/null +++ b/docs/codeql/support/ql-training.rst @@ -0,0 +1,63 @@ +CodeQL training and variant analysis examples +============================================= + +CodeQL and variant analysis +--------------------------- + +Variant analysis is the process of using a known vulnerability as a seed to find similar problems in your code. Security engineers typically perform variant analysis to identify possible vulnerabilities and to ensure that these threats are properly fixed across multiple code bases. + +CodeQL is the code analysis engine that underpins LGTM, the community driven security analysis platform. Together, CodeQL and LGTM provide continuous monitoring and scalable variant analysis for your projects, even if you don’t have your own team of dedicated security engineers. You can read more about using CodeQL and LGTM in variant analysis on the `Security Lab research page `__. + +CodeQL is easy to learn, and exploring code using CodeQL is the most efficient way to perform variant analysis. + +Learning CodeQL for variant analysis +------------------------------------ + +Start learning how to use CodeQL in variant analysis for a specific language by looking at the topics below. Each topic links to a short presentation on CodeQL, its libraries, or an example variant discovered using CodeQL. + +.. |arrow-l| unicode:: U+2190 + +.. |arrow-r| unicode:: U+2192 + +.. |info| unicode:: U+24D8 + +When you have selected a presentation, use |arrow-r| and |arrow-l| to navigate between slides. +Press **p** to view the additional notes on slides that have an information icon |info| in the top right corner, and press **f** to enter full-screen mode. + +The presentations contain a number of query examples. +We recommend that you download `CodeQL for Visual Studio Code `__ and add the example database for each presentation so that you can find the bugs mentioned in the slides. + + +.. pull-quote:: + + Information + + The presentations listed below are used in CodeQL and variant analysis training sessions run by GitHub engineers. + Therefore, be aware that the slides are designed to be presented by an instructor. + If you are using the slides without an instructor, please use the additional notes to help guide you through the examples. + +CodeQL and variant analysis for C/C++ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +- `Introduction to variant analysis: CodeQL for C/C++ `__–an introduction to variant analysis and CodeQL for C/C++ programmers. +- `Example: Bad overflow guard `__–an example of iterative query development to find bad overflow guards in a C++ project. +- `Program representation: CodeQL for C/C++ `__–information on how CodeQL analysis represents C/C++ programs. +- `Introduction to local data flow `__–an introduction to analyzing local data flow in C/C++ using CodeQL, including an example demonstrating how to develop a query to find a real CVE. +- `Exercise: snprintf overflow `__–an example demonstrating how to develop a data flow query. +- `Introduction to global data flow `__–an introduction to analyzing global data flow in C/C++ using CodeQL. +- `Analyzing control flow: CodeQL for C/C++ `__–an introduction to analyzing control flow in C/C++ using CodeQL. + +CodeQL and variant analysis for Java +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +- `Introduction to variant analysis: CodeQL for Java `__–an introduction to variant analysis and CodeQL for Java programmers. +- `Example: Query injection `__–an example of iterative query development to find unsanitized SPARQL injections in a Java project. +- `Program representation: CodeQL for Java `__–information on how CodeQL analysis represents Java programs. +- `Introduction to local data flow `__–an introduction to analyzing local data flow in Java using CodeQL, including an example demonstrating how to develop a query to find a real CVE. +- `Exercise: Apache Struts `__–an example demonstrating how to develop a data flow query. +- `Introduction to global data flow `__–an introduction to analyzing global data flow in Java using CodeQL. + +Further reading +~~~~~~~~~~~~~~~ + +- `GitHub Security Lab `__ \ No newline at end of file diff --git a/docs/codeql/support/reusables/frameworks.rst b/docs/codeql/support/reusables/frameworks.rst index 0eb6b3680bc..867c0cce036 100644 --- a/docs/codeql/support/reusables/frameworks.rst +++ b/docs/codeql/support/reusables/frameworks.rst @@ -27,10 +27,13 @@ Go built-in support :widths: auto Name, Category + Chi, Web framework + Echo, Web framework Gin, Web framework glog, Logging library go-restful, Web application framework go-sh, Utility library + GoKit, Microservice toolkit Gokogiri, XPath library golang.org/x/crypto/ssh, Network communicator golang.org/x/net/websocket, Network communicator @@ -51,6 +54,9 @@ Go built-in support mux, HTTP request router and dispatcher nhooyr.io/websocket, Network communicator pg, Database + proto, Serialization + Revel, Web framework + Spew, Logging library sqlx, Database SendGrid, Email library Squirrel, Database diff --git a/docs/codeql/support/reusables/versions-compilers.rst b/docs/codeql/support/reusables/versions-compilers.rst index 9de6af6aa60..39e30bbc7cb 100644 --- a/docs/codeql/support/reusables/versions-compilers.rst +++ b/docs/codeql/support/reusables/versions-compilers.rst @@ -15,7 +15,7 @@ .NET Core up to 3.1","``.sln``, ``.csproj``, ``.cs``, ``.cshtml``, ``.xaml``" Go (aka Golang), "Go up to 1.15", "Go 1.11 or more recent", ``.go`` - Java,"Java 6 to 14 [3]_","javac (OpenJDK and Oracle JDK), + Java,"Java 7 to 15 [3]_","javac (OpenJDK and Oracle JDK), Eclipse compiler for Java (ECJ) [4]_",``.java`` JavaScript,ECMAScript 2019 or lower,Not applicable,"``.js``, ``.jsx``, ``.mjs``, ``.es``, ``.es6``, ``.htm``, ``.html``, ``.xhm``, ``.xhtml``, ``.vue``, ``.json``, ``.yaml``, ``.yml``, ``.raml``, ``.xml`` [5]_" @@ -26,7 +26,7 @@ .. [1] Support for the clang-cl compiler is preliminary. .. [2] Support for the Arm Compiler (armcc) is preliminary. - .. [3] Builds that execute on Java 6 to 14 can be analyzed. The analysis understands Java 14 standard language features. + .. [3] Builds that execute on Java 7 to 15 can be analyzed. The analysis understands Java 15 standard language features. .. [4] ECJ is supported when the build invokes it via the Maven Compiler plugin or the Takari Lifecycle plugin. .. [5] JSX and Flow code, YAML, JSON, HTML, and XML files may also be analyzed with JavaScript files. .. [6] TypeScript analysis is performed by running the JavaScript extractor with TypeScript enabled. This is the default for LGTM. diff --git a/docs/codeql/writing-codeql-queries/codeql-queries/about-codeql-queries.rst b/docs/codeql/writing-codeql-queries/about-codeql-queries.rst similarity index 93% rename from docs/codeql/writing-codeql-queries/codeql-queries/about-codeql-queries.rst rename to docs/codeql/writing-codeql-queries/about-codeql-queries.rst index 24b68a0ad28..171d2596b3f 100644 --- a/docs/codeql/writing-codeql-queries/codeql-queries/about-codeql-queries.rst +++ b/docs/codeql/writing-codeql-queries/about-codeql-queries.rst @@ -13,7 +13,7 @@ CodeQL includes queries to find the most relevant and interesting problems for e - **Alert queries**: queries that highlight issues in specific locations in your code. - **Path queries**: queries that describe the flow of information between a source and a sink in your code. -You can add custom queries to `custom query packs `__ to analyze your projects in `LGTM `__, use them to analyze a database with the ":ref:`CodeQL CLI `," or you can contribute to the standard CodeQL queries in our `open source repository on GitHub `__. +You can add custom queries to :doc:`QL packs <../codeql-cli/about-ql-packs>` to analyze your projects with "`Code scanning `__", use them to analyze a database with the ":ref:`CodeQL CLI `," or you can contribute to the standard CodeQL queries in our `open source repository on GitHub `__. This topic is a basic introduction to query files. You can find more information on writing queries for specific programming languages in the ":ref:`CodeQL language guides `," and detailed technical information about QL in the ":ref:`QL language reference `." For more information on how to format your code when contributing queries to the GitHub repository, see the `CodeQL style guide `__. @@ -21,7 +21,9 @@ For more information on how to format your code when contributing queries to the Basic query structure ********************* -:ref:`Queries ` written with CodeQL have the file extension ``.ql``, and contain a ``select`` clause. Many of the existing queries include additional optional information, and have the following structure:: +:ref:`Queries ` written with CodeQL have the file extension ``.ql``, and contain a ``select`` clause. Many of the existing queries include additional optional information, and have the following structure: + +.. code-block:: ql /** * @@ -77,7 +79,7 @@ When writing your own alert queries, you would typically import the standard lib There are also libraries containing commonly used predicates, types, and other modules associated with different analyses, including data flow, control flow, and taint-tracking. In order to calculate path graphs, path queries require you to import a data flow library into the query file. For more information, see ":doc:`Creating path queries `." -You can explore the contents of all the standard libraries in the `CodeQL library reference documentation `__ or in the `GitHub repository `__. +You can explore the contents of all the standard libraries in the `CodeQL library reference documentation `__ or in the `GitHub repository `__. Optional CodeQL classes and predicates -------------------------------------- @@ -117,7 +119,7 @@ Viewing the standard CodeQL queries One of the easiest ways to get started writing your own queries is to modify an existing query. To view the standard CodeQL queries, or to try out other examples, visit the `CodeQL `__ and `CodeQL for Go `__ repositories on GitHub. -You can also find examples of queries developed to find security vulnerabilities and bugs in open source software projects on the `GitHub Security Lab website `__ and in the associated `repository `__. +You can also find examples of queries developed to find security vulnerabilities and bugs in open source software projects on the `GitHub Security Lab website `__ and in the associated `repository `__. Contributing queries ******************** diff --git a/docs/codeql/writing-codeql-queries/codeql-queries/about-data-flow-analysis.rst b/docs/codeql/writing-codeql-queries/about-data-flow-analysis.rst similarity index 97% rename from docs/codeql/writing-codeql-queries/codeql-queries/about-data-flow-analysis.rst rename to docs/codeql/writing-codeql-queries/about-data-flow-analysis.rst index 2b349c9adf6..71fd639069e 100644 --- a/docs/codeql/writing-codeql-queries/codeql-queries/about-data-flow-analysis.rst +++ b/docs/codeql/writing-codeql-queries/about-data-flow-analysis.rst @@ -19,7 +19,7 @@ See the following tutorials for more information about analyzing data flow in sp - ":ref:`Analyzing data flow in C/C++ `" - ":ref:`Analyzing data flow in C# `" - ":ref:`Analyzing data flow in Java `" -- ":ref:`Analyzing data flow in JavaScript/TypeScript `" +- ":ref:`Analyzing data flow in JavaScript/TypeScript `" - ":ref:`Analyzing data flow and tracking tainted data in Python `" .. pull-quote:: @@ -67,7 +67,7 @@ To overcome these potential problems, two kinds of data flow are modeled in the - Global data flow, effectively considers the data flow within an entire program, by calculating data flow between functions and through object properties. Computing global data flow is typically more time and energy intensive than local data flow, therefore queries should be refined to look for more specific sources and sinks. -Many CodeQL queries contain examples of both local and global data flow analysis. See `the built-in queries `__ for details. +Many CodeQL queries contain examples of both local and global data flow analysis. For more information, see `CodeQL query help `__. Normal data flow vs taint tracking ********************************** diff --git a/docs/codeql/writing-codeql-queries/ql-tutorials/catch-the-fire-starter.rst b/docs/codeql/writing-codeql-queries/catch-the-fire-starter.rst similarity index 99% rename from docs/codeql/writing-codeql-queries/ql-tutorials/catch-the-fire-starter.rst rename to docs/codeql/writing-codeql-queries/catch-the-fire-starter.rst index 0f40ba87a9a..60840e8bc9f 100644 --- a/docs/codeql/writing-codeql-queries/ql-tutorials/catch-the-fire-starter.rst +++ b/docs/codeql/writing-codeql-queries/catch-the-fire-starter.rst @@ -149,4 +149,4 @@ You have found the two fire starters! They are arrested and the villagers are on Further reading --------------- -.. include:: ../../reusables/codeql-ref-tools-further-reading.rst +.. include:: ../reusables/codeql-ref-tools-further-reading.rst diff --git a/docs/codeql/writing-codeql-queries/codeql-queries/index.rst b/docs/codeql/writing-codeql-queries/codeql-queries.rst similarity index 100% rename from docs/codeql/writing-codeql-queries/codeql-queries/index.rst rename to docs/codeql/writing-codeql-queries/codeql-queries.rst diff --git a/docs/codeql/writing-codeql-queries/codeql-queries/creating-path-queries.rst b/docs/codeql/writing-codeql-queries/creating-path-queries.rst similarity index 89% rename from docs/codeql/writing-codeql-queries/codeql-queries/creating-path-queries.rst rename to docs/codeql/writing-codeql-queries/creating-path-queries.rst index 74e512d43c1..9b15b6ed4cb 100644 --- a/docs/codeql/writing-codeql-queries/codeql-queries/creating-path-queries.rst +++ b/docs/codeql/writing-codeql-queries/creating-path-queries.rst @@ -27,20 +27,14 @@ For more language-specific information on analyzing data flow, see: - ":ref:`Analyzing data flow in C/C++ `" - ":ref:`Analyzing data flow in C# `" - ":ref:`Analyzing data flow in Java `" -- ":ref:`Analyzing data flow in JavaScript/TypeScript `" +- ":ref:`Analyzing data flow in JavaScript/TypeScript `" - ":ref:`Analyzing data flow and tracking tainted data in Python `" Path query examples ******************* -The easiest way to get started writing your own path query is to modify one of the existing queries. Visit the links below to see all the built-in path queries: - -- `C/C++ path queries `__ -- `C# path queries `__ -- `Java path queries `__ -- `JavaScript path queries `__ -- `Python path queries `__ +The easiest way to get started writing your own path query is to modify one of the existing queries. For more information, see the `CodeQL query help `__. The Security Lab researchers have used path queries to find security vulnerabilities in various open source projects. To see articles describing how these queries were written, as well as other posts describing other aspects of security research such as exploiting vulnerabilities, see the `GitHub Security Lab website `__. @@ -50,7 +44,9 @@ Constructing a path query Path queries require certain metadata, query predicates, and ``select`` statement structures. Many of the built-in path queries included in CodeQL follow a simple structure, which depends on how the language you are analyzing is modeled with CodeQL. -For C/C++, C#, Java, and JavaScript you should use the following template:: +For C/C++, C#, Java, and JavaScript you should use the following template: + +.. code-block:: ql /** * ... @@ -58,7 +54,7 @@ For C/C++, C#, Java, and JavaScript you should use the following template:: * ... */ - import + import import DataFlow::PathGraph ... @@ -72,7 +68,9 @@ Where: - ``source`` and ``sink`` are nodes on the `path graph `__, and ``DataFlow::PathNode`` is their type. - ``Configuration`` is a class containing the predicates which define how data may flow between the ``source`` and the ``sink``. -For Python you should use a slightly different template:: +For Python you should use a slightly different template: + +.. code-block:: ql /** * ... @@ -110,30 +108,36 @@ To do this you need to define a :ref:`query predicate ` called This predicate defines the edge relations of the graph you are computing, and it is used to compute the paths related to each result that your query generates. You can import a predefined ``edges`` predicate from a path graph module in one of the standard data flow libraries. In addition to the path graph module, the data flow libraries contain the other ``classes``, ``predicates``, and ``modules`` that are commonly used in data flow analysis. The import statement to use depends on the language that you are analyzing. -For C/C++, C#, Java, and JavaScript you would use:: +For C/C++, C#, Java, and JavaScript you would use: + +.. code-block:: ql import DataFlow::PathGraph This statement imports the ``PathGraph`` module from the data flow library (``DataFlow.qll``), in which ``edges`` is defined. -For Python, the ``Paths`` module contains the ``edges`` predicate:: +For Python, the ``Paths`` module contains the ``edges`` predicate: + +.. code-block:: ql import semmle.python.security.Paths -You can also import libraries specifically designed to implement data flow analysis in various common frameworks and environments, and many additional libraries are included with CodeQL. To see examples of the different libraries used in data flow analysis, see the links to the built-in queries above or browse the `standard libraries `__. +You can also import libraries specifically designed to implement data flow analysis in various common frameworks and environments, and many additional libraries are included with CodeQL. To see examples of the different libraries used in data flow analysis, see the links to the built-in queries above or browse the `standard libraries `__. For all languages, you can also optionally define a ``nodes`` query predicate, which specifies the nodes of the path graph that you are interested in. If ``nodes`` is defined, only edges with endpoints defined by these nodes are selected. If ``nodes`` is not defined, you select all possible endpoints of ``edges``. Defining your own ``edges`` predicate ------------------------------------- -You can also define your own ``edges`` predicate in the body of your query. It should take the following form:: +You can also define your own ``edges`` predicate in the body of your query. It should take the following form: + +.. code-block:: ql query predicate edges(PathNode a, PathNode b) { /** Logical conditions which hold if `(a,b)` is an edge in the data flow graph */ } -For more examples of how to define an ``edges`` predicate, visit the `standard CodeQL libraries `__ and search for ``edges``. +For more examples of how to define an ``edges`` predicate, visit the `standard CodeQL libraries `__ and search for ``edges``. Declaring sources and sinks *************************** @@ -142,7 +146,9 @@ You must provide information about the ``source`` and ``sink`` in your path quer The name and the type of the ``source`` and the ``sink`` must be declared in the ``from`` statement of the query, and the types must be compatible with the nodes of the graph computed by the ``edges`` predicate. If you are querying C/C++, C#, Java, or JavaScript code (and you have used ``import DataFlow::PathGraph`` in your query), the definitions of the ``source`` and ``sink`` are accessed via the ``Configuration`` class in the data flow library. You should declare all three of these objects in the ``from`` statement. -For example:: +For example: + +.. code-block:: ql from Configuration config, DataFlow::PathNode source, DataFlow::PathNode sink @@ -155,11 +161,13 @@ For more information on using the configuration class in your analysis see the s You can also create a configuration for different frameworks and environments by extending the ``Configuration`` class. For more information, see ":ref:`Types `" in the QL language reference. -If you are querying Python code (and you have used ``import semmle.python.security.Paths`` in your query) you should declare ``TaintedPathSource source, TaintedPathSink sink`` in your ``from`` statement. You do not need to declare a ``Configuration`` class as the definitions of the ``TaintedPathSource`` and ``TaintedPathSink`` contain all of the type information that is required:: +If you are querying Python code (and you have used ``import semmle.python.security.Paths`` in your query) you should declare ``TaintedPathSource source, TaintedPathSink sink`` in your ``from`` statement. You do not need to declare a ``Configuration`` class as the definitions of the ``TaintedPathSource`` and ``TaintedPathSink`` contain all of the type information that is required: + +.. code-block:: ql from TaintedPathSource source, TaintedPathSink sink -You can extend your query by adding different sources and sinks by either defining them in the query, or by importing predefined sources and sinks for specific frameworks and libraries. See the `Python path queries `__ for further details. +You can extend your query by adding different sources and sinks by either defining them in the query, or by importing predefined sources and sinks for specific frameworks and libraries. For more information, see the `CodeQL query help for Python `__. Defining flow conditions ************************ @@ -169,11 +177,15 @@ This clause can use :ref:`aggregations `, :ref:`predicates `. *Show/hide code* .. literalinclude:: river-crossing-1.ql + :language: ql :lines: 33-40,87 We are interested in two particular states, namely the initial state and the goal state, @@ -94,6 +97,7 @@ Assuming that all items start on the left shore and end up on the right shore, d *Show/hide code* .. literalinclude:: river-crossing-1.ql + :language: ql :lines: 89-97 .. pull-quote:: @@ -112,6 +116,7 @@ Using the above note, the QL code so far looks like this: *Show/hide code* .. literalinclude:: river-crossing.ql + :language: ql :lines: 15-52,103-113 Model the action of "ferrying" @@ -130,6 +135,7 @@ after ferrying a particular cargo. (Hint: Use the predicate ``other``.) *Show/hide code* .. literalinclude:: river-crossing.ql + :language: ql :lines: 54-67 Of course, not all ferrying actions are possible. Add some extra conditions to describe when a ferrying @@ -147,6 +153,7 @@ For example, follow these steps: *Show/hide code* .. literalinclude:: river-crossing.ql + :language: ql :lines: 69-81 Find paths from one state to another @@ -185,6 +192,7 @@ for example ``steps <= 7``. *Show/hide code* .. literalinclude:: river-crossing-1.ql + :language: ql :lines: 70-86 However, although this ensures that the solution is finite, it can still contain loops if the upper bound @@ -205,7 +213,7 @@ the given path without revisiting any previously visited states. revisiting any previous states, and there is a ``safeFerry`` action from the intermediate state to the result state. (Hint: To check whether a state has previously been visited, you could check if - there is an `index of `__ + there is an `index of `__ ``visitedStates`` at which the state occurs.) .. container:: toggle @@ -215,6 +223,7 @@ the given path without revisiting any previously visited states. *Show/hide code* .. literalinclude:: river-crossing.ql + :language: ql :lines: 83-102 Display the results @@ -230,6 +239,7 @@ that returns the resulting path. *Show/hide code* .. literalinclude:: river-crossing.ql + :language: ql :lines: 115-117 The :ref:`don't-care expression ` (``_``), @@ -269,4 +279,4 @@ Here are some more example queries that solve the river crossing puzzle: Further reading --------------- -.. include:: ../../reusables/codeql-ref-tools-further-reading.rst +.. include:: ../reusables/codeql-ref-tools-further-reading.rst diff --git a/docs/codeql/writing-codeql-queries/ql-tutorials/crown-the-rightful-heir.rst b/docs/codeql/writing-codeql-queries/crown-the-rightful-heir.rst similarity index 99% rename from docs/codeql/writing-codeql-queries/ql-tutorials/crown-the-rightful-heir.rst rename to docs/codeql/writing-codeql-queries/crown-the-rightful-heir.rst index 9e987d7635d..a9a8ace0775 100644 --- a/docs/codeql/writing-codeql-queries/ql-tutorials/crown-the-rightful-heir.rst +++ b/docs/codeql/writing-codeql-queries/crown-the-rightful-heir.rst @@ -163,4 +163,4 @@ You could also try writing more of your own QL queries to find interesting facts Further reading --------------- -.. include:: ../../reusables/codeql-ref-tools-further-reading.rst +.. include:: ../reusables/codeql-ref-tools-further-reading.rst diff --git a/docs/codeql/writing-codeql-queries/codeql-queries/defining-the-results-of-a-query.rst b/docs/codeql/writing-codeql-queries/defining-the-results-of-a-query.rst similarity index 97% rename from docs/codeql/writing-codeql-queries/codeql-queries/defining-the-results-of-a-query.rst rename to docs/codeql/writing-codeql-queries/defining-the-results-of-a-query.rst index 347bb66576d..9b17b257ac9 100644 --- a/docs/codeql/writing-codeql-queries/codeql-queries/defining-the-results-of-a-query.rst +++ b/docs/codeql/writing-codeql-queries/defining-the-results-of-a-query.rst @@ -53,7 +53,7 @@ This basic select statement has two columns: #. Element to display the alert on: ``f`` corresponds to ``File``. #. String message to display: ``"This file is similar to another file."`` -.. image:: ../../images/ql-select-statement-basic.png +.. image:: ../images/ql-select-statement-basic.png :alt: Results of basic select statement :class: border @@ -69,7 +69,7 @@ The alert message defined by the basic select statement is constant and doesn't #. Element: ``f`` as before. #. String message: ``"This file is similar to "``—the string text is combined with the file name for the ``other``, similar file, returned by ``getBaseName()``. -.. image:: ../../images/ql-select-statement-filename.png +.. image:: ../images/ql-select-statement-filename.png :alt: Results of extended select statement :class: border @@ -104,7 +104,7 @@ You could go further and change the ``select`` statement to report on the simila The new elements added here don't need to be clickable, so we added them directly to the description string. -.. image:: ../../images/ql-select-statement-similarity.png +.. image:: ../images/ql-select-statement-similarity.png :alt: Results showing the extent of similarity :class: border diff --git a/docs/codeql/writing-codeql-queries/ql-tutorials/find-the-thief.rst b/docs/codeql/writing-codeql-queries/find-the-thief.rst similarity index 99% rename from docs/codeql/writing-codeql-queries/ql-tutorials/find-the-thief.rst rename to docs/codeql/writing-codeql-queries/find-the-thief.rst index c4ae5679ce1..131423b8058 100644 --- a/docs/codeql/writing-codeql-queries/ql-tutorials/find-the-thief.rst +++ b/docs/codeql/writing-codeql-queries/find-the-thief.rst @@ -50,7 +50,7 @@ There is too much information to search through by hand, so you decide to use yo #. Open the `query console on LGTM.com `__ to get started. #. Select a language and a demo project. For this tutorial, any language and project will do. -#. Delete the default code ``import select "hello world"``. +#. Delete the default code ``import select "hello world"``. QL libraries ------------ @@ -294,4 +294,4 @@ Have you found the thief? Further reading --------------- -.. include:: ../../reusables/codeql-ref-tools-further-reading.rst +.. include:: ../reusables/codeql-ref-tools-further-reading.rst diff --git a/docs/codeql/writing-codeql-queries/index.rst b/docs/codeql/writing-codeql-queries/index.rst index fd63abd9c78..0459156a49b 100644 --- a/docs/codeql/writing-codeql-queries/index.rst +++ b/docs/codeql/writing-codeql-queries/index.rst @@ -3,7 +3,14 @@ Writing CodeQL queries ====================== -.. toctree:: +Get to know more about queries and learn some key query-writing skills by solving puzzles. - ql-tutorials/index - codeql-queries/index \ No newline at end of file +- :ref:`CodeQL queries `: CodeQL queries are used in code scanning analyses to find problems in source code, including potential security vulnerabilities. + +- :ref:`QL tutorials `: Solve puzzles to learn the basics of QL before you analyze code with CodeQL. The tutorials teach you how to write queries and introduce you to key logic concepts along the way. + +.. toctree:: + :hidden: + + codeql-queries + ql-tutorials diff --git a/docs/codeql/writing-codeql-queries/ql-tutorials/introduction-to-ql.rst b/docs/codeql/writing-codeql-queries/introduction-to-ql.rst similarity index 95% rename from docs/codeql/writing-codeql-queries/ql-tutorials/introduction-to-ql.rst rename to docs/codeql/writing-codeql-queries/introduction-to-ql.rst index 8bf5e9b2d91..83006046c14 100644 --- a/docs/codeql/writing-codeql-queries/ql-tutorials/introduction-to-ql.rst +++ b/docs/codeql/writing-codeql-queries/introduction-to-ql.rst @@ -23,7 +23,7 @@ Once you have selected a language, the query console is populated with the query .. code-block:: ql - import + import select "hello world" @@ -55,7 +55,7 @@ You can write simple queries using the some of the basic functions that are avai Exercise 1 ~~~~~~~~~~ -Write a query which returns the length of the string ``"lgtm"``. (Hint: `here `__ is the list of the functions that can be applied to strings.) +Write a query which returns the length of the string ``"lgtm"``. (Hint: `here `__ is the list of the functions that can be applied to strings.) ➤ `See answer in the query console on LGTM.com `__ @@ -124,7 +124,7 @@ The following example queries *do* use these databases and give you an idea of h Queries using the CodeQL libraries can find errors and uncover variants of important security vulnerabilities in codebases. Visit `GitHub Security Lab `__ to read about examples of vulnerabilities that we have recently found in open source projects. -To import the CodeQL library for a specific programming language, type ``import `` at the start of the query. +To import the CodeQL library for a specific programming language, type ``import `` at the start of the query. .. code-block:: ql diff --git a/docs/codeql/writing-codeql-queries/codeql-queries/metadata-for-codeql-queries.rst b/docs/codeql/writing-codeql-queries/metadata-for-codeql-queries.rst similarity index 98% rename from docs/codeql/writing-codeql-queries/codeql-queries/metadata-for-codeql-queries.rst rename to docs/codeql/writing-codeql-queries/metadata-for-codeql-queries.rst index fc00f63216a..93e164ac8ed 100644 --- a/docs/codeql/writing-codeql-queries/codeql-queries/metadata-for-codeql-queries.rst +++ b/docs/codeql/writing-codeql-queries/metadata-for-codeql-queries.rst @@ -8,7 +8,7 @@ Metadata tells users important information about CodeQL queries. You must includ About query metadata -------------------- -Any query that is run as part of an analysis includes a number of properties, known as query metadata. Metadata is included at the top of each query file as the content of a :ref:`QLDoc ` comment. +Any query that is run as part of an analysis includes a number of properties, known as query metadata. Metadata is included at the top of each query file as the content of a QLDoc comment. This metadata tells LGTM and the CodeQL :ref:`extension for VS Code ` how to handle the query and display its results correctly. It also gives other users information about what the query results mean. For more information on query metadata, see the `query metadata style guide `__ in our `open source repository `__ on GitHub. @@ -28,7 +28,7 @@ The following properties are supported by all query files: +=======================+===========================+=======================================================================================================================================================================================================================================================================================================================================================================+ | ``@description`` | ```` | A sentence or short paragraph to describe the purpose of the query and *why* the result is useful or important. The description is written in plain text, and uses single quotes (``'``) to enclose code elements. | +-----------------------+---------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| ``@id`` | ```` | A sequence of words composed of lowercase letters or digits, delimited by ``/`` or ``-``, identifying and classifying the query. Each query must have a **unique** ID. To ensure this, it may be helpful to use a fixed structure for each ID. For example, the standard LGTM queries have the following format: ``/``. | +| ``@id`` | ```` | A sequence of words composed of lowercase letters or digits, delimited by ``/`` or ``-``, identifying and classifying the query. Each query must have a **unique** ID. To ensure this, it may be helpful to use a fixed structure for each ID. For example, the standard LGTM queries have the following format: ``/``. | +-----------------------+---------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | ``@kind`` | | ``problem`` | Identifies the query is an alert (``@kind problem``) or a path (``@kind path-problem``). For more information on these query types, see ":doc:`About CodeQL queries `." | | | | ``path-problem`` | | @@ -62,6 +62,6 @@ Here is the metadata for one of the standard Java queries: |image0| -.. |image0| image:: ../../images/query-metadata.png +.. |image0| image:: ../images/query-metadata.png For more examples of query metadata, see the standard CodeQL queries in our `GitHub repository `__. diff --git a/docs/codeql/writing-codeql-queries/codeql-queries/providing-locations-in-codeql-queries.rst b/docs/codeql/writing-codeql-queries/providing-locations-in-codeql-queries.rst similarity index 100% rename from docs/codeql/writing-codeql-queries/codeql-queries/providing-locations-in-codeql-queries.rst rename to docs/codeql/writing-codeql-queries/providing-locations-in-codeql-queries.rst diff --git a/docs/codeql/writing-codeql-queries/ql-tutorials/index.rst b/docs/codeql/writing-codeql-queries/ql-tutorials.rst similarity index 100% rename from docs/codeql/writing-codeql-queries/ql-tutorials/index.rst rename to docs/codeql/writing-codeql-queries/ql-tutorials.rst diff --git a/docs/codeql/writing-codeql-queries/codeql-queries/query-help-files.rst b/docs/codeql/writing-codeql-queries/query-help-files.rst similarity index 99% rename from docs/codeql/writing-codeql-queries/codeql-queries/query-help-files.rst rename to docs/codeql/writing-codeql-queries/query-help-files.rst index fd0dd7bea4f..093915d050b 100644 --- a/docs/codeql/writing-codeql-queries/codeql-queries/query-help-files.rst +++ b/docs/codeql/writing-codeql-queries/query-help-files.rst @@ -13,7 +13,7 @@ For more information about how to write useful query help in a style that is con Note - You can access the query help for CodeQL queries by visiting the `Built-in query pages `__. + You can access the query help for CodeQL queries by visiting `CodeQL query help `__. You can also access the raw query help files in the `GitHub repository `__. For example, see the `JavaScript security queries `__ and `C/C++ critical queries `__. diff --git a/docs/codeql/writing-codeql-queries/ql-tutorials/river-crossing-1.ql b/docs/codeql/writing-codeql-queries/river-crossing-1.ql similarity index 100% rename from docs/codeql/writing-codeql-queries/ql-tutorials/river-crossing-1.ql rename to docs/codeql/writing-codeql-queries/river-crossing-1.ql diff --git a/docs/codeql/writing-codeql-queries/ql-tutorials/river-crossing.ql b/docs/codeql/writing-codeql-queries/river-crossing.ql similarity index 100% rename from docs/codeql/writing-codeql-queries/ql-tutorials/river-crossing.ql rename to docs/codeql/writing-codeql-queries/river-crossing.ql diff --git a/docs/codeql/writing-codeql-queries/codeql-queries/troubleshooting-query-performance.rst b/docs/codeql/writing-codeql-queries/troubleshooting-query-performance.rst similarity index 94% rename from docs/codeql/writing-codeql-queries/codeql-queries/troubleshooting-query-performance.rst rename to docs/codeql/writing-codeql-queries/troubleshooting-query-performance.rst index ebe0d24d876..41f5883e0b7 100644 --- a/docs/codeql/writing-codeql-queries/codeql-queries/troubleshooting-query-performance.rst +++ b/docs/codeql/writing-codeql-queries/troubleshooting-query-performance.rst @@ -27,7 +27,9 @@ The performance of a predicate can often be judged by considering roughly how ma One way of creating badly performing predicates is by using two variables without relating them in any way, or only relating them using a negation. This leads to computing the `Cartesian product `__ between the sets of possible values for each variable, potentially generating a huge table of results. This can occur if you don't specify restrictions on your variables. -For instance, consider the following predicate that checks whether a Java method ``m`` may access a field ``f``:: +For instance, consider the following predicate that checks whether a Java method ``m`` may access a field ``f``: + +.. code-block:: ql predicate mayAccess(Method m, Field f) { f.getAnAccess().getEnclosingCallable() = m @@ -39,7 +41,9 @@ The predicate holds if ``m`` contains an access to ``f``, but also conservativel However, if ``m`` is a native method, the table computed by ``mayAccess`` will contain a row ``m, f`` for *all* fields ``f`` in the codebase, making it potentially very large. -This example shows a similar mistake in a member predicate:: +This example shows a similar mistake in a member predicate: + +.. code-block:: ql class Foo extends Class { ... @@ -57,11 +61,15 @@ Use specific types ~~~~~~~~~~~~~~~~~~ ":ref:`Types `" provide an upper bound on the size of a relation. -This helps the query optimizer be more effective, so it's generally good to use the most specific types possible. For example:: +This helps the query optimizer be more effective, so it's generally good to use the most specific types possible. For example: + +.. code-block:: ql predicate foo(LoggingCall e) -is preferred over:: +is preferred over: + +.. code-block:: ql predicate foo(Expr e) @@ -95,7 +103,9 @@ Avoid complex recursion ":ref:`Recursion `" is about self-referencing definitions. It can be extremely powerful as long as it is used appropriately. On the whole, you should try to make recursive predicates as simple as possible. -That is, you should define a *base case* that allows the predicate to *bottom out*, along with a single *recursive call*:: +That is, you should define a *base case* that allows the predicate to *bottom out*, along with a single *recursive call*: + +.. code-block:: ql int depth(Stmt s) { exists(Callable c | c.getBody() = s | result = 0) // base case @@ -153,4 +163,4 @@ Now the structure we want is clearer. We've separated out the easy part into its Further reading --------------- -.. include:: ../../reusables/codeql-ref-tools-further-reading.rst +.. include:: ../reusables/codeql-ref-tools-further-reading.rst diff --git a/docs/pre-commit-hook-setup.md b/docs/pre-commit-hook-setup.md new file mode 100644 index 00000000000..9927acba85c --- /dev/null +++ b/docs/pre-commit-hook-setup.md @@ -0,0 +1,16 @@ +# CodeQL pre-commit-hook setup + +As stated in [CONTRIBUTING](../CONTRIBUTING.md) all CodeQL files must be formatted according to our [CodeQL style guide](ql-style-guide.md). You can use our pre-commit hook to avoid committing incorrectly formatted code. To use it, simply copy the [pre-commit](../misc/scripts/pre-commit) script to `.git/hooks/pre-commit` and make sure that: + +- The script is executable. On Linux and macOS this can be done using `chmod +x`. +- The CodeQL CLI has been added to your `PATH`. + +The script will abort a commit that contains incorrectly formatted code in .ql or .qll files and print an error message like: + +``` +> git commit -m "My commit." +ql/cpp/ql/src/Options.qll would change by autoformatting. +ql/cpp/ql/src/printAst.ql would change by autoformatting. +``` + +If you prefer to have the script automatically format the code (and not abort the commit), you can replace the line `codeql query format --check-only` with `codeql query format --in-place` (and `exit $exitVal` with `exit 0`). diff --git a/docs/qldoc-style-guide.md b/docs/qldoc-style-guide.md index 79871ae8d9f..fde4d3ea2f8 100644 --- a/docs/qldoc-style-guide.md +++ b/docs/qldoc-style-guide.md @@ -6,7 +6,7 @@ Valid QL comments are known as QLDoc. This document describes the recommended st ### General requirements -1. Documentation must adhere to the [QLDoc specification](https://help.semmle.com/QL/ql-handbook/qldoc.html). +1. Documentation must adhere to the [QLDoc specification](https://codeql.github.com/docs/ql-language-reference/ql-language-specification/#qldoc). 1. Documentation comments should be appropriate for users of the code. 1. Documentation for maintainers of the code must use normal comments. 1. Use `/** ... */` for documentation, even for single line comments. diff --git a/docs/query-metadata-style-guide.md b/docs/query-metadata-style-guide.md index e029339c1af..21e5897e243 100644 --- a/docs/query-metadata-style-guide.md +++ b/docs/query-metadata-style-guide.md @@ -26,7 +26,7 @@ For examples of query files for the languages supported by CodeQL, visit the fol ## Metadata area -Query file metadata contains important information that defines the identifier and purpose of the query. The metadata is included as the content of a valid [QLDoc](https://help.semmle.com/QL/ql-handbook/qldoc.html) comment, on lines with leading whitespace followed by `*`, between an initial `/**` and a trailing `*/`. For example: +Query file metadata contains important information that defines the identifier and purpose of the query. The metadata is included as the content of a valid [QLDoc](https://codeql.github.com/docs/ql-language-reference/ql-language-specification/#qldoc) comment, on lines with leading whitespace followed by `*`, between an initial `/**` and a trailing `*/`. For example: ``` /** diff --git a/java/change-notes/2020-12-09-xxe-fp-fix.md b/java/change-notes/2020-12-09-xxe-fp-fix.md new file mode 100644 index 00000000000..2ccf4bf369a --- /dev/null +++ b/java/change-notes/2020-12-09-xxe-fp-fix.md @@ -0,0 +1,4 @@ +lgtm,codescanning +* The query "Resolving XML external entity in user-controlled data" (`java/xxe`) has been improved to report fewer false positives when a `SAXParserFactory` is configured safely. + + diff --git a/java/change-notes/2021-01-12-unsafe-hostname-verification.md b/java/change-notes/2021-01-12-unsafe-hostname-verification.md new file mode 100644 index 00000000000..6da83c2509e --- /dev/null +++ b/java/change-notes/2021-01-12-unsafe-hostname-verification.md @@ -0,0 +1,4 @@ +lgtm,codescanning +* A new query "Unsafe hostname verification" + (`java/unsafe-hostname-verification`) has been added. This query finds unsafe + `HostnameVerifier`s that allow man-in-the-middle attacks. diff --git a/java/change-notes/2021-01-14-java-15-support.md b/java/change-notes/2021-01-14-java-15-support.md new file mode 100644 index 00000000000..44f07c865d8 --- /dev/null +++ b/java/change-notes/2021-01-14-java-15-support.md @@ -0,0 +1,2 @@ +lgtm,codescanning +* The Java extractor has been upgraded to support Java 15. diff --git a/java/change-notes/2021-01-19-struts-xml-extraction.md b/java/change-notes/2021-01-19-struts-xml-extraction.md new file mode 100644 index 00000000000..ce0ff2f30c2 --- /dev/null +++ b/java/change-notes/2021-01-19-struts-xml-extraction.md @@ -0,0 +1,2 @@ +lgtm,codescanning +* XML files named `struts.xml` are now extracted by default. diff --git a/java/change-notes/2021-02-15-commons-array-utils.md b/java/change-notes/2021-02-15-commons-array-utils.md new file mode 100644 index 00000000000..a689a08e98c --- /dev/null +++ b/java/change-notes/2021-02-15-commons-array-utils.md @@ -0,0 +1,2 @@ +lgtm,codescanning +* Added support for the Apache Commons Lang ArrayUtils library. diff --git a/java/change-notes/2021-02-15-snakeyaml-fn-fix.md b/java/change-notes/2021-02-15-snakeyaml-fn-fix.md new file mode 100644 index 00000000000..ed08bdfe8c6 --- /dev/null +++ b/java/change-notes/2021-02-15-snakeyaml-fn-fix.md @@ -0,0 +1,5 @@ +lgtm,codescanning +* The query "Unsafe Deserialization" (`java/unsafe-deserialization`) has been + improved to report those cases where SnakeYaml `Constructor` is used to fix + the unmarshaled object graph root's type but injection is still possible in + nested nodes of the object graph. diff --git a/java/ql/src/Security/CWE/CWE-297/UnsafeHostnameVerification.java b/java/ql/src/Security/CWE/CWE-297/UnsafeHostnameVerification.java new file mode 100644 index 00000000000..f50424b96c4 --- /dev/null +++ b/java/ql/src/Security/CWE/CWE-297/UnsafeHostnameVerification.java @@ -0,0 +1,30 @@ +public static void main(String[] args) { + + { + HostnameVerifier verifier = new HostnameVerifier() { + @Override + public boolean verify(String hostname, SSLSession session) { + return true; // BAD: accept even if the hostname doesn't match + } + }; + HttpsURLConnection.setDefaultHostnameVerifier(verifier); + } + + { + HostnameVerifier verifier = new HostnameVerifier() { + @Override + public boolean verify(String hostname, SSLSession session) { + try { // GOOD: verify the certificate + Certificate[] certs = session.getPeerCertificates(); + X509Certificate x509 = (X509Certificate) certs[0]; + check(new String[]{host}, x509); + return true; + } catch (SSLException e) { + return false; + } + } + }; + HttpsURLConnection.setDefaultHostnameVerifier(verifier); + } + +} \ No newline at end of file diff --git a/java/ql/src/Security/CWE/CWE-297/UnsafeHostnameVerification.qhelp b/java/ql/src/Security/CWE/CWE-297/UnsafeHostnameVerification.qhelp new file mode 100644 index 00000000000..520174bf4c5 --- /dev/null +++ b/java/ql/src/Security/CWE/CWE-297/UnsafeHostnameVerification.qhelp @@ -0,0 +1,50 @@ + + + +

    +If a HostnameVerifier always returns true it will not verify the hostname at all. +This stops Transport Layer Security (TLS) providing any security and allows an attacker to perform a man-in-the-middle attack against the application. +

    + +

    +An attack might look like this: +

    + +
      +
    1. The program connects to https://example.com.
    2. +
    3. The attacker intercepts this connection and presents an apparently-valid certificate of their choosing.
    4. +
    5. The TrustManager of the program verifies that the certificate has been issued by a trusted certificate authority.
    6. +
    7. The Java HTTPS library checks whether the certificate has been issued for the host example.com. This check fails because the certificate has been issued for a domain controlled by the attacker, for example: malicious.domain.
    8. +
    9. The HTTPS library wants to reject the certificate because the hostname does not match. Before doing this it checks whether a HostnameVerifier exists.
    10. +
    11. Your HostnameVerifier is called which returns true for any certificate so also for this one.
    12. +
    13. The program proceeds with the connection since your HostnameVerifier accepted it.
    14. +
    15. The attacker can now read the data your program sends to https://example.com +and/or alter its replies while the program thinks the connection is secure.
    16. +
    + +
    + + +

    +Do not use an open HostnameVerifier. +If you have a configuration problem with TLS/HTTPS, you should always solve the configuration problem instead of using an open verifier. +

    + +
    + + +

    +In the first (bad) example, the HostnameVerifier always returns true. +This allows an attacker to perform a man-in-the-middle attack, because any certificate is accepted despite an incorrect hostname. +In the second (good) example, the HostnameVerifier only returns true when the certificate has been correctly checked. +

    + +
    + + +
  • Android developers: Security with HTTPS and SSL.
  • +
  • Terse systems blog: Fixing Hostname Verification.
  • +
    +
    diff --git a/java/ql/src/Security/CWE/CWE-297/UnsafeHostnameVerification.ql b/java/ql/src/Security/CWE/CWE-297/UnsafeHostnameVerification.ql new file mode 100644 index 00000000000..9c060565f28 --- /dev/null +++ b/java/ql/src/Security/CWE/CWE-297/UnsafeHostnameVerification.ql @@ -0,0 +1,163 @@ +/** + * @name Unsafe hostname verification + * @description Marking a certificate as valid for a host without checking the certificate hostname allows an attacker to perform a machine-in-the-middle attack. + * @kind path-problem + * @problem.severity error + * @precision high + * @id java/unsafe-hostname-verification + * @tags security + * external/cwe/cwe-297 + */ + +import java +import semmle.code.java.controlflow.Guards +import semmle.code.java.dataflow.DataFlow +import semmle.code.java.dataflow.FlowSources +import semmle.code.java.security.Encryption +import DataFlow::PathGraph + +/** + * Holds if `m` always returns `true` ignoring any exceptional flow. + */ +private predicate alwaysReturnsTrue(HostnameVerifierVerify m) { + forex(ReturnStmt rs | rs.getEnclosingCallable() = m | + rs.getResult().(CompileTimeConstantExpr).getBooleanValue() = true + ) +} + +/** + * A class that overrides the `javax.net.ssl.HostnameVerifier.verify` method and **always** returns `true` (though it could also exit due to an uncaught exception), thus + * accepting any certificate despite a hostname mismatch. + */ +class TrustAllHostnameVerifier extends RefType { + TrustAllHostnameVerifier() { + this.getASupertype*() instanceof HostnameVerifier and + exists(HostnameVerifierVerify m | + m.getDeclaringType() = this and + alwaysReturnsTrue(m) + ) + } +} + +/** + * A configuration to model the flow of a `TrustAllHostnameVerifier` to a `set(Default)HostnameVerifier` call. + */ +class TrustAllHostnameVerifierConfiguration extends DataFlow::Configuration { + TrustAllHostnameVerifierConfiguration() { this = "TrustAllHostnameVerifierConfiguration" } + + override predicate isSource(DataFlow::Node source) { + source.asExpr().(ClassInstanceExpr).getConstructedType() instanceof TrustAllHostnameVerifier + } + + override predicate isSink(DataFlow::Node sink) { + exists(MethodAccess ma, Method m | + (m instanceof SetDefaultHostnameVerifierMethod or m instanceof SetHostnameVerifierMethod) and + ma.getMethod() = m + | + ma.getArgument(0) = sink.asExpr() + ) + } + + override predicate isBarrier(DataFlow::Node barrier) { + // ignore nodes that are in functions that intentionally disable hostname verification + barrier + .getEnclosingCallable() + .getName() + /* + * Regex: (_)* : + * some methods have underscores. + * Regex: (no|ignore|disable)(strictssl|ssl|verify|verification|hostname) + * noStrictSSL ignoreSsl + * Regex: (set)?(accept|trust|ignore|allow)(all|every|any) + * acceptAll trustAll ignoreAll setTrustAnyHttps + * Regex: (use|do|enable)insecure + * useInsecureSSL + * Regex: (set|do|use)?no.*(check|validation|verify|verification) + * setNoCertificateCheck + * Regex: disable + * disableChecks + */ + + .regexpMatch("^(?i)(_)*((no|ignore|disable)(strictssl|ssl|verify|verification|hostname)" + + "|(set)?(accept|trust|ignore|allow)(all|every|any)" + + "|(use|do|enable)insecure|(set|do|use)?no.*(check|validation|verify|verification)|disable).*$") + } +} + +bindingset[result] +private string getAFlagName() { + result + .regexpMatch("(?i).*(secure|disable|selfCert|selfSign|validat|verif|trust|ignore|nocertificatecheck).*") +} + +/** + * A flag has to either be of type `String`, `boolean` or `Boolean`. + */ +private class FlagType extends Type { + FlagType() { + this instanceof TypeString + or + this instanceof BooleanType + } +} + +private predicate isEqualsIgnoreCaseMethodAccess(MethodAccess ma) { + ma.getMethod().hasName("equalsIgnoreCase") and + ma.getMethod().getDeclaringType() instanceof TypeString +} + +/** Holds if `source` should is considered a flag. */ +private predicate isFlag(DataFlow::Node source) { + exists(VarAccess v | v.getVariable().getName() = getAFlagName() | + source.asExpr() = v and v.getType() instanceof FlagType + ) + or + exists(StringLiteral s | s.getRepresentedString() = getAFlagName() | source.asExpr() = s) + or + exists(MethodAccess ma | ma.getMethod().getName() = getAFlagName() | + source.asExpr() = ma and + ma.getType() instanceof FlagType and + not isEqualsIgnoreCaseMethodAccess(ma) + ) +} + +/** Holds if there is flow from `node1` to `node2` either due to local flow or due to custom flow steps. */ +private predicate flagFlowStep(DataFlow::Node node1, DataFlow::Node node2) { + DataFlow::localFlowStep(node1, node2) + or + exists(MethodAccess ma | ma.getMethod() = any(EnvReadMethod m) | + ma = node2.asExpr() and ma.getAnArgument() = node1.asExpr() + ) + or + exists(MethodAccess ma | + ma.getMethod().hasName("parseBoolean") and + ma.getMethod().getDeclaringType().hasQualifiedName("java.lang", "Boolean") + | + ma = node2.asExpr() and ma.getAnArgument() = node1.asExpr() + ) +} + +/** Gets a guard that depends on a flag. */ +private Guard getAGuard() { + exists(DataFlow::Node source, DataFlow::Node sink | + isFlag(source) and + flagFlowStep*(source, sink) and + sink.asExpr() = result + ) +} + +/** Holds if `node` is guarded by a flag that suggests an intentionally insecure feature. */ +private predicate isNodeGuardedByFlag(DataFlow::Node node) { + exists(Guard g | g.controls(node.asExpr().getBasicBlock(), _) | g = getAGuard()) +} + +from + DataFlow::PathNode source, DataFlow::PathNode sink, TrustAllHostnameVerifierConfiguration cfg, + RefType verifier +where + cfg.hasFlowPath(source, sink) and + not isNodeGuardedByFlag(sink.getNode()) and + verifier = source.getNode().asExpr().(ClassInstanceExpr).getConstructedType() +select sink, source, sink, + "$@ that is defined $@ and accepts any certificate as valid, is used here.", source, + "This hostname verifier", verifier, "here" diff --git a/java/ql/src/Security/CWE/CWE-327/BrokenCryptoAlgorithm.qhelp b/java/ql/src/Security/CWE/CWE-327/BrokenCryptoAlgorithm.qhelp index cd3f86f6bed..1d8e8db6798 100644 --- a/java/ql/src/Security/CWE/CWE-327/BrokenCryptoAlgorithm.qhelp +++ b/java/ql/src/Security/CWE/CWE-327/BrokenCryptoAlgorithm.qhelp @@ -12,7 +12,7 @@ data.

    -

    Ensure that you use a strong, modern cryptographic algorithm. Use at least AES-128 or RSA-2048.

    +

    Ensure that you use a strong, modern cryptographic algorithm. Use at least AES-128 or RSA-2048. Do not use the ECB encryption mode since it is vulnerable to replay and other attacks.

    diff --git a/java/ql/src/experimental/Security/CWE/CWE-273/UnsafeCertTrust.java b/java/ql/src/experimental/Security/CWE/CWE-273/UnsafeCertTrust.java index 65698ac33a3..b3536fa7d1d 100644 --- a/java/ql/src/experimental/Security/CWE/CWE-273/UnsafeCertTrust.java +++ b/java/ql/src/experimental/Security/CWE/CWE-273/UnsafeCertTrust.java @@ -1,30 +1,4 @@ public static void main(String[] args) { - { - HostnameVerifier verifier = new HostnameVerifier() { - @Override - public boolean verify(String hostname, SSLSession session) { - try { //GOOD: verify the certificate - Certificate[] certs = session.getPeerCertificates(); - X509Certificate x509 = (X509Certificate) certs[0]; - check(new String[]{host}, x509); - return true; - } catch (SSLException e) { - return false; - } - } - }; - HttpsURLConnection.setDefaultHostnameVerifier(verifier); - } - - { - HostnameVerifier verifier = new HostnameVerifier() { - @Override - public boolean verify(String hostname, SSLSession session) { - return true; // BAD: accept even if the hostname doesn't match - } - }; - HttpsURLConnection.setDefaultHostnameVerifier(verifier); - } { X509TrustManager trustAllCertManager = new X509TrustManager() { diff --git a/java/ql/src/experimental/Security/CWE/CWE-273/UnsafeCertTrust.qhelp b/java/ql/src/experimental/Security/CWE/CWE-273/UnsafeCertTrust.qhelp index 2e8d08fd68b..9a6bdb82cba 100644 --- a/java/ql/src/experimental/Security/CWE/CWE-273/UnsafeCertTrust.qhelp +++ b/java/ql/src/experimental/Security/CWE/CWE-273/UnsafeCertTrust.qhelp @@ -4,10 +4,10 @@ -

    Java offers two mechanisms for SSL authentication - trust manager and hostname verifier. Trust manager validates the peer's certificate chain while hostname verification establishes that the hostname in the URL matches the hostname in the server's identification.

    +

    Java offers two mechanisms for SSL authentication - trust manager and hostname verifier (checked by the java/insecure-hostname-verifier query). Trust manager validates the peer's certificate chain while hostname verification establishes that the hostname in the URL matches the hostname in the server's identification.

    And when SSLSocket or SSLEngine is created without a valid parameter of setEndpointIdentificationAlgorithm, hostname verification is disabled by default.

    -

    Unsafe implementation of the interface X509TrustManager, HostnameVerifier, and SSLSocket/SSLEngine ignores all SSL certificate validation errors when establishing an HTTPS connection, thereby making the app vulnerable to man-in-the-middle attacks.

    -

    This query checks whether trust manager is set to trust all certificates, the hostname verifier is turned off, or setEndpointIdentificationAlgorithm is missing. The query also covers a special implementation com.rabbitmq.client.ConnectionFactory.

    +

    Unsafe implementation of the interface X509TrustManager and SSLSocket/SSLEngine ignores all SSL certificate validation errors when establishing an HTTPS connection, thereby making the app vulnerable to man-in-the-middle attacks.

    +

    This query checks whether trust manager is set to trust all certificates or setEndpointIdentificationAlgorithm is missing. The query also covers a special implementation com.rabbitmq.client.ConnectionFactory.

    @@ -15,7 +15,7 @@ -

    The following two examples show two ways of configuring X509 trust cert manager and hostname verifier. In the 'BAD' case, +

    The following two examples show two ways of configuring X509 trust cert manager. In the 'BAD' case, no validation is performed thus any certificate is trusted. In the 'GOOD' case, the proper validation is performed.

    diff --git a/java/ql/src/experimental/Security/CWE/CWE-273/UnsafeCertTrust.ql b/java/ql/src/experimental/Security/CWE/CWE-273/UnsafeCertTrust.ql index 497e87b37ac..3dca54a8de6 100644 --- a/java/ql/src/experimental/Security/CWE/CWE-273/UnsafeCertTrust.ql +++ b/java/ql/src/experimental/Security/CWE/CWE-273/UnsafeCertTrust.ql @@ -1,6 +1,6 @@ /** - * @name Unsafe certificate trust and improper hostname verification - * @description Unsafe implementation of the interface X509TrustManager, HostnameVerifier, and SSLSocket/SSLEngine ignores all SSL certificate validation errors when establishing an HTTPS connection, thereby making the app vulnerable to man-in-the-middle attacks. + * @name Unsafe certificate trust + * @description Unsafe implementation of the interface X509TrustManager and SSLSocket/SSLEngine ignores all SSL certificate validation errors when establishing an HTTPS connection, thereby making the app vulnerable to man-in-the-middle attacks. * @kind problem * @id java/unsafe-cert-trust * @tags security @@ -53,42 +53,6 @@ class X509TrustAllManagerInit extends MethodAccess { } } -/** - * HostnameVerifier class that allows a certificate whose CN (Common Name) does not match the host name in the URL - */ -class TrustAllHostnameVerifier extends RefType { - TrustAllHostnameVerifier() { - this.getASupertype*() instanceof HostnameVerifier and - exists(Method m, ReturnStmt rt | - m.getDeclaringType() = this and - m.hasName("verify") and - rt.getEnclosingCallable() = m and - rt.getResult().(BooleanLiteral).getBooleanValue() = true - ) - } -} - -/** - * The setDefaultHostnameVerifier method of HttpsURLConnection with the trust all configuration - */ -class TrustAllHostnameVerify extends MethodAccess { - TrustAllHostnameVerify() { - this.getMethod().hasName("setDefaultHostnameVerifier") and - this.getMethod().getDeclaringType() instanceof HttpsURLConnection and //httpsURLConnection.setDefaultHostnameVerifier method - ( - exists(NestedClass nc | - nc.getASupertype*() instanceof TrustAllHostnameVerifier and - this.getArgument(0).getType() = nc //Scenario of HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() {...}); - ) - or - exists(Variable v | - this.getArgument(0).(VarAccess).getVariable() = v and - v.getInitializer().getType() instanceof TrustAllHostnameVerifier //Scenario of HttpsURLConnection.setDefaultHostnameVerifier(verifier); - ) - ) - } -} - class SSLEngine extends RefType { SSLEngine() { this.hasQualifiedName("javax.net.ssl", "SSLEngine") } } @@ -239,7 +203,6 @@ class RabbitMQEnableHostnameVerificationNotSet extends MethodAccess { from MethodAccess aa where - aa instanceof TrustAllHostnameVerify or aa instanceof X509TrustAllManagerInit or aa instanceof SSLEndpointIdentificationNotSet or aa instanceof RabbitMQEnableHostnameVerificationNotSet diff --git a/java/ql/src/experimental/Security/CWE/CWE-295/JxBrowserWithoutCertValidation.java b/java/ql/src/experimental/Security/CWE/CWE-295/JxBrowserWithoutCertValidation.java new file mode 100644 index 00000000000..e45039e0fef --- /dev/null +++ b/java/ql/src/experimental/Security/CWE/CWE-295/JxBrowserWithoutCertValidation.java @@ -0,0 +1,23 @@ +public static void main(String[] args) { + { + Browser browser = new Browser(); + browser.loadURL("https://example.com"); + // no further calls + // BAD: The browser ignores any certificate error by default! + } + + { + Browser browser = new Browser(); + browser.setLoadHandler(new LoadHandler() { + public boolean onLoad(LoadParams params) { + return true; + } + + public boolean onCertificateError(CertificateErrorParams params){ + return true; // GOOD: This means that loading will be cancelled on certificate errors + } + }); // GOOD: A secure `LoadHandler` is used. + browser.loadURL("https://example.com"); + + } +} \ No newline at end of file diff --git a/java/ql/src/experimental/Security/CWE/CWE-295/JxBrowserWithoutCertValidation.qhelp b/java/ql/src/experimental/Security/CWE/CWE-295/JxBrowserWithoutCertValidation.qhelp new file mode 100644 index 00000000000..7327573b8ba --- /dev/null +++ b/java/ql/src/experimental/Security/CWE/CWE-295/JxBrowserWithoutCertValidation.qhelp @@ -0,0 +1,32 @@ + + + + +

    JxBrowser is a Java library that allows to embed the Chromium browser inside Java applications. +Versions smaller than 6.24 by default ignore any HTTPS certificate errors thereby allowing man-in-the-middle attacks. +

    +
    + + +

    Do either of these:

    +
      +
    • Update to version 6.24 or 7.x.x as these correctly reject certificate errors by default.
    • +
    • Add a custom implementation of the LoadHandler interface whose onCertificateError method always returns true indicating that loading should be cancelled. + Then use the setLoadHandler method with your custom LoadHandler on every Browser you use.
    • +
    +
    + + +

    The following two examples show two ways of using a Browser. In the 'BAD' case, +all certificate errors are ignored. In the 'GOOD' case, certificate errors are rejected.

    + +
    + + +
  • Teamdev: + +Changelog of JxBrowser 6.24.
  • +
    +
    diff --git a/java/ql/src/experimental/Security/CWE/CWE-295/JxBrowserWithoutCertValidation.ql b/java/ql/src/experimental/Security/CWE/CWE-295/JxBrowserWithoutCertValidation.ql new file mode 100644 index 00000000000..aecffaf3f3b --- /dev/null +++ b/java/ql/src/experimental/Security/CWE/CWE-295/JxBrowserWithoutCertValidation.ql @@ -0,0 +1,86 @@ +/** + * @name JxBrowser with disabled certificate validation + * @description Insecure configuration of JxBrowser disables certificate validation making the app vulnerable to man-in-the-middle attacks. + * @kind problem + * @id java/jxbrowser/disabled-certificate-validation + * @tags security + * external/cwe/cwe-295 + */ + +import java +import semmle.code.java.security.Encryption +import semmle.code.java.dataflow.DataFlow + +/* + * This query is version specific to JxBrowser < 6.24. The version is indirectly detected. + * In version 6.x.x the `Browser` class is in a different package compared to version 7.x.x. + */ + +/** + * Holds if a safe JxBrowser 6.x.x version is used, such as version 6.24. + * This is detected by the the presence of the `addBoundsListener` in the `Browser` class. + */ +private predicate isSafeJxBrowserVersion() { + exists(Method m | m.getDeclaringType() instanceof JxBrowser | m.hasName("addBoundsListener")) +} + +/** The `com.teamdev.jxbrowser.chromium.Browser` class. */ +private class JxBrowser extends RefType { + JxBrowser() { this.hasQualifiedName("com.teamdev.jxbrowser.chromium", "Browser") } +} + +/** The `setLoadHandler` method on the `com.teamdev.jxbrowser.chromium.Browser` class. */ +private class JxBrowserSetLoadHandler extends Method { + JxBrowserSetLoadHandler() { + this.hasName("setLoadHandler") and this.getDeclaringType() instanceof JxBrowser + } +} + +/** The `com.teamdev.jxbrowser.chromium.LoadHandler` interface. */ +private class JxBrowserLoadHandler extends RefType { + JxBrowserLoadHandler() { this.hasQualifiedName("com.teamdev.jxbrowser.chromium", "LoadHandler") } +} + +private predicate isOnCertificateErrorMethodSafe(Method m) { + forex(ReturnStmt rs | rs.getEnclosingCallable() = m | + rs.getResult().(CompileTimeConstantExpr).getBooleanValue() = true + ) +} + +/** A class that securely implements the `com.teamdev.jxbrowser.chromium.LoadHandler` interface. */ +private class JxBrowserSafeLoadHandler extends RefType { + JxBrowserSafeLoadHandler() { + this.getASupertype() instanceof JxBrowserLoadHandler and + exists(Method m | m.hasName("onCertificateError") and m.getDeclaringType() = this | + isOnCertificateErrorMethodSafe(m) + ) + } +} + +/** + * Models flow from the source `new Browser()` to a sink `browser.setLoadHandler(loadHandler)` where `loadHandler` + * has been determined to be safe. + */ +private class JxBrowserFlowConfiguration extends DataFlow::Configuration { + JxBrowserFlowConfiguration() { this = "JxBrowserFlowConfiguration" } + + override predicate isSource(DataFlow::Node src) { + exists(ClassInstanceExpr newJxBrowser | newJxBrowser.getConstructedType() instanceof JxBrowser | + newJxBrowser = src.asExpr() + ) + } + + override predicate isSink(DataFlow::Node sink) { + exists(MethodAccess ma | ma.getMethod() instanceof JxBrowserSetLoadHandler | + ma.getArgument(0).getType() instanceof JxBrowserSafeLoadHandler and + ma.getQualifier() = sink.asExpr() + ) + } +} + +from JxBrowserFlowConfiguration cfg, DataFlow::Node src +where + cfg.isSource(src) and + not cfg.hasFlow(src, _) and + not isSafeJxBrowserVersion() +select src, "This JxBrowser instance may not check HTTPS certificates." diff --git a/java/ql/src/experimental/Security/CWE/CWE-312/CleartextStorageSharedPrefs.java b/java/ql/src/experimental/Security/CWE/CWE-312/CleartextStorageSharedPrefs.java new file mode 100644 index 00000000000..f4fbeaa230b --- /dev/null +++ b/java/ql/src/experimental/Security/CWE/CWE-312/CleartextStorageSharedPrefs.java @@ -0,0 +1,39 @@ +public void testSetSharedPrefs(Context context, String name, String password) +{ + { + // BAD - save sensitive information in cleartext + SharedPreferences sharedPrefs = context.getSharedPreferences("user_prefs", Context.MODE_PRIVATE); + Editor editor = sharedPrefs.edit(); + editor.putString("name", name); + editor.putString("password", password); + editor.commit(); + } + + { + // GOOD - save sensitive information in encrypted format + SharedPreferences sharedPrefs = context.getSharedPreferences("user_prefs", Context.MODE_PRIVATE); + Editor editor = sharedPrefs.edit(); + editor.putString("name", encrypt(name)); + editor.putString("password", encrypt(password)); + editor.commit(); + } + + { + // GOOD - save sensitive information using the built-in `EncryptedSharedPreferences` class in androidx. + MasterKey masterKey = new MasterKey.Builder(context, MasterKey.DEFAULT_MASTER_KEY_ALIAS) + .setKeyScheme(MasterKey.KeyScheme.AES256_GCM) + .build(); + + SharedPreferences sharedPreferences = EncryptedSharedPreferences.create( + context, + "secret_shared_prefs", + masterKey, + EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV, + EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM); + + SharedPreferences.Editor editor = sharedPreferences.edit(); + editor.putString("name", name); + editor.putString("password", password); + editor.commit(); + } +} diff --git a/java/ql/src/experimental/Security/CWE/CWE-312/CleartextStorageSharedPrefs.qhelp b/java/ql/src/experimental/Security/CWE/CWE-312/CleartextStorageSharedPrefs.qhelp new file mode 100644 index 00000000000..90f87f30b91 --- /dev/null +++ b/java/ql/src/experimental/Security/CWE/CWE-312/CleartextStorageSharedPrefs.qhelp @@ -0,0 +1,40 @@ + + + +

    + SharedPreferences is an Android API that stores application preferences using simple sets of data values. Almost every Android application uses this API. It allows to easily save, alter, and retrieve the values stored in the user's profile. However, sensitive information should not be saved in cleartext. Otherwise it can be accessed by any process or user on rooted devices, or can be disclosed through chained vulnerabilities e.g. unexpected access to its private storage through exposed components. +

    +
    + + +

    + Use the EncryptedSharedPreferences API or other encryption algorithms for storing sensitive information. +

    +
    + + +

    + In the first example, sensitive user information is stored in cleartext. +

    + +

    + In the second and third examples, the code encrypts sensitive information before saving it to the device. +

    + +
    + + +
  • + CWE: + CWE-312: Cleartext Storage of Sensitive Information +
  • +
  • + Android Developers: + Work with data more securely +
  • +
  • + ProAndroidDev: + Encrypted Preferences in Android +
  • +
    +
    diff --git a/java/ql/src/experimental/Security/CWE/CWE-312/CleartextStorageSharedPrefs.ql b/java/ql/src/experimental/Security/CWE/CWE-312/CleartextStorageSharedPrefs.ql new file mode 100644 index 00000000000..fcfe3f82651 --- /dev/null +++ b/java/ql/src/experimental/Security/CWE/CWE-312/CleartextStorageSharedPrefs.ql @@ -0,0 +1,163 @@ +/** + * @name Cleartext storage of sensitive information using `SharedPreferences` on Android + * @description Cleartext Storage of Sensitive Information using SharedPreferences on Android allows access for users with root privileges or unexpected exposure from chained vulnerabilities. + * @kind problem + * @id java/android/cleartext-storage-shared-prefs + * @tags security + * external/cwe/cwe-312 + */ + +import java +import semmle.code.java.dataflow.DataFlow4 +import semmle.code.java.dataflow.DataFlow5 +import semmle.code.java.dataflow.TaintTracking +import semmle.code.java.frameworks.android.Intent +import semmle.code.java.frameworks.android.SharedPreferences +import semmle.code.java.security.SensitiveActions + +/** Holds if the method call is a setter method of `SharedPreferences`. */ +private predicate sharedPreferencesInput(DataFlow::Node sharedPrefs, Expr input) { + exists(MethodAccess m | + m.getMethod() instanceof PutSharedPreferenceMethod and + input = m.getArgument(1) and + not exists(EncryptedValueFlowConfig conf | conf.hasFlow(_, DataFlow::exprNode(input))) and + sharedPrefs.asExpr() = m.getQualifier() + ) +} + +/** Holds if the method call is the store method of `SharedPreferences`. */ +private predicate sharedPreferencesStore(DataFlow::Node sharedPrefs, Expr store) { + exists(MethodAccess m | + m.getMethod() instanceof StoreSharedPreferenceMethod and + store = m and + sharedPrefs.asExpr() = m.getQualifier() + ) +} + +/** Flow from `SharedPreferences` to either a setter or a store method. */ +class SharedPreferencesFlowConfig extends DataFlow::Configuration { + SharedPreferencesFlowConfig() { + this = "CleartextStorageSharedPrefs::SharedPreferencesFlowConfig" + } + + override predicate isSource(DataFlow::Node src) { + src.asExpr() instanceof SharedPreferencesEditorMethodAccess + } + + override predicate isSink(DataFlow::Node sink) { + sharedPreferencesInput(sink, _) or + sharedPreferencesStore(sink, _) + } +} + +/** + * Method call of encrypting sensitive information. + * As there are various implementations of encryption (reversible and non-reversible) from both JDK and third parties, this class simply checks method name to take a best guess to reduce false positives. + */ +class EncryptedSensitiveMethodAccess extends MethodAccess { + EncryptedSensitiveMethodAccess() { + this.getMethod().getName().toLowerCase().matches(["%encrypt%", "%hash%"]) + } +} + +/** Flow configuration of encrypting sensitive information. */ +class EncryptedValueFlowConfig extends DataFlow5::Configuration { + EncryptedValueFlowConfig() { this = "CleartextStorageSharedPrefs::EncryptedValueFlowConfig" } + + override predicate isSource(DataFlow5::Node src) { + exists(EncryptedSensitiveMethodAccess ema | src.asExpr() = ema) + } + + override predicate isSink(DataFlow5::Node sink) { + exists(MethodAccess ma | + ma.getMethod() instanceof PutSharedPreferenceMethod and + sink.asExpr() = ma.getArgument(1) + ) + } +} + +/** Flow from the create method of `androidx.security.crypto.EncryptedSharedPreferences` to its instance. */ +private class EncryptedSharedPrefFlowConfig extends DataFlow4::Configuration { + EncryptedSharedPrefFlowConfig() { + this = "CleartextStorageSharedPrefs::EncryptedSharedPrefFlowConfig" + } + + override predicate isSource(DataFlow4::Node src) { + src.asExpr().(MethodAccess).getMethod() instanceof CreateEncryptedSharedPreferencesMethod + } + + override predicate isSink(DataFlow4::Node sink) { + sink.asExpr().getType() instanceof SharedPreferences + } +} + +/** The call to get a `SharedPreferences.Editor` object, which can set shared preferences or be stored to device. */ +class SharedPreferencesEditorMethodAccess extends MethodAccess { + SharedPreferencesEditorMethodAccess() { + this.getMethod() instanceof GetSharedPreferencesEditorMethod and + not exists( + EncryptedSharedPrefFlowConfig config // not exists `SharedPreferences sharedPreferences = EncryptedSharedPreferences.create(...)` + | + config.hasFlow(_, DataFlow::exprNode(this.getQualifier())) + ) + } + + /** Gets an input, for example `password` in `editor.putString("password", password);`. */ + Expr getAnInput() { + exists(SharedPreferencesFlowConfig conf, DataFlow::Node n | + sharedPreferencesInput(n, result) and + conf.hasFlow(DataFlow::exprNode(this), n) + ) + } + + /** Gets a store, for example `editor.commit();`. */ + Expr getAStore() { + exists(SharedPreferencesFlowConfig conf, DataFlow::Node n | + sharedPreferencesStore(n, result) and + conf.hasFlow(DataFlow::exprNode(this), n) + ) + } +} + +/** + * Flow from sensitive expressions to shared preferences. + * Note it can be merged into `SensitiveSourceFlowConfig` of `Security/CWE/CWE-312/SensitiveStorage.qll` when this query is promoted from the experimental directory. + */ +private class SensitiveSharedPrefsFlowConfig extends TaintTracking::Configuration { + SensitiveSharedPrefsFlowConfig() { + this = "CleartextStorageSharedPrefs::SensitiveSharedPrefsFlowConfig" + } + + override predicate isSource(DataFlow::Node src) { src.asExpr() instanceof SensitiveExpr } + + override predicate isSink(DataFlow::Node sink) { + exists(MethodAccess m | + m.getMethod() instanceof PutSharedPreferenceMethod and + sink.asExpr() = m.getArgument(1) + ) + } +} + +/** Class for shared preferences that may contain 'sensitive' information */ +class SensitiveSharedPrefsSource extends Expr { + SensitiveSharedPrefsSource() { + // SensitiveExpr is abstract, this lets us inherit from it without + // being a technical subclass + this instanceof SensitiveExpr + } + + /** Holds if this source flows to the `sink`. */ + predicate flowsTo(Expr sink) { + exists(SensitiveSharedPrefsFlowConfig conf | + conf.hasFlow(DataFlow::exprNode(this), DataFlow::exprNode(sink)) + ) + } +} + +from SensitiveSharedPrefsSource data, SharedPreferencesEditorMethodAccess s, Expr input, Expr store +where + input = s.getAnInput() and + store = s.getAStore() and + data.flowsTo(input) +select store, "'SharedPreferences' class $@ containing $@ is stored here. Data was added $@.", s, + s.toString(), data, "sensitive data", input, "here" diff --git a/java/ql/src/experimental/Security/CWE/CWE-326/InsufficientKeySize.java b/java/ql/src/experimental/Security/CWE/CWE-326/InsufficientKeySize.java new file mode 100644 index 00000000000..ff30196abb5 --- /dev/null +++ b/java/ql/src/experimental/Security/CWE/CWE-326/InsufficientKeySize.java @@ -0,0 +1,37 @@ +public class InsufficientKeySize { + public void CryptoMethod() { + KeyGenerator keyGen1 = KeyGenerator.getInstance("AES"); + // BAD: Key size is less than 128 + keyGen1.init(64); + + KeyGenerator keyGen2 = KeyGenerator.getInstance("AES"); + // GOOD: Key size is no less than 128 + keyGen2.init(128); + + KeyPairGenerator keyPairGen1 = KeyPairGenerator.getInstance("RSA"); + // BAD: Key size is less than 2048 + keyPairGen1.initialize(1024); + + KeyPairGenerator keyPairGen2 = KeyPairGenerator.getInstance("RSA"); + // GOOD: Key size is no less than 2048 + keyPairGen2.initialize(2048); + + KeyPairGenerator keyPairGen3 = KeyPairGenerator.getInstance("DSA"); + // BAD: Key size is less than 2048 + keyPairGen3.initialize(1024); + + KeyPairGenerator keyPairGen4 = KeyPairGenerator.getInstance("DSA"); + // GOOD: Key size is no less than 2048 + keyPairGen4.initialize(2048); + + KeyPairGenerator keyPairGen5 = KeyPairGenerator.getInstance("EC"); + // BAD: Key size is less than 256 + ECGenParameterSpec ecSpec1 = new ECGenParameterSpec("secp112r1"); + keyPairGen5.initialize(ecSpec1); + + KeyPairGenerator keyPairGen6 = KeyPairGenerator.getInstance("EC"); + // GOOD: Key size is no less than 256 + ECGenParameterSpec ecSpec2 = new ECGenParameterSpec("secp256r1"); + keyPairGen6.initialize(ecSpec2); + } +} diff --git a/java/ql/src/experimental/Security/CWE/CWE-326/InsufficientKeySize.qhelp b/java/ql/src/experimental/Security/CWE/CWE-326/InsufficientKeySize.qhelp new file mode 100644 index 00000000000..4d4ec76f060 --- /dev/null +++ b/java/ql/src/experimental/Security/CWE/CWE-326/InsufficientKeySize.qhelp @@ -0,0 +1,29 @@ + + + +

    This rule finds uses of encryption algorithms with too small a key size. Encryption algorithms +are vulnerable to brute force attack when too small a key size is used.

    +
    + + +

    The key should be at least 2048 bits long when using RSA and DSA encryption, 256 bits long when using EC encryption, and 128 bits long when using +symmetric encryption.

    +
    + + + +
  • + Wikipedia. + Key size +
  • +
  • + SonarSource. + Cryptographic keys should be robust +
  • +
  • + CWE. + CWE-326: Inadequate Encryption Strength +
  • + +
    +
    \ No newline at end of file diff --git a/java/ql/src/experimental/Security/CWE/CWE-326/InsufficientKeySize.ql b/java/ql/src/experimental/Security/CWE/CWE-326/InsufficientKeySize.ql new file mode 100644 index 00000000000..41242a44805 --- /dev/null +++ b/java/ql/src/experimental/Security/CWE/CWE-326/InsufficientKeySize.ql @@ -0,0 +1,151 @@ +/** + * @name Weak encryption: Insufficient key size + * @description Finds uses of encryption algorithms with too small a key size + * @kind problem + * @id java/insufficient-key-size + * @tags security + * external/cwe/cwe-326 + */ + +import java +import semmle.code.java.security.Encryption +import semmle.code.java.dataflow.TaintTracking + +/** The Java class `java.security.spec.ECGenParameterSpec`. */ +class ECGenParameterSpec extends RefType { + ECGenParameterSpec() { this.hasQualifiedName("java.security.spec", "ECGenParameterSpec") } +} + +/** The `init` method declared in `javax.crypto.KeyGenerator`. */ +class KeyGeneratorInitMethod extends Method { + KeyGeneratorInitMethod() { + getDeclaringType() instanceof KeyGenerator and + hasName("init") + } +} + +/** The `initialize` method declared in `java.security.KeyPairGenerator`. */ +class KeyPairGeneratorInitMethod extends Method { + KeyPairGeneratorInitMethod() { + getDeclaringType() instanceof KeyPairGenerator and + hasName("initialize") + } +} + +/** Returns the key size in the EC algorithm string */ +bindingset[algorithm] +int getECKeySize(string algorithm) { + algorithm.matches("sec%") and // specification such as "secp256r1" + result = algorithm.regexpCapture("sec[p|t](\\d+)[a-zA-Z].*", 1).toInt() + or + algorithm.matches("X9.62%") and //specification such as "X9.62 prime192v2" + result = algorithm.regexpCapture("X9\\.62 .*[a-zA-Z](\\d+)[a-zA-Z].*", 1).toInt() + or + (algorithm.matches("prime%") or algorithm.matches("c2tnb%")) and //specification such as "prime192v2" + result = algorithm.regexpCapture(".*[a-zA-Z](\\d+)[a-zA-Z].*", 1).toInt() +} + +/** Taint configuration tracking flow from a key generator to a `init` method call. */ +class KeyGeneratorInitConfiguration extends TaintTracking::Configuration { + KeyGeneratorInitConfiguration() { this = "KeyGeneratorInitConfiguration" } + + override predicate isSource(DataFlow::Node source) { + exists(JavaxCryptoKeyGenerator jcg | jcg = source.asExpr()) + } + + override predicate isSink(DataFlow::Node sink) { + exists(MethodAccess ma | + ma.getMethod() instanceof KeyGeneratorInitMethod and + sink.asExpr() = ma.getQualifier() + ) + } +} + +/** Taint configuration tracking flow from a keypair generator to a `initialize` method call. */ +class KeyPairGeneratorInitConfiguration extends TaintTracking::Configuration { + KeyPairGeneratorInitConfiguration() { this = "KeyPairGeneratorInitConfiguration" } + + override predicate isSource(DataFlow::Node source) { + exists(JavaSecurityKeyPairGenerator jkg | jkg = source.asExpr()) + } + + override predicate isSink(DataFlow::Node sink) { + exists(MethodAccess ma | + ma.getMethod() instanceof KeyPairGeneratorInitMethod and + sink.asExpr() = ma.getQualifier() + ) + } +} + +/** Holds if a symmetric `KeyGenerator` implementing encryption algorithm `type` and initialized by `ma` uses an insufficient key size. `msg` provides a human-readable description of the problem. */ +bindingset[type] +predicate hasShortSymmetricKey(MethodAccess ma, string msg, string type) { + ma.getMethod() instanceof KeyGeneratorInitMethod and + exists( + JavaxCryptoKeyGenerator jcg, KeyGeneratorInitConfiguration cc, DataFlow::PathNode source, + DataFlow::PathNode dest + | + jcg.getAlgoSpec().(StringLiteral).getValue() = type and + source.getNode().asExpr() = jcg and + dest.getNode().asExpr() = ma.getQualifier() and + cc.hasFlowPath(source, dest) + ) and + ma.getArgument(0).(IntegerLiteral).getIntValue() < 128 and + msg = "Key size should be at least 128 bits for " + type + " encryption." +} + +/** Holds if an AES `KeyGenerator` initialized by `ma` uses an insufficient key size. `msg` provides a human-readable description of the problem. */ +predicate hasShortAESKey(MethodAccess ma, string msg) { hasShortSymmetricKey(ma, msg, "AES") } + +/** Holds if an asymmetric `KeyPairGenerator` implementing encryption algorithm `type` and initialized by `ma` uses an insufficient key size. `msg` provides a human-readable description of the problem. */ +bindingset[type] +predicate hasShortAsymmetricKeyPair(MethodAccess ma, string msg, string type) { + ma.getMethod() instanceof KeyPairGeneratorInitMethod and + exists( + JavaSecurityKeyPairGenerator jpg, KeyPairGeneratorInitConfiguration kc, + DataFlow::PathNode source, DataFlow::PathNode dest + | + jpg.getAlgoSpec().(StringLiteral).getValue().toUpperCase() = type and + source.getNode().asExpr() = jpg and + dest.getNode().asExpr() = ma.getQualifier() and + kc.hasFlowPath(source, dest) + ) and + ma.getArgument(0).(IntegerLiteral).getIntValue() < 2048 and + msg = "Key size should be at least 2048 bits for " + type + " encryption." +} + +/** Holds if a DSA `KeyPairGenerator` initialized by `ma` uses an insufficient key size. `msg` provides a human-readable description of the problem. */ +predicate hasShortDSAKeyPair(MethodAccess ma, string msg) { + hasShortAsymmetricKeyPair(ma, msg, "DSA") or hasShortAsymmetricKeyPair(ma, msg, "DH") +} + +/** Holds if a RSA `KeyPairGenerator` initialized by `ma` uses an insufficient key size. `msg` provides a human-readable description of the problem. */ +predicate hasShortRSAKeyPair(MethodAccess ma, string msg) { + hasShortAsymmetricKeyPair(ma, msg, "RSA") +} + +/** Holds if an EC `KeyPairGenerator` initialized by `ma` uses an insufficient key size. `msg` provides a human-readable description of the problem. */ +predicate hasShortECKeyPair(MethodAccess ma, string msg) { + ma.getMethod() instanceof KeyPairGeneratorInitMethod and + exists( + JavaSecurityKeyPairGenerator jpg, KeyPairGeneratorInitConfiguration kc, + DataFlow::PathNode source, DataFlow::PathNode dest, ClassInstanceExpr cie + | + jpg.getAlgoSpec().(StringLiteral).getValue().matches("EC%") and // ECC variants such as ECDH and ECDSA + source.getNode().asExpr() = jpg and + dest.getNode().asExpr() = ma.getQualifier() and + kc.hasFlowPath(source, dest) and + DataFlow::localExprFlow(cie, ma.getArgument(0)) and + ma.getArgument(0).getType() instanceof ECGenParameterSpec and + getECKeySize(cie.getArgument(0).(StringLiteral).getRepresentedString()) < 256 + ) and + msg = "Key size should be at least 256 bits for EC encryption." +} + +from Expr e, string msg +where + hasShortAESKey(e, msg) or + hasShortDSAKeyPair(e, msg) or + hasShortRSAKeyPair(e, msg) or + hasShortECKeyPair(e, msg) +select e, msg diff --git a/java/ql/src/experimental/Security/CWE/CWE-522/InsecureBasicAuth.ql b/java/ql/src/experimental/Security/CWE/CWE-522/InsecureBasicAuth.ql index 1fadb5bda69..3ec836a0117 100644 --- a/java/ql/src/experimental/Security/CWE/CWE-522/InsecureBasicAuth.ql +++ b/java/ql/src/experimental/Security/CWE/CWE-522/InsecureBasicAuth.ql @@ -14,14 +14,6 @@ import semmle.code.java.frameworks.ApacheHttp import semmle.code.java.dataflow.TaintTracking import DataFlow::PathGraph -/** - * Gets a regular expression for matching private hosts, which only matches the host portion therefore checking for port is not necessary. - */ -private string getPrivateHostRegex() { - result = - "(?i)localhost(?:[:/?#].*)?|127\\.0\\.0\\.1(?:[:/?#].*)?|10(?:\\.[0-9]+){3}(?:[:/?#].*)?|172\\.16(?:\\.[0-9]+){2}(?:[:/?#].*)?|192.168(?:\\.[0-9]+){2}(?:[:/?#].*)?|\\[?0:0:0:0:0:0:0:1\\]?(?:[:/?#].*)?|\\[?::1\\]?(?:[:/?#].*)?" -} - /** * Class of Java URL constructor. */ @@ -76,7 +68,7 @@ class HttpStringLiteral extends StringLiteral { // Match URLs with the HTTP protocol and without private IP addresses to reduce false positives. exists(string s | this.getRepresentedString() = s | s.regexpMatch("(?i)http://[\\[a-zA-Z0-9].*") and - not s.substring(7, s.length()).regexpMatch(getPrivateHostRegex()) + not s.substring(7, s.length()) instanceof PrivateHostName ) } } @@ -101,7 +93,7 @@ predicate concatHttpString(Expr protocol, Expr host) { host.(VarAccess).getVariable().getAnAssignedValue().(CompileTimeConstantExpr).getStringValue() | hostString.length() = 0 or // Empty host is loopback address - hostString.regexpMatch(getPrivateHostRegex()) + hostString instanceof PrivateHostName ) } diff --git a/java/ql/src/experimental/Security/CWE/CWE-522/InsecureLdapAuth.java b/java/ql/src/experimental/Security/CWE/CWE-522/InsecureLdapAuth.java new file mode 100644 index 00000000000..3c5f6555100 --- /dev/null +++ b/java/ql/src/experimental/Security/CWE/CWE-522/InsecureLdapAuth.java @@ -0,0 +1,24 @@ +public class InsecureLdapAuth { + /** LDAP authentication */ + public DirContext ldapAuth(String ldapUserName, String password) { + { + // BAD: LDAP authentication in cleartext + String ldapUrl = "ldap://ad.your-server.com:389"; + } + + { + // GOOD: LDAPS authentication over SSL + String ldapUrl = "ldaps://ad.your-server.com:636"; + } + + Hashtable environment = new Hashtable(); + environment.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory"); + environment.put(Context.PROVIDER_URL, ldapUrl); + environment.put(Context.REFERRAL, "follow"); + environment.put(Context.SECURITY_AUTHENTICATION, "simple"); + environment.put(Context.SECURITY_PRINCIPAL, ldapUserName); + environment.put(Context.SECURITY_CREDENTIALS, password); + DirContext dirContext = new InitialDirContext(environment); + return dirContext; + } +} diff --git a/java/ql/src/experimental/Security/CWE/CWE-522/InsecureLdapAuth.qhelp b/java/ql/src/experimental/Security/CWE/CWE-522/InsecureLdapAuth.qhelp new file mode 100644 index 00000000000..c729759a06e --- /dev/null +++ b/java/ql/src/experimental/Security/CWE/CWE-522/InsecureLdapAuth.qhelp @@ -0,0 +1,27 @@ + + + + +

    When using the Java LDAP API to perform LDAPv3-style extended operations and controls, a context with connection properties including user credentials is started. Transmission of LDAP credentials in cleartext allows remote attackers to obtain sensitive information by sniffing the network.

    +
    + + +

    Use LDAPS to send credentials through SSL or use SASL authentication.

    +
    + + +

    The following example shows two ways of using LDAP authentication. In the 'BAD' case, the credentials are transmitted in cleartext. In the 'GOOD' case, the credentials are transmitted over SSL.

    + +
    + + +
  • + Oracle: + LDAP and LDAPS URLs +
  • +
  • + Oracle: + Simple authentication +
  • +
    +
    diff --git a/java/ql/src/experimental/Security/CWE/CWE-522/InsecureLdapAuth.ql b/java/ql/src/experimental/Security/CWE/CWE-522/InsecureLdapAuth.ql new file mode 100644 index 00000000000..8411a128c9c --- /dev/null +++ b/java/ql/src/experimental/Security/CWE/CWE-522/InsecureLdapAuth.ql @@ -0,0 +1,213 @@ +/** + * @name Insecure LDAP authentication + * @description LDAP authentication with credentials sent in cleartext. + * @kind path-problem + * @id java/insecure-ldap-auth + * @tags security + * external/cwe-522 + * external/cwe-319 + */ + +import java +import DataFlow +import semmle.code.java.frameworks.Jndi +import semmle.code.java.frameworks.Networking +import semmle.code.java.dataflow.TaintTracking +import DataFlow::PathGraph + +/** + * Insecure (non-SSL, non-private) LDAP URL string literal. + */ +class InsecureLdapUrlLiteral extends StringLiteral { + InsecureLdapUrlLiteral() { + // Match connection strings with the LDAP protocol and without private IP addresses to reduce false positives. + exists(string s | this.getRepresentedString() = s | + s.regexpMatch("(?i)ldap://[\\[a-zA-Z0-9].*") and + not s.substring(7, s.length()) instanceof PrivateHostName + ) + } +} + +/** The interface `javax.naming.Context`. */ +class TypeNamingContext extends Interface { + TypeNamingContext() { this.hasQualifiedName("javax.naming", "Context") } +} + +/** The class `java.util.Hashtable`. */ +class TypeHashtable extends Class { + TypeHashtable() { this.getSourceDeclaration().hasQualifiedName("java.util", "Hashtable") } +} + +/** + * Holds if a non-private LDAP string is concatenated from both protocol and host. + */ +predicate concatInsecureLdapString(Expr protocol, Expr host) { + protocol.(CompileTimeConstantExpr).getStringValue() = "ldap://" and + not exists(string hostString | + hostString = host.(CompileTimeConstantExpr).getStringValue() or + hostString = + host.(VarAccess).getVariable().getAnAssignedValue().(CompileTimeConstantExpr).getStringValue() + | + hostString.length() = 0 or // Empty host is loopback address + hostString instanceof PrivateHostName + ) +} + +/** Gets the leftmost operand in a concatenated string */ +Expr getLeftmostConcatOperand(Expr expr) { + if expr instanceof AddExpr + then result = getLeftmostConcatOperand(expr.(AddExpr).getLeftOperand()) + else result = expr +} + +/** + * String concatenated with `InsecureLdapUrlLiteral`. + */ +class InsecureLdapUrl extends Expr { + InsecureLdapUrl() { + this instanceof InsecureLdapUrlLiteral + or + concatInsecureLdapString(this.(AddExpr).getLeftOperand(), + getLeftmostConcatOperand(this.(AddExpr).getRightOperand())) + } +} + +/** + * Holds if `ma` writes the `java.naming.provider.url` (also known as `Context.PROVIDER_URL`) key of a `Hashtable`. + */ +predicate isProviderUrlSetter(MethodAccess ma) { + ma.getMethod().getDeclaringType().getAnAncestor() instanceof TypeHashtable and + ma.getMethod().hasName(["put", "setProperty"]) and + ( + ma.getArgument(0).(CompileTimeConstantExpr).getStringValue() = "java.naming.provider.url" + or + exists(Field f | + ma.getArgument(0) = f.getAnAccess() and + f.hasName("PROVIDER_URL") and + f.getDeclaringType() instanceof TypeNamingContext + ) + ) +} + +/** + * Holds if `ma` sets `fieldValue` to `envValue` in some `Hashtable`. + */ +bindingset[fieldValue, envValue] +predicate hasFieldValueEnv(MethodAccess ma, string fieldValue, string envValue) { + // environment.put("java.naming.security.authentication", "simple") + ma.getMethod().getDeclaringType().getAnAncestor() instanceof TypeHashtable and + ma.getMethod().hasName(["put", "setProperty"]) and + ma.getArgument(0).(CompileTimeConstantExpr).getStringValue() = fieldValue and + ma.getArgument(1).(CompileTimeConstantExpr).getStringValue() = envValue +} + +/** + * Holds if `ma` sets attribute name `fieldName` to `envValue` in some `Hashtable`. + */ +bindingset[fieldName, envValue] +predicate hasFieldNameEnv(MethodAccess ma, string fieldName, string envValue) { + // environment.put(Context.SECURITY_AUTHENTICATION, "simple") + ma.getMethod().getDeclaringType().getAnAncestor() instanceof TypeHashtable and + ma.getMethod().hasName(["put", "setProperty"]) and + exists(Field f | + ma.getArgument(0) = f.getAnAccess() and + f.hasName(fieldName) and + f.getDeclaringType() instanceof TypeNamingContext + ) and + ma.getArgument(1).(CompileTimeConstantExpr).getStringValue() = envValue +} + +/** + * Holds if `ma` sets `java.naming.security.authentication` (also known as `Context.SECURITY_AUTHENTICATION`) to `simple` in some `Hashtable`. + */ +predicate isBasicAuthEnv(MethodAccess ma) { + hasFieldValueEnv(ma, "java.naming.security.authentication", "simple") or + hasFieldNameEnv(ma, "SECURITY_AUTHENTICATION", "simple") +} + +/** + * Holds if `ma` sets `java.naming.security.protocol` (also known as `Context.SECURITY_PROTOCOL`) to `ssl` in some `Hashtable`. + */ +predicate isSSLEnv(MethodAccess ma) { + hasFieldValueEnv(ma, "java.naming.security.protocol", "ssl") or + hasFieldNameEnv(ma, "SECURITY_PROTOCOL", "ssl") +} + +/** + * A taint-tracking configuration for `ldap://` URL in LDAP authentication. + */ +class InsecureUrlFlowConfig extends TaintTracking::Configuration { + InsecureUrlFlowConfig() { this = "InsecureLdapAuth:InsecureUrlFlowConfig" } + + /** Source of `ldap://` connection string. */ + override predicate isSource(DataFlow::Node src) { src.asExpr() instanceof InsecureLdapUrl } + + /** Sink of directory context creation. */ + override predicate isSink(DataFlow::Node sink) { + exists(ConstructorCall cc | + cc.getConstructedType().getASupertype*() instanceof TypeDirContext and + sink.asExpr() = cc.getArgument(0) + ) + } + + /** Method call of `env.put()`. */ + override predicate isAdditionalTaintStep(DataFlow::Node pred, DataFlow::Node succ) { + exists(MethodAccess ma | + pred.asExpr() = ma.getArgument(1) and + isProviderUrlSetter(ma) and + succ.asExpr() = ma.getQualifier() + ) + } +} + +/** + * A taint-tracking configuration for `simple` basic-authentication in LDAP configuration. + */ +class BasicAuthFlowConfig extends DataFlow::Configuration { + BasicAuthFlowConfig() { this = "InsecureLdapAuth:BasicAuthFlowConfig" } + + /** Source of `simple` configuration. */ + override predicate isSource(DataFlow::Node src) { + exists(MethodAccess ma | + isBasicAuthEnv(ma) and ma.getQualifier() = src.(PostUpdateNode).getPreUpdateNode().asExpr() + ) + } + + /** Sink of directory context creation. */ + override predicate isSink(DataFlow::Node sink) { + exists(ConstructorCall cc | + cc.getConstructedType().getASupertype*() instanceof TypeDirContext and + sink.asExpr() = cc.getArgument(0) + ) + } +} + +/** + * A taint-tracking configuration for `ssl` configuration in LDAP authentication. + */ +class SSLFlowConfig extends DataFlow::Configuration { + SSLFlowConfig() { this = "InsecureLdapAuth:SSLFlowConfig" } + + /** Source of `ssl` configuration. */ + override predicate isSource(DataFlow::Node src) { + exists(MethodAccess ma | + isSSLEnv(ma) and ma.getQualifier() = src.(PostUpdateNode).getPreUpdateNode().asExpr() + ) + } + + /** Sink of directory context creation. */ + override predicate isSink(DataFlow::Node sink) { + exists(ConstructorCall cc | + cc.getConstructedType().getASupertype*() instanceof TypeDirContext and + sink.asExpr() = cc.getArgument(0) + ) + } +} + +from DataFlow::PathNode source, DataFlow::PathNode sink, InsecureUrlFlowConfig config +where + config.hasFlowPath(source, sink) and + exists(BasicAuthFlowConfig bc | bc.hasFlowTo(sink.getNode())) and + not exists(SSLFlowConfig sc | sc.hasFlowTo(sink.getNode())) +select sink.getNode(), source, sink, "Insecure LDAP authentication from $@.", source.getNode(), + "LDAP connection string" diff --git a/java/ql/src/experimental/Security/CWE/CWE-555/PasswordInConfigurationFile.qhelp b/java/ql/src/experimental/Security/CWE/CWE-555/PasswordInConfigurationFile.qhelp new file mode 100644 index 00000000000..691d718ba7e --- /dev/null +++ b/java/ql/src/experimental/Security/CWE/CWE-555/PasswordInConfigurationFile.qhelp @@ -0,0 +1,40 @@ + + + +

    + Storing a plaintext password in a configuration file allows anyone who can read the file to access the password-protected resources. +

    +
    + + +

    + Passwords stored in configuration files should be encrypted. Utilities provided by application servers like keystore and password vault can be used to encrypt and manage passwords. +

    +
    + + +

    + In the first example, the password of a datasource configuration is stored in cleartext in the context.xml file of a Java EE application. +

    + +

    + In the second example, the password of a datasource configuration is encrypted and managed by a password vault. +

    + +
    + + +
  • + CWE: + CWE-555: J2EE Misconfiguration: Plaintext Password in Configuration File +
  • +
  • + RedHat Security Guide: + Store and Retrieve Encrypted Sensitive Strings in the Java Keystore +
  • +
  • + SonarSource: + Hard-coded credentials are security-sensitive +
  • +
    +
    diff --git a/java/ql/src/experimental/Security/CWE/CWE-555/PasswordInConfigurationFile.ql b/java/ql/src/experimental/Security/CWE/CWE-555/PasswordInConfigurationFile.ql new file mode 100644 index 00000000000..a8ed7ec538e --- /dev/null +++ b/java/ql/src/experimental/Security/CWE/CWE-555/PasswordInConfigurationFile.ql @@ -0,0 +1,49 @@ +/** + * @name Password in configuration file + * @description Finds passwords in configuration files. + * @kind problem + * @id java/password-in-configuration + * @tags security + * external/cwe/cwe-555 + * external/cwe/cwe-256 + * external/cwe/cwe-260 + */ + +import java + +/** Holds if the attribute value is not a cleartext password */ +bindingset[value] +predicate isNotPassword(string value) { + value = "" // Empty string + or + value.regexpMatch("\\$\\{.*\\}") // Variable placeholder ${password} + or + value.matches("%=") // A basic check of encrypted passwords ending with padding characters, which could be improved to be more accurate. +} + +/** Holds if the attribute value has an embedded password */ +bindingset[value] +predicate hasEmbeddedPassword(string value) { + exists(string password | + password = value.regexpCapture("(?is).*(pwd|password)\\s*=([^;:,]*).*", 2).trim() and + not isNotPassword(password) + ) +} + +from XMLAttribute nameAttr +where + nameAttr.getName().toLowerCase() in ["password", "pwd"] and + not isNotPassword(nameAttr.getValue().trim()) // Attribute name "password" or "pwd" + or + exists( + XMLAttribute valueAttr // name/value pair like + | + valueAttr.getElement() = nameAttr.getElement() and + nameAttr.getName().toLowerCase() = "name" and + nameAttr.getValue().toLowerCase() in ["password", "pwd"] and + valueAttr.getName().toLowerCase() = "value" and + not isNotPassword(valueAttr.getValue().trim()) + ) + or + hasEmbeddedPassword(nameAttr.getValue().trim()) // Attribute value matches password pattern +select nameAttr, "Plaintext password in configuration file." diff --git a/java/ql/src/experimental/Security/CWE/CWE-555/context.xml b/java/ql/src/experimental/Security/CWE/CWE-555/context.xml new file mode 100644 index 00000000000..8b45d06d253 --- /dev/null +++ b/java/ql/src/experimental/Security/CWE/CWE-555/context.xml @@ -0,0 +1,17 @@ + + + + + + + + + \ No newline at end of file diff --git a/java/ql/src/experimental/CWE-918/RequestForgery.java b/java/ql/src/experimental/Security/CWE/CWE-918/RequestForgery.java similarity index 100% rename from java/ql/src/experimental/CWE-918/RequestForgery.java rename to java/ql/src/experimental/Security/CWE/CWE-918/RequestForgery.java diff --git a/java/ql/src/experimental/CWE-918/RequestForgery.qhelp b/java/ql/src/experimental/Security/CWE/CWE-918/RequestForgery.qhelp similarity index 100% rename from java/ql/src/experimental/CWE-918/RequestForgery.qhelp rename to java/ql/src/experimental/Security/CWE/CWE-918/RequestForgery.qhelp diff --git a/java/ql/src/experimental/CWE-918/RequestForgery.ql b/java/ql/src/experimental/Security/CWE/CWE-918/RequestForgery.ql similarity index 100% rename from java/ql/src/experimental/CWE-918/RequestForgery.ql rename to java/ql/src/experimental/Security/CWE/CWE-918/RequestForgery.ql diff --git a/java/ql/src/experimental/CWE-918/RequestForgery.qll b/java/ql/src/experimental/Security/CWE/CWE-918/RequestForgery.qll similarity index 100% rename from java/ql/src/experimental/CWE-918/RequestForgery.qll rename to java/ql/src/experimental/Security/CWE/CWE-918/RequestForgery.qll diff --git a/java/ql/src/semmle/code/java/Expr.qll b/java/ql/src/semmle/code/java/Expr.qll index 50f4a210d60..aef353088be 100755 --- a/java/ql/src/semmle/code/java/Expr.qll +++ b/java/ql/src/semmle/code/java/Expr.qll @@ -438,7 +438,7 @@ class ArrayCreationExpr extends Expr, @arraycreationexpr { result.getIndex() = index } - /** Gets the initializer of this array creation expression. */ + /** Gets the initializer of this array creation expression, if any. */ ArrayInit getInit() { result.isNthChildOf(this, -2) } /** @@ -446,7 +446,7 @@ class ArrayCreationExpr extends Expr, @arraycreationexpr { */ int getFirstDimensionSize() { if exists(getInit()) - then result = count(getInit().getAnInit()) + then result = getInit().getSize() else result = getDimension(0).(CompileTimeConstantExpr).getIntValue() } @@ -456,7 +456,17 @@ class ArrayCreationExpr extends Expr, @arraycreationexpr { override string getAPrimaryQlClass() { result = "ArrayCreationExpr" } } -/** An array initializer occurs in an array creation expression. */ +/** + * An array initializer consisting of an opening and closing curly bracket and + * optionally containing expressions (which themselves can be array initializers) + * representing the elements of the array. For example: `{ 'a', 'b' }`. + * + * This expression type matches array initializers representing the values for + * annotation elements as well, despite the Java Language Specification considering + * them a separate type, `ElementValueArrayInitializer`. It does however not match + * values for an array annotation element which consist of a single element + * without enclosing curly brackets (as per JLS). + */ class ArrayInit extends Expr, @arrayinit { /** * An expression occurring in this initializer. @@ -469,6 +479,12 @@ class ArrayInit extends Expr, @arrayinit { /** Gets the initializer occurring at the specified (zero-based) position. */ Expr getInit(int index) { result = this.getAnInit() and result.getIndex() = index } + /** + * Gets the number of expressions in this initializer, that is, the size the + * created array will have. + */ + int getSize() { result = count(getAnInit()) } + /** Gets a printable representation of this expression. */ override string toString() { result = "{...}" } diff --git a/java/ql/src/semmle/code/java/JDK.qll b/java/ql/src/semmle/code/java/JDK.qll index d9a1a15e5d3..3b71396c920 100644 --- a/java/ql/src/semmle/code/java/JDK.qll +++ b/java/ql/src/semmle/code/java/JDK.qll @@ -211,6 +211,21 @@ class MethodSystemGetProperty extends Method { } } +/** + * An access to a method named `getProperty` on class `java.lang.System`. + */ +class MethodAccessSystemGetProperty extends MethodAccess { + MethodAccessSystemGetProperty() { getMethod() instanceof MethodSystemGetProperty } + + /** + * Holds if this call has a compile-time constant first argument with the value `propertyName`. + * For example: `System.getProperty("user.dir")`. + */ + predicate hasCompileTimeConstantGetPropertyName(string propertyName) { + this.getArgument(0).(CompileTimeConstantExpr).getStringValue() = propertyName + } +} + /** * Any method named `exit` on class `java.lang.Runtime` or `java.lang.System`. */ diff --git a/java/ql/src/semmle/code/java/Member.qll b/java/ql/src/semmle/code/java/Member.qll index e9d4fe82978..a0e988bd386 100755 --- a/java/ql/src/semmle/code/java/Member.qll +++ b/java/ql/src/semmle/code/java/Member.qll @@ -23,6 +23,14 @@ class Member extends Element, Annotatable, Modifiable, @member { /** Gets the qualified name of this member. */ string getQualifiedName() { result = getDeclaringType().getName() + "." + getName() } + /** + * Holds if this member has the specified name and is declared in the + * specified package and type. + */ + predicate hasQualifiedName(string package, string type, string name) { + this.getDeclaringType().hasQualifiedName(package, type) and this.hasName(name) + } + /** Holds if this member is package protected, that is, neither public nor private nor protected. */ predicate isPackageProtected() { not isPrivate() and diff --git a/java/ql/src/semmle/code/java/dataflow/FlowSources.qll b/java/ql/src/semmle/code/java/dataflow/FlowSources.qll index 2d568670b26..4359fdbcbc2 100644 --- a/java/ql/src/semmle/code/java/dataflow/FlowSources.qll +++ b/java/ql/src/semmle/code/java/dataflow/FlowSources.qll @@ -226,7 +226,7 @@ class EnvInput extends LocalUserInput { ) or // Results from various specific methods. - this.asExpr().(MethodAccess).getMethod() instanceof EnvTaintedMethod + this.asExpr().(MethodAccess).getMethod() instanceof EnvReadMethod or // Access to `System.in`. exists(Field f | this.asExpr() = f.getAnAccess() | f instanceof SystemIn) @@ -292,8 +292,9 @@ private class SpringWebRequestGetMethod extends Method { } } -private class EnvTaintedMethod extends Method { - EnvTaintedMethod() { +/** A method that reads from the environment, such as `System.getProperty` or `System.getenv`. */ +class EnvReadMethod extends Method { + EnvReadMethod() { this instanceof MethodSystemGetenv or this instanceof PropertiesGetPropertyMethod or this instanceof MethodSystemGetProperty diff --git a/java/ql/src/semmle/code/java/dataflow/FlowSteps.qll b/java/ql/src/semmle/code/java/dataflow/FlowSteps.qll index d129ee6544e..cb219650414 100644 --- a/java/ql/src/semmle/code/java/dataflow/FlowSteps.qll +++ b/java/ql/src/semmle/code/java/dataflow/FlowSteps.qll @@ -16,6 +16,7 @@ module Frameworks { private import semmle.code.java.frameworks.Guice private import semmle.code.java.frameworks.Protobuf private import semmle.code.java.frameworks.guava.Guava + private import semmle.code.java.frameworks.apache.Lang } /** diff --git a/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl.qll b/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl.qll index d9f5acdd279..59cc8d529a7 100644 --- a/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl.qll +++ b/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl.qll @@ -3598,6 +3598,7 @@ private module FlowExploration { or exists(PartialPathNodeRev mid | revPartialPathStep(mid, node, sc1, sc2, ap, config) and + not clearsContent(node, ap.getHead()) and not fullBarrier(node, config) and distSink(node.getEnclosingCallable(), config) <= config.explorationLimit() ) @@ -3611,6 +3612,7 @@ private module FlowExploration { exists(PartialPathNodeFwd mid | partialPathStep(mid, node, cc, sc1, sc2, ap, config) and not fullBarrier(node, config) and + not clearsContent(node, ap.getHead().getContent()) and if node instanceof CastingNode then compatibleTypes(getNodeType(node), ap.getType()) else any() diff --git a/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl2.qll b/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl2.qll index d9f5acdd279..59cc8d529a7 100644 --- a/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl2.qll +++ b/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl2.qll @@ -3598,6 +3598,7 @@ private module FlowExploration { or exists(PartialPathNodeRev mid | revPartialPathStep(mid, node, sc1, sc2, ap, config) and + not clearsContent(node, ap.getHead()) and not fullBarrier(node, config) and distSink(node.getEnclosingCallable(), config) <= config.explorationLimit() ) @@ -3611,6 +3612,7 @@ private module FlowExploration { exists(PartialPathNodeFwd mid | partialPathStep(mid, node, cc, sc1, sc2, ap, config) and not fullBarrier(node, config) and + not clearsContent(node, ap.getHead().getContent()) and if node instanceof CastingNode then compatibleTypes(getNodeType(node), ap.getType()) else any() diff --git a/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl3.qll b/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl3.qll index d9f5acdd279..59cc8d529a7 100644 --- a/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl3.qll +++ b/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl3.qll @@ -3598,6 +3598,7 @@ private module FlowExploration { or exists(PartialPathNodeRev mid | revPartialPathStep(mid, node, sc1, sc2, ap, config) and + not clearsContent(node, ap.getHead()) and not fullBarrier(node, config) and distSink(node.getEnclosingCallable(), config) <= config.explorationLimit() ) @@ -3611,6 +3612,7 @@ private module FlowExploration { exists(PartialPathNodeFwd mid | partialPathStep(mid, node, cc, sc1, sc2, ap, config) and not fullBarrier(node, config) and + not clearsContent(node, ap.getHead().getContent()) and if node instanceof CastingNode then compatibleTypes(getNodeType(node), ap.getType()) else any() diff --git a/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl4.qll b/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl4.qll index d9f5acdd279..59cc8d529a7 100644 --- a/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl4.qll +++ b/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl4.qll @@ -3598,6 +3598,7 @@ private module FlowExploration { or exists(PartialPathNodeRev mid | revPartialPathStep(mid, node, sc1, sc2, ap, config) and + not clearsContent(node, ap.getHead()) and not fullBarrier(node, config) and distSink(node.getEnclosingCallable(), config) <= config.explorationLimit() ) @@ -3611,6 +3612,7 @@ private module FlowExploration { exists(PartialPathNodeFwd mid | partialPathStep(mid, node, cc, sc1, sc2, ap, config) and not fullBarrier(node, config) and + not clearsContent(node, ap.getHead().getContent()) and if node instanceof CastingNode then compatibleTypes(getNodeType(node), ap.getType()) else any() diff --git a/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl5.qll b/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl5.qll index d9f5acdd279..59cc8d529a7 100644 --- a/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl5.qll +++ b/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl5.qll @@ -3598,6 +3598,7 @@ private module FlowExploration { or exists(PartialPathNodeRev mid | revPartialPathStep(mid, node, sc1, sc2, ap, config) and + not clearsContent(node, ap.getHead()) and not fullBarrier(node, config) and distSink(node.getEnclosingCallable(), config) <= config.explorationLimit() ) @@ -3611,6 +3612,7 @@ private module FlowExploration { exists(PartialPathNodeFwd mid | partialPathStep(mid, node, cc, sc1, sc2, ap, config) and not fullBarrier(node, config) and + not clearsContent(node, ap.getHead().getContent()) and if node instanceof CastingNode then compatibleTypes(getNodeType(node), ap.getType()) else any() diff --git a/java/ql/src/semmle/code/java/dataflow/internal/TaintTrackingUtil.qll b/java/ql/src/semmle/code/java/dataflow/internal/TaintTrackingUtil.qll index b627d59783f..69189d949f1 100644 --- a/java/ql/src/semmle/code/java/dataflow/internal/TaintTrackingUtil.qll +++ b/java/ql/src/semmle/code/java/dataflow/internal/TaintTrackingUtil.qll @@ -345,7 +345,9 @@ private predicate taintPreservingQualifierToMethod(Method m) { m.getDeclaringType() instanceof TypeUri and m.hasName("toURL") or - m instanceof GetterMethod and m.getDeclaringType() instanceof SpringUntrustedDataType + m instanceof GetterMethod and + m.getDeclaringType().getASubtype*() instanceof SpringUntrustedDataType and + not m.getDeclaringType() instanceof TypeObject or m.getDeclaringType() instanceof SpringHttpEntity and m.getName().regexpMatch("getBody|getHeaders") diff --git a/java/ql/src/semmle/code/java/frameworks/Networking.qll b/java/ql/src/semmle/code/java/frameworks/Networking.qll index 988510dd2e9..cad948ed2f4 100644 --- a/java/ql/src/semmle/code/java/frameworks/Networking.qll +++ b/java/ql/src/semmle/code/java/frameworks/Networking.qll @@ -129,3 +129,14 @@ class UrlOpenConnectionMethod extends Method { this.getName() = "openConnection" } } + +/** + * A string matching private host names of IPv4 and IPv6, which only matches the host portion therefore checking for port is not necessary. + * Several examples are localhost, reserved IPv4 IP addresses including 127.0.0.1, 10.x.x.x, 172.16.x,x, 192.168.x,x, and reserved IPv6 addresses including [0:0:0:0:0:0:0:1] and [::1] + */ +class PrivateHostName extends string { + bindingset[this] + PrivateHostName() { + this.regexpMatch("(?i)localhost(?:[:/?#].*)?|127\\.0\\.0\\.1(?:[:/?#].*)?|10(?:\\.[0-9]+){3}(?:[:/?#].*)?|172\\.16(?:\\.[0-9]+){2}(?:[:/?#].*)?|192.168(?:\\.[0-9]+){2}(?:[:/?#].*)?|\\[?0:0:0:0:0:0:0:1\\]?(?:[:/?#].*)?|\\[?::1\\]?(?:[:/?#].*)?") + } +} diff --git a/java/ql/src/semmle/code/java/frameworks/SnakeYaml.qll b/java/ql/src/semmle/code/java/frameworks/SnakeYaml.qll index 5c277b7200b..db5687f916a 100644 --- a/java/ql/src/semmle/code/java/frameworks/SnakeYaml.qll +++ b/java/ql/src/semmle/code/java/frameworks/SnakeYaml.qll @@ -7,13 +7,6 @@ import semmle.code.java.dataflow.DataFlow import semmle.code.java.dataflow.DataFlow2 import semmle.code.java.dataflow.DataFlow3 -/** - * The class `org.yaml.snakeyaml.constructor.Constructor`. - */ -class SnakeYamlConstructor extends RefType { - SnakeYamlConstructor() { this.hasQualifiedName("org.yaml.snakeyaml.constructor", "Constructor") } -} - /** * The class `org.yaml.snakeyaml.constructor.SafeConstructor`. */ @@ -24,15 +17,10 @@ class SnakeYamlSafeConstructor extends RefType { } /** - * An instance of `SafeConstructor` or a `Constructor` that only allows the type that is passed into its argument. + * An instance of `SafeConstructor`. */ class SafeSnakeYamlConstruction extends ClassInstanceExpr { - SafeSnakeYamlConstruction() { - this.getConstructedType() instanceof SnakeYamlSafeConstructor - or - this.getConstructedType() instanceof SnakeYamlConstructor and - this.getNumArgument() > 0 - } + SafeSnakeYamlConstruction() { this.getConstructedType() instanceof SnakeYamlSafeConstructor } } /** diff --git a/java/ql/src/semmle/code/java/frameworks/android/SharedPreferences.qll b/java/ql/src/semmle/code/java/frameworks/android/SharedPreferences.qll new file mode 100644 index 00000000000..a3298fd70d8 --- /dev/null +++ b/java/ql/src/semmle/code/java/frameworks/android/SharedPreferences.qll @@ -0,0 +1,57 @@ +/** Provides classes related to `android.content.SharedPreferences`. */ + +import java + +/** The interface `android.content.SharedPreferences`. */ +class SharedPreferences extends Interface { + SharedPreferences() { this.hasQualifiedName("android.content", "SharedPreferences") } +} + +/** The class `androidx.security.crypto.EncryptedSharedPreferences`, which implements `SharedPreferences` with encryption support. */ +class EncryptedSharedPreferences extends Class { + EncryptedSharedPreferences() { + this.hasQualifiedName("androidx.security.crypto", "EncryptedSharedPreferences") + } +} + +/** The `create` method of `androidx.security.crypto.EncryptedSharedPreferences`. */ +class CreateEncryptedSharedPreferencesMethod extends Method { + CreateEncryptedSharedPreferencesMethod() { + this.getDeclaringType() instanceof EncryptedSharedPreferences and + this.hasName("create") + } +} + +/** The method `android.content.SharedPreferences::edit`, which returns an `android.content.SharedPreferences.Editor`. */ +class GetSharedPreferencesEditorMethod extends Method { + GetSharedPreferencesEditorMethod() { + this.getDeclaringType() instanceof SharedPreferences and + this.hasName("edit") and + this.getReturnType() instanceof SharedPreferencesEditor + } +} + +/** The interface `android.content.SharedPreferences.Editor`. */ +class SharedPreferencesEditor extends Interface { + SharedPreferencesEditor() { this.hasQualifiedName("android.content", "SharedPreferences$Editor") } +} + +/** + * A method that updates a key-value pair in a + * `android.content.SharedPreferences` through a `SharedPreferences.Editor`. The + * value is not written until a `StorePreferenceMethod` is called. + */ +class PutSharedPreferenceMethod extends Method { + PutSharedPreferenceMethod() { + this.getDeclaringType() instanceof SharedPreferencesEditor and + this.getName().matches("put%") + } +} + +/** A method on `SharedPreferences.Editor` that writes the pending changes to the underlying `android.content.SharedPreferences`. */ +class StoreSharedPreferenceMethod extends Method { + StoreSharedPreferenceMethod() { + this.getDeclaringType() instanceof SharedPreferencesEditor and + this.hasName(["commit", "apply"]) + } +} diff --git a/java/ql/src/semmle/code/java/frameworks/apache/Lang.qll b/java/ql/src/semmle/code/java/frameworks/apache/Lang.qll index dcf91b36132..6f5c8e0d8d1 100644 --- a/java/ql/src/semmle/code/java/frameworks/apache/Lang.qll +++ b/java/ql/src/semmle/code/java/frameworks/apache/Lang.qll @@ -1,27 +1,65 @@ /** Definitions related to the Apache Commons Lang library. */ import java +private import semmle.code.java.dataflow.FlowSteps -/*--- Types ---*/ -/** The class `org.apache.commons.lang.RandomStringUtils` or `org.apache.commons.lang3.RandomStringUtils`. */ +/** + * The class `org.apache.commons.lang.RandomStringUtils` or `org.apache.commons.lang3.RandomStringUtils`. + */ class TypeApacheRandomStringUtils extends Class { TypeApacheRandomStringUtils() { - hasQualifiedName("org.apache.commons.lang", "RandomStringUtils") or - hasQualifiedName("org.apache.commons.lang3", "RandomStringUtils") + this.hasQualifiedName(["org.apache.commons.lang", "org.apache.commons.lang3"], + "RandomStringUtils") + } +} + +/** + * The class `org.apache.commons.lang.ArrayUtils` or `org.apache.commons.lang3.ArrayUtils`. + */ +class TypeApacheArrayUtils extends Class { + TypeApacheArrayUtils() { + hasQualifiedName(["org.apache.commons.lang", "org.apache.commons.lang3"], "ArrayUtils") } } -/*--- Methods ---*/ /** * The method `deserialize` in either `org.apache.commons.lang.SerializationUtils` * or `org.apache.commons.lang3.SerializationUtils`. */ class MethodApacheSerializationUtilsDeserialize extends Method { MethodApacheSerializationUtilsDeserialize() { - ( - this.getDeclaringType().hasQualifiedName("org.apache.commons.lang", "SerializationUtils") or - this.getDeclaringType().hasQualifiedName("org.apache.commons.lang3", "SerializationUtils") - ) and + this.getDeclaringType() + .hasQualifiedName(["org.apache.commons.lang", "org.apache.commons.lang3"], + "SerializationUtils") and this.hasName("deserialize") } } + +/** + * A taint preserving method on `org.apache.commons.lang.ArrayUtils` or `org.apache.commons.lang3.ArrayUtils` + */ +private class ApacheLangArrayUtilsTaintPreservingMethod extends TaintPreservingCallable { + ApacheLangArrayUtilsTaintPreservingMethod() { + this.getDeclaringType() instanceof TypeApacheArrayUtils + } + + override predicate returnsTaintFrom(int src) { + this.hasName(["addAll", "addFirst"]) and + src = [0 .. getNumberOfParameters() - 1] + or + this.hasName([ + "clone", "nullToEmpty", "remove", "removeAll", "removeElement", "removeElements", "reverse", + "shift", "shuffle", "subarray", "swap", "toArray", "toMap", "toObject", "toPrimitive", + "toString", "toStringArray" + ]) and + src = 0 + or + this.hasName("add") and + this.getNumberOfParameters() = 2 and + src = [0, 1] + or + this.hasName("add") and + this.getNumberOfParameters() = 3 and + src = [0, 2] + } +} diff --git a/java/ql/src/semmle/code/java/frameworks/guava/Collections.qll b/java/ql/src/semmle/code/java/frameworks/guava/Collections.qll new file mode 100644 index 00000000000..58558b2ffc0 --- /dev/null +++ b/java/ql/src/semmle/code/java/frameworks/guava/Collections.qll @@ -0,0 +1,360 @@ +/** Definitions of flow steps through the collection types in the Guava framework */ + +import java +private import semmle.code.java.dataflow.DataFlow +private import semmle.code.java.dataflow.FlowSteps +private import semmle.code.java.Collections + +private string guavaCollectPackage() { result = "com.google.common.collect" } + +/** A reference type that extends a parameterization of one of the various immutable container types. */ +private class ImmutableContainerType extends RefType { + string kind; + + ImmutableContainerType() { + this.getSourceDeclaration().getASourceSupertype*().hasQualifiedName(guavaCollectPackage(), kind) and + kind = ["ImmutableCollection", "ImmutableMap", "ImmutableMultimap", "ImmutableTable"] + } + + /** + * Gets the name of the most general superclass of this type + * from among `ImmutableCollection`, `ImmutableMap`, `ImmutableMultimap`, and `ImmutableTable`. + */ + string getKind() { result = kind } +} + +/** A nested `Builder` class of one of the various immutable container classes */ +private class ContainerBuilder extends NestedType { + ContainerBuilder() { + this.hasName("Builder") and + this.getEnclosingType() instanceof ImmutableContainerType + } +} + +private class BuilderBuildMethod extends TaintPreservingCallable { + BuilderBuildMethod() { + this.getDeclaringType().getASourceSupertype*() instanceof ContainerBuilder and + // abstract ImmutableCollection build() + // similar for other builder types + this.hasName("build") + } + + override predicate returnsTaintFrom(int arg) { arg = -1 } +} + +/** A method on a `Builder` class that adds elements to the container being built */ +private class BuilderAddMethod extends TaintPreservingCallable { + int argument; + + BuilderAddMethod() { + this.getDeclaringType().getASourceSupertype*() instanceof ContainerBuilder and + ( + // abstract ImmutableCollection.Builder add(E element) + // ImmutableCollection.Builder add(E... elements) + // ImmutableCollection.Builder addAll(Iterable elements) + // ImmutableCollection.Builder addAll(Iterator elements) + // ImmutableMultiset.Builder addCopies(E element, int occurrences) + // ImmutableMultiset.Builder setCount(E element, int count) + this.hasName(["add", "addAll", "addCopies", "setCount"]) and + argument = 0 + or + // ImmutableMap.Builder put(K key, V value) + // ImmutableMap.Builder put(Map.Entry entry) + // ImmutableMap.Builder putAll(Map map) + // ImmutableMap.Builder putAll(Iterable> entries) + // ImmutableMultimap.Builder put(K key, V value) + // ImmutableMultimap.Builder put(Map.Entry entry) + // ImmutableMultimap.Builder putAll(Iterable> entries) + // ImmutableMultimap.Builder putAll(K key, Iterable values) + // ImmutableMultimap.Builder putAll(K key, V... values) + // ImmutableMultimap.Builder putAll(Multimap multimap) + // ImmutableTable.Builder put(R rowKey, C columnKey, V value) + // ImmutableTable.Builder put(Table.Cell cell) + // ImmutableTable.Builder putAll(Table table) + this.hasName(["put", "putAll"]) and + argument = getNumberOfParameters() - 1 + ) + } + + override predicate returnsTaintFrom(int arg) { arg = [-1, argument] } + + override predicate transfersTaint(int src, int sink) { src = argument and sink = -1 } +} + +/** + * In a chained call `b.add(x).add(y).add(z)`, represents a flow step from the return value of + * this expression to the post update node of `b` (valid because the builder add methods return their qualifier). + * This is sufficient to express flow from `y` and `z` to `b`. + */ +private class ChainedBuilderAddStep extends AdditionalTaintStep { + override predicate step(DataFlow::Node src, DataFlow::Node sink) { + exists(MethodAccess ma | + ma.getMethod() instanceof BuilderAddMethod and + src.asExpr() = ma and + chainedBuilderMethod+(sink.(DataFlow::PostUpdateNode).getPreUpdateNode().asExpr()) = ma + ) + } +} + +private MethodAccess chainedBuilderMethod(Expr e) { + result.getQualifier() = e and + result.getMethod() instanceof BuilderAddMethod +} + +/** + * A reference type that extends a parameterization of `com.google.common.collect.Multimap`. + */ +class MultimapType extends RefType { + MultimapType() { + this.getSourceDeclaration() + .getASourceSupertype*() + .hasQualifiedName(guavaCollectPackage(), "Multimap") + } + + /** Gets the type of keys stored in this map. */ + RefType getKeyType() { + exists(GenericInterface map | map.hasQualifiedName(guavaCollectPackage(), "Multimap") | + indirectlyInstantiates(this, map, 0, result) + ) + } + + /** Gets the type of values stored in this map. */ + RefType getValueType() { + exists(GenericInterface map | map.hasQualifiedName(guavaCollectPackage(), "Multimap") | + indirectlyInstantiates(this, map, 1, result) + ) + } +} + +private class MultimapWriteMethod extends TaintPreservingCallable { + MultimapWriteMethod() { + this.getDeclaringType() instanceof MultimapType and + // boolean put(K key, V value) + // boolean putAll(K key, Iterable values) + // boolean putAll(Multimap multimap) + // Collection replaceValues(K key, Iterable values) + this.hasName(["put", "putAll", "replaceValues"]) + } + + override predicate transfersTaint(int src, int sink) { + src = getNumberOfParameters() - 1 and + sink = -1 + } +} + +private class MultimapReadMethod extends TaintPreservingCallable { + MultimapReadMethod() { + this.getDeclaringType() instanceof MultimapType and + // Collection replaceValues(K key, Iterable values) + // Collection removeAll(@CompatibleWith("K") Object key) + // Collection get(K key) + // Collection values() + // Collection> entries() + // Map> asMap() + this.hasName(["replaceValues", "removeAll", "get", "values", "entries", "asMap"]) + } + + override predicate returnsTaintFrom(int arg) { arg = -1 } + // Not implemented: Some of these methods return "views", which when modified will modify the map itself. + // However, taint flow from these views to the map is not implemented. +} + +/** + * A reference type that extends a parameterization of `com.google.common.collect.Table`. + */ +class TableType extends RefType { + TableType() { + this.getSourceDeclaration() + .getASourceSupertype*() + .hasQualifiedName(guavaCollectPackage(), "Table") + } + + /** Gets the type of row keys stored in this table. */ + RefType getRowType() { + exists(GenericInterface table | table.hasQualifiedName(guavaCollectPackage(), "Table") | + indirectlyInstantiates(this, table, 0, result) + ) + } + + /** Gets the type of column keys stored in this table. */ + RefType getColumnType() { + exists(GenericInterface table | table.hasQualifiedName(guavaCollectPackage(), "Table") | + indirectlyInstantiates(this, table, 1, result) + ) + } + + /** Gets the type of values stored in this table. */ + RefType getValueType() { + exists(GenericInterface table | table.hasQualifiedName(guavaCollectPackage(), "Table") | + indirectlyInstantiates(this, table, 2, result) + ) + } +} + +private class TableWriteMethod extends TaintPreservingCallable { + TableWriteMethod() { + this.getDeclaringType() instanceof TableType and + // V put(R rowKey, C columnKey, V value) + // void putAll(Table table) + this.hasName(["put", "putAll"]) + } + + override predicate transfersTaint(int src, int sink) { + src = getNumberOfParameters() - 1 and + sink = -1 + } +} + +private class TableReadMethod extends TaintPreservingCallable { + TableReadMethod() { + this.getDeclaringType() instanceof TableType and + // V put(R rowKey, C columnKey, V value) + // V remove(@CompatibleWith("R") Object rowKey, @CompatibleWith("C") Object columnKey) + // V get(@CompatibleWith("R") Object rowKey, @CompatibleWith("C") Object columnKey) + // Map row(R rowKey) + // Map column(C columnKey) + // Set> cellSet() + // Collection values() + // Map> rowMap() + // Map> columnMap() + this.hasName([ + "put", "remove", "get", "row", "column", "cellSet", "values", "rowMap", "columnMap" + ]) + } + + override predicate returnsTaintFrom(int arg) { arg = -1 } + // Not implemented: Some of these methods return "views", which when modified will modify the table itself. + // However, taint flow from these views to the table is not implemented. +} + +private class TableCellReadMethod extends TaintPreservingCallable { + TableCellReadMethod() { + exists(NestedType cell | + cell.getEnclosingType() instanceof TableType and + cell.hasName("Cell") and + this.getDeclaringType().getSourceDeclaration().getASourceSupertype*() = cell and + // V getValue() + this.hasName("getValue") + ) + } + + override predicate returnsTaintFrom(int arg) { arg = -1 } +} + +/** + * An `of` static method on the various immutable container types. + */ +private class OfMethod extends TaintPreservingCallable { + string kind; + + OfMethod() { + this.getDeclaringType().(ImmutableContainerType).getKind() = kind and + // static ImmutableList of(E e1, E e2, E e3, E e4, E e5, E e6) + // static ImmutableMap of(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4) + // static ImmutableMultimap of(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4) + // static ImmutableTable of(R rowKey, C columnKey, V value) + // etc for other types and numbers of parameters + this.hasName("of") and + this.isStatic() + } + + override predicate returnsTaintFrom(int arg) { + arg = [0 .. getNumberOfParameters()] and + (kind.regexpMatch(".*[Mm]ap") implies arg % 2 = 1) and + (kind = "ImmutableTable" implies arg % 3 = 2) + } +} + +private class ComparatorType extends RefType { + ComparatorType() { this.getASourceSupertype*().hasQualifiedName("java.util", "Comparator") } +} + +/** + * A `copyOf`, `sortedCopyOf`, or `copyOfSorted` static method on the various immutable container types. + */ +private class CopyOfMethod extends TaintPreservingCallable { + CopyOfMethod() { + this.getDeclaringType() instanceof ImmutableContainerType and + // static ImmutableList copyOf(E[] elements) + // static ImmutableList copyOf(Iterable elements) + // static ImmutableList copyOf(Collection elements) + // static ImmutableList copyOf(Iterator elements) + // static > ImmutableList sortedCopyOf(Iterable elements) + // static ImmutableList sortedCopyOf(Comparator comparator, Iterable elements) + // static ImmutableMap copyOf(Map map) + // static ImmutableMap copyOf(Iterable> entries) + // static ImmutableMultimap copyOf(Multimap multimap) + // static ImmutableMultimap copyOf(Iterable> entries) + // static ImmutableTable copyOf(Table table) + // static ImmutableSortedMap copyOf(Map map) + // static ImmutableSortedMap copyOf(Map map, Comparator comparator) + // static ImmutableSortedMap copyOfSorted(SortedMap map) + // static ImmutableSortedSet copyOf(Iterator elements) + // static ImmutableSortedSet copyOf(Comparator comparator, Iterator elements) + // static ImmutableSortedSet copyOfSorted(SortedSet sortedSet) + // etc + this.hasName(["copyOf", "sortedCopyOf", "copyOfSorted"]) and + this.isStatic() + } + + override predicate returnsTaintFrom(int arg) { + arg = [0 .. getNumberOfParameters()] and + not getParameterType(arg) instanceof ComparatorType + } +} + +private class CollectionAsListMethod extends TaintPreservingCallable { + CollectionAsListMethod() { + this.getDeclaringType() + .getASourceSupertype*() + .hasQualifiedName(guavaCollectPackage(), "ImmutableCollection") and + // public ImmutableList asList() + this.hasName("asList") + } + + override predicate returnsTaintFrom(int arg) { arg = -1 } +} + +/** + * A taint-preserving static method of `com.google.common.collect.Sets`. + */ +private class SetsMethod extends TaintPreservingCallable { + int arg; + + SetsMethod() { + this.getDeclaringType().hasQualifiedName(guavaCollectPackage(), "Sets") and + this.isStatic() and + ( + // static HashSet newHashSet(E... elements) + // static Set newConcurrentHashSet(Iterable elements) + // static CopyOnWriteArraySet newCopyOnWriteArraySet(Iterable elements) + // etc + this.getName().matches("new%Set") and + arg = 0 + or + // static Set> cartesianProduct(List> sets) + // static Set> cartesianProduct(Set... sets) + // static Set> combinations(Set set, int size) + // static Sets.SetView difference(Set set1, Set set2) + // static NavigableSet filter(NavigableSet unfiltered, Predicate predicate) + // static Set filter(Set unfiltered, Predicate predicate) + // static SortedSet filter(SortedSet unfiltered, Predicate predicate) + // static Set> powerSet(Set set) + // static > NavigableSet subSet(NavigableSet set, Range range) + // static NavigableSet synchronizedNavigableSet(NavigableSet navigableSet) + // static NavigableSet unmodifiableNavigableSet(NavigableSet set) + this.hasName([ + "cartesianProduct", "combinations", "difference", "filter", "powerSet", "subSet", + "synchronizedNavigableSet", "unmodifyableNavigableSet" + ]) and + arg = 0 + or + // static Sets.SetView symmetricDifference(Set set1, Set set2) + // static Sets.SetView union(Set set1, Set set2) + this.hasName(["symmetricDifference", "union"]) and + arg = [0, 1] + ) + } + + override predicate returnsTaintFrom(int arg_) { arg_ = arg } +} diff --git a/java/ql/src/semmle/code/java/frameworks/guava/Guava.qll b/java/ql/src/semmle/code/java/frameworks/guava/Guava.qll index 7278ff0277d..c6bdf0ea9b9 100644 --- a/java/ql/src/semmle/code/java/frameworks/guava/Guava.qll +++ b/java/ql/src/semmle/code/java/frameworks/guava/Guava.qll @@ -4,3 +4,5 @@ import java import StringUtils +import Collections +import Preconditions diff --git a/java/ql/src/semmle/code/java/frameworks/guava/Preconditions.qll b/java/ql/src/semmle/code/java/frameworks/guava/Preconditions.qll new file mode 100644 index 00000000000..f9fce517988 --- /dev/null +++ b/java/ql/src/semmle/code/java/frameworks/guava/Preconditions.qll @@ -0,0 +1,23 @@ +/** Definitions of flow steps through the Preconditions class in the Guava framework. */ + +import java +private import semmle.code.java.dataflow.FlowSteps + +/** + * The class `com.google.common.base.Preconditions`. + */ +class TypeGuavaPreconditions extends Class { + TypeGuavaPreconditions() { this.hasQualifiedName("com.google.common.base", "Preconditions") } +} + +/** + * A method that returns its argumnets. + */ +private class GuavaPreconditionsMethod extends TaintPreservingCallable { + GuavaPreconditionsMethod() { + this.getDeclaringType() instanceof TypeGuavaPreconditions and + this.hasName("checkNotNull") + } + + override predicate returnsTaintFrom(int src) { src = 0 } +} diff --git a/java/ql/src/semmle/code/java/security/Encryption.qll b/java/ql/src/semmle/code/java/security/Encryption.qll index ea7a33151f8..ddbaf9cba73 100644 --- a/java/ql/src/semmle/code/java/security/Encryption.qll +++ b/java/ql/src/semmle/code/java/security/Encryption.qll @@ -29,13 +29,32 @@ class SSLContext extends RefType { SSLContext() { hasQualifiedName("javax.net.ssl", "SSLContext") } } +/** The `javax.net.ssl.SSLSession` class. */ +class SSLSession extends RefType { + SSLSession() { hasQualifiedName("javax.net.ssl", "SSLSession") } +} + class HostnameVerifier extends RefType { HostnameVerifier() { hasQualifiedName("javax.net.ssl", "HostnameVerifier") } } +/** The Java class `javax.crypto.KeyGenerator`. */ +class KeyGenerator extends RefType { + KeyGenerator() { this.hasQualifiedName("javax.crypto", "KeyGenerator") } +} + +/** The Java class `java.security.KeyPairGenerator`. */ +class KeyPairGenerator extends RefType { + KeyPairGenerator() { this.hasQualifiedName("java.security", "KeyPairGenerator") } +} + +/** The `verify` method of the class `javax.net.ssl.HostnameVerifier`. */ class HostnameVerifierVerify extends Method { HostnameVerifierVerify() { - hasName("verify") and getDeclaringType().getASupertype*() instanceof HostnameVerifier + hasName("verify") and + getDeclaringType().getASupertype*() instanceof HostnameVerifier and + getParameterType(0) instanceof TypeString and + getParameterType(1) instanceof SSLSession } } @@ -74,6 +93,14 @@ class SetHostnameVerifierMethod extends Method { } } +/** The `setDefaultHostnameVerifier` method of the class `javax.net.ssl.HttpsURLConnection`. */ +class SetDefaultHostnameVerifierMethod extends Method { + SetDefaultHostnameVerifierMethod() { + hasName("setDefaultHostnameVerifier") and + getDeclaringType().getASupertype*() instanceof HttpsURLConnection + } +} + bindingset[algorithmString] private string algorithmRegex(string algorithmString) { // Algorithms usually appear in names surrounded by characters that are not @@ -97,7 +124,9 @@ string getAnInsecureAlgorithmName() { result = "RC2" or result = "RC4" or result = "RC5" or - result = "ARCFOUR" // a variant of RC4 + result = "ARCFOUR" or // a variant of RC4 + result = "ECB" or // encryption mode ECB like AES/ECB/NoPadding is vulnerable to replay and other attacks + result = "AES/CBC/PKCS[5|7]Padding" // CBC mode of operation with PKCS#5 (or PKCS#7) padding is vulnerable to padding oracle attacks } /** @@ -139,7 +168,7 @@ string getASecureAlgorithmName() { result = "SHA512" or result = "CCM" or result = "GCM" or - result = "AES" or + result = "AES([^a-zA-Z](?!ECB|CBC/PKCS[5|7]Padding)).*" or result = "Blowfish" or result = "ECIES" } @@ -229,7 +258,7 @@ class JavaxCryptoSecretKey extends JavaxCryptoAlgoSpec { class JavaxCryptoKeyGenerator extends JavaxCryptoAlgoSpec { JavaxCryptoKeyGenerator() { exists(Method m | m.getAReference() = this | - m.getDeclaringType().getQualifiedName() = "javax.crypto.KeyGenerator" and + m.getDeclaringType() instanceof KeyGenerator and m.getName() = "getInstance" ) } @@ -285,3 +314,15 @@ class JavaSecuritySignature extends JavaSecurityAlgoSpec { override Expr getAlgoSpec() { result = this.(ConstructorCall).getArgument(0) } } + +/** A method call to the Java class `java.security.KeyPairGenerator`. */ +class JavaSecurityKeyPairGenerator extends JavaxCryptoAlgoSpec { + JavaSecurityKeyPairGenerator() { + exists(Method m | m.getAReference() = this | + m.getDeclaringType() instanceof KeyPairGenerator and + m.getName() = "getInstance" + ) + } + + override Expr getAlgoSpec() { result = this.(MethodAccess).getArgument(0) } +} diff --git a/java/ql/src/semmle/code/java/security/ExternalAPIs.qll b/java/ql/src/semmle/code/java/security/ExternalAPIs.qll index 57d085eba75..f2675645a6a 100644 --- a/java/ql/src/semmle/code/java/security/ExternalAPIs.qll +++ b/java/ql/src/semmle/code/java/security/ExternalAPIs.qll @@ -75,8 +75,9 @@ class ExternalAPIDataNode extends DataFlow::Node { m.getASourceOverriddenMethod() = call.getCallee().getSourceDeclaration() and m.fromSource() ) and - // Not already modeled as a taint step + // Not already modeled as a taint step (we need both of these to handle `AdditionalTaintStep` subclasses as well) not exists(DataFlow::Node next | TaintTracking::localTaintStep(this, next)) and + not exists(DataFlow::Node next | TaintTracking::defaultAdditionalTaintStep(this, next)) and // Not a call to a known safe external API not call.getCallee() instanceof SafeExternalAPIMethod } diff --git a/java/ql/src/semmle/code/java/security/XmlParsers.qll b/java/ql/src/semmle/code/java/security/XmlParsers.qll index 7701af08923..685c5754fc9 100644 --- a/java/ql/src/semmle/code/java/security/XmlParsers.qll +++ b/java/ql/src/semmle/code/java/security/XmlParsers.qll @@ -481,6 +481,10 @@ class SAXParserFactoryConfig extends ParserConfig { class SafeSAXParserFactory extends VarAccess { SafeSAXParserFactory() { exists(Variable v | v = this.getVariable() | + exists(SAXParserFactoryConfig config | config.getQualifier() = v.getAnAccess() | + config.enables(singleSafeConfig()) + ) + or exists(SAXParserFactoryConfig config | config.getQualifier() = v.getAnAccess() | config .disables(any(ConstantStringExpr s | diff --git a/java/ql/src/semmle/code/xml/MavenPom.qll b/java/ql/src/semmle/code/xml/MavenPom.qll index 0a545c0bc99..f13680b2b44 100644 --- a/java/ql/src/semmle/code/xml/MavenPom.qll +++ b/java/ql/src/semmle/code/xml/MavenPom.qll @@ -28,7 +28,7 @@ class ProtoPom extends XMLElement { Version getVersion() { result = this.getAChild() } /** - * Gets a string representing the version, or an empty string if no version + * Gets a string representing the version, or an empty string if no `version` * tag was provided. */ string getVersionString() { @@ -53,7 +53,7 @@ class Pom extends ProtoPom { Pom() { this.getName() = "project" and // Ignore "dependency-reduced-pom" files - these are generated by the - // shading plugin, and duplicate existing pom files. + // Maven Shade Plugin, and duplicate existing POM files. this.getFile().getStem() != "dependency-reduced-pom" } @@ -77,7 +77,7 @@ class Pom extends ProtoPom { /** Gets a child XML element named "dependencies". */ Dependencies getDependencies() { result = this.getAChild() } - /** Gets a child XML element named `dependencyManagement`. */ + /** Gets a child XML element named "dependencyManagement". */ DependencyManagement getDependencyManagement() { result = getAChild() } /** Gets a Dependency element for this POM. */ @@ -100,7 +100,8 @@ class Pom extends ProtoPom { } /** - * Gets a property value defined for this project with the given name. + * Gets a property value defined for this project with the given name, either in a local + * `` section, or in the `` section of an ancestor POM. */ PomProperty getProperty(string name) { result.getName() = name and @@ -112,7 +113,7 @@ class Pom extends ProtoPom { */ PomElement getProjectProperty() { ( - // It must either be a child of the pom, or a child of the parent node of the pom + // It must either be a child of the POM, or a child of the parent node of the POM result = getAChild() or result = getParentPom().getAChild() and @@ -124,8 +125,8 @@ class Pom extends ProtoPom { } /** - * Resolve the given placeholder (if possible) in the static context of this pom. Resolution - * occurs by considering the properties defined by this project. + * Resolve the given placeholder (if possible) in the static context of this POM. Resolution + * occurs by considering the properties defined by this project or an ancestor project. */ string resolvePlaceholder(string name) { if name.prefix(8) = "project." @@ -142,32 +143,33 @@ class Pom extends ProtoPom { } /** - * Gets all the dependencies that are exported by this pom. An exported dependency is one that - * is transitively available, i.e. one with scope compile. + * Gets all the dependencies that are exported by this POM. An exported dependency is one that + * is transitively available, i.e. one with scope "compile". */ Dependency getAnExportedDependency() { result = getADependency() and result.getScope() = "compile" } /** - * Gets a pom dependency that is exported by this pom. An exported dependency is one that - * is transitively available, i.e. one with scope compile. + * Gets a POM dependency that is exported by this POM. An exported dependency is one that + * is transitively available, i.e. one with scope "compile". */ Pom getAnExportedPom() { result = getAnExportedDependency().getPom() } /** - * Gets the `` element of this pom, if any. + * Gets the `` element of this POM, if any. */ Parent getParentElement() { result = getAChild() } /** - * Gets the pom referred to by the `` element of this pom, if any. + * Gets the POM referred to by the `` element of this POM, if any. */ Pom getParentPom() { result = getParentElement().getPom() } /** * Gets the version specified for dependency `dep` in a `dependencyManagement` - * section if this pom or one of its ancestors. + * section in this POM or one of its ancestors, or an empty string if no version + * is specified. */ string getVersionStringForDependency(Dependency dep) { if exists(getDependencyManagement().getDependency(dep)) @@ -223,12 +225,13 @@ class Dependency extends ProtoPom { Pom getPom() { result.getShortCoordinate() = this.getShortCoordinate() } /** - * Gets the jar file that we think maven resolved this dependency to (if any). + * Gets the jar file that Maven likely resolved this dependency to (if any). + * See `MavenRepo.getAnArtifact(ProtoPom)` for how this match is determined. */ File getJar() { exists(MavenRepo mr | result = mr.getAnArtifact(this)) } /** - * Gets the scope of this dependency. If the scope tag is present, this will + * Gets the scope of this dependency. If the `scope` tag is present, this will * be the string contents of that tag, otherwise it defaults to "compile". */ string getScope() { @@ -249,14 +252,14 @@ class Dependency extends ProtoPom { } /** - * A Maven dependency element that represents an actual dependency from a given pom project. + * A Maven dependency element that represents an actual dependency from a given POM project. */ class PomDependency extends Dependency { PomDependency() { exists(Pom source | - // This dependency must be a dependency of a pom - dependency tags can also appear in the dependency - // management section, where they do not directly contribute to the dependencies of the containing - // pom. + // This dependency must be a dependency of a POM - dependency tags can also appear in the + // dependencyManagement section, where they do not directly contribute to the dependencies of + // the containing POM. source.getADependency() = this and // Consider dependencies that can be used at compile time. ( @@ -284,7 +287,7 @@ class PomElement extends XMLElement { s = allCharactersString() and if s.matches("${%") then - // Resolve the placeholder in the parent pom + // Resolve the placeholder in the parent POM result = getParent*().(Pom).resolvePlaceholder(s.substring(2, s.length() - 1)) else result = s ) @@ -330,7 +333,7 @@ class Dependencies extends PomElement { Dependency getADependency() { result = this.getAChild() } } -/** An XML element named `dependencyManagement`, as found in Maven POM XML files. */ +/** An XML element named "dependencyManagement", as found in Maven POM XML files. */ class DependencyManagement extends PomElement { DependencyManagement() { getName() = "dependencyManagement" } @@ -349,7 +352,7 @@ class DependencyManagement extends PomElement { } /** - * An XML element name "properties", as found in Maven POM XML files. + * An XML element named "properties", as found in Maven POM XML files. */ class PomProperties extends PomElement { PomProperties() { this.getName() = "properties" } @@ -366,8 +369,8 @@ class PomProperty extends PomElement { } /** - * A folder that represents a maven local repository using the standard layout. Any folder called - * "repository" with a parent name ".m2" is considered to be a maven repository. + * A folder that represents a local Maven repository using the standard layout. Any folder called + * "repository" with a parent name ".m2" is considered to be a Maven repository. */ class MavenRepo extends Folder { MavenRepo() { getBaseName() = "repository" and getParentContainer().getBaseName() = ".m2" } @@ -378,10 +381,10 @@ class MavenRepo extends Folder { File getAJarFile() { result = getAChildContainer*().(File) and result.getExtension() = "jar" } /** - * Gets any jar artifacts in this repository that match the pom project definition. This is an - * over approximation. For soft qualifiers (e.g. 1.0) we return precise matches in preference to - * artefact only matches. For hard qualifiers (e.g. [1.0]) we return only precise matches. For - * all other qualifiers, we return all matches regardless of version. + * Gets any jar artifacts in this repository that match the POM project definition. This is an + * over approximation. For soft qualifiers (e.g. 1.0) precise matches are returned in preference + * to artifact-only matches. For hard qualifiers (e.g. [1.0]) only precise matches are returned. + * For all other qualifiers, all matches are returned regardless of version. */ MavenRepoJar getAnArtifact(ProtoPom pom) { result = getAJarFile() and @@ -389,7 +392,7 @@ class MavenRepo extends Folder { then // Either a hard match qualifier, or soft and there is at least one precise match result.preciseMatch(pom) - else result.artefactMatches(pom) + else result.artifactMatches(pom) } } @@ -401,16 +404,19 @@ private predicate versionHardMatch(ProtoPom pom) { } /** - * A jar file inside a maven repository. + * A jar file inside a Maven repository. * * See: https://cwiki.apache.org/confluence/display/MAVENOLD/Repository+Layout+-+Final */ class MavenRepoJar extends File { MavenRepoJar() { exists(MavenRepo mr | mr.getAJarFile() = this) } - string getGroupID() { + /** + * Gets the `groupId` of this jar. + */ + string getGroupId() { exists(MavenRepo mr | mr.getAJarFile() = this | - // Assuming the standard layout, the first part of the directory structure from the maven + // Assuming the standard layout, the first part of the directory structure from the Maven // repository will be the groupId converted to a path by replacing "." with "/". result = getParentContainer() @@ -422,24 +428,45 @@ class MavenRepoJar extends File { ) } - string getArtefactID() { result = getParentContainer().getParentContainer().getBaseName() } + /** + * DEPRECATED: name changed to `getGroupId` for consistent use of camel-case. + */ + deprecated string getGroupID() { result = getGroupId() } + /** + * Gets the `artifactId` of this jar. + */ + string getArtifactId() { result = getParentContainer().getParentContainer().getBaseName() } + + /** + * DEPRECATED: name changed to `getArtifactId` for consistent casing and consistent spelling with Maven. + */ + deprecated string getArtefactID() { result = getArtifactId() } + + /** + * Gets the artifact version string of this jar. + */ string getVersion() { result = getParentContainer().getBaseName() } /** - * Holds if this jar is an artefact for the given pom or dependency, regardless of which version it is. + * Holds if this jar is an artifact for the given POM or dependency, regardless of which version it is. */ - predicate artefactMatches(ProtoPom pom) { - pom.getGroup().getValue() = getGroupID() and - pom.getArtifact().getValue() = getArtefactID() + predicate artifactMatches(ProtoPom pom) { + pom.getGroup().getValue() = getGroupId() and + pom.getArtifact().getValue() = getArtifactId() } /** - * Holds if this jar is both an artefact for the pom, and has a version string that matches the pom + * DEPRECATED: name changed to `artifactMatches` for consistent spelling with Maven. + */ + deprecated predicate artefactMatches(ProtoPom pom) { artifactMatches(pom) } + + /** + * Holds if this jar is both an artifact for the POM, and has a version string that matches the POM * version string. Only soft and hard version matches are supported. */ predicate preciseMatch(ProtoPom pom) { - artefactMatches(pom) and + artifactMatches(pom) and if versionHardMatch(pom) then ("[" + getVersion() + "]").matches(pom.getVersionString() + "%") else getVersion().matches(pom.getVersionString() + "%") diff --git a/java/ql/test/experimental/query-tests/security/CWE-273/UnsafeCertTrust.expected b/java/ql/test/experimental/query-tests/security/CWE-273/UnsafeCertTrust.expected index c0ea40f9bdb..5d2da21289e 100644 --- a/java/ql/test/experimental/query-tests/security/CWE-273/UnsafeCertTrust.expected +++ b/java/ql/test/experimental/query-tests/security/CWE-273/UnsafeCertTrust.expected @@ -1,7 +1,5 @@ | UnsafeCertTrustTest.java:27:4:27:74 | init(...) | Unsafe configuration of trusted certificates | | UnsafeCertTrustTest.java:42:4:42:38 | init(...) | Unsafe configuration of trusted certificates | -| UnsafeCertTrustTest.java:55:3:60:4 | setDefaultHostnameVerifier(...) | Unsafe configuration of trusted certificates | -| UnsafeCertTrustTest.java:73:3:73:57 | setDefaultHostnameVerifier(...) | Unsafe configuration of trusted certificates | -| UnsafeCertTrustTest.java:124:25:124:52 | createSSLEngine(...) | Unsafe configuration of trusted certificates | -| UnsafeCertTrustTest.java:135:25:135:52 | createSSLEngine(...) | Unsafe configuration of trusted certificates | -| UnsafeCertTrustTest.java:144:34:144:83 | createSocket(...) | Unsafe configuration of trusted certificates | +| UnsafeCertTrustTest.java:92:25:92:52 | createSSLEngine(...) | Unsafe configuration of trusted certificates | +| UnsafeCertTrustTest.java:103:25:103:52 | createSSLEngine(...) | Unsafe configuration of trusted certificates | +| UnsafeCertTrustTest.java:112:34:112:83 | createSocket(...) | Unsafe configuration of trusted certificates | diff --git a/java/ql/test/experimental/query-tests/security/CWE-273/UnsafeCertTrustTest.java b/java/ql/test/experimental/query-tests/security/CWE-273/UnsafeCertTrustTest.java index ff62035fd33..1e8ecbbc20d 100644 --- a/java/ql/test/experimental/query-tests/security/CWE-273/UnsafeCertTrustTest.java +++ b/java/ql/test/experimental/query-tests/security/CWE-273/UnsafeCertTrustTest.java @@ -48,31 +48,6 @@ public class UnsafeCertTrustTest { } } - /** - * Test the implementation of trusting all hostnames as an anonymous class - */ - public void testTrustAllHostnameOfAnonymousClass() { - HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() { - @Override - public boolean verify(String hostname, SSLSession session) { - return true; // Noncompliant - } - }); - } - - /** - * Test the implementation of trusting all hostnames as a variable - */ - public void testTrustAllHostnameOfVariable() { - HostnameVerifier verifier = new HostnameVerifier() { - @Override - public boolean verify(String hostname, SSLSession session) { - return true; // Noncompliant - } - }; - HttpsURLConnection.setDefaultHostnameVerifier(verifier); - } - private static final X509TrustManager TRUST_ALL_CERTIFICATES = new X509TrustManager() { @Override public void checkClientTrusted(final X509Certificate[] chain, final String authType) @@ -109,17 +84,10 @@ public class UnsafeCertTrustTest { } }; - public static final HostnameVerifier ALLOW_ALL_HOSTNAME_VERIFIER = new HostnameVerifier() { - @Override - public boolean verify(String hostname, SSLSession session) { - return true; // Noncompliant - } - }; - /** * Test the endpoint identification of SSL engine is set to null */ - public void testSSLEngineEndpointIdSetNull() { + public void testSSLEngineEndpointIdSetNull() throws java.security.NoSuchAlgorithmException { SSLContext sslContext = SSLContext.getInstance("TLS"); SSLEngine sslEngine = sslContext.createSSLEngine(); SSLParameters sslParameters = sslEngine.getSSLParameters(); @@ -130,7 +98,7 @@ public class UnsafeCertTrustTest { /** * Test the endpoint identification of SSL engine is not set */ - public void testSSLEngineEndpointIdNotSet() { + public void testSSLEngineEndpointIdNotSet() throws java.security.NoSuchAlgorithmException { SSLContext sslContext = SSLContext.getInstance("TLS"); SSLEngine sslEngine = sslContext.createSSLEngine(); } @@ -138,7 +106,7 @@ public class UnsafeCertTrustTest { /** * Test the endpoint identification of SSL socket is not set */ - public void testSSLSocketEndpointIdNotSet() { + public void testSSLSocketEndpointIdNotSet() throws java.security.NoSuchAlgorithmException, java.io.IOException { SSLContext sslContext = SSLContext.getInstance("TLS"); final SSLSocketFactory socketFactory = sslContext.getSocketFactory(); SSLSocket socket = (SSLSocket) socketFactory.createSocket("www.example.com", 443); @@ -147,7 +115,7 @@ public class UnsafeCertTrustTest { /** * Test the endpoint identification of regular socket is not set */ - public void testSocketEndpointIdNotSet() { + public void testSocketEndpointIdNotSet() throws java.io.IOException { SocketFactory socketFactory = SocketFactory.getDefault(); Socket socket = socketFactory.createSocket("www.example.com", 80); } @@ -159,4 +127,4 @@ public class UnsafeCertTrustTest { // ConnectionFactory connectionFactory = new ConnectionFactory(); // connectionFactory.useSslProtocol(); // } -} \ No newline at end of file +} diff --git a/java/ql/test/experimental/query-tests/security/CWE-295/jxbrowser-6.23.1/JxBrowserWithoutCertValidation.expected b/java/ql/test/experimental/query-tests/security/CWE-295/jxbrowser-6.23.1/JxBrowserWithoutCertValidation.expected new file mode 100644 index 00000000000..605aca10a26 --- /dev/null +++ b/java/ql/test/experimental/query-tests/security/CWE-295/jxbrowser-6.23.1/JxBrowserWithoutCertValidation.expected @@ -0,0 +1 @@ +| JxBrowserWithoutCertValidationV6_23_1.java:17:27:17:39 | new Browser(...) | This JxBrowser instance may not check HTTPS certificates. | diff --git a/java/ql/test/experimental/query-tests/security/CWE-295/jxbrowser-6.23.1/JxBrowserWithoutCertValidation.qlref b/java/ql/test/experimental/query-tests/security/CWE-295/jxbrowser-6.23.1/JxBrowserWithoutCertValidation.qlref new file mode 100644 index 00000000000..cab6f2a4962 --- /dev/null +++ b/java/ql/test/experimental/query-tests/security/CWE-295/jxbrowser-6.23.1/JxBrowserWithoutCertValidation.qlref @@ -0,0 +1 @@ +experimental/Security/CWE/CWE-295/JxBrowserWithoutCertValidation.ql diff --git a/java/ql/test/experimental/query-tests/security/CWE-295/jxbrowser-6.23.1/JxBrowserWithoutCertValidationV6_23_1.java b/java/ql/test/experimental/query-tests/security/CWE-295/jxbrowser-6.23.1/JxBrowserWithoutCertValidationV6_23_1.java new file mode 100644 index 00000000000..8f7be261413 --- /dev/null +++ b/java/ql/test/experimental/query-tests/security/CWE-295/jxbrowser-6.23.1/JxBrowserWithoutCertValidationV6_23_1.java @@ -0,0 +1,36 @@ +import com.teamdev.jxbrowser.chromium.Browser; +import com.teamdev.jxbrowser.chromium.LoadHandler; +import com.teamdev.jxbrowser.chromium.LoadParams; +import com.teamdev.jxbrowser.chromium.CertificateErrorParams; + +public class JxBrowserWithoutCertValidationV6_23_1 { + + public static void main(String[] args) { + + badUsage(); + + goodUsage(); + + } + + private static void badUsage() { + Browser browser = new Browser(); + browser.loadURL("https://example.com"); + // no further calls + // BAD: The browser ignores any certificate error by default! + } + + private static void goodUsage() { + Browser browser = new Browser(); + browser.setLoadHandler(new LoadHandler() { + public boolean onLoad(LoadParams params) { + return true; + } + + public boolean onCertificateError(CertificateErrorParams params) { + return true; // GOOD: This means that loading will be cancelled on certificate errors + } + }); // GOOD: A secure `LoadHandler` is used. + browser.loadURL("https://example.com"); + } +} \ No newline at end of file diff --git a/java/ql/test/experimental/query-tests/security/CWE-295/jxbrowser-6.23.1/options b/java/ql/test/experimental/query-tests/security/CWE-295/jxbrowser-6.23.1/options new file mode 100644 index 00000000000..37339271f9c --- /dev/null +++ b/java/ql/test/experimental/query-tests/security/CWE-295/jxbrowser-6.23.1/options @@ -0,0 +1 @@ + //semmle-extractor-options: --javac-args -cp ${testdir}/../../../../stubs/jxbrowser-6.23.1 \ No newline at end of file diff --git a/java/ql/test/experimental/query-tests/security/CWE-295/jxbrowser-6.24/JxBrowserWithoutCertValidation.expected b/java/ql/test/experimental/query-tests/security/CWE-295/jxbrowser-6.24/JxBrowserWithoutCertValidation.expected new file mode 100644 index 00000000000..e69de29bb2d diff --git a/java/ql/test/experimental/query-tests/security/CWE-295/jxbrowser-6.24/JxBrowserWithoutCertValidation.qlref b/java/ql/test/experimental/query-tests/security/CWE-295/jxbrowser-6.24/JxBrowserWithoutCertValidation.qlref new file mode 100644 index 00000000000..cab6f2a4962 --- /dev/null +++ b/java/ql/test/experimental/query-tests/security/CWE-295/jxbrowser-6.24/JxBrowserWithoutCertValidation.qlref @@ -0,0 +1 @@ +experimental/Security/CWE/CWE-295/JxBrowserWithoutCertValidation.ql diff --git a/java/ql/test/experimental/query-tests/security/CWE-295/jxbrowser-6.24/JxBrowserWithoutCertValidationV6_24.java b/java/ql/test/experimental/query-tests/security/CWE-295/jxbrowser-6.24/JxBrowserWithoutCertValidationV6_24.java new file mode 100644 index 00000000000..62057fcb8ef --- /dev/null +++ b/java/ql/test/experimental/query-tests/security/CWE-295/jxbrowser-6.24/JxBrowserWithoutCertValidationV6_24.java @@ -0,0 +1,36 @@ +import com.teamdev.jxbrowser.chromium.Browser; +import com.teamdev.jxbrowser.chromium.LoadHandler; +import com.teamdev.jxbrowser.chromium.LoadParams; +import com.teamdev.jxbrowser.chromium.CertificateErrorParams; + +public class JxBrowserWithoutCertValidationV6_24 { + + public static void main(String[] args) { + + goodUsage(); + + goodUsage2(); + + } + + private static void goodUsage() { + Browser browser = new Browser(); + browser.loadURL("https://example.com"); + // no further calls + // GOOD: On version 6.24 the browser properly validates certificates by default! + } + + private static void goodUsage2() { + Browser browser = new Browser(); + browser.setLoadHandler(new LoadHandler() { + public boolean onLoad(LoadParams params) { + return true; + } + + public boolean onCertificateError(CertificateErrorParams params) { + return true; // GOOD: This means that loading will be cancelled on certificate errors + } + }); // GOOD: A secure `LoadHandler` is used. + browser.loadURL("https://example.com"); + } +} \ No newline at end of file diff --git a/java/ql/test/experimental/query-tests/security/CWE-295/jxbrowser-6.24/options b/java/ql/test/experimental/query-tests/security/CWE-295/jxbrowser-6.24/options new file mode 100644 index 00000000000..f001bf777a2 --- /dev/null +++ b/java/ql/test/experimental/query-tests/security/CWE-295/jxbrowser-6.24/options @@ -0,0 +1 @@ + //semmle-extractor-options: --javac-args -cp ${testdir}/../../../../stubs/jxbrowser-6.24 \ No newline at end of file diff --git a/java/ql/test/experimental/query-tests/security/CWE-297/InsecureJavaMail.java b/java/ql/test/experimental/query-tests/security/CWE-297/InsecureJavaMail.java index 05d700437dd..62c64027695 100644 --- a/java/ql/test/experimental/query-tests/security/CWE-297/InsecureJavaMail.java +++ b/java/ql/test/experimental/query-tests/security/CWE-297/InsecureJavaMail.java @@ -29,7 +29,7 @@ class InsecureJavaMail { final Session session = Session.getInstance(properties, authenticator); } - public void testSimpleMail() { + public void testSimpleMail() throws Exception { Email email = new SimpleEmail(); email.setHostName("config.hostName"); email.setSmtpPort(25); @@ -42,4 +42,4 @@ class InsecureJavaMail { email.addTo("toAddress"); email.send(); } -} \ No newline at end of file +} diff --git a/java/ql/test/experimental/query-tests/security/CWE-312/CleartextStorageSharedPrefs.expected b/java/ql/test/experimental/query-tests/security/CWE-312/CleartextStorageSharedPrefs.expected new file mode 100644 index 00000000000..ab1db3fe099 --- /dev/null +++ b/java/ql/test/experimental/query-tests/security/CWE-312/CleartextStorageSharedPrefs.expected @@ -0,0 +1 @@ +| CleartextStorageSharedPrefs.java:19:3:19:17 | commit(...) | 'SharedPreferences' class $@ containing $@ is stored here. Data was added $@. | CleartextStorageSharedPrefs.java:16:19:16:36 | edit(...) | edit(...) | CleartextStorageSharedPrefs.java:18:32:18:39 | password | sensitive data | CleartextStorageSharedPrefs.java:18:32:18:39 | password | here | diff --git a/java/ql/test/experimental/query-tests/security/CWE-312/CleartextStorageSharedPrefs.java b/java/ql/test/experimental/query-tests/security/CWE-312/CleartextStorageSharedPrefs.java new file mode 100644 index 00000000000..39614c82234 --- /dev/null +++ b/java/ql/test/experimental/query-tests/security/CWE-312/CleartextStorageSharedPrefs.java @@ -0,0 +1,109 @@ +import android.app.Activity; +import android.content.Context; +import android.content.SharedPreferences; +import android.content.SharedPreferences.Editor; +import androidx.security.crypto.MasterKey; +import androidx.security.crypto.EncryptedSharedPreferences; +import java.nio.charset.StandardCharsets; +import java.util.Base64; +import java.security.MessageDigest; + +/* Android activity that tests saving sensitive information in `SharedPreferences` */ +public class CleartextStorageSharedPrefs extends Activity { + // BAD - save sensitive information in cleartext + public void testSetSharedPrefs1(Context context, String name, String password) { + SharedPreferences sharedPrefs = context.getSharedPreferences("user_prefs", Context.MODE_PRIVATE); + Editor editor = sharedPrefs.edit(); + editor.putString("name", name); + editor.putString("password", password); + editor.commit(); + } + + // GOOD - save sensitive information in encrypted format + public void testSetSharedPrefs2(Context context, String name, String password) throws Exception { + SharedPreferences sharedPrefs = context.getSharedPreferences("user_prefs", Context.MODE_PRIVATE); + Editor editor = sharedPrefs.edit(); + editor.putString("name", encrypt(name)); + editor.putString("password", encrypt(password)); + editor.commit(); + } + + private static String encrypt(String cleartext) throws Exception { + // Use an encryption or hashing algorithm in real world. The demo below just returns its hash. + MessageDigest digest = MessageDigest.getInstance("SHA-256"); + byte[] hash = digest.digest(cleartext.getBytes(StandardCharsets.UTF_8)); + String encoded = Base64.getEncoder().encodeToString(hash); + return encoded; + } + + // GOOD - save sensitive information in encrypted format using separate variables + public void testSetSharedPrefs3(Context context, String name, String password) throws Exception { + String encUsername = encrypt(name); + String encPassword = encrypt(password); + SharedPreferences sharedPrefs = context.getSharedPreferences("user_prefs", Context.MODE_PRIVATE); + Editor editor = sharedPrefs.edit(); + editor.putString("name", encUsername); + editor.putString("password", encPassword); + editor.commit(); + } + + + // GOOD - save sensitive information using the built-in `EncryptedSharedPreferences` class in androidx + public void testSetSharedPrefs4(Context context, String name, String password) throws Exception { + MasterKey masterKey = new MasterKey.Builder(context, MasterKey.DEFAULT_MASTER_KEY_ALIAS) + .setKeyScheme(MasterKey.KeyScheme.AES256_GCM) + .build(); + + SharedPreferences sharedPreferences = EncryptedSharedPreferences.create( + context, + "secret_shared_prefs", + masterKey, + EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV, + EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM); + + // Use the shared preferences and editor as you normally would + SharedPreferences.Editor editor = sharedPreferences.edit(); + editor.putString("name", name); + editor.putString("password", password); + editor.commit(); + } + + // GOOD - save sensitive information using the built-in `EncryptedSharedPreferences` class in androidx + public void testSetSharedPrefs5(Context context, String name, String password) throws Exception { + MasterKey masterKey = new MasterKey.Builder(context, MasterKey.DEFAULT_MASTER_KEY_ALIAS) + .setKeyScheme(MasterKey.KeyScheme.AES256_GCM) + .build(); + + SharedPreferences.Editor editor = EncryptedSharedPreferences.create( + context, + "secret_shared_prefs", + masterKey, + EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV, + EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM) + .edit(); + + // Use the shared preferences and editor as you normally would + editor.putString("name", name); + editor.putString("password", password); + editor.commit(); + } + + // GOOD - save sensitive information using the built-in `EncryptedSharedPreferences` class in androidx + public void testSetSharedPrefs6(Context context, String name, String password) throws Exception { + MasterKey masterKey = new MasterKey.Builder(context, MasterKey.DEFAULT_MASTER_KEY_ALIAS) + .setKeyScheme(MasterKey.KeyScheme.AES256_GCM) + .build(); + + SharedPreferences.Editor editor = EncryptedSharedPreferences.create( + context, + "secret_shared_prefs", + masterKey, + EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV, + EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM) + .edit() + .putString("name", name) // Use the shared preferences and editor as you normally would + .putString("password", password); + + editor.commit(); + } +} diff --git a/java/ql/test/experimental/query-tests/security/CWE-312/CleartextStorageSharedPrefs.qlref b/java/ql/test/experimental/query-tests/security/CWE-312/CleartextStorageSharedPrefs.qlref new file mode 100644 index 00000000000..9319c78be05 --- /dev/null +++ b/java/ql/test/experimental/query-tests/security/CWE-312/CleartextStorageSharedPrefs.qlref @@ -0,0 +1 @@ +experimental/Security/CWE/CWE-312/CleartextStorageSharedPrefs.ql diff --git a/java/ql/test/experimental/query-tests/security/CWE-312/options b/java/ql/test/experimental/query-tests/security/CWE-312/options new file mode 100644 index 00000000000..43e25f608b6 --- /dev/null +++ b/java/ql/test/experimental/query-tests/security/CWE-312/options @@ -0,0 +1 @@ +// semmle-extractor-options: --javac-args -cp ${testdir}/../../../../stubs/google-android-9.0.0 diff --git a/java/ql/test/experimental/query-tests/security/CWE-326/InsufficientKeySize.expected b/java/ql/test/experimental/query-tests/security/CWE-326/InsufficientKeySize.expected new file mode 100644 index 00000000000..421335b84ff --- /dev/null +++ b/java/ql/test/experimental/query-tests/security/CWE-326/InsufficientKeySize.expected @@ -0,0 +1,11 @@ +| InsufficientKeySize.java:9:9:9:24 | init(...) | Key size should be at least 128 bits for AES encryption. | +| InsufficientKeySize.java:17:9:17:36 | initialize(...) | Key size should be at least 2048 bits for RSA encryption. | +| InsufficientKeySize.java:25:9:25:36 | initialize(...) | Key size should be at least 2048 bits for DSA encryption. | +| InsufficientKeySize.java:34:9:34:39 | initialize(...) | Key size should be at least 256 bits for EC encryption. | +| InsufficientKeySize.java:38:9:38:67 | initialize(...) | Key size should be at least 256 bits for EC encryption. | +| InsufficientKeySize.java:48:9:48:39 | initialize(...) | Key size should be at least 256 bits for EC encryption. | +| InsufficientKeySize.java:53:9:53:39 | initialize(...) | Key size should be at least 256 bits for EC encryption. | +| InsufficientKeySize.java:58:9:58:40 | initialize(...) | Key size should be at least 256 bits for EC encryption. | +| InsufficientKeySize.java:68:9:68:40 | initialize(...) | Key size should be at least 256 bits for EC encryption. | +| InsufficientKeySize.java:78:9:78:40 | initialize(...) | Key size should be at least 256 bits for EC encryption. | +| InsufficientKeySize.java:87:9:87:37 | initialize(...) | Key size should be at least 2048 bits for DH encryption. | diff --git a/java/ql/test/experimental/query-tests/security/CWE-326/InsufficientKeySize.java b/java/ql/test/experimental/query-tests/security/CWE-326/InsufficientKeySize.java new file mode 100644 index 00000000000..a606017a27e --- /dev/null +++ b/java/ql/test/experimental/query-tests/security/CWE-326/InsufficientKeySize.java @@ -0,0 +1,93 @@ +import java.security.KeyPairGenerator; +import java.security.spec.ECGenParameterSpec; +import javax.crypto.KeyGenerator; + +public class InsufficientKeySize { + public void CryptoMethod() throws java.security.NoSuchAlgorithmException, java.security.InvalidAlgorithmParameterException { + KeyGenerator keyGen1 = KeyGenerator.getInstance("AES"); + // BAD: Key size is less than 128 + keyGen1.init(64); + + KeyGenerator keyGen2 = KeyGenerator.getInstance("AES"); + // GOOD: Key size is no less than 128 + keyGen2.init(128); + + KeyPairGenerator keyPairGen1 = KeyPairGenerator.getInstance("RSA"); + // BAD: Key size is less than 2048 + keyPairGen1.initialize(1024); + + KeyPairGenerator keyPairGen2 = KeyPairGenerator.getInstance("RSA"); + // GOOD: Key size is no less than 2048 + keyPairGen2.initialize(2048); + + KeyPairGenerator keyPairGen3 = KeyPairGenerator.getInstance("DSA"); + // BAD: Key size is less than 2048 + keyPairGen3.initialize(1024); + + KeyPairGenerator keyPairGen4 = KeyPairGenerator.getInstance("DSA"); + // GOOD: Key size is no less than 2048 + keyPairGen4.initialize(2048); + + KeyPairGenerator keyPairGen5 = KeyPairGenerator.getInstance("EC"); + // BAD: Key size is less than 256 + ECGenParameterSpec ecSpec1 = new ECGenParameterSpec("secp112r1"); + keyPairGen5.initialize(ecSpec1); + + KeyPairGenerator keyPairGen6 = KeyPairGenerator.getInstance("EC"); + // BAD: Key size is less than 256 + keyPairGen6.initialize(new ECGenParameterSpec("secp112r1")); + + KeyPairGenerator keyPairGen7 = KeyPairGenerator.getInstance("EC"); + // GOOD: Key size is no less than 256 + ECGenParameterSpec ecSpec2 = new ECGenParameterSpec("secp256r1"); + keyPairGen7.initialize(ecSpec2); + + KeyPairGenerator keyPairGen8 = KeyPairGenerator.getInstance("EC"); + // BAD: Key size is less than 256 + ECGenParameterSpec ecSpec3 = new ECGenParameterSpec("X9.62 prime192v2"); + keyPairGen8.initialize(ecSpec3); + + KeyPairGenerator keyPairGen9 = KeyPairGenerator.getInstance("EC"); + // BAD: Key size is less than 256 + ECGenParameterSpec ecSpec4 = new ECGenParameterSpec("X9.62 c2tnb191v3"); + keyPairGen9.initialize(ecSpec4); + + KeyPairGenerator keyPairGen10 = KeyPairGenerator.getInstance("EC"); + // BAD: Key size is less than 256 + ECGenParameterSpec ecSpec5 = new ECGenParameterSpec("sect163k1"); + keyPairGen10.initialize(ecSpec5); + + KeyPairGenerator keyPairGen11 = KeyPairGenerator.getInstance("EC"); + // GOOD: Key size is no less than 256 + ECGenParameterSpec ecSpec6 = new ECGenParameterSpec("X9.62 c2tnb359v1"); + keyPairGen11.initialize(ecSpec6); + + KeyPairGenerator keyPairGen12 = KeyPairGenerator.getInstance("EC"); + // BAD: Key size is less than 256 + ECGenParameterSpec ecSpec7 = new ECGenParameterSpec("prime192v2"); + keyPairGen12.initialize(ecSpec7); + + KeyPairGenerator keyPairGen13 = KeyPairGenerator.getInstance("EC"); + // BAD: Key size is no less than 256 + ECGenParameterSpec ecSpec8 = new ECGenParameterSpec("prime256v1"); + keyPairGen13.initialize(ecSpec8); + + KeyPairGenerator keyPairGen14 = KeyPairGenerator.getInstance("EC"); + // BAD: Key size is less than 256 + ECGenParameterSpec ecSpec9 = new ECGenParameterSpec("c2tnb191v1"); + keyPairGen14.initialize(ecSpec9); + + KeyPairGenerator keyPairGen15 = KeyPairGenerator.getInstance("EC"); + // BAD: Key size is no less than 256 + ECGenParameterSpec ecSpec10 = new ECGenParameterSpec("c2tnb431r1"); + keyPairGen15.initialize(ecSpec10); + + KeyPairGenerator keyPairGen16 = KeyPairGenerator.getInstance("dh"); + // BAD: Key size is less than 2048 + keyPairGen16.initialize(1024); + + KeyPairGenerator keyPairGen17 = KeyPairGenerator.getInstance("DH"); + // GOOD: Key size is no less than 2048 + keyPairGen17.initialize(2048); + } +} diff --git a/java/ql/test/experimental/query-tests/security/CWE-326/InsufficientKeySize.qlref b/java/ql/test/experimental/query-tests/security/CWE-326/InsufficientKeySize.qlref new file mode 100644 index 00000000000..2b35cd6921e --- /dev/null +++ b/java/ql/test/experimental/query-tests/security/CWE-326/InsufficientKeySize.qlref @@ -0,0 +1 @@ +experimental/Security/CWE/CWE-326/InsufficientKeySize.ql \ No newline at end of file diff --git a/java/ql/test/experimental/query-tests/security/CWE-522/InsecureBasicAuth.java b/java/ql/test/experimental/query-tests/security/CWE-522/InsecureBasicAuth.java index 1f7be303471..c59af48e09b 100644 --- a/java/ql/test/experimental/query-tests/security/CWE-522/InsecureBasicAuth.java +++ b/java/ql/test/experimental/query-tests/security/CWE-522/InsecureBasicAuth.java @@ -57,7 +57,7 @@ public class InsecureBasicAuth { /** * Test basic authentication with Apache HTTP POST request using the URI constructor with one argument. */ - public void testApacheHttpRequest4(String username, String password) { + public void testApacheHttpRequest4(String username, String password) throws Exception { String uriStr = "http://www.example.com/rest/getuser.do?uid=abcdx"; URI uri = new URI(uriStr); HttpRequestBase post = new HttpPost(uri); @@ -74,7 +74,7 @@ public class InsecureBasicAuth { /** * Test basic authentication with Apache HTTP POST request using a URI constructor with multiple arguments. */ - public void testApacheHttpRequest5(String username, String password) { + public void testApacheHttpRequest5(String username, String password) throws Exception { HttpRequestBase post = new HttpPost(new URI("http", "www.example.com", "/test", "abc=123", null)); post.setHeader("Accept", "application/json"); post.setHeader("Content-type", "application/json"); @@ -122,7 +122,7 @@ public class InsecureBasicAuth { /** * Test basic authentication with Java HTTP URL connection using the `URL(String spec)` constructor. */ - public void testHttpUrlConnection(String username, String password) { + public void testHttpUrlConnection(String username, String password) throws Exception { String urlStr = "http://www.example.com/rest/getuser.do?uid=abcdx"; String authString = username + ":" + password; String encoding = Base64.getEncoder().encodeToString(authString.getBytes("UTF-8")); @@ -136,7 +136,7 @@ public class InsecureBasicAuth { /** * Test basic authentication with Java HTTP URL connection using the `URL(String protocol, String host, String file)` constructor. */ - public void testHttpUrlConnection2(String username, String password) { + public void testHttpUrlConnection2(String username, String password) throws Exception { String host = "www.example.com"; String path = "/rest/getuser.do?uid=abcdx"; String protocol = "http"; @@ -152,7 +152,7 @@ public class InsecureBasicAuth { /** * Test basic authentication with Java HTTP URL connection using a constructor with private URL. */ - public void testHttpUrlConnection3(String username, String password) { + public void testHttpUrlConnection3(String username, String password) throws Exception { String host = "LOCALHOST"; String authString = username + ":" + password; String encoding = Base64.getEncoder().encodeToString(authString.getBytes("UTF-8")); @@ -161,4 +161,4 @@ public class InsecureBasicAuth { conn.setDoOutput(true); conn.setRequestProperty("Authorization", "Basic " + encoding); } -} \ No newline at end of file +} diff --git a/java/ql/test/experimental/query-tests/security/CWE-522/InsecureLdapAuth.expected b/java/ql/test/experimental/query-tests/security/CWE-522/InsecureLdapAuth.expected new file mode 100644 index 00000000000..863e8e55dcf --- /dev/null +++ b/java/ql/test/experimental/query-tests/security/CWE-522/InsecureLdapAuth.expected @@ -0,0 +1,70 @@ +edges +| InsecureLdapAuth.java:11:20:11:50 | "ldap://ad.your-server.com:389" : String | InsecureLdapAuth.java:20:49:20:59 | environment | +| InsecureLdapAuth.java:17:3:17:13 | environment [post update] : Hashtable | InsecureLdapAuth.java:20:49:20:59 | environment | +| InsecureLdapAuth.java:25:20:25:39 | ... + ... : String | InsecureLdapAuth.java:34:49:34:59 | environment | +| InsecureLdapAuth.java:31:3:31:13 | environment [post update] : Hashtable | InsecureLdapAuth.java:34:49:34:59 | environment | +| InsecureLdapAuth.java:45:3:45:13 | environment [post update] : Hashtable | InsecureLdapAuth.java:48:49:48:59 | environment | +| InsecureLdapAuth.java:53:20:53:50 | "ldap://ad.your-server.com:636" : String | InsecureLdapAuth.java:63:49:63:59 | environment | +| InsecureLdapAuth.java:59:3:59:13 | environment [post update] : Hashtable | InsecureLdapAuth.java:63:49:63:59 | environment | +| InsecureLdapAuth.java:62:3:62:13 | environment [post update] : Hashtable | InsecureLdapAuth.java:63:49:63:59 | environment | +| InsecureLdapAuth.java:68:20:68:50 | "ldap://ad.your-server.com:389" : String | InsecureLdapAuth.java:77:49:77:59 | environment | +| InsecureLdapAuth.java:88:3:88:13 | environment [post update] : Hashtable | InsecureLdapAuth.java:91:49:91:59 | environment | +| InsecureLdapAuth.java:96:20:96:50 | "ldap://ad.your-server.com:389" : String | InsecureLdapAuth.java:105:59:105:69 | environment | +| InsecureLdapAuth.java:102:3:102:13 | environment [post update] : Hashtable | InsecureLdapAuth.java:105:59:105:69 | environment | +| InsecureLdapAuth.java:111:20:111:50 | "ldap://ad.your-server.com:389" : String | InsecureLdapAuth.java:120:49:120:59 | environment | +| InsecureLdapAuth.java:117:3:117:13 | environment [post update] : Hashtable | InsecureLdapAuth.java:120:49:120:59 | environment | +| InsecureLdapAuth.java:124:3:124:5 | env [post update] : Hashtable | InsecureLdapAuth.java:137:10:137:20 | environment [post update] : Hashtable | +| InsecureLdapAuth.java:128:3:128:5 | env [post update] : Hashtable | InsecureLdapAuth.java:141:16:141:26 | environment [post update] : Hashtable | +| InsecureLdapAuth.java:128:3:128:5 | env [post update] : Hashtable | InsecureLdapAuth.java:152:16:152:26 | environment [post update] : Hashtable | +| InsecureLdapAuth.java:135:20:135:39 | ... + ... : String | InsecureLdapAuth.java:142:50:142:60 | environment | +| InsecureLdapAuth.java:137:10:137:20 | environment [post update] : Hashtable | InsecureLdapAuth.java:142:50:142:60 | environment | +| InsecureLdapAuth.java:141:16:141:26 | environment [post update] : Hashtable | InsecureLdapAuth.java:142:50:142:60 | environment | +| InsecureLdapAuth.java:147:20:147:39 | ... + ... : String | InsecureLdapAuth.java:153:50:153:60 | environment | +| InsecureLdapAuth.java:152:16:152:26 | environment [post update] : Hashtable | InsecureLdapAuth.java:153:50:153:60 | environment | +nodes +| InsecureLdapAuth.java:11:20:11:50 | "ldap://ad.your-server.com:389" : String | semmle.label | "ldap://ad.your-server.com:389" : String | +| InsecureLdapAuth.java:17:3:17:13 | environment [post update] : Hashtable | semmle.label | environment [post update] : Hashtable | +| InsecureLdapAuth.java:20:49:20:59 | environment | semmle.label | environment | +| InsecureLdapAuth.java:20:49:20:59 | environment | semmle.label | environment | +| InsecureLdapAuth.java:25:20:25:39 | ... + ... : String | semmle.label | ... + ... : String | +| InsecureLdapAuth.java:31:3:31:13 | environment [post update] : Hashtable | semmle.label | environment [post update] : Hashtable | +| InsecureLdapAuth.java:34:49:34:59 | environment | semmle.label | environment | +| InsecureLdapAuth.java:34:49:34:59 | environment | semmle.label | environment | +| InsecureLdapAuth.java:45:3:45:13 | environment [post update] : Hashtable | semmle.label | environment [post update] : Hashtable | +| InsecureLdapAuth.java:48:49:48:59 | environment | semmle.label | environment | +| InsecureLdapAuth.java:53:20:53:50 | "ldap://ad.your-server.com:636" : String | semmle.label | "ldap://ad.your-server.com:636" : String | +| InsecureLdapAuth.java:59:3:59:13 | environment [post update] : Hashtable | semmle.label | environment [post update] : Hashtable | +| InsecureLdapAuth.java:62:3:62:13 | environment [post update] : Hashtable | semmle.label | environment [post update] : Hashtable | +| InsecureLdapAuth.java:63:49:63:59 | environment | semmle.label | environment | +| InsecureLdapAuth.java:63:49:63:59 | environment | semmle.label | environment | +| InsecureLdapAuth.java:63:49:63:59 | environment | semmle.label | environment | +| InsecureLdapAuth.java:68:20:68:50 | "ldap://ad.your-server.com:389" : String | semmle.label | "ldap://ad.your-server.com:389" : String | +| InsecureLdapAuth.java:77:49:77:59 | environment | semmle.label | environment | +| InsecureLdapAuth.java:88:3:88:13 | environment [post update] : Hashtable | semmle.label | environment [post update] : Hashtable | +| InsecureLdapAuth.java:91:49:91:59 | environment | semmle.label | environment | +| InsecureLdapAuth.java:96:20:96:50 | "ldap://ad.your-server.com:389" : String | semmle.label | "ldap://ad.your-server.com:389" : String | +| InsecureLdapAuth.java:102:3:102:13 | environment [post update] : Hashtable | semmle.label | environment [post update] : Hashtable | +| InsecureLdapAuth.java:105:59:105:69 | environment | semmle.label | environment | +| InsecureLdapAuth.java:105:59:105:69 | environment | semmle.label | environment | +| InsecureLdapAuth.java:111:20:111:50 | "ldap://ad.your-server.com:389" : String | semmle.label | "ldap://ad.your-server.com:389" : String | +| InsecureLdapAuth.java:117:3:117:13 | environment [post update] : Hashtable | semmle.label | environment [post update] : Hashtable | +| InsecureLdapAuth.java:120:49:120:59 | environment | semmle.label | environment | +| InsecureLdapAuth.java:120:49:120:59 | environment | semmle.label | environment | +| InsecureLdapAuth.java:124:3:124:5 | env [post update] : Hashtable | semmle.label | env [post update] : Hashtable | +| InsecureLdapAuth.java:128:3:128:5 | env [post update] : Hashtable | semmle.label | env [post update] : Hashtable | +| InsecureLdapAuth.java:135:20:135:39 | ... + ... : String | semmle.label | ... + ... : String | +| InsecureLdapAuth.java:137:10:137:20 | environment [post update] : Hashtable | semmle.label | environment [post update] : Hashtable | +| InsecureLdapAuth.java:141:16:141:26 | environment [post update] : Hashtable | semmle.label | environment [post update] : Hashtable | +| InsecureLdapAuth.java:142:50:142:60 | environment | semmle.label | environment | +| InsecureLdapAuth.java:142:50:142:60 | environment | semmle.label | environment | +| InsecureLdapAuth.java:142:50:142:60 | environment | semmle.label | environment | +| InsecureLdapAuth.java:147:20:147:39 | ... + ... : String | semmle.label | ... + ... : String | +| InsecureLdapAuth.java:152:16:152:26 | environment [post update] : Hashtable | semmle.label | environment [post update] : Hashtable | +| InsecureLdapAuth.java:153:50:153:60 | environment | semmle.label | environment | +| InsecureLdapAuth.java:153:50:153:60 | environment | semmle.label | environment | +#select +| InsecureLdapAuth.java:20:49:20:59 | environment | InsecureLdapAuth.java:11:20:11:50 | "ldap://ad.your-server.com:389" : String | InsecureLdapAuth.java:20:49:20:59 | environment | Insecure LDAP authentication from $@. | InsecureLdapAuth.java:11:20:11:50 | "ldap://ad.your-server.com:389" | LDAP connection string | +| InsecureLdapAuth.java:34:49:34:59 | environment | InsecureLdapAuth.java:25:20:25:39 | ... + ... : String | InsecureLdapAuth.java:34:49:34:59 | environment | Insecure LDAP authentication from $@. | InsecureLdapAuth.java:25:20:25:39 | ... + ... | LDAP connection string | +| InsecureLdapAuth.java:105:59:105:69 | environment | InsecureLdapAuth.java:96:20:96:50 | "ldap://ad.your-server.com:389" : String | InsecureLdapAuth.java:105:59:105:69 | environment | Insecure LDAP authentication from $@. | InsecureLdapAuth.java:96:20:96:50 | "ldap://ad.your-server.com:389" | LDAP connection string | +| InsecureLdapAuth.java:120:49:120:59 | environment | InsecureLdapAuth.java:111:20:111:50 | "ldap://ad.your-server.com:389" : String | InsecureLdapAuth.java:120:49:120:59 | environment | Insecure LDAP authentication from $@. | InsecureLdapAuth.java:111:20:111:50 | "ldap://ad.your-server.com:389" | LDAP connection string | +| InsecureLdapAuth.java:153:50:153:60 | environment | InsecureLdapAuth.java:147:20:147:39 | ... + ... : String | InsecureLdapAuth.java:153:50:153:60 | environment | Insecure LDAP authentication from $@. | InsecureLdapAuth.java:147:20:147:39 | ... + ... | LDAP connection string | diff --git a/java/ql/test/experimental/query-tests/security/CWE-522/InsecureLdapAuth.java b/java/ql/test/experimental/query-tests/security/CWE-522/InsecureLdapAuth.java new file mode 100644 index 00000000000..978a4df671b --- /dev/null +++ b/java/ql/test/experimental/query-tests/security/CWE-522/InsecureLdapAuth.java @@ -0,0 +1,155 @@ +import java.util.Hashtable; + +import javax.naming.Context; +import javax.naming.directory.DirContext; +import javax.naming.directory.InitialDirContext; +import javax.naming.ldap.InitialLdapContext; + +public class InsecureLdapAuth { + // BAD - Test LDAP authentication in cleartext using `DirContext`. + public void testCleartextLdapAuth(String ldapUserName, String password) throws Exception { + String ldapUrl = "ldap://ad.your-server.com:389"; + Hashtable environment = new Hashtable(); + environment.put(Context.INITIAL_CONTEXT_FACTORY, + "com.sun.jndi.ldap.LdapCtxFactory"); + environment.put(Context.PROVIDER_URL, ldapUrl); + environment.put(Context.REFERRAL, "follow"); + environment.put(Context.SECURITY_AUTHENTICATION, "simple"); + environment.put(Context.SECURITY_PRINCIPAL, ldapUserName); + environment.put(Context.SECURITY_CREDENTIALS, password); + DirContext dirContext = new InitialDirContext(environment); + } + + // BAD - Test LDAP authentication in cleartext using `DirContext`. + public void testCleartextLdapAuth(String ldapUserName, String password, String serverName) throws Exception { + String ldapUrl = "ldap://"+serverName+":389"; + Hashtable environment = new Hashtable(); + environment.put(Context.INITIAL_CONTEXT_FACTORY, + "com.sun.jndi.ldap.LdapCtxFactory"); + environment.put(Context.PROVIDER_URL, ldapUrl); + environment.put(Context.REFERRAL, "follow"); + environment.put(Context.SECURITY_AUTHENTICATION, "simple"); + environment.put(Context.SECURITY_PRINCIPAL, ldapUserName); + environment.put(Context.SECURITY_CREDENTIALS, password); + DirContext dirContext = new InitialDirContext(environment); + } + + // GOOD - Test LDAP authentication over SSL. + public void testSslLdapAuth(String ldapUserName, String password) throws Exception { + String ldapUrl = "ldaps://ad.your-server.com:636"; + Hashtable environment = new Hashtable(); + environment.put(Context.INITIAL_CONTEXT_FACTORY, + "com.sun.jndi.ldap.LdapCtxFactory"); + environment.put(Context.PROVIDER_URL, ldapUrl); + environment.put(Context.REFERRAL, "follow"); + environment.put(Context.SECURITY_AUTHENTICATION, "simple"); + environment.put(Context.SECURITY_PRINCIPAL, ldapUserName); + environment.put(Context.SECURITY_CREDENTIALS, password); + DirContext dirContext = new InitialDirContext(environment); + } + + // GOOD - Test LDAP authentication over SSL. + public void testSslLdapAuth2(String ldapUserName, String password) throws Exception { + String ldapUrl = "ldap://ad.your-server.com:636"; + Hashtable environment = new Hashtable(); + environment.put(Context.INITIAL_CONTEXT_FACTORY, + "com.sun.jndi.ldap.LdapCtxFactory"); + environment.put(Context.PROVIDER_URL, ldapUrl); + environment.put(Context.REFERRAL, "follow"); + environment.put(Context.SECURITY_AUTHENTICATION, "simple"); + environment.put(Context.SECURITY_PRINCIPAL, ldapUserName); + environment.put(Context.SECURITY_CREDENTIALS, password); + environment.put(Context.SECURITY_PROTOCOL, "ssl"); + DirContext dirContext = new InitialDirContext(environment); + } + + // GOOD - Test LDAP authentication with SASL authentication. + public void testSaslLdapAuth(String ldapUserName, String password) throws Exception { + String ldapUrl = "ldap://ad.your-server.com:389"; + Hashtable environment = new Hashtable(); + environment.put(Context.INITIAL_CONTEXT_FACTORY, + "com.sun.jndi.ldap.LdapCtxFactory"); + environment.put(Context.PROVIDER_URL, ldapUrl); + environment.put(Context.REFERRAL, "follow"); + environment.put(Context.SECURITY_AUTHENTICATION, "DIGEST-MD5 GSSAPI"); + environment.put(Context.SECURITY_PRINCIPAL, ldapUserName); + environment.put(Context.SECURITY_CREDENTIALS, password); + DirContext dirContext = new InitialDirContext(environment); + } + + // GOOD - Test LDAP authentication in cleartext connecting to local LDAP server. + public void testCleartextLdapAuth2(String ldapUserName, String password) throws Exception { + String ldapUrl = "ldap://localhost:389"; + Hashtable environment = new Hashtable(); + environment.put(Context.INITIAL_CONTEXT_FACTORY, + "com.sun.jndi.ldap.LdapCtxFactory"); + environment.put(Context.PROVIDER_URL, ldapUrl); + environment.put(Context.REFERRAL, "follow"); + environment.put(Context.SECURITY_AUTHENTICATION, "simple"); + environment.put(Context.SECURITY_PRINCIPAL, ldapUserName); + environment.put(Context.SECURITY_CREDENTIALS, password); + DirContext dirContext = new InitialDirContext(environment); + } + + // BAD - Test LDAP authentication in cleartext using `InitialLdapContext`. + public void testCleartextLdapAuth3(String ldapUserName, String password) throws Exception { + String ldapUrl = "ldap://ad.your-server.com:389"; + Hashtable environment = new Hashtable(); + environment.put(Context.INITIAL_CONTEXT_FACTORY, + "com.sun.jndi.ldap.LdapCtxFactory"); + environment.put(Context.PROVIDER_URL, ldapUrl); + environment.put(Context.REFERRAL, "follow"); + environment.put(Context.SECURITY_AUTHENTICATION, "simple"); + environment.put(Context.SECURITY_PRINCIPAL, ldapUserName); + environment.put(Context.SECURITY_CREDENTIALS, password); + InitialLdapContext ldapContext = new InitialLdapContext(environment, null); + } + + + // BAD - Test LDAP authentication in cleartext using `DirContext` and string literals. + public void testCleartextLdapAuth4(String ldapUserName, String password) throws Exception { + String ldapUrl = "ldap://ad.your-server.com:389"; + Hashtable environment = new Hashtable(); + environment.put("java.naming.factory.initial", + "com.sun.jndi.ldap.LdapCtxFactory"); + environment.put("java.naming.provider.url", ldapUrl); + environment.put("java.naming.referral", "follow"); + environment.put("java.naming.security.authentication", "simple"); + environment.put("java.naming.security.principal", ldapUserName); + environment.put("java.naming.security.credentials", password); + DirContext dirContext = new InitialDirContext(environment); + } + + private void setSSL(Hashtable env) { + env.put(Context.SECURITY_PROTOCOL, "ssl"); + } + + private void setBasicAuth(Hashtable env, String ldapUserName, String password) { + env.put(Context.SECURITY_AUTHENTICATION, "simple"); + env.put(Context.SECURITY_PRINCIPAL, ldapUserName); + env.put(Context.SECURITY_CREDENTIALS, password); + } + + // GOOD - Test LDAP authentication with `ssl` configuration and basic authentication. + public void testCleartextLdapAuth5(String ldapUserName, String password, String serverName) throws Exception { + String ldapUrl = "ldap://"+serverName+":389"; + Hashtable environment = new Hashtable(); + setSSL(environment); + environment.put(Context.INITIAL_CONTEXT_FACTORY, + "com.sun.jndi.ldap.LdapCtxFactory"); + environment.put(Context.PROVIDER_URL, ldapUrl); + setBasicAuth(environment, ldapUserName, password); + DirContext dirContext = new InitialLdapContext(environment, null); + } + + // BAD - Test LDAP authentication with basic authentication. + public void testCleartextLdapAuth6(String ldapUserName, String password, String serverName) throws Exception { + String ldapUrl = "ldap://"+serverName+":389"; + Hashtable environment = new Hashtable(); + environment.put(Context.INITIAL_CONTEXT_FACTORY, + "com.sun.jndi.ldap.LdapCtxFactory"); + environment.put(Context.PROVIDER_URL, ldapUrl); + setBasicAuth(environment, ldapUserName, password); + DirContext dirContext = new InitialLdapContext(environment, null); + } +} diff --git a/java/ql/test/experimental/query-tests/security/CWE-522/InsecureLdapAuth.qlref b/java/ql/test/experimental/query-tests/security/CWE-522/InsecureLdapAuth.qlref new file mode 100644 index 00000000000..c2baa984177 --- /dev/null +++ b/java/ql/test/experimental/query-tests/security/CWE-522/InsecureLdapAuth.qlref @@ -0,0 +1 @@ +experimental/Security/CWE/CWE-522/InsecureLdapAuth.ql diff --git a/java/ql/test/experimental/query-tests/security/CWE-555/PasswordInConfigurationFile.expected b/java/ql/test/experimental/query-tests/security/CWE-555/PasswordInConfigurationFile.expected new file mode 100644 index 00000000000..fac44a3c2ec --- /dev/null +++ b/java/ql/test/experimental/query-tests/security/CWE-555/PasswordInConfigurationFile.expected @@ -0,0 +1,3 @@ +| applicationContext.xml:9:3:9:48 | name=password | Plaintext password in configuration file. | +| context.xml:4:2:8:50 | password=1234 | Plaintext password in configuration file. | +| custom-config.xml:3:2:3:137 | value=server=myoracle.example.com;port=1521;database=testdb;username=root;password=test1234 | Plaintext password in configuration file. | diff --git a/java/ql/test/experimental/query-tests/security/CWE-555/PasswordInConfigurationFile.qlref b/java/ql/test/experimental/query-tests/security/CWE-555/PasswordInConfigurationFile.qlref new file mode 100644 index 00000000000..b996de13723 --- /dev/null +++ b/java/ql/test/experimental/query-tests/security/CWE-555/PasswordInConfigurationFile.qlref @@ -0,0 +1 @@ +experimental/Security/CWE/CWE-555/PasswordInConfigurationFile.ql diff --git a/java/ql/test/experimental/query-tests/security/CWE-555/applicationContext.xml b/java/ql/test/experimental/query-tests/security/CWE-555/applicationContext.xml new file mode 100644 index 00000000000..040c866759b --- /dev/null +++ b/java/ql/test/experimental/query-tests/security/CWE-555/applicationContext.xml @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + + + com.example.entity.Users + + + + + + hibernate.dialect=org.hibernate.dialect.MySQLDialect + hibernate.hbm2ddl.auto=update + hibernate.show_sql=true + hibernate.cache.use_second_level_cache=false + hibernate.cache.provider_class=org.hibernate.cache.internal.NoCacheProvider + hibernate.generate_statistics=true + + + + diff --git a/java/ql/test/experimental/query-tests/security/CWE-555/context.xml b/java/ql/test/experimental/query-tests/security/CWE-555/context.xml new file mode 100644 index 00000000000..6ea601bc6d7 --- /dev/null +++ b/java/ql/test/experimental/query-tests/security/CWE-555/context.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/java/ql/test/experimental/query-tests/security/CWE-555/custom-config.xml b/java/ql/test/experimental/query-tests/security/CWE-555/custom-config.xml new file mode 100644 index 00000000000..3569f0d09de --- /dev/null +++ b/java/ql/test/experimental/query-tests/security/CWE-555/custom-config.xml @@ -0,0 +1,4 @@ + + + + diff --git a/java/ql/test/experimental/query-tests/security/CWE-918/RequestForgery.qlref b/java/ql/test/experimental/query-tests/security/CWE-918/RequestForgery.qlref index 3d529ae5a2c..3e35024c212 100644 --- a/java/ql/test/experimental/query-tests/security/CWE-918/RequestForgery.qlref +++ b/java/ql/test/experimental/query-tests/security/CWE-918/RequestForgery.qlref @@ -1 +1 @@ -experimental/CWE-918/RequestForgery.ql \ No newline at end of file +experimental/Security/CWE/CWE-918/RequestForgery.ql diff --git a/java/ql/test/experimental/query-tests/security/CWE-918/SpringSSRF.java b/java/ql/test/experimental/query-tests/security/CWE-918/SpringSSRF.java index ddd8ecc3dd6..a7d3cb32b87 100644 --- a/java/ql/test/experimental/query-tests/security/CWE-918/SpringSSRF.java +++ b/java/ql/test/experimental/query-tests/security/CWE-918/SpringSSRF.java @@ -26,7 +26,7 @@ public class SpringSSRF extends HttpServlet { String fooResourceUrl = request2.getParameter("uri");; RestTemplate restTemplate = new RestTemplate(); HttpEntity request = new HttpEntity<>(new String("bar")); - + try { { ResponseEntity response = restTemplate.getForEntity(fooResourceUrl + "/1", String.class); @@ -68,5 +68,6 @@ public class SpringSSRF extends HttpServlet { { restTemplate.put(fooResourceUrl, new String("object")); } + } catch (org.springframework.web.client.RestClientException | java.net.URISyntaxException e) {} } } diff --git a/java/ql/test/experimental/stubs/jxbrowser-6.23.1/com/teamdev/jxbrowser/chromium/Browser.java b/java/ql/test/experimental/stubs/jxbrowser-6.23.1/com/teamdev/jxbrowser/chromium/Browser.java new file mode 100644 index 00000000000..327a4b4ecd8 --- /dev/null +++ b/java/ql/test/experimental/stubs/jxbrowser-6.23.1/com/teamdev/jxbrowser/chromium/Browser.java @@ -0,0 +1,9 @@ +package com.teamdev.jxbrowser.chromium; + +public class Browser extends java.lang.Object { + public void setLoadHandler(LoadHandler handler) { + } + + public void loadURL(String url) { + } +} \ No newline at end of file diff --git a/java/ql/test/experimental/stubs/jxbrowser-6.23.1/com/teamdev/jxbrowser/chromium/CertificateErrorParams.java b/java/ql/test/experimental/stubs/jxbrowser-6.23.1/com/teamdev/jxbrowser/chromium/CertificateErrorParams.java new file mode 100644 index 00000000000..904b98a6c51 --- /dev/null +++ b/java/ql/test/experimental/stubs/jxbrowser-6.23.1/com/teamdev/jxbrowser/chromium/CertificateErrorParams.java @@ -0,0 +1,5 @@ +package com.teamdev.jxbrowser.chromium; + +public final class CertificateErrorParams extends Object { + +} \ No newline at end of file diff --git a/java/ql/test/experimental/stubs/jxbrowser-6.23.1/com/teamdev/jxbrowser/chromium/LoadHandler.java b/java/ql/test/experimental/stubs/jxbrowser-6.23.1/com/teamdev/jxbrowser/chromium/LoadHandler.java new file mode 100644 index 00000000000..a628d88439c --- /dev/null +++ b/java/ql/test/experimental/stubs/jxbrowser-6.23.1/com/teamdev/jxbrowser/chromium/LoadHandler.java @@ -0,0 +1,7 @@ +package com.teamdev.jxbrowser.chromium; + +public interface LoadHandler { + boolean onCertificateError(CertificateErrorParams params); + + boolean onLoad(LoadParams params); +} \ No newline at end of file diff --git a/java/ql/test/experimental/stubs/jxbrowser-6.23.1/com/teamdev/jxbrowser/chromium/LoadParams.java b/java/ql/test/experimental/stubs/jxbrowser-6.23.1/com/teamdev/jxbrowser/chromium/LoadParams.java new file mode 100644 index 00000000000..213e54f1dbc --- /dev/null +++ b/java/ql/test/experimental/stubs/jxbrowser-6.23.1/com/teamdev/jxbrowser/chromium/LoadParams.java @@ -0,0 +1,5 @@ +package com.teamdev.jxbrowser.chromium; + +public final class LoadParams extends Object { + +} \ No newline at end of file diff --git a/java/ql/test/experimental/stubs/jxbrowser-6.24/com/teamdev/jxbrowser/chromium/BoundsListener.java b/java/ql/test/experimental/stubs/jxbrowser-6.24/com/teamdev/jxbrowser/chromium/BoundsListener.java new file mode 100644 index 00000000000..39bb56e0565 --- /dev/null +++ b/java/ql/test/experimental/stubs/jxbrowser-6.24/com/teamdev/jxbrowser/chromium/BoundsListener.java @@ -0,0 +1,5 @@ +package com.teamdev.jxbrowser.chromium; + +public interface BoundsListener { + +} \ No newline at end of file diff --git a/java/ql/test/experimental/stubs/jxbrowser-6.24/com/teamdev/jxbrowser/chromium/Browser.java b/java/ql/test/experimental/stubs/jxbrowser-6.24/com/teamdev/jxbrowser/chromium/Browser.java new file mode 100644 index 00000000000..c32656e4228 --- /dev/null +++ b/java/ql/test/experimental/stubs/jxbrowser-6.24/com/teamdev/jxbrowser/chromium/Browser.java @@ -0,0 +1,13 @@ +package com.teamdev.jxbrowser.chromium; + +public class Browser extends java.lang.Object { + public void setLoadHandler(LoadHandler handler) { + } + + public void loadURL(String url) { + } + + public void addBoundsListener(BoundsListener listener) { + + } +} \ No newline at end of file diff --git a/java/ql/test/experimental/stubs/jxbrowser-6.24/com/teamdev/jxbrowser/chromium/CertificateErrorParams.java b/java/ql/test/experimental/stubs/jxbrowser-6.24/com/teamdev/jxbrowser/chromium/CertificateErrorParams.java new file mode 100644 index 00000000000..904b98a6c51 --- /dev/null +++ b/java/ql/test/experimental/stubs/jxbrowser-6.24/com/teamdev/jxbrowser/chromium/CertificateErrorParams.java @@ -0,0 +1,5 @@ +package com.teamdev.jxbrowser.chromium; + +public final class CertificateErrorParams extends Object { + +} \ No newline at end of file diff --git a/java/ql/test/experimental/stubs/jxbrowser-6.24/com/teamdev/jxbrowser/chromium/LoadHandler.java b/java/ql/test/experimental/stubs/jxbrowser-6.24/com/teamdev/jxbrowser/chromium/LoadHandler.java new file mode 100644 index 00000000000..a628d88439c --- /dev/null +++ b/java/ql/test/experimental/stubs/jxbrowser-6.24/com/teamdev/jxbrowser/chromium/LoadHandler.java @@ -0,0 +1,7 @@ +package com.teamdev.jxbrowser.chromium; + +public interface LoadHandler { + boolean onCertificateError(CertificateErrorParams params); + + boolean onLoad(LoadParams params); +} \ No newline at end of file diff --git a/java/ql/test/experimental/stubs/jxbrowser-6.24/com/teamdev/jxbrowser/chromium/LoadParams.java b/java/ql/test/experimental/stubs/jxbrowser-6.24/com/teamdev/jxbrowser/chromium/LoadParams.java new file mode 100644 index 00000000000..213e54f1dbc --- /dev/null +++ b/java/ql/test/experimental/stubs/jxbrowser-6.24/com/teamdev/jxbrowser/chromium/LoadParams.java @@ -0,0 +1,5 @@ +package com.teamdev.jxbrowser.chromium; + +public final class LoadParams extends Object { + +} \ No newline at end of file diff --git a/java/ql/test/library-tests/Encryption/Test.java b/java/ql/test/library-tests/Encryption/Test.java index e5a1996f28c..613476292ef 100644 --- a/java/ql/test/library-tests/Encryption/Test.java +++ b/java/ql/test/library-tests/Encryption/Test.java @@ -10,7 +10,9 @@ class Test { "des", "des_function", "function_using_des", - "EncryptWithDES"); + "EncryptWithDES", + "AES/ECB/NoPadding", + "AES/CBC/PKCS5Padding"); List goodStrings = Arrays.asList( "AES", diff --git a/java/ql/test/library-tests/Encryption/cryptoalgospec.expected b/java/ql/test/library-tests/Encryption/cryptoalgospec.expected index f9564b1df25..f066e6a0b0b 100644 --- a/java/ql/test/library-tests/Encryption/cryptoalgospec.expected +++ b/java/ql/test/library-tests/Encryption/cryptoalgospec.expected @@ -1,2 +1,2 @@ -| Test.java:35:4:35:17 | super(...) | Test.java:35:10:35:15 | "some" | -| Test.java:39:3:39:38 | getInstance(...) | Test.java:39:29:39:37 | "another" | +| Test.java:37:4:37:17 | super(...) | Test.java:37:10:37:15 | "some" | +| Test.java:41:3:41:38 | getInstance(...) | Test.java:41:29:41:37 | "another" | diff --git a/java/ql/test/library-tests/Encryption/insecure.expected b/java/ql/test/library-tests/Encryption/insecure.expected index 1e9728f0fcd..1bc1dc71e4d 100644 --- a/java/ql/test/library-tests/Encryption/insecure.expected +++ b/java/ql/test/library-tests/Encryption/insecure.expected @@ -3,3 +3,5 @@ | Test.java:11:4:11:17 | "des_function" | | Test.java:12:4:12:23 | "function_using_des" | | Test.java:13:4:13:19 | "EncryptWithDES" | +| Test.java:14:4:14:22 | "AES/ECB/NoPadding" | +| Test.java:15:4:15:25 | "AES/CBC/PKCS5Padding" | diff --git a/java/ql/test/library-tests/Encryption/secure.expected b/java/ql/test/library-tests/Encryption/secure.expected index f1b206d7205..a305f4ae778 100644 --- a/java/ql/test/library-tests/Encryption/secure.expected +++ b/java/ql/test/library-tests/Encryption/secure.expected @@ -1,2 +1,2 @@ -| Test.java:16:4:16:8 | "AES" | -| Test.java:17:4:17:17 | "AES_function" | +| Test.java:18:4:18:8 | "AES" | +| Test.java:19:4:19:17 | "AES_function" | diff --git a/java/ql/test/library-tests/ExternalProcess/Test.java b/java/ql/test/library-tests/ExternalProcess/Test.java index c3554589282..ee29327ef90 100644 --- a/java/ql/test/library-tests/ExternalProcess/Test.java +++ b/java/ql/test/library-tests/ExternalProcess/Test.java @@ -43,28 +43,28 @@ class Test { new Bogus().exec("Irrelevant version of exec"); } - void apacheExecute1() { + void apacheExecute1() throws IOException { String line = "AcroRd32.exe /p /h some.file"; CommandLine cmdLine = CommandLine.parse(line); DefaultExecutor executor = new DefaultExecutor(); int exitValue = executor.execute(cmdLine); } - void apacheExecute2() { + void apacheExecute2() throws IOException { String line = "AcroRd32.exe /p /h some.file"; CommandLine cmdLine = CommandLine.parse(line, null); DefaultExecutor executor = new DefaultExecutor(); int exitValue = executor.execute(cmdLine); } - void apacheExecute3() { + void apacheExecute3() throws IOException { CommandLine cmdLine = new CommandLine("AcroRd32.exe"); cmdLine.addArguments("/p /h some.file"); DefaultExecutor executor = new DefaultExecutor(); int exitValue = executor.execute(cmdLine); } - void apacheExecute4() { + void apacheExecute4() throws IOException { CommandLine cmdLine = new CommandLine("AcroRd32.exe"); cmdLine.addArguments("/p /h some.file", false); DefaultExecutor executor = new DefaultExecutor(); diff --git a/java/ql/test/library-tests/JDK/PrintAst.expected b/java/ql/test/library-tests/JDK/PrintAst.expected index ff260ac6c38..74967e122e3 100644 --- a/java/ql/test/library-tests/JDK/PrintAst.expected +++ b/java/ql/test/library-tests/JDK/PrintAst.expected @@ -60,3 +60,38 @@ jdk/A.java: # 28| 0: [ArrayTypeAccess] ...[] # 28| 0: [TypeAccess] String # 28| 5: [BlockStmt] stmt +jdk/SystemGetPropertyCall.java: +# 0| [CompilationUnit] SystemGetPropertyCall +# 3| 1: [Class] SystemGetPropertyCall +# 4| 3: [FieldDeclaration] String USER_DIR_PROPERTY, ...; +# 4| -1: [TypeAccess] String +# 4| 0: [StringLiteral] "user.dir" +# 6| 4: [Method] a +# 6| 3: [TypeAccess] void +# 6| 5: [BlockStmt] stmt +# 7| 0: [ExprStmt] stmt +# 7| 0: [MethodAccess] getProperty(...) +# 7| -1: [TypeAccess] System +# 7| 0: [StringLiteral] "user.dir" +# 10| 5: [Method] b +# 10| 3: [TypeAccess] void +# 10| 5: [BlockStmt] stmt +# 11| 0: [ExprStmt] stmt +# 11| 0: [MethodAccess] getProperty(...) +# 11| -1: [TypeAccess] System +# 11| 0: [StringLiteral] "user.dir" +# 11| 1: [StringLiteral] "HOME" +# 14| 6: [Method] c +# 14| 3: [TypeAccess] void +# 14| 5: [BlockStmt] stmt +# 15| 0: [ExprStmt] stmt +# 15| 0: [MethodAccess] getProperty(...) +# 15| -1: [TypeAccess] System +# 15| 0: [VarAccess] USER_DIR_PROPERTY +# 18| 7: [Method] d +# 18| 3: [TypeAccess] void +# 18| 5: [BlockStmt] stmt +# 19| 0: [ExprStmt] stmt +# 19| 0: [MethodAccess] getProperty(...) +# 19| -1: [TypeAccess] System +# 19| 0: [StringLiteral] "random.property" diff --git a/java/ql/test/library-tests/JDK/SystemGetPropertyCall.expected b/java/ql/test/library-tests/JDK/SystemGetPropertyCall.expected new file mode 100644 index 00000000000..e96a74fe1a6 --- /dev/null +++ b/java/ql/test/library-tests/JDK/SystemGetPropertyCall.expected @@ -0,0 +1,3 @@ +| jdk/SystemGetPropertyCall.java:7:9:7:38 | getProperty(...) | +| jdk/SystemGetPropertyCall.java:11:9:11:46 | getProperty(...) | +| jdk/SystemGetPropertyCall.java:15:9:15:45 | getProperty(...) | diff --git a/java/ql/test/library-tests/JDK/SystemGetPropertyCall.ql b/java/ql/test/library-tests/JDK/SystemGetPropertyCall.ql new file mode 100644 index 00000000000..4ccacefa2c2 --- /dev/null +++ b/java/ql/test/library-tests/JDK/SystemGetPropertyCall.ql @@ -0,0 +1,5 @@ +import java + +from MethodAccessSystemGetProperty ma +where ma.hasCompileTimeConstantGetPropertyName("user.dir") +select ma diff --git a/java/ql/test/library-tests/JDK/jdk/SystemGetPropertyCall.java b/java/ql/test/library-tests/JDK/jdk/SystemGetPropertyCall.java new file mode 100644 index 00000000000..750f1e8b83c --- /dev/null +++ b/java/ql/test/library-tests/JDK/jdk/SystemGetPropertyCall.java @@ -0,0 +1,21 @@ +package jdk; + +public class SystemGetPropertyCall { + private static final String USER_DIR_PROPERTY = "user.dir"; + + void a() { + System.getProperty("user.dir"); + } + + void b() { + System.getProperty("user.dir", "HOME"); + } + + void c() { + System.getProperty(USER_DIR_PROPERTY); + } + + void d() { + System.getProperty("random.property"); + } +} diff --git a/java/ql/test/library-tests/RelativePaths/Test.java b/java/ql/test/library-tests/RelativePaths/Test.java index 860b7ffbecf..4c020819121 100644 --- a/java/ql/test/library-tests/RelativePaths/Test.java +++ b/java/ql/test/library-tests/RelativePaths/Test.java @@ -1,5 +1,5 @@ class Test { - public static void main(String[] args) { + public static void main(String[] args) throws java.io.IOException { // Relative paths Runtime.getRuntime().exec("make"); Runtime.getRuntime().exec("m"); diff --git a/java/ql/test/library-tests/commentedcode/CommentedCode.java b/java/ql/test/library-tests/commentedcode/CommentedCode.java index fa14ad7cc69..02bee2fe2f9 100644 --- a/java/ql/test/library-tests/commentedcode/CommentedCode.java +++ b/java/ql/test/library-tests/commentedcode/CommentedCode.java @@ -88,8 +88,8 @@ public class CommentedCode { *   ; *   ; */ + return -1; } - // public static int commentedOutMethod(){ // // return 123; diff --git a/java/ql/test/library-tests/dataflow/capture/A.java b/java/ql/test/library-tests/dataflow/capture/A.java index 2311179499a..8bc40f9ae77 100644 --- a/java/ql/test/library-tests/dataflow/capture/A.java +++ b/java/ql/test/library-tests/dataflow/capture/A.java @@ -32,7 +32,7 @@ public class A { case 0: return p; case 1: return s; case 2: return b1.getElem(); - case 3: return b2.getElem(); + default:return b2.getElem(); } } }; diff --git a/java/ql/test/library-tests/dataflow/taint-ioutils/Test.java b/java/ql/test/library-tests/dataflow/taint-ioutils/Test.java index 1d616184705..a6660c87252 100644 --- a/java/ql/test/library-tests/dataflow/taint-ioutils/Test.java +++ b/java/ql/test/library-tests/dataflow/taint-ioutils/Test.java @@ -8,7 +8,7 @@ import java.util.List; import org.apache.commons.io.IOUtils; class Test { - public static void ioutils() { + public static void ioutils() throws java.io.FileNotFoundException, java.io.IOException { InputStream inp = new FileInputStream("test"); // user input InputStream buf = IOUtils.buffer(inp); diff --git a/java/ql/test/library-tests/dataflow/taint-jackson/Test.java b/java/ql/test/library-tests/dataflow/taint-jackson/Test.java index 6c3a7dbf4b5..2caf9e4ee80 100644 --- a/java/ql/test/library-tests/dataflow/taint-jackson/Test.java +++ b/java/ql/test/library-tests/dataflow/taint-jackson/Test.java @@ -14,7 +14,7 @@ class Test { return "tainted"; } - public static void jacksonObjectMapper() { + public static void jacksonObjectMapper() throws java.io.FileNotFoundException, java.io.UnsupportedEncodingException { String s = taint(); ObjectMapper om = new ObjectMapper(); File file = new File("testFile"); @@ -32,7 +32,7 @@ class Test { System.out.println(reconstructed); } - public static void jacksonObjectWriter() { + public static void jacksonObjectWriter() throws java.io.FileNotFoundException, java.io.UnsupportedEncodingException { String s = taint(); ObjectWriter ow = new ObjectWriter(); File file = new File("testFile"); diff --git a/java/ql/test/library-tests/dataflow/taint/A.java b/java/ql/test/library-tests/dataflow/taint/A.java index e3a38d8e191..55fd9796586 100644 --- a/java/ql/test/library-tests/dataflow/taint/A.java +++ b/java/ql/test/library-tests/dataflow/taint/A.java @@ -15,7 +15,7 @@ public class A { sink(b2); } - void test2() { + void test2() throws IOException { ByteArrayOutputStream bOutput = new ByteArrayOutputStream(); bOutput.write(taint()); byte[] b = bOutput.toByteArray(); @@ -25,11 +25,11 @@ public class A { sink(b2); } - void streamWrite(ByteArrayOutputStream baos, byte[] data) { + void streamWrite(ByteArrayOutputStream baos, byte[] data) throws IOException { baos.write(data); } - void test3(ByteArrayOutputStream baos) { + void test3(ByteArrayOutputStream baos) throws IOException { streamWrite(baos, taint()); sink(baos.toByteArray()); } @@ -38,11 +38,11 @@ public class A { ByteArrayOutputStream baos = new ByteArrayOutputStream(); } - void streamWriteHolder(BaosHolder bh, byte[] data) { + void streamWriteHolder(BaosHolder bh, byte[] data) throws IOException { bh.baos.write(data); } - void test4(BaosHolder bh) { + void test4(BaosHolder bh) throws IOException { streamWriteHolder(bh, taint()); sink(bh.baos.toByteArray()); } @@ -51,7 +51,7 @@ public class A { byte[] data = new byte[10]; } - void test5_a(DataHolder dh) { + void test5_a(DataHolder dh) throws IOException { ByteArrayInputStream bais = new ByteArrayInputStream(taint()); bais.read(dh.data); test5_b(dh); diff --git a/java/ql/test/library-tests/dataflow/taint/B.java b/java/ql/test/library-tests/dataflow/taint/B.java index b53c49bdc39..81b007e6871 100644 --- a/java/ql/test/library-tests/dataflow/taint/B.java +++ b/java/ql/test/library-tests/dataflow/taint/B.java @@ -11,7 +11,7 @@ public class B { public static void sink(Object o) { } - public static void maintest() { + public static void maintest() throws java.io.UnsupportedEncodingException, java.net.MalformedURLException { String[] args = taint(); // tainted - access to main args String[] aaaargs = args; diff --git a/java/ql/test/library-tests/dataflow/taintsources/IntentSources.java b/java/ql/test/library-tests/dataflow/taintsources/IntentSources.java index 960bbff0bce..6f0051f0d10 100644 --- a/java/ql/test/library-tests/dataflow/taintsources/IntentSources.java +++ b/java/ql/test/library-tests/dataflow/taintsources/IntentSources.java @@ -4,21 +4,21 @@ import android.app.Activity; public class IntentSources extends Activity { - public void test() { + public void test() throws java.io.IOException { String trouble = this.getIntent().getStringExtra("key"); Runtime.getRuntime().exec(trouble); } - public void test2() { + public void test2() throws java.io.IOException { String trouble = getIntent().getStringExtra("key"); Runtime.getRuntime().exec(trouble); } - public void test3() { + public void test3() throws java.io.IOException { String trouble = getIntent().getExtras().getString("key"); Runtime.getRuntime().exec(trouble); @@ -29,9 +29,9 @@ public class IntentSources extends Activity { class OtherClass { - public void test(IntentSources is) { + public void test(IntentSources is) throws java.io.IOException { String trouble = is.getIntent().getStringExtra("key"); Runtime.getRuntime().exec(trouble); } -} \ No newline at end of file +} diff --git a/java/ql/test/library-tests/dataflow/taintsources/RmiFlow.java b/java/ql/test/library-tests/dataflow/taintsources/RmiFlow.java index eeab5a1fa09..69d7c9449ee 100644 --- a/java/ql/test/library-tests/dataflow/taintsources/RmiFlow.java +++ b/java/ql/test/library-tests/dataflow/taintsources/RmiFlow.java @@ -4,5 +4,5 @@ import java.rmi.Remote; import java.rmi.RemoteException; public interface RmiFlow extends Remote { - String listDirectory(String path); + String listDirectory(String path) throws java.io.IOException; } diff --git a/java/ql/test/library-tests/dataflow/taintsources/RmiFlowImpl.java b/java/ql/test/library-tests/dataflow/taintsources/RmiFlowImpl.java index eee65d5c64e..f75c6ddf2b7 100644 --- a/java/ql/test/library-tests/dataflow/taintsources/RmiFlowImpl.java +++ b/java/ql/test/library-tests/dataflow/taintsources/RmiFlowImpl.java @@ -1,13 +1,13 @@ package security.library.dataflow; public class RmiFlowImpl implements RmiFlow { - public String listDirectory(String path) { + public String listDirectory(String path) throws java.io.IOException { String command = "ls " + path; Runtime.getRuntime().exec(command); return "pretend there are some results here"; } - public String notRemotable(String path) { + public String notRemotable(String path) throws java.io.IOException { String command = "ls " + path; Runtime.getRuntime().exec(command); return "pretend there are some results here"; diff --git a/java/ql/test/library-tests/dataflow/taintsources/remote.expected b/java/ql/test/library-tests/dataflow/taintsources/remote.expected index 57acdb6d26c..e4f1dac7ca6 100644 --- a/java/ql/test/library-tests/dataflow/taintsources/remote.expected +++ b/java/ql/test/library-tests/dataflow/taintsources/remote.expected @@ -5,21 +5,21 @@ | A.java:41:5:41:53 | getInputStream(...) | A.java:41:5:41:53 | getInputStream(...) | | A.java:42:5:42:45 | getInputStream(...) | A.java:42:5:42:45 | getInputStream(...) | | A.java:43:5:43:47 | getHostName(...) | A.java:43:5:43:47 | getHostName(...) | -| IntentSources.java:9:20:9:35 | getIntent(...) | ../../../stubs/google-android-9.0.0/android/content/Intent.java:1057:19:1057:32 | parameter this | +| IntentSources.java:9:20:9:35 | getIntent(...) | ../../../stubs/google-android-9.0.0/android/content/Intent.java:1059:19:1059:32 | parameter this | | IntentSources.java:9:20:9:35 | getIntent(...) | IntentSources.java:9:20:9:35 | getIntent(...) | | IntentSources.java:9:20:9:35 | getIntent(...) | IntentSources.java:9:20:9:57 | getStringExtra(...) | | IntentSources.java:9:20:9:35 | getIntent(...) | IntentSources.java:10:29:10:35 | trouble | -| IntentSources.java:16:20:16:30 | getIntent(...) | ../../../stubs/google-android-9.0.0/android/content/Intent.java:1057:19:1057:32 | parameter this | +| IntentSources.java:16:20:16:30 | getIntent(...) | ../../../stubs/google-android-9.0.0/android/content/Intent.java:1059:19:1059:32 | parameter this | | IntentSources.java:16:20:16:30 | getIntent(...) | IntentSources.java:16:20:16:30 | getIntent(...) | | IntentSources.java:16:20:16:30 | getIntent(...) | IntentSources.java:16:20:16:52 | getStringExtra(...) | | IntentSources.java:16:20:16:30 | getIntent(...) | IntentSources.java:17:29:17:35 | trouble | -| IntentSources.java:23:20:23:30 | getIntent(...) | ../../../stubs/google-android-9.0.0/android/content/Intent.java:1356:19:1356:27 | parameter this | -| IntentSources.java:23:20:23:30 | getIntent(...) | ../../../stubs/google-android-9.0.0/android/os/BaseBundle.java:599:19:599:27 | parameter this | +| IntentSources.java:23:20:23:30 | getIntent(...) | ../../../stubs/google-android-9.0.0/android/content/Intent.java:1358:19:1358:27 | parameter this | +| IntentSources.java:23:20:23:30 | getIntent(...) | ../../../stubs/google-android-9.0.0/android/os/BaseBundle.java:600:19:600:27 | parameter this | | IntentSources.java:23:20:23:30 | getIntent(...) | IntentSources.java:23:20:23:30 | getIntent(...) | | IntentSources.java:23:20:23:30 | getIntent(...) | IntentSources.java:23:20:23:42 | getExtras(...) | | IntentSources.java:23:20:23:30 | getIntent(...) | IntentSources.java:23:20:23:59 | getString(...) | | IntentSources.java:23:20:23:30 | getIntent(...) | IntentSources.java:24:29:24:35 | trouble | -| IntentSources.java:33:20:33:33 | getIntent(...) | ../../../stubs/google-android-9.0.0/android/content/Intent.java:1057:19:1057:32 | parameter this | +| IntentSources.java:33:20:33:33 | getIntent(...) | ../../../stubs/google-android-9.0.0/android/content/Intent.java:1059:19:1059:32 | parameter this | | IntentSources.java:33:20:33:33 | getIntent(...) | IntentSources.java:33:20:33:33 | getIntent(...) | | IntentSources.java:33:20:33:33 | getIntent(...) | IntentSources.java:33:20:33:55 | getStringExtra(...) | | IntentSources.java:33:20:33:33 | getIntent(...) | IntentSources.java:34:29:34:35 | trouble | diff --git a/java/ql/test/library-tests/dispatch/ViableCallable.java b/java/ql/test/library-tests/dispatch/ViableCallable.java index 1e404463c05..f698ea0fb9d 100644 --- a/java/ql/test/library-tests/dispatch/ViableCallable.java +++ b/java/ql/test/library-tests/dispatch/ViableCallable.java @@ -36,7 +36,7 @@ class ViableCallable { i2.f("", 0l); } - TMock Mock() { throw new Exception(); } + TMock Mock() { throw new Error(); } void CreateTypeInstance() { Run(new C2(), null, null, null); @@ -63,7 +63,7 @@ abstract class C1 { M(x, 8); } - public void f(T1_C1 x, T2_C1 y) { throw new Exception(); } + public void f(T1_C1 x, T2_C1 y) { throw new Error(); } } interface I1 { @@ -80,27 +80,27 @@ interface I2 { class C2 extends C1 implements I1 { @Override - public T_C2 M(String x, T3_C2 y) { throw new Exception(); } + public T_C2 M(String x, T3_C2 y) { throw new Error(); } } class C3 extends C1 implements I2 { @Override - public Long M(String x, T3_C3 y) { throw new Exception(); } + public Long M(String x, T3_C3 y) { throw new Error(); } } class C4 extends C1 { @Override - public Boolean M(T_C4[] x, T3_C4 y) { throw new Exception(); } + public Boolean M(T_C4[] x, T3_C4 y) { throw new Error(); } } class C5 extends C1 { @Override - public Boolean M(String x, T3_C5 y) { throw new Exception(); } + public Boolean M(String x, T3_C5 y) { throw new Error(); } } class C6 extends C1 { @Override - public T2_C6 M(T1_C6 x, T3_C6 y) { throw new Exception(); } + public T2_C6 M(T1_C6 x, T3_C6 y) { throw new Error(); } public void Run(T1_C6 x) { // Viable callables: C6.M(), C7.M() @@ -113,7 +113,7 @@ class C6 extends C1 { class C7 extends C6 { @Override - public Byte M(T1_C7 x, T3_C7 y) { throw new Exception(); } + public Byte M(T1_C7 x, T3_C7 y) { throw new Error(); } public void Run(T1_C7 x) { // Viable callables: C7.M() @@ -129,11 +129,11 @@ class C7 extends C6 { class C8 extends C1 { @Override - public T2_C8 M(String x, T3_C8 y) { throw new Exception(); } + public T2_C8 M(String x, T3_C8 y) { throw new Error(); } } class C9 extends C8 { @Override - public Boolean M(String x, T3_C9 y) { throw new Exception(); } + public Boolean M(String x, T3_C9 y) { throw new Error(); } } diff --git a/java/ql/test/library-tests/dispatch/ViableCallable2.java b/java/ql/test/library-tests/dispatch/ViableCallable2.java index a1d17b63162..79ecc9d3cd0 100644 --- a/java/ql/test/library-tests/dispatch/ViableCallable2.java +++ b/java/ql/test/library-tests/dispatch/ViableCallable2.java @@ -20,10 +20,10 @@ class ViableCallable2 { } class A { - public void m() { throw new Exception(); } + public void m() { throw new Error(); } } class B extends A { @Override - public void m() { throw new Exception(); } + public void m() { throw new Error(); } } diff --git a/java/ql/test/library-tests/frameworks/guava/TestCollect.java b/java/ql/test/library-tests/frameworks/guava/TestCollect.java new file mode 100644 index 00000000000..c5f01f2d2d1 --- /dev/null +++ b/java/ql/test/library-tests/frameworks/guava/TestCollect.java @@ -0,0 +1,122 @@ +package com.google.common.collect; + +import java.util.Map; +import java.util.SortedSet; +import java.util.SortedMap; +import java.util.Comparator; + +class TestCollect { + String taint() { return "tainted"; } + + void sink(Object o) {} + + void test1() { + String x = taint(); + + ImmutableSet xs = ImmutableSet.of(x, "y", "z"); + sink(xs.asList()); + + ImmutableSet ys = ImmutableSet.of("a", "b", "c"); + + sink(Sets.filter(Sets.union(xs, ys), y -> true)); + + sink(Sets.newHashSet("a", "b", "c", "d", x)); + } + + void test2() { + sink(ImmutableList.of(taint(), taint(), taint(), taint())); // expect 4 alerts + sink(ImmutableMap.of(taint(), taint(), taint(), taint())); // expect 2 alerts + sink(ImmutableMultimap.of(taint(), taint(), taint(), taint())); // expect 2 alerts + sink(ImmutableTable.of(taint(),taint(), taint())); // expect 1 alert + } + + void test3() { + String x = taint(); + + ImmutableList.Builder b = ImmutableList.builder(); + + b.add("a"); + sink(b); + b.add(x); + sink(b.build()); + + b = ImmutableList.builder(); + + b.add("a").add(x); + sink(b.build()); + + sink(ImmutableList.builder().add("a").add(x).build()); + + ImmutableMap.Builder b2 = ImmutableMap.builder(); + b2.put(x,"v"); + sink(b2); + b2.put("k",x); + sink(b2.build()); + } + + void test4(Table t1, Table t2, Table t3) { + String x = taint(); + t1.put(x, "c", "v"); + sink(t1); + t1.put("r", x, "v"); + sink(t1); + t1.put("r", "c", x); + sink(t1); + sink(t1.row("r")); + + t2.putAll(t1); + for (Table.Cell c : t2.cellSet()) { + sink(c.getValue()); + } + + sink(t1.remove("r", "c")); + + t3.row("r").put("c", x); + sink(t3); // Not detected + } + + void test4(Multimap m1, Multimap m2, Multimap m3, + Multimap m4, Multimap m5){ + String x = taint(); + m1.put("k", x); + sink(m1); + sink(m1.get("k")); + + m2.putAll("k", ImmutableList.of("a", x, "b")); + sink(m2); + + m3.putAll(m1); + sink(m3); + + m4.replaceValues("k", m1.replaceValues("k", ImmutableList.of("a"))); + for (Map.Entry e : m4.entries()) { + sink(e.getValue()); + } + + m5.asMap().get("k").add(x); + sink(m5); // Not detected + } + + void test5(Comparator comp, SortedSet sorS, SortedMap sorM) { + ImmutableSortedSet s = ImmutableSortedSet.of(taint()); + + sink(s); + sink(ImmutableSortedSet.copyOf(s)); + sink(ImmutableSortedSet.copyOf(comp, s)); + + sorS.add(taint()); + sink(ImmutableSortedSet.copyOfSorted(sorS)); + + sink(ImmutableList.sortedCopyOf(s)); + sink(ImmutableList.sortedCopyOf(comp, s)); + + ImmutableSortedMap m = ImmutableSortedMap.of("k", taint()); + + sink(m); + sink(ImmutableSortedMap.copyOf(m)); + sink(ImmutableSortedMap.copyOf(m, comp)); + + sorM.put("k", taint()); + sink(ImmutableSortedMap.copyOfSorted(sorM)); + } +} \ No newline at end of file diff --git a/java/ql/test/library-tests/frameworks/guava/Test.java b/java/ql/test/library-tests/frameworks/guava/TestStrings.java similarity index 98% rename from java/ql/test/library-tests/frameworks/guava/Test.java rename to java/ql/test/library-tests/frameworks/guava/TestStrings.java index da64ea30083..e85cb0bc965 100644 --- a/java/ql/test/library-tests/frameworks/guava/Test.java +++ b/java/ql/test/library-tests/frameworks/guava/TestStrings.java @@ -6,7 +6,7 @@ import com.google.common.base.Joiner; import java.util.Map; import java.util.HashMap; -class Test { +class TestStrings { String taint() { return "tainted"; } void sink(Object o) {} diff --git a/java/ql/test/library-tests/frameworks/guava/flow.expected b/java/ql/test/library-tests/frameworks/guava/flow.expected index 809dcfd6f84..52276485cf9 100644 --- a/java/ql/test/library-tests/frameworks/guava/flow.expected +++ b/java/ql/test/library-tests/frameworks/guava/flow.expected @@ -1,17 +1,52 @@ -| Test.java:15:20:15:26 | taint(...) | Test.java:17:14:17:41 | padStart(...) | -| Test.java:15:20:15:26 | taint(...) | Test.java:18:14:18:39 | padEnd(...) | -| Test.java:15:20:15:26 | taint(...) | Test.java:19:14:19:33 | repeat(...) | -| Test.java:15:20:15:26 | taint(...) | Test.java:20:14:20:56 | emptyToNull(...) | -| Test.java:15:20:15:26 | taint(...) | Test.java:21:14:21:40 | lenientFormat(...) | -| Test.java:15:20:15:26 | taint(...) | Test.java:24:14:24:51 | lenientFormat(...) | -| Test.java:28:20:28:26 | taint(...) | Test.java:32:14:32:23 | split(...) | -| Test.java:28:20:28:26 | taint(...) | Test.java:33:14:33:29 | splitToList(...) | -| Test.java:28:20:28:26 | taint(...) | Test.java:35:14:35:50 | split(...) | -| Test.java:39:20:39:26 | taint(...) | Test.java:46:14:46:54 | appendTo(...) | -| Test.java:39:20:39:26 | taint(...) | Test.java:47:14:47:26 | toString(...) | -| Test.java:39:20:39:26 | taint(...) | Test.java:48:14:48:51 | appendTo(...) | -| Test.java:39:20:39:26 | taint(...) | Test.java:49:14:49:26 | toString(...) | -| Test.java:39:20:39:26 | taint(...) | Test.java:52:14:52:42 | appendTo(...) | -| Test.java:39:20:39:26 | taint(...) | Test.java:57:14:57:56 | join(...) | -| Test.java:39:20:39:26 | taint(...) | Test.java:58:14:58:82 | join(...) | -| Test.java:39:20:39:26 | taint(...) | Test.java:60:14:60:58 | join(...) | +| TestCollect.java:14:20:14:26 | taint(...) | TestCollect.java:17:14:17:24 | asList(...) | +| TestCollect.java:14:20:14:26 | taint(...) | TestCollect.java:21:14:21:55 | filter(...) | +| TestCollect.java:14:20:14:26 | taint(...) | TestCollect.java:23:14:23:51 | newHashSet(...) | +| TestCollect.java:27:31:27:37 | taint(...) | TestCollect.java:27:14:27:65 | of(...) | +| TestCollect.java:27:40:27:46 | taint(...) | TestCollect.java:27:14:27:65 | of(...) | +| TestCollect.java:27:49:27:55 | taint(...) | TestCollect.java:27:14:27:65 | of(...) | +| TestCollect.java:27:58:27:64 | taint(...) | TestCollect.java:27:14:27:65 | of(...) | +| TestCollect.java:28:39:28:45 | taint(...) | TestCollect.java:28:14:28:64 | of(...) | +| TestCollect.java:28:57:28:63 | taint(...) | TestCollect.java:28:14:28:64 | of(...) | +| TestCollect.java:29:44:29:50 | taint(...) | TestCollect.java:29:14:29:69 | of(...) | +| TestCollect.java:29:62:29:68 | taint(...) | TestCollect.java:29:14:29:69 | of(...) | +| TestCollect.java:30:49:30:55 | taint(...) | TestCollect.java:30:14:30:56 | of(...) | +| TestCollect.java:34:20:34:26 | taint(...) | TestCollect.java:41:14:41:22 | build(...) | +| TestCollect.java:34:20:34:26 | taint(...) | TestCollect.java:46:14:46:22 | build(...) | +| TestCollect.java:34:20:34:26 | taint(...) | TestCollect.java:48:14:48:60 | build(...) | +| TestCollect.java:34:20:34:26 | taint(...) | TestCollect.java:54:14:54:23 | build(...) | +| TestCollect.java:58:20:58:26 | taint(...) | TestCollect.java:64:14:64:15 | t1 | +| TestCollect.java:58:20:58:26 | taint(...) | TestCollect.java:65:14:65:24 | row(...) | +| TestCollect.java:58:20:58:26 | taint(...) | TestCollect.java:69:18:69:29 | getValue(...) | +| TestCollect.java:58:20:58:26 | taint(...) | TestCollect.java:72:14:72:32 | remove(...) | +| TestCollect.java:80:20:80:26 | taint(...) | TestCollect.java:82:14:82:15 | m1 | +| TestCollect.java:80:20:80:26 | taint(...) | TestCollect.java:83:14:83:24 | get(...) | +| TestCollect.java:80:20:80:26 | taint(...) | TestCollect.java:86:14:86:15 | m2 | +| TestCollect.java:80:20:80:26 | taint(...) | TestCollect.java:89:14:89:15 | m3 | +| TestCollect.java:80:20:80:26 | taint(...) | TestCollect.java:93:18:93:29 | getValue(...) | +| TestCollect.java:101:62:101:68 | taint(...) | TestCollect.java:103:14:103:14 | s | +| TestCollect.java:101:62:101:68 | taint(...) | TestCollect.java:104:14:104:41 | copyOf(...) | +| TestCollect.java:101:62:101:68 | taint(...) | TestCollect.java:105:14:105:47 | copyOf(...) | +| TestCollect.java:101:62:101:68 | taint(...) | TestCollect.java:110:14:110:42 | sortedCopyOf(...) | +| TestCollect.java:101:62:101:68 | taint(...) | TestCollect.java:111:14:111:48 | sortedCopyOf(...) | +| TestCollect.java:107:18:107:24 | taint(...) | TestCollect.java:108:14:108:50 | copyOfSorted(...) | +| TestCollect.java:113:75:113:81 | taint(...) | TestCollect.java:115:14:115:14 | m | +| TestCollect.java:113:75:113:81 | taint(...) | TestCollect.java:116:14:116:41 | copyOf(...) | +| TestCollect.java:113:75:113:81 | taint(...) | TestCollect.java:117:14:117:47 | copyOf(...) | +| TestCollect.java:119:23:119:29 | taint(...) | TestCollect.java:120:14:120:50 | copyOfSorted(...) | +| TestStrings.java:15:20:15:26 | taint(...) | TestStrings.java:17:14:17:41 | padStart(...) | +| TestStrings.java:15:20:15:26 | taint(...) | TestStrings.java:18:14:18:39 | padEnd(...) | +| TestStrings.java:15:20:15:26 | taint(...) | TestStrings.java:19:14:19:33 | repeat(...) | +| TestStrings.java:15:20:15:26 | taint(...) | TestStrings.java:20:14:20:56 | emptyToNull(...) | +| TestStrings.java:15:20:15:26 | taint(...) | TestStrings.java:21:14:21:40 | lenientFormat(...) | +| TestStrings.java:15:20:15:26 | taint(...) | TestStrings.java:24:14:24:51 | lenientFormat(...) | +| TestStrings.java:28:20:28:26 | taint(...) | TestStrings.java:32:14:32:23 | split(...) | +| TestStrings.java:28:20:28:26 | taint(...) | TestStrings.java:33:14:33:29 | splitToList(...) | +| TestStrings.java:28:20:28:26 | taint(...) | TestStrings.java:35:14:35:50 | split(...) | +| TestStrings.java:39:20:39:26 | taint(...) | TestStrings.java:46:14:46:54 | appendTo(...) | +| TestStrings.java:39:20:39:26 | taint(...) | TestStrings.java:47:14:47:26 | toString(...) | +| TestStrings.java:39:20:39:26 | taint(...) | TestStrings.java:48:14:48:51 | appendTo(...) | +| TestStrings.java:39:20:39:26 | taint(...) | TestStrings.java:49:14:49:26 | toString(...) | +| TestStrings.java:39:20:39:26 | taint(...) | TestStrings.java:52:14:52:42 | appendTo(...) | +| TestStrings.java:39:20:39:26 | taint(...) | TestStrings.java:57:14:57:56 | join(...) | +| TestStrings.java:39:20:39:26 | taint(...) | TestStrings.java:58:14:58:82 | join(...) | +| TestStrings.java:39:20:39:26 | taint(...) | TestStrings.java:60:14:60:58 | join(...) | diff --git a/java/ql/test/library-tests/guards/Logic.java b/java/ql/test/library-tests/guards/Logic.java index a07890a4a75..afe646908a0 100644 --- a/java/ql/test/library-tests/guards/Logic.java +++ b/java/ql/test/library-tests/guards/Logic.java @@ -41,7 +41,7 @@ public class Logic { } private static void checkTrue(boolean b, String msg) { - if (!b) throw new Exception(msg); + if (!b) throw new Error (msg); } private static void checkFalse(boolean b, String msg) { diff --git a/java/ql/test/library-tests/guards/Test.java b/java/ql/test/library-tests/guards/Test.java index 59f63917b09..d4441f98fdd 100644 --- a/java/ql/test/library-tests/guards/Test.java +++ b/java/ql/test/library-tests/guards/Test.java @@ -3,7 +3,7 @@ class Test { void test(int x) { z = 0; if (x < 0) { - throw new Exception(); + throw new Error(); } int y = 0; while(x >= 0) { diff --git a/java/ql/test/library-tests/pathcreation/PathCreation.java b/java/ql/test/library-tests/pathcreation/PathCreation.java index dcdb28adf45..fcd1eed3e28 100644 --- a/java/ql/test/library-tests/pathcreation/PathCreation.java +++ b/java/ql/test/library-tests/pathcreation/PathCreation.java @@ -18,7 +18,7 @@ class PathCreation { File f = new File(new File("dir"), "sub"); } - public void testNewFileWithURI() { + public void testNewFileWithURI() throws java.net.URISyntaxException { File f = new File(new URI("dir")); } @@ -27,7 +27,7 @@ class PathCreation { Path p2 = Path.of("dir", "sub"); } - public void testPathOfWithURI() { + public void testPathOfWithURI() throws java.net.URISyntaxException { Path p = Path.of(new URI("dir")); } @@ -36,7 +36,7 @@ class PathCreation { Path p2 = Paths.get("dir", "sub"); } - public void testPathsGetWithURI() { + public void testPathsGetWithURI() throws java.net.URISyntaxException { Path p = Paths.get(new URI("dir")); } @@ -53,19 +53,19 @@ class PathCreation { Path p = Path.of("dir").resolve("sub"); } - public void testNewFileWriterWithString() { + public void testNewFileWriterWithString() throws java.io.IOException { FileWriter fw = new FileWriter("dir"); } - public void testNewFileReaderWithString() { + public void testNewFileReaderWithString() throws java.io.FileNotFoundException { FileReader fr = new FileReader("dir"); } - public void testNewFileOutputStreamWithString() { + public void testNewFileOutputStreamWithString() throws java.io.FileNotFoundException { FileOutputStream fos = new FileOutputStream("dir"); } - public void testNewFileInputStreamWithString() { + public void testNewFileInputStreamWithString() throws java.io.FileNotFoundException { FileInputStream fis = new FileInputStream("dir"); } } diff --git a/java/ql/test/library-tests/reflection/reflection/ReflectiveAccess.java b/java/ql/test/library-tests/reflection/reflection/ReflectiveAccess.java index 2a729af39fd..99687ea2649 100644 --- a/java/ql/test/library-tests/reflection/reflection/ReflectiveAccess.java +++ b/java/ql/test/library-tests/reflection/reflection/ReflectiveAccess.java @@ -14,7 +14,7 @@ public class ReflectiveAccess { return classContainingAnnotation.getAnnotation(annotationClass); } - public static void main(String[] args) { + public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException { Class testClass = Class.forName("reflection.ReflectiveAccess$TestClass"); testClass.newInstance(); diff --git a/java/ql/test/library-tests/successors/TestThrow2/TestThrow2.java b/java/ql/test/library-tests/successors/TestThrow2/TestThrow2.java index c3652aa161c..29f86a7bb58 100644 --- a/java/ql/test/library-tests/successors/TestThrow2/TestThrow2.java +++ b/java/ql/test/library-tests/successors/TestThrow2/TestThrow2.java @@ -5,8 +5,8 @@ class TestThrow2 { { try { thrower(); - } catch (Exception e) { + } catch (Throwable e) { ; } } -} \ No newline at end of file +} diff --git a/java/ql/test/qlpack.yml b/java/ql/test/qlpack.yml index 75a27d69080..1db4e776c00 100644 --- a/java/ql/test/qlpack.yml +++ b/java/ql/test/qlpack.yml @@ -2,3 +2,4 @@ name: codeql-java-tests version: 0.0.0 libraryPathDependencies: codeql-java extractor: java +tests: . diff --git a/java/ql/test/query-tests/CloseResource/CloseReader/CloseReader.java b/java/ql/test/query-tests/CloseResource/CloseReader/CloseReader.java index 38549f5873c..7d78f8dbfef 100644 --- a/java/ql/test/query-tests/CloseResource/CloseReader/CloseReader.java +++ b/java/ql/test/query-tests/CloseResource/CloseReader/CloseReader.java @@ -100,7 +100,7 @@ class CloseReader { private void init(InputStreamReader reader) { fileRd = new BufferedReader(reader); } - public void readStuff() { + public void readStuff() throws java.io.IOException { System.out.println(fileRd.readLine()); fileRd.close(); } diff --git a/java/ql/test/query-tests/ContinueInFalseLoop/A.java b/java/ql/test/query-tests/ContinueInFalseLoop/A.java index 14c4ee0e7aa..51f381b94c8 100644 --- a/java/ql/test/query-tests/ContinueInFalseLoop/A.java +++ b/java/ql/test/query-tests/ContinueInFalseLoop/A.java @@ -30,21 +30,21 @@ public class A { break; } while (c.cond()); - // --- while, for loops --- - while (false) { - if (c.cond()) - continue; // GOOD [never reached, if the condition changed so it was then the result would no longer apply] - if (c.cond()) - break; - } - for (i = 0; false; i++) { - if (c.cond()) - continue; // GOOD [never reached, if the condition changed so it was then the result would no longer apply] - if (c.cond()) - break; - } + + + + + + + + + + + + + // --- nested loops --- diff --git a/java/ql/test/query-tests/MissingCallToSuperClone/Test.java b/java/ql/test/query-tests/MissingCallToSuperClone/Test.java index 77efe645ef5..a236543a695 100644 --- a/java/ql/test/query-tests/MissingCallToSuperClone/Test.java +++ b/java/ql/test/query-tests/MissingCallToSuperClone/Test.java @@ -1,10 +1,10 @@ class IAmAGoodCloneable implements Cloneable { - public Object clone() { + public Object clone() throws CloneNotSupportedException { return super.clone(); } } -class Sub1 extends IAmAGoodCloneable { public Object clone() { return super.clone(); } } +class Sub1 extends IAmAGoodCloneable { public Object clone() throws CloneNotSupportedException { return super.clone(); } } class IAmABadCloneable implements Cloneable { public Object clone() { diff --git a/java/ql/test/query-tests/MissingInstanceofInEquals/GoodReturn.java b/java/ql/test/query-tests/MissingInstanceofInEquals/GoodReturn.java index 593469fe6fb..0de780e4162 100644 --- a/java/ql/test/query-tests/MissingInstanceofInEquals/GoodReturn.java +++ b/java/ql/test/query-tests/MissingInstanceofInEquals/GoodReturn.java @@ -3,7 +3,7 @@ class GoodReturn { @Override public int hashCode() { - getClass().hashCode(); + return getClass().hashCode(); } @Override diff --git a/java/ql/test/query-tests/Nullness/C.java b/java/ql/test/query-tests/Nullness/C.java index c9fe368a394..ac6a5f291da 100644 --- a/java/ql/test/query-tests/Nullness/C.java +++ b/java/ql/test/query-tests/Nullness/C.java @@ -171,7 +171,7 @@ public class C { private void verifyBool(boolean b) { if (!b) { - throw new Exception(); + throw new Error(); } } @@ -192,7 +192,7 @@ public class C { private void verifyNotNull(Object obj) { if (obj == null) { - throw new Exception(); + throw new Error(); } } diff --git a/java/ql/test/query-tests/RangeAnalysis/A.java b/java/ql/test/query-tests/RangeAnalysis/A.java index f2cb4918387..53fbc62f83b 100644 --- a/java/ql/test/query-tests/RangeAnalysis/A.java +++ b/java/ql/test/query-tests/RangeAnalysis/A.java @@ -5,7 +5,7 @@ public class A { public A(int[] arr2, int n) { if (arr2.length % 2 != 0) - throw new Exception(); + throw new Error(); this.arr2 = arr2; this.arr3 = new int[n << 1]; } @@ -168,7 +168,7 @@ public class A { if (n > 0) { a = n > 0 ? new int[3 * n] : null; } - int sum; + int sum = 0; if (a != null) { for (int i = 0; i < a.length; i += 3) { sum += a[i + 2]; // OK diff --git a/java/ql/test/query-tests/UseBraces/UseBraces.java b/java/ql/test/query-tests/UseBraces/UseBraces.java index c823456cd2a..756050b2c44 100644 --- a/java/ql/test/query-tests/UseBraces/UseBraces.java +++ b/java/ql/test/query-tests/UseBraces/UseBraces.java @@ -7,9 +7,9 @@ class UseBraces void f() { } void g() { } void h() { } - void test() + void test(boolean bb) { - int x, y; + int x = 0, y; int[] branches = new int[10]; // If-then statement @@ -67,27 +67,27 @@ class UseBraces // While statement - while(false) + while(bb) { f(); } g(); // No alert - while(false) + while(bb) f(); g(); - while(false) + while(bb ) f(); g(); // Alert g(); // No alert - while(false) + while(bb ) f(); g(); // Alert - while(false) + while(bb) if (x != 0) x = 1; // Do-while statement diff --git a/java/ql/test/query-tests/UselessComparisonTest/Test.java b/java/ql/test/query-tests/UselessComparisonTest/Test.java index 4b9d7488317..eafac84dea5 100644 --- a/java/ql/test/query-tests/UselessComparisonTest/Test.java +++ b/java/ql/test/query-tests/UselessComparisonTest/Test.java @@ -3,7 +3,7 @@ class Test { void test(int x) { z = getInt(); if (x < 0 || z < 0) { - throw new Exception(); + throw new Error(); } int y = 0; if (x >= 0) y++; // useless test due to test in line 5 being false diff --git a/java/ql/test/query-tests/UselessNullCheck/A.java b/java/ql/test/query-tests/UselessNullCheck/A.java index 017629ec516..009f5efadd3 100644 --- a/java/ql/test/query-tests/UselessNullCheck/A.java +++ b/java/ql/test/query-tests/UselessNullCheck/A.java @@ -7,7 +7,7 @@ public class A { new Object(); } catch(Exception e) { if (e == null) { // Useless check - throw new Exception(); + throw new Error(); } } } @@ -16,7 +16,7 @@ public class A { if (o instanceof A) { A a = (A)o; if (a != null) { // Useless check - throw new Exception(); + throw new Error(); } } } diff --git a/java/ql/test/query-tests/dead-code/DeadField/ReflectionTest.java b/java/ql/test/query-tests/dead-code/DeadField/ReflectionTest.java index 418975b0281..72ca3ae46f6 100644 --- a/java/ql/test/query-tests/dead-code/DeadField/ReflectionTest.java +++ b/java/ql/test/query-tests/dead-code/DeadField/ReflectionTest.java @@ -16,7 +16,7 @@ public class ReflectionTest { public int shadowedField; } - public static void main(String[] args) { + public static void main(String[] args) throws NoSuchFieldException { // Ensure the two classes are live, otherwise we might hide some results new ParentClass(); new ChildClass(); diff --git a/java/ql/test/query-tests/dead-code/DeadMethod/ReflectionMethodTest.java b/java/ql/test/query-tests/dead-code/DeadMethod/ReflectionMethodTest.java index 4336655a664..c77718f9750 100644 --- a/java/ql/test/query-tests/dead-code/DeadMethod/ReflectionMethodTest.java +++ b/java/ql/test/query-tests/dead-code/DeadMethod/ReflectionMethodTest.java @@ -19,7 +19,7 @@ public class ReflectionMethodTest { public void test4() { } } - public static void main(String[] args) throws InstantiationException, IllegalAccessException, ClassNotFoundException { + public static void main(String[] args) throws InstantiationException, IllegalAccessException, ClassNotFoundException, NoSuchMethodException { // Get class by name Class.forName("ReflectionTest$TestObject1").getMethod("test1"); // Use classloader diff --git a/java/ql/test/query-tests/security/CWE-022/semmle/tests/ZipTest.java b/java/ql/test/query-tests/security/CWE-022/semmle/tests/ZipTest.java index 46ed97e2d98..b5bee61b965 100644 --- a/java/ql/test/query-tests/security/CWE-022/semmle/tests/ZipTest.java +++ b/java/ql/test/query-tests/security/CWE-022/semmle/tests/ZipTest.java @@ -3,7 +3,7 @@ import java.nio.file.*; import java.util.zip.*; public class ZipTest { - public void m1(ZipEntry entry, File dir) { + public void m1(ZipEntry entry, File dir) throws Exception { String name = entry.getName(); File file = new File(dir, name); FileOutputStream os = new FileOutputStream(file); // ZipSlip @@ -11,7 +11,7 @@ public class ZipTest { FileWriter fw = new FileWriter(file); // ZipSlip } - public void m2(ZipEntry entry, File dir) { + public void m2(ZipEntry entry, File dir) throws Exception { String name = entry.getName(); File file = new File(dir, name); File canFile = file.getCanonicalFile(); @@ -21,7 +21,7 @@ public class ZipTest { FileOutputStream os = new FileOutputStream(file); // OK } - public void m3(ZipEntry entry, File dir) { + public void m3(ZipEntry entry, File dir) throws Exception { String name = entry.getName(); File file = new File(dir, name); if (!file.toPath().normalize().startsWith(dir.toPath())) @@ -29,20 +29,20 @@ public class ZipTest { FileOutputStream os = new FileOutputStream(file); // OK } - private void validate(File tgtdir, File file) { + private void validate(File tgtdir, File file) throws Exception { File canFile = file.getCanonicalFile(); if (!canFile.toPath().startsWith(tgtdir.toPath())) throw new Exception(); } - public void m4(ZipEntry entry, File dir) { + public void m4(ZipEntry entry, File dir) throws Exception { String name = entry.getName(); File file = new File(dir, name); validate(dir, file); FileOutputStream os = new FileOutputStream(file); // OK } - public void m5(ZipEntry entry, File dir) { + public void m5(ZipEntry entry, File dir) throws Exception { String name = entry.getName(); File file = new File(dir, name); Path absfile = file.toPath().toAbsolutePath().normalize(); @@ -52,7 +52,7 @@ public class ZipTest { FileOutputStream os = new FileOutputStream(file); // OK } - public void m6(ZipEntry entry, Path dir) { + public void m6(ZipEntry entry, Path dir) throws Exception { String canonicalDest = dir.toFile().getCanonicalPath(); Path target = dir.resolve(entry.getName()); String canonicalTarget = target.toFile().getCanonicalPath(); diff --git a/java/ql/test/query-tests/security/CWE-078/Test.java b/java/ql/test/query-tests/security/CWE-078/Test.java index 6e185b86bbd..1ac5dc47882 100644 --- a/java/ql/test/query-tests/security/CWE-078/Test.java +++ b/java/ql/test/query-tests/security/CWE-078/Test.java @@ -3,7 +3,7 @@ import java.util.List; import java.util.ArrayList; class Test { - public static void shellCommand(String arg) { + public static void shellCommand(String arg) throws java.io.IOException { ProcessBuilder pb = new ProcessBuilder("/bin/bash -c echo " + arg); pb.start(); @@ -25,7 +25,7 @@ class Test { pb.start(); } - public static void nonShellCommand(String arg) { + public static void nonShellCommand(String arg) throws java.io.IOException { ProcessBuilder pb = new ProcessBuilder("./customTool " + arg); pb.start(); @@ -46,7 +46,7 @@ class Test { pb.start(); } - public static void relativeCommand() { + public static void relativeCommand() throws java.io.IOException { ProcessBuilder pb = new ProcessBuilder("ls"); pb.start(); @@ -54,11 +54,11 @@ class Test { pb.start(); } - public static void main(String[] args) { + public static void main(String[] args) throws java.io.IOException { String arg = args.length > 1 ? args[1] : "default"; shellCommand(arg); nonShellCommand(arg); relativeCommand(); } -} \ No newline at end of file +} diff --git a/java/ql/test/query-tests/security/CWE-297/UnsafeHostnameVerification.expected b/java/ql/test/query-tests/security/CWE-297/UnsafeHostnameVerification.expected new file mode 100644 index 00000000000..acb9f1eabe0 --- /dev/null +++ b/java/ql/test/query-tests/security/CWE-297/UnsafeHostnameVerification.expected @@ -0,0 +1,21 @@ +edges +| UnsafeHostnameVerification.java:66:37:80:9 | new (...) : new HostnameVerifier(...) { ... } | UnsafeHostnameVerification.java:81:55:81:62 | verifier | +| UnsafeHostnameVerification.java:88:37:93:9 | new (...) : new HostnameVerifier(...) { ... } | UnsafeHostnameVerification.java:94:55:94:62 | verifier | +| UnsafeHostnameVerification.java:97:72:102:5 | new (...) : new HostnameVerifier(...) { ... } | UnsafeHostnameVerification.java:34:59:34:85 | ALLOW_ALL_HOSTNAME_VERIFIER | +nodes +| UnsafeHostnameVerification.java:14:55:19:9 | new (...) | semmle.label | new (...) | +| UnsafeHostnameVerification.java:26:55:26:71 | ...->... | semmle.label | ...->... | +| UnsafeHostnameVerification.java:34:59:34:85 | ALLOW_ALL_HOSTNAME_VERIFIER | semmle.label | ALLOW_ALL_HOSTNAME_VERIFIER | +| UnsafeHostnameVerification.java:47:55:47:71 | ...->... | semmle.label | ...->... | +| UnsafeHostnameVerification.java:59:59:59:85 | ...->... | semmle.label | ...->... | +| UnsafeHostnameVerification.java:66:37:80:9 | new (...) : new HostnameVerifier(...) { ... } | semmle.label | new (...) : new HostnameVerifier(...) { ... } | +| UnsafeHostnameVerification.java:81:55:81:62 | verifier | semmle.label | verifier | +| UnsafeHostnameVerification.java:88:37:93:9 | new (...) : new HostnameVerifier(...) { ... } | semmle.label | new (...) : new HostnameVerifier(...) { ... } | +| UnsafeHostnameVerification.java:94:55:94:62 | verifier | semmle.label | verifier | +| UnsafeHostnameVerification.java:97:72:102:5 | new (...) : new HostnameVerifier(...) { ... } | semmle.label | new (...) : new HostnameVerifier(...) { ... } | +#select +| UnsafeHostnameVerification.java:14:55:19:9 | new (...) | UnsafeHostnameVerification.java:14:55:19:9 | new (...) | UnsafeHostnameVerification.java:14:55:19:9 | new (...) | $@ that is defined $@ and accepts any certificate as valid, is used here. | UnsafeHostnameVerification.java:14:55:19:9 | new (...) | This hostname verifier | UnsafeHostnameVerification.java:14:59:14:74 | new HostnameVerifier(...) { ... } | here | +| UnsafeHostnameVerification.java:26:55:26:71 | ...->... | UnsafeHostnameVerification.java:26:55:26:71 | ...->... | UnsafeHostnameVerification.java:26:55:26:71 | ...->... | $@ that is defined $@ and accepts any certificate as valid, is used here. | UnsafeHostnameVerification.java:26:55:26:71 | ...->... | This hostname verifier | UnsafeHostnameVerification.java:26:55:26:71 | new HostnameVerifier(...) { ... } | here | +| UnsafeHostnameVerification.java:47:55:47:71 | ...->... | UnsafeHostnameVerification.java:47:55:47:71 | ...->... | UnsafeHostnameVerification.java:47:55:47:71 | ...->... | $@ that is defined $@ and accepts any certificate as valid, is used here. | UnsafeHostnameVerification.java:47:55:47:71 | ...->... | This hostname verifier | UnsafeHostnameVerification.java:47:55:47:71 | new HostnameVerifier(...) { ... } | here | +| UnsafeHostnameVerification.java:81:55:81:62 | verifier | UnsafeHostnameVerification.java:66:37:80:9 | new (...) : new HostnameVerifier(...) { ... } | UnsafeHostnameVerification.java:81:55:81:62 | verifier | $@ that is defined $@ and accepts any certificate as valid, is used here. | UnsafeHostnameVerification.java:66:37:80:9 | new (...) : new HostnameVerifier(...) { ... } | This hostname verifier | UnsafeHostnameVerification.java:66:41:66:56 | new HostnameVerifier(...) { ... } | here | +| UnsafeHostnameVerification.java:94:55:94:62 | verifier | UnsafeHostnameVerification.java:88:37:93:9 | new (...) : new HostnameVerifier(...) { ... } | UnsafeHostnameVerification.java:94:55:94:62 | verifier | $@ that is defined $@ and accepts any certificate as valid, is used here. | UnsafeHostnameVerification.java:88:37:93:9 | new (...) : new HostnameVerifier(...) { ... } | This hostname verifier | UnsafeHostnameVerification.java:88:41:88:56 | new HostnameVerifier(...) { ... } | here | diff --git a/java/ql/test/query-tests/security/CWE-297/UnsafeHostnameVerification.java b/java/ql/test/query-tests/security/CWE-297/UnsafeHostnameVerification.java new file mode 100644 index 00000000000..c893e0b8eef --- /dev/null +++ b/java/ql/test/query-tests/security/CWE-297/UnsafeHostnameVerification.java @@ -0,0 +1,103 @@ +import javax.net.ssl.HostnameVerifier; +import javax.net.ssl.HttpsURLConnection; +import javax.net.ssl.SSLSession; +import java.security.cert.Certificate; + +public class UnsafeHostnameVerification { + + private static final boolean DISABLE_VERIFICATION = true; + + /** + * Test the implementation of trusting all hostnames as an anonymous class + */ + public void testTrustAllHostnameOfAnonymousClass() { + HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() { + @Override + public boolean verify(String hostname, SSLSession session) { + return true; // BAD, always returns true + } + }); + } + + /** + * Test the implementation of trusting all hostnames as a lambda. + */ + public void testTrustAllHostnameLambda() { + HttpsURLConnection.setDefaultHostnameVerifier((name, s) -> true); // BAD, always returns true + } + + /** + * Test an all-trusting hostname verifier that is guarded by a flag + */ + public void testGuardedByFlagTrustAllHostname() { + if (DISABLE_VERIFICATION) { + HttpsURLConnection.setDefaultHostnameVerifier(ALLOW_ALL_HOSTNAME_VERIFIER); // GOOD: The all-trusting + // hostname verifier is guarded + // by a feature flag + } + } + + public void testGuardedByFlagAccrossCalls() { + if (DISABLE_VERIFICATION) { + functionThatActuallyDisablesVerification(); + } + } + + private void functionThatActuallyDisablesVerification() { + HttpsURLConnection.setDefaultHostnameVerifier((name, s) -> true); // GOOD [but detected as BAD], because we only + // check guards inside a function + // and not accross function calls. This is considerer GOOD because the call to + // `functionThatActuallyDisablesVerification` is guarded by a feature flag in + // `testGuardedByFlagAccrossCalls`. + // Although this is not ideal as another function could directly call + // `functionThatActuallyDisablesVerification` WITHOUT checking the feature flag. + } + + public void testTrustAllHostnameDependingOnDerivedValue() { + String enabled = System.getProperty("disableHostnameVerification"); + if (Boolean.parseBoolean(enabled)) { + HttpsURLConnection.setDefaultHostnameVerifier((hostname, session) -> true); // GOOD, because it depends on a + // feature + // flag. + } + } + + public void testTrustAllHostnameWithExceptions() { + HostnameVerifier verifier = new HostnameVerifier() { + @Override + public boolean verify(String hostname, SSLSession session) { + try { verify(hostname, session.getPeerCertificates()); } catch (Exception e) { throw new RuntimeException(); } + return true; // GOOD [but detected as BAD]. The verification of the certificate is done in + // another method and + // in the case of a mismatch, an `Exception` is thrown so the `return true` + // statement never gets executed. + } + + // Black-box method that properly verifies the certificate but throws an + // `Exception` in the case of a mismatch. + private void verify(String hostname, Certificate[] certs) { + } + }; + HttpsURLConnection.setDefaultHostnameVerifier(verifier); + } + + /** + * Test the implementation of trusting all hostnames as a variable + */ + public void testTrustAllHostnameOfVariable() { + HostnameVerifier verifier = new HostnameVerifier() { + @Override + public boolean verify(String hostname, SSLSession session) { + return true; // BAD, always returns true + } + }; + HttpsURLConnection.setDefaultHostnameVerifier(verifier); + } + + public static final HostnameVerifier ALLOW_ALL_HOSTNAME_VERIFIER = new HostnameVerifier() { + @Override + public boolean verify(String hostname, SSLSession session) { + return true; // BAD, always returns true + } + }; +} diff --git a/java/ql/test/query-tests/security/CWE-297/UnsafeHostnameVerification.qlref b/java/ql/test/query-tests/security/CWE-297/UnsafeHostnameVerification.qlref new file mode 100644 index 00000000000..2e449e119d1 --- /dev/null +++ b/java/ql/test/query-tests/security/CWE-297/UnsafeHostnameVerification.qlref @@ -0,0 +1 @@ +Security/CWE/CWE-297/UnsafeHostnameVerification.ql diff --git a/java/ql/test/query-tests/security/CWE-311/CWE-319/Test.java b/java/ql/test/query-tests/security/CWE-311/CWE-319/Test.java index 568a9d89f85..9e2f3f923e8 100644 --- a/java/ql/test/query-tests/security/CWE-311/CWE-319/Test.java +++ b/java/ql/test/query-tests/security/CWE-311/CWE-319/Test.java @@ -3,7 +3,7 @@ import javax.net.ssl.HttpsURLConnection; import java.io.*; class Test { - public void m1(HttpURLConnection connection) { + public void m1(HttpURLConnection connection) throws java.io.IOException { InputStream input; if (connection instanceof HttpsURLConnection) { input = connection.getInputStream(); // OK diff --git a/java/ql/test/query-tests/security/CWE-421/semmle/Test.java b/java/ql/test/query-tests/security/CWE-421/semmle/Test.java index 31d20ae133a..0e2dc665a4b 100644 --- a/java/ql/test/query-tests/security/CWE-421/semmle/Test.java +++ b/java/ql/test/query-tests/security/CWE-421/semmle/Test.java @@ -31,7 +31,7 @@ class Test { return true; } - public void doConnect(int desiredPort, String username) { + public void doConnect(int desiredPort, String username) throws Exception { ServerSocket listenSocket = new ServerSocket(desiredPort); if (isAuthenticated(username)) { @@ -56,7 +56,7 @@ class Test { } - public void doConnectChannel(int desiredPort, String username) { + public void doConnectChannel(int desiredPort, String username) throws Exception { ServerSocketChannel listenChannel = ServerSocketChannel.open(); SocketAddress port = new InetSocketAddress(desiredPort); listenChannel.bind(port); diff --git a/java/ql/test/query-tests/security/CWE-502/A.java b/java/ql/test/query-tests/security/CWE-502/A.java index 3b3de5f8ed2..50090f69132 100644 --- a/java/ql/test/query-tests/security/CWE-502/A.java +++ b/java/ql/test/query-tests/security/CWE-502/A.java @@ -9,32 +9,32 @@ import org.yaml.snakeyaml.constructor.Constructor; import org.yaml.snakeyaml.Yaml; public class A { - public Object deserialize1(Socket sock) { + public Object deserialize1(Socket sock) throws java.io.IOException, ClassNotFoundException { InputStream inputStream = sock.getInputStream(); ObjectInputStream in = new ObjectInputStream(inputStream); return in.readObject(); // unsafe } - public Object deserialize2(Socket sock) { + public Object deserialize2(Socket sock) throws java.io.IOException, ClassNotFoundException { InputStream inputStream = sock.getInputStream(); ObjectInputStream in = new ObjectInputStream(inputStream); return in.readUnshared(); // unsafe } - public Object deserialize3(Socket sock) { + public Object deserialize3(Socket sock) throws java.io.IOException { InputStream inputStream = sock.getInputStream(); XMLDecoder d = new XMLDecoder(inputStream); return d.readObject(); // unsafe } - public Object deserialize4(Socket sock) { + public Object deserialize4(Socket sock) throws java.io.IOException { XStream xs = new XStream(); InputStream inputStream = sock.getInputStream(); Reader reader = new InputStreamReader(inputStream); return xs.fromXML(reader); // unsafe } - public void deserialize5(Socket sock) { + public void deserialize5(Socket sock) throws java.io.IOException { Kryo kryo = new Kryo(); Input input = new Input(sock.getInputStream()); A a1 = kryo.readObject(input, A.class); // unsafe @@ -42,20 +42,20 @@ public class A { Object o = kryo.readClassAndObject(input); // unsafe } - private Kryo getSafeKryo() { + private Kryo getSafeKryo() throws java.io.IOException { Kryo kryo = new Kryo(); kryo.setRegistrationRequired(true); // ... kryo.register(A.class) ... return kryo; } - public void deserialize6(Socket sock) { + public void deserialize6(Socket sock) throws java.io.IOException { Kryo kryo = getSafeKryo(); Input input = new Input(sock.getInputStream()); Object o = kryo.readClassAndObject(input); // OK } - public void deserializeSnakeYaml(Socket sock) { + public void deserializeSnakeYaml(Socket sock) throws java.io.IOException { Yaml yaml = new Yaml(); InputStream input = sock.getInputStream(); Object o = yaml.load(input); //unsafe @@ -65,7 +65,7 @@ public class A { A o5 = yaml.loadAs(new InputStreamReader(input), A.class); //unsafe } - public void deserializeSnakeYaml2(Socket sock) { + public void deserializeSnakeYaml2(Socket sock) throws java.io.IOException { Yaml yaml = new Yaml(new Constructor()); InputStream input = sock.getInputStream(); Object o = yaml.load(input); //unsafe @@ -75,7 +75,7 @@ public class A { A o5 = yaml.loadAs(new InputStreamReader(input), A.class); //unsafe } - public void deserializeSnakeYaml3(Socket sock) { + public void deserializeSnakeYaml3(Socket sock) throws java.io.IOException { Yaml yaml = new Yaml(new SafeConstructor()); InputStream input = sock.getInputStream(); Object o = yaml.load(input); //OK @@ -85,13 +85,13 @@ public class A { A o5 = yaml.loadAs(new InputStreamReader(input), A.class); //OK } - public void deserializeSnakeYaml4(Socket sock) { + public void deserializeSnakeYaml4(Socket sock) throws java.io.IOException { Yaml yaml = new Yaml(new Constructor(A.class)); InputStream input = sock.getInputStream(); - Object o = yaml.load(input); //OK - Object o2 = yaml.loadAll(input); //OK - Object o3 = yaml.parse(new InputStreamReader(input)); //OK - A o4 = yaml.loadAs(input, A.class); //OK - A o5 = yaml.loadAs(new InputStreamReader(input), A.class); //OK + Object o = yaml.load(input); //unsafe + Object o2 = yaml.loadAll(input); //unsafe + Object o3 = yaml.parse(new InputStreamReader(input)); //unsafe + A o4 = yaml.loadAs(input, A.class); //unsafe + A o5 = yaml.loadAs(new InputStreamReader(input), A.class); //unsafe } } diff --git a/java/ql/test/query-tests/security/CWE-502/B.java b/java/ql/test/query-tests/security/CWE-502/B.java index 671442a9346..a12555edd70 100644 --- a/java/ql/test/query-tests/security/CWE-502/B.java +++ b/java/ql/test/query-tests/security/CWE-502/B.java @@ -3,19 +3,19 @@ import java.net.Socket; import com.alibaba.fastjson.JSON; public class B { - public Object deserializeJson1(Socket sock) { + public Object deserializeJson1(Socket sock) throws java.io.IOException { InputStream inputStream = sock.getInputStream(); return JSON.parseObject(inputStream, null); // unsafe } - public Object deserializeJson2(Socket sock) { + public Object deserializeJson2(Socket sock) throws java.io.IOException { InputStream inputStream = sock.getInputStream(); byte[] bytes = new byte[100]; inputStream.read(bytes); return JSON.parse(bytes); // unsafe } - public Object deserializeJson3(Socket sock) { + public Object deserializeJson3(Socket sock) throws java.io.IOException { InputStream inputStream = sock.getInputStream(); byte[] bytes = new byte[100]; inputStream.read(bytes); @@ -23,7 +23,7 @@ public class B { return JSON.parseObject(s); // unsafe } - public Object deserializeJson4(Socket sock) { + public Object deserializeJson4(Socket sock) throws java.io.IOException { InputStream inputStream = sock.getInputStream(); byte[] bytes = new byte[100]; inputStream.read(bytes); diff --git a/java/ql/test/query-tests/security/CWE-502/UnsafeDeserialization.expected b/java/ql/test/query-tests/security/CWE-502/UnsafeDeserialization.expected index 672a692c03f..f575a093d6e 100644 --- a/java/ql/test/query-tests/security/CWE-502/UnsafeDeserialization.expected +++ b/java/ql/test/query-tests/security/CWE-502/UnsafeDeserialization.expected @@ -16,6 +16,11 @@ edges | A.java:70:25:70:45 | getInputStream(...) : InputStream | A.java:73:28:73:55 | new InputStreamReader(...) | | A.java:70:25:70:45 | getInputStream(...) : InputStream | A.java:74:24:74:28 | input | | A.java:70:25:70:45 | getInputStream(...) : InputStream | A.java:75:24:75:51 | new InputStreamReader(...) | +| A.java:90:25:90:45 | getInputStream(...) : InputStream | A.java:91:26:91:30 | input | +| A.java:90:25:90:45 | getInputStream(...) : InputStream | A.java:92:30:92:34 | input | +| A.java:90:25:90:45 | getInputStream(...) : InputStream | A.java:93:28:93:55 | new InputStreamReader(...) | +| A.java:90:25:90:45 | getInputStream(...) : InputStream | A.java:94:24:94:28 | input | +| A.java:90:25:90:45 | getInputStream(...) : InputStream | A.java:95:24:95:51 | new InputStreamReader(...) | | B.java:7:31:7:51 | getInputStream(...) : InputStream | B.java:8:29:8:39 | inputStream | | B.java:12:31:12:51 | getInputStream(...) : InputStream | B.java:15:23:15:27 | bytes | | B.java:19:31:19:51 | getInputStream(...) : InputStream | B.java:23:29:23:29 | s | @@ -46,6 +51,12 @@ nodes | A.java:73:28:73:55 | new InputStreamReader(...) | semmle.label | new InputStreamReader(...) | | A.java:74:24:74:28 | input | semmle.label | input | | A.java:75:24:75:51 | new InputStreamReader(...) | semmle.label | new InputStreamReader(...) | +| A.java:90:25:90:45 | getInputStream(...) : InputStream | semmle.label | getInputStream(...) : InputStream | +| A.java:91:26:91:30 | input | semmle.label | input | +| A.java:92:30:92:34 | input | semmle.label | input | +| A.java:93:28:93:55 | new InputStreamReader(...) | semmle.label | new InputStreamReader(...) | +| A.java:94:24:94:28 | input | semmle.label | input | +| A.java:95:24:95:51 | new InputStreamReader(...) | semmle.label | new InputStreamReader(...) | | B.java:7:31:7:51 | getInputStream(...) : InputStream | semmle.label | getInputStream(...) : InputStream | | B.java:8:29:8:39 | inputStream | semmle.label | inputStream | | B.java:12:31:12:51 | getInputStream(...) : InputStream | semmle.label | getInputStream(...) : InputStream | @@ -74,6 +85,11 @@ nodes | A.java:73:17:73:56 | parse(...) | A.java:70:25:70:45 | getInputStream(...) : InputStream | A.java:73:28:73:55 | new InputStreamReader(...) | Unsafe deserialization of $@. | A.java:70:25:70:45 | getInputStream(...) | user input | | A.java:74:12:74:38 | loadAs(...) | A.java:70:25:70:45 | getInputStream(...) : InputStream | A.java:74:24:74:28 | input | Unsafe deserialization of $@. | A.java:70:25:70:45 | getInputStream(...) | user input | | A.java:75:12:75:61 | loadAs(...) | A.java:70:25:70:45 | getInputStream(...) : InputStream | A.java:75:24:75:51 | new InputStreamReader(...) | Unsafe deserialization of $@. | A.java:70:25:70:45 | getInputStream(...) | user input | +| A.java:91:16:91:31 | load(...) | A.java:90:25:90:45 | getInputStream(...) : InputStream | A.java:91:26:91:30 | input | Unsafe deserialization of $@. | A.java:90:25:90:45 | getInputStream(...) | user input | +| A.java:92:17:92:35 | loadAll(...) | A.java:90:25:90:45 | getInputStream(...) : InputStream | A.java:92:30:92:34 | input | Unsafe deserialization of $@. | A.java:90:25:90:45 | getInputStream(...) | user input | +| A.java:93:17:93:56 | parse(...) | A.java:90:25:90:45 | getInputStream(...) : InputStream | A.java:93:28:93:55 | new InputStreamReader(...) | Unsafe deserialization of $@. | A.java:90:25:90:45 | getInputStream(...) | user input | +| A.java:94:12:94:38 | loadAs(...) | A.java:90:25:90:45 | getInputStream(...) : InputStream | A.java:94:24:94:28 | input | Unsafe deserialization of $@. | A.java:90:25:90:45 | getInputStream(...) | user input | +| A.java:95:12:95:61 | loadAs(...) | A.java:90:25:90:45 | getInputStream(...) : InputStream | A.java:95:24:95:51 | new InputStreamReader(...) | Unsafe deserialization of $@. | A.java:90:25:90:45 | getInputStream(...) | user input | | B.java:8:12:8:46 | parseObject(...) | B.java:7:31:7:51 | getInputStream(...) : InputStream | B.java:8:29:8:39 | inputStream | Unsafe deserialization of $@. | B.java:7:31:7:51 | getInputStream(...) | user input | | B.java:15:12:15:28 | parse(...) | B.java:12:31:12:51 | getInputStream(...) : InputStream | B.java:15:23:15:27 | bytes | Unsafe deserialization of $@. | B.java:12:31:12:51 | getInputStream(...) | user input | | B.java:23:12:23:30 | parseObject(...) | B.java:19:31:19:51 | getInputStream(...) : InputStream | B.java:23:29:23:29 | s | Unsafe deserialization of $@. | B.java:19:31:19:51 | getInputStream(...) | user input | diff --git a/java/ql/test/query-tests/security/CWE-611/DocumentBuilderTests.java b/java/ql/test/query-tests/security/CWE-611/DocumentBuilderTests.java index f70b44e2f1a..cb25141a90d 100644 --- a/java/ql/test/query-tests/security/CWE-611/DocumentBuilderTests.java +++ b/java/ql/test/query-tests/security/CWE-611/DocumentBuilderTests.java @@ -102,7 +102,7 @@ class DocumentBuilderTests { builder.parse(source.getInputStream()); //unsafe } - private static DocumentBuilderFactory getDocumentBuilderFactory() { + private static DocumentBuilderFactory getDocumentBuilderFactory() throws Exception { DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); String feature = ""; feature = "http://xml.org/sax/features/external-parameter-entities"; @@ -115,8 +115,8 @@ class DocumentBuilderTests { private static final ThreadLocal XML_DOCUMENT_BUILDER = new ThreadLocal() { @Override protected DocumentBuilder initialValue() { - DocumentBuilderFactory factory = getDocumentBuilderFactory(); try { + DocumentBuilderFactory factory = getDocumentBuilderFactory(); return factory.newDocumentBuilder(); } catch (Exception ex) { throw new RuntimeException(ex); diff --git a/java/ql/test/query-tests/security/CWE-611/SAXParserTests.java b/java/ql/test/query-tests/security/CWE-611/SAXParserTests.java index 882cb79bac8..f8079dd1bc8 100644 --- a/java/ql/test/query-tests/security/CWE-611/SAXParserTests.java +++ b/java/ql/test/query-tests/security/CWE-611/SAXParserTests.java @@ -2,7 +2,7 @@ import java.net.Socket; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; - +import javax.xml.XMLConstants; import org.xml.sax.helpers.DefaultHandler; public class SAXParserTests { @@ -72,4 +72,12 @@ public class SAXParserTests { SAXParser parser = factory.newSAXParser(); parser.parse(sock.getInputStream(), new DefaultHandler()); //unsafe } + + public void safeParser2(Socket sock) throws Exception { + SAXParserFactory factory = SAXParserFactory.newInstance(); + factory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true); + factory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); + SAXParser parser = factory.newSAXParser(); + parser.parse(sock.getInputStream(), new DefaultHandler()); //safe + } } diff --git a/java/ql/test/query-tests/security/CWE-732/semmle/tests/Test.java b/java/ql/test/query-tests/security/CWE-732/semmle/tests/Test.java index ec1dfd1289c..8717203802d 100644 --- a/java/ql/test/query-tests/security/CWE-732/semmle/tests/Test.java +++ b/java/ql/test/query-tests/security/CWE-732/semmle/tests/Test.java @@ -31,11 +31,11 @@ class Test { new FileInputStream(f2); } - public static void readFile(File f) { + public static void readFile(File f) throws java.io.FileNotFoundException { new FileReader(f); } public static void setWorldWritable(File f) { f.setWritable(true, false); } -} \ No newline at end of file +} diff --git a/java/ql/test/query-tests/security/CWE-833/semmle/tests/LockOrderInconsistency.expected b/java/ql/test/query-tests/security/CWE-833/semmle/tests/LockOrderInconsistency.expected index 89a404374cc..995d2a75277 100644 --- a/java/ql/test/query-tests/security/CWE-833/semmle/tests/LockOrderInconsistency.expected +++ b/java/ql/test/query-tests/security/CWE-833/semmle/tests/LockOrderInconsistency.expected @@ -1,4 +1,4 @@ -| MethodAccessLockOrder.java:29:4:29:40 | transferFrom(...) | Synchronization here and $@ may be performed in reverse order starting $@ and result in deadlock. | MethodAccessLockOrder.java:8:21:8:41 | subtract(...) | here | MethodAccessLockOrder.java:31:4:31:40 | transferFrom(...) | here | +| MethodAccessLockOrder.java:29:11:29:47 | transferFrom(...) | Synchronization here and $@ may be performed in reverse order starting $@ and result in deadlock. | MethodAccessLockOrder.java:8:21:8:41 | subtract(...) | here | MethodAccessLockOrder.java:31:11:31:47 | transferFrom(...) | here | | ReentrantLockOrder.java:11:4:11:21 | lock(...) | Synchronization here and $@ may be performed in reverse order starting $@ and result in deadlock. | ReentrantLockOrder.java:12:4:12:21 | lock(...) | here | ReentrantLockOrder.java:28:4:28:21 | lock(...) | here | | ReentrantLockOrder.java:28:4:28:21 | lock(...) | Synchronization here and $@ may be performed in reverse order starting $@ and result in deadlock. | ReentrantLockOrder.java:29:4:29:21 | lock(...) | here | ReentrantLockOrder.java:11:4:11:21 | lock(...) | here | | SynchronizedStmtLockOrder.java:8:16:8:26 | primaryLock | Synchronization here and $@ may be performed in reverse order starting $@ and result in deadlock. | SynchronizedStmtLockOrder.java:9:17:9:27 | savingsLock | here | SynchronizedStmtLockOrder.java:22:16:22:26 | savingsLock | here | diff --git a/java/ql/test/query-tests/security/CWE-833/semmle/tests/MethodAccessLockOrder.java b/java/ql/test/query-tests/security/CWE-833/semmle/tests/MethodAccessLockOrder.java index 9092bfee427..e02364c05ec 100644 --- a/java/ql/test/query-tests/security/CWE-833/semmle/tests/MethodAccessLockOrder.java +++ b/java/ql/test/query-tests/security/CWE-833/semmle/tests/MethodAccessLockOrder.java @@ -26,9 +26,9 @@ class MethodAccessLockOrder { public boolean initiateTransfer(boolean fromSavings, int amount) { // AVOID: inconsistent lock order if (fromSavings) { - primary.transferFrom(savings, amount); + return primary.transferFrom(savings, amount); } else { - savings.transferFrom(primary, amount); + return savings.transferFrom(primary, amount); } } diff --git a/java/ql/test/stubs/google-android-9.0.0/android/app/Activity.java b/java/ql/test/stubs/google-android-9.0.0/android/app/Activity.java index 19a2662b96c..e04f68a203d 100644 --- a/java/ql/test/stubs/google-android-9.0.0/android/app/Activity.java +++ b/java/ql/test/stubs/google-android-9.0.0/android/app/Activity.java @@ -1019,6 +1019,7 @@ public class Activity { * @see Activity#requireViewById(int) */ public T findViewById(int id) { + return null; } /** @@ -1141,4 +1142,4 @@ public class Activity { */ public void startActivities(Intent[] intents, Bundle options) { } -} \ No newline at end of file +} diff --git a/java/ql/test/stubs/google-android-9.0.0/android/content/Context.java b/java/ql/test/stubs/google-android-9.0.0/android/content/Context.java index e1ce2140a06..6507cbd371d 100644 --- a/java/ql/test/stubs/google-android-9.0.0/android/content/Context.java +++ b/java/ql/test/stubs/google-android-9.0.0/android/content/Context.java @@ -26,6 +26,84 @@ import android.os.Bundle; * broadcasting and receiving intents, etc. */ public abstract class Context { + /** + * File creation mode: the default mode, where the created file can only + * be accessed by the calling application (or all applications sharing the + * same user ID). + * @see #MODE_WORLD_READABLE + * @see #MODE_WORLD_WRITEABLE + */ + public static final int MODE_PRIVATE = 0x0000; + + /** + * @deprecated Creating world-readable files is very dangerous, and likely + * to cause security holes in applications. It is strongly discouraged; + * instead, applications should use more formal mechanism for interactions + * such as {@link ContentProvider}, {@link BroadcastReceiver}, and + * {@link android.app.Service}. There are no guarantees that this + * access mode will remain on a file, such as when it goes through a + * backup and restore. + * File creation mode: allow all other applications to have read access + * to the created file. + * @see #MODE_PRIVATE + * @see #MODE_WORLD_WRITEABLE + */ + @Deprecated + public static final int MODE_WORLD_READABLE = 0x0001; + + /** + * @deprecated Creating world-writable files is very dangerous, and likely + * to cause security holes in applications. It is strongly discouraged; + * instead, applications should use more formal mechanism for interactions + * such as {@link ContentProvider}, {@link BroadcastReceiver}, and + * {@link android.app.Service}. There are no guarantees that this + * access mode will remain on a file, such as when it goes through a + * backup and restore. + * File creation mode: allow all other applications to have write access + * to the created file. + * @see #MODE_PRIVATE + * @see #MODE_WORLD_READABLE + */ + @Deprecated + public static final int MODE_WORLD_WRITEABLE = 0x0002; + + /** + * File creation mode: for use with {@link #openFileOutput}, if the file + * already exists then write data to the end of the existing file + * instead of erasing it. + * @see #openFileOutput + */ + public static final int MODE_APPEND = 0x8000; + + /** + * SharedPreference loading flag: when set, the file on disk will + * be checked for modification even if the shared preferences + * instance is already loaded in this process. This behavior is + * sometimes desired in cases where the application has multiple + * processes, all writing to the same SharedPreferences file. + * Generally there are better forms of communication between + * processes, though. + * + *

    This was the legacy (but undocumented) behavior in and + * before Gingerbread (Android 2.3) and this flag is implied when + * targetting such releases. For applications targetting SDK + * versions greater than Android 2.3, this flag must be + * explicitly set if desired. + * + * @see #getSharedPreferences + */ + public static final int MODE_MULTI_PROCESS = 0x0004; + + /** + * Database open flag: when set, the database is opened with write-ahead + * logging enabled by default. + * + * @see #openOrCreateDatabase(String, int, CursorFactory) + * @see #openOrCreateDatabase(String, int, CursorFactory, DatabaseErrorHandler) + * @see SQLiteDatabase#enableWriteAheadLogging + */ + public static final int MODE_ENABLE_WRITE_AHEAD_LOGGING = 0x0008; + /** * Return the context of the single, global Application object of the current * process. This generally should only be used if you need a Context whose @@ -76,19 +154,42 @@ public abstract class Context { public abstract File getFileStreamPath(String name); /** - * Returns the absolute path on the filesystem where a file created with - * {@link #getSharedPreferences(String, int)} is stored. - *

    - * The returned path may change over time if the calling app is moved to an - * adopted storage device, so only relative paths should be persisted. + * {@hide} + * Return the full path to the shared prefs file for the given prefs group name. * - * @param name The name of the shared preferences for which you would like to - * get a path. - * @return An absolute path to the given file. - * @see #getSharedPreferences(String, int) - * @removed + *

    Note: this is not generally useful for applications, since they should + * not be directly accessing the file system. */ - public abstract File getSharedPreferencesPath(String name); + public abstract File getSharedPrefsFile(String name); + + /** + * Retrieve and hold the contents of the preferences file 'name', returning + * a SharedPreferences through which you can retrieve and modify its + * values. Only one instance of the SharedPreferences object is returned + * to any callers for the same name, meaning they will see each other's + * edits as soon as they are made. + * + * @param name Desired preferences file. If a preferences file by this name + * does not exist, it will be created when you retrieve an + * editor (SharedPreferences.edit()) and then commit changes (Editor.commit()). + * @param mode Operating mode. Use 0 or {@link #MODE_PRIVATE} for the + * default operation, {@link #MODE_WORLD_READABLE} + * and {@link #MODE_WORLD_WRITEABLE} to control permissions. The bit + * {@link #MODE_MULTI_PROCESS} can also be used if multiple processes + * are mutating the same SharedPreferences file. {@link #MODE_MULTI_PROCESS} + * is always on in apps targetting Gingerbread (Android 2.3) and below, and + * off by default in later versions. + * + * @return Returns the single SharedPreferences instance that can be used + * to retrieve and modify the preference values. + * + * @see #MODE_PRIVATE + * @see #MODE_WORLD_READABLE + * @see #MODE_WORLD_WRITEABLE + * @see #MODE_MULTI_PROCESS + */ + public abstract SharedPreferences getSharedPreferences(String name, + int mode); /** * Returns the absolute path to the directory on the filesystem where all diff --git a/java/ql/test/stubs/google-android-9.0.0/android/content/Intent.java b/java/ql/test/stubs/google-android-9.0.0/android/content/Intent.java index 292069c0f71..09422c7a48a 100644 --- a/java/ql/test/stubs/google-android-9.0.0/android/content/Intent.java +++ b/java/ql/test/stubs/google-android-9.0.0/android/content/Intent.java @@ -821,6 +821,7 @@ public class Intent implements Parcelable, Cloneable { */ @Deprecated public static Intent getIntent(String uri) { + return null; } /** @@ -845,6 +846,7 @@ public class Intent implements Parcelable, Cloneable { * @see #toUri */ public static Intent parseUri(String uri, int flags) { + return null; } /** @@ -2069,4 +2071,4 @@ public class Intent implements Parcelable, Cloneable { return null; } -} \ No newline at end of file +} diff --git a/java/ql/test/stubs/google-android-9.0.0/android/content/SharedPreferences.java b/java/ql/test/stubs/google-android-9.0.0/android/content/SharedPreferences.java new file mode 100644 index 00000000000..faac2f1d41e --- /dev/null +++ b/java/ql/test/stubs/google-android-9.0.0/android/content/SharedPreferences.java @@ -0,0 +1,362 @@ +/* + * Copyright (C) 2006 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package android.content; + +import java.util.Map; +import java.util.Set; +/** + * Interface for accessing and modifying preference data returned by {@link + * Context#getSharedPreferences}. For any particular set of preferences, + * there is a single instance of this class that all clients share. + * Modifications to the preferences must go through an {@link Editor} object + * to ensure the preference values remain in a consistent state and control + * when they are committed to storage. Objects that are returned from the + * various get methods must be treated as immutable by the application. + * + *

    Note: currently this class does not support use across multiple + * processes. This will be added later. + * + *

    + *

    Developer Guides

    + *

    For more information about using SharedPreferences, read the + * Data Storage + * developer guide.

    + * + * @see Context#getSharedPreferences + */ +public interface SharedPreferences { + /** + * Interface definition for a callback to be invoked when a shared + * preference is changed. + */ + public interface OnSharedPreferenceChangeListener { + /** + * Called when a shared preference is changed, added, or removed. This + * may be called even if a preference is set to its existing value. + * + *

    This callback will be run on your main thread. + * + * @param sharedPreferences The {@link SharedPreferences} that received + * the change. + * @param key The key of the preference that was changed, added, or + * removed. + */ + void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key); + } + + /** + * Interface used for modifying values in a {@link SharedPreferences} + * object. All changes you make in an editor are batched, and not copied + * back to the original {@link SharedPreferences} until you call {@link #commit} + * or {@link #apply} + */ + public interface Editor { + /** + * Set a String value in the preferences editor, to be written back once + * {@link #commit} or {@link #apply} are called. + * + * @param key The name of the preference to modify. + * @param value The new value for the preference. Supplying {@code null} + * as the value is equivalent to calling {@link #remove(String)} with + * this key. + * + * @return Returns a reference to the same Editor object, so you can + * chain put calls together. + */ + Editor putString(String key, String value); + + /** + * Set a set of String values in the preferences editor, to be written + * back once {@link #commit} is called. + * + * @param key The name of the preference to modify. + * @param values The set of new values for the preference. Passing {@code null} + * for this argument is equivalent to calling {@link #remove(String)} with + * this key. + * @return Returns a reference to the same Editor object, so you can + * chain put calls together. + */ + Editor putStringSet(String key, Set values); + + /** + * Set an int value in the preferences editor, to be written back once + * {@link #commit} or {@link #apply} are called. + * + * @param key The name of the preference to modify. + * @param value The new value for the preference. + * + * @return Returns a reference to the same Editor object, so you can + * chain put calls together. + */ + Editor putInt(String key, int value); + + /** + * Set a long value in the preferences editor, to be written back once + * {@link #commit} or {@link #apply} are called. + * + * @param key The name of the preference to modify. + * @param value The new value for the preference. + * + * @return Returns a reference to the same Editor object, so you can + * chain put calls together. + */ + Editor putLong(String key, long value); + + /** + * Set a float value in the preferences editor, to be written back once + * {@link #commit} or {@link #apply} are called. + * + * @param key The name of the preference to modify. + * @param value The new value for the preference. + * + * @return Returns a reference to the same Editor object, so you can + * chain put calls together. + */ + Editor putFloat(String key, float value); + + /** + * Set a boolean value in the preferences editor, to be written back + * once {@link #commit} or {@link #apply} are called. + * + * @param key The name of the preference to modify. + * @param value The new value for the preference. + * + * @return Returns a reference to the same Editor object, so you can + * chain put calls together. + */ + Editor putBoolean(String key, boolean value); + /** + * Mark in the editor that a preference value should be removed, which + * will be done in the actual preferences once {@link #commit} is + * called. + * + *

    Note that when committing back to the preferences, all removals + * are done first, regardless of whether you called remove before + * or after put methods on this editor. + * + * @param key The name of the preference to remove. + * + * @return Returns a reference to the same Editor object, so you can + * chain put calls together. + */ + Editor remove(String key); + /** + * Mark in the editor to remove all values from the + * preferences. Once commit is called, the only remaining preferences + * will be any that you have defined in this editor. + * + *

    Note that when committing back to the preferences, the clear + * is done first, regardless of whether you called clear before + * or after put methods on this editor. + * + * @return Returns a reference to the same Editor object, so you can + * chain put calls together. + */ + Editor clear(); + /** + * Commit your preferences changes back from this Editor to the + * {@link SharedPreferences} object it is editing. This atomically + * performs the requested modifications, replacing whatever is currently + * in the SharedPreferences. + * + *

    Note that when two editors are modifying preferences at the same + * time, the last one to call commit wins. + * + *

    If you don't care about the return value and you're + * using this from your application's main thread, consider + * using {@link #apply} instead. + * + * @return Returns true if the new values were successfully written + * to persistent storage. + */ + boolean commit(); + /** + * Commit your preferences changes back from this Editor to the + * {@link SharedPreferences} object it is editing. This atomically + * performs the requested modifications, replacing whatever is currently + * in the SharedPreferences. + * + *

    Note that when two editors are modifying preferences at the same + * time, the last one to call apply wins. + * + *

    Unlike {@link #commit}, which writes its preferences out + * to persistent storage synchronously, {@link #apply} + * commits its changes to the in-memory + * {@link SharedPreferences} immediately but starts an + * asynchronous commit to disk and you won't be notified of + * any failures. If another editor on this + * {@link SharedPreferences} does a regular {@link #commit} + * while a {@link #apply} is still outstanding, the + * {@link #commit} will block until all async commits are + * completed as well as the commit itself. + * + *

    As {@link SharedPreferences} instances are singletons within + * a process, it's safe to replace any instance of {@link #commit} with + * {@link #apply} if you were already ignoring the return value. + * + *

    You don't need to worry about Android component + * lifecycles and their interaction with apply() + * writing to disk. The framework makes sure in-flight disk + * writes from apply() complete before switching + * states. + * + *

    The SharedPreferences.Editor interface + * isn't expected to be implemented directly. However, if you + * previously did implement it and are now getting errors + * about missing apply(), you can simply call + * {@link #commit} from apply(). + */ + void apply(); + } + /** + * Retrieve all values from the preferences. + * + *

    Note that you must not modify the collection returned + * by this method, or alter any of its contents. The consistency of your + * stored data is not guaranteed if you do. + * + * @return Returns a map containing a list of pairs key/value representing + * the preferences. + * + * @throws NullPointerException + */ + Map getAll(); + /** + * Retrieve a String value from the preferences. + * + * @param key The name of the preference to retrieve. + * @param defValue Value to return if this preference does not exist. + * + * @return Returns the preference value if it exists, or defValue. Throws + * ClassCastException if there is a preference with this name that is not + * a String. + * + * @throws ClassCastException + */ + String getString(String key, String defValue); + + /** + * Retrieve a set of String values from the preferences. + * + *

    Note that you must not modify the set instance returned + * by this call. The consistency of the stored data is not guaranteed + * if you do, nor is your ability to modify the instance at all. + * + * @param key The name of the preference to retrieve. + * @param defValues Values to return if this preference does not exist. + * + * @return Returns the preference values if they exist, or defValues. + * Throws ClassCastException if there is a preference with this name + * that is not a Set. + * + * @throws ClassCastException + */ + Set getStringSet(String key, Set defValues); + + /** + * Retrieve an int value from the preferences. + * + * @param key The name of the preference to retrieve. + * @param defValue Value to return if this preference does not exist. + * + * @return Returns the preference value if it exists, or defValue. Throws + * ClassCastException if there is a preference with this name that is not + * an int. + * + * @throws ClassCastException + */ + int getInt(String key, int defValue); + + /** + * Retrieve a long value from the preferences. + * + * @param key The name of the preference to retrieve. + * @param defValue Value to return if this preference does not exist. + * + * @return Returns the preference value if it exists, or defValue. Throws + * ClassCastException if there is a preference with this name that is not + * a long. + * + * @throws ClassCastException + */ + long getLong(String key, long defValue); + + /** + * Retrieve a float value from the preferences. + * + * @param key The name of the preference to retrieve. + * @param defValue Value to return if this preference does not exist. + * + * @return Returns the preference value if it exists, or defValue. Throws + * ClassCastException if there is a preference with this name that is not + * a float. + * + * @throws ClassCastException + */ + float getFloat(String key, float defValue); + + /** + * Retrieve a boolean value from the preferences. + * + * @param key The name of the preference to retrieve. + * @param defValue Value to return if this preference does not exist. + * + * @return Returns the preference value if it exists, or defValue. Throws + * ClassCastException if there is a preference with this name that is not + * a boolean. + * + * @throws ClassCastException + */ + boolean getBoolean(String key, boolean defValue); + /** + * Checks whether the preferences contains a preference. + * + * @param key The name of the preference to check. + * @return Returns true if the preference exists in the preferences, + * otherwise false. + */ + boolean contains(String key); + + /** + * Create a new Editor for these preferences, through which you can make + * modifications to the data in the preferences and atomically commit those + * changes back to the SharedPreferences object. + * + *

    Note that you must call {@link Editor#commit} to have any + * changes you perform in the Editor actually show up in the + * SharedPreferences. + * + * @return Returns a new instance of the {@link Editor} interface, allowing + * you to modify the values in this SharedPreferences object. + */ + Editor edit(); + + /** + * Registers a callback to be invoked when a change happens to a preference. + * + * @param listener The callback that will run. + * @see #unregisterOnSharedPreferenceChangeListener + */ + void registerOnSharedPreferenceChangeListener(OnSharedPreferenceChangeListener listener); + + /** + * Unregisters a previous callback. + * + * @param listener The callback that should be unregistered. + * @see #registerOnSharedPreferenceChangeListener + */ + void unregisterOnSharedPreferenceChangeListener(OnSharedPreferenceChangeListener listener); +} diff --git a/java/ql/test/stubs/google-android-9.0.0/android/os/BaseBundle.java b/java/ql/test/stubs/google-android-9.0.0/android/os/BaseBundle.java index 4b85ae8e67a..3ac33642ab4 100644 --- a/java/ql/test/stubs/google-android-9.0.0/android/os/BaseBundle.java +++ b/java/ql/test/stubs/google-android-9.0.0/android/os/BaseBundle.java @@ -97,6 +97,7 @@ public class BaseBundle { * @hide */ public String getPairValue() { + return null; } /** diff --git a/java/ql/test/stubs/google-android-9.0.0/android/os/Parcel.java b/java/ql/test/stubs/google-android-9.0.0/android/os/Parcel.java index 2670e258e4f..077da662edb 100644 --- a/java/ql/test/stubs/google-android-9.0.0/android/os/Parcel.java +++ b/java/ql/test/stubs/google-android-9.0.0/android/os/Parcel.java @@ -229,6 +229,7 @@ public final class Parcel { } public final float[] createFloatArray() { + return null; } public final void readFloatArray(float[] val) { diff --git a/java/ql/test/stubs/google-android-9.0.0/androidx/security/crypto/EncryptedSharedPreferences.java b/java/ql/test/stubs/google-android-9.0.0/androidx/security/crypto/EncryptedSharedPreferences.java new file mode 100644 index 00000000000..8ca1443d049 --- /dev/null +++ b/java/ql/test/stubs/google-android-9.0.0/androidx/security/crypto/EncryptedSharedPreferences.java @@ -0,0 +1,172 @@ +/* + * Copyright 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package androidx.security.crypto; + +import android.content.Context; +import android.content.SharedPreferences; +import java.io.IOException; +import java.security.GeneralSecurityException; + +import java.util.Map; +import java.util.Set; + +/** + * An implementation of {@link SharedPreferences} that encrypts keys and values. + * + *

    + *  String masterKeyAlias = MasterKeys.getOrCreate(MasterKeys.AES256_GCM_SPEC);
    + *
    + *  SharedPreferences sharedPreferences = EncryptedSharedPreferences.create(
    + *      "secret_shared_prefs",
    + *      masterKeyAlias,
    + *      context,
    + *      EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV,
    + *      EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM
    + *  );
    + *
    + *  // use the shared preferences and editor as you normally would
    + *  SharedPreferences.Editor editor = sharedPreferences.edit();
    + * 
    + */ +public final class EncryptedSharedPreferences implements SharedPreferences { + /** + * Opens an instance of encrypted SharedPreferences + * + * @param fileName The name of the file to open; can not contain path + * separators. + * @param masterKey The master key to use. + * @param prefKeyEncryptionScheme The scheme to use for encrypting keys. + * @param prefValueEncryptionScheme The scheme to use for encrypting values. + * @return The SharedPreferences instance that encrypts all data. + * @throws GeneralSecurityException when a bad master key or keyset has been attempted + * @throws IOException when fileName can not be used + */ + public static SharedPreferences create(Context context, + String fileName, + MasterKey masterKey, + PrefKeyEncryptionScheme prefKeyEncryptionScheme, + PrefValueEncryptionScheme prefValueEncryptionScheme) + throws GeneralSecurityException, IOException { + return null; + } + + /** + * Opens an instance of encrypted SharedPreferences + * + * @param fileName The name of the file to open; can not contain path + * separators. + * @param masterKeyAlias The alias of the master key to use. + * @param context The context to use to open the preferences file. + * @param prefKeyEncryptionScheme The scheme to use for encrypting keys. + * @param prefValueEncryptionScheme The scheme to use for encrypting values. + * @return The SharedPreferences instance that encrypts all data. + * @throws GeneralSecurityException when a bad master key or keyset has been attempted + * @throws IOException when fileName can not be used + * @deprecated Use {@link #create(Context, String, MasterKey, + * PrefKeyEncryptionScheme, PrefValueEncryptionScheme)} instead. + */ + @Deprecated + public static SharedPreferences create(String fileName, + String masterKeyAlias, + Context context, + PrefKeyEncryptionScheme prefKeyEncryptionScheme, + PrefValueEncryptionScheme prefValueEncryptionScheme) + throws GeneralSecurityException, IOException { + return null; + } + + /** + * The encryption scheme to encrypt keys. + */ + public enum PrefKeyEncryptionScheme { + /** + * Pref keys are encrypted deterministically with AES256-SIV-CMAC (RFC 5297). + * + * For more information please see the Tink documentation: + * + * AesSivKeyManager.aes256SivTemplate() + */ + AES256_SIV; + } + /** + * The encryption scheme to encrypt values. + */ + public enum PrefValueEncryptionScheme { + /** + * Pref values are encrypted with AES256-GCM. The associated data is the encrypted pref key. + * + * For more information please see the Tink documentation: + * + * AesGcmKeyManager.aes256GcmTemplate() + */ + AES256_GCM; + } + + // SharedPreferences methods + @Override + public Map getAll() { + return null; + } + + @Override + public String getString(String key, String defValue) { + return null; + } + + @Override + public Set getStringSet(String key, Set defValues) { + return null; + } + + @Override + public int getInt(String key, int defValue) { + return -1; + } + + @Override + public long getLong(String key, long defValue) { + return -1; + } + + @Override + public float getFloat(String key, float defValue) { + return -1; + } + + @Override + public boolean getBoolean(String key, boolean defValue) { + return false; + } + + @Override + public boolean contains(String key) { + return false; + } + + @Override + public SharedPreferences.Editor edit() { + return null; + } + + @Override + public void registerOnSharedPreferenceChangeListener( + OnSharedPreferenceChangeListener listener) { + } + @Override + public void unregisterOnSharedPreferenceChangeListener( + OnSharedPreferenceChangeListener listener) { + } +} diff --git a/java/ql/test/stubs/google-android-9.0.0/androidx/security/crypto/MasterKey.java b/java/ql/test/stubs/google-android-9.0.0/androidx/security/crypto/MasterKey.java new file mode 100644 index 00000000000..c8f696db300 --- /dev/null +++ b/java/ql/test/stubs/google-android-9.0.0/androidx/security/crypto/MasterKey.java @@ -0,0 +1,191 @@ +/* + * Copyright 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package androidx.security.crypto; + +import android.content.Context; + +import java.io.IOException; +import java.security.GeneralSecurityException; + +/** + * Wrapper for a master key used in the library. + * + * On Android M (API 23) and above, this is class references a key that's stored in the + * Android Keystore. On Android L (API 21, 22), there isn't a master key. + */ +public final class MasterKey { + static final String KEYSTORE_PATH_URI = "android-keystore://"; + /** + * The default master key alias. + */ + public static final String DEFAULT_MASTER_KEY_ALIAS = "_androidx_security_master_key_"; + + /** + * The default and recommended size for the master key. + */ + public static final int DEFAULT_AES_GCM_MASTER_KEY_SIZE = 256; + + /** + * Algorithm/Cipher choices used for the master key. + */ + public enum KeyScheme { + AES256_GCM + } + + /** + * The default validity period for authentication in seconds. + */ + public static int getDefaultAuthenticationValidityDurationSeconds() { + return -1; + } + + /* package */ MasterKey(String keyAlias, Object keyGenParameterSpec) { + } + + /** + * Checks if this key is backed by the Android Keystore. + * + * @return {@code true} if the key is in Android Keystore, {@code false} otherwise. This + * method always returns false when called on Android Lollipop (API 21 and 22). + */ + public boolean isKeyStoreBacked() { + return false; + } + + /** + * Gets whether user authentication is required to use this key. + * + * This method always returns {@code false} on Android L (API 21 + 22). + */ + public boolean isUserAuthenticationRequired() { + return false; + } + + /** + * Gets the duration in seconds that the key is unlocked for following user authentication. + * + * The value returned for this method is only meaningful on Android M+ (API 23) when + * {@link #isUserAuthenticationRequired()} returns {@code true}. + * + * @return The duration the key is unlocked for in seconds. + */ + public int getUserAuthenticationValidityDurationSeconds() { + return -1; + } + + /** + * Gets whether the key is backed by strong box. + */ + public boolean isStrongBoxBacked() { + return false; + } + + /* package */ String getKeyAlias() { + return null; + } + + /** + * Builder for generating a {@link MasterKey}. + */ + public static final class Builder { + /** + * Creates a builder for a {@link MasterKey} using the default alias of + * {@link #DEFAULT_MASTER_KEY_ALIAS}. + * + * @param context The context to use with this master key. + */ + public Builder(Context context) { + } + + /** + * Creates a builder for a {@link MasterKey}. + * + * @param context The context to use with this master key. + */ + public Builder(Context context, String keyAlias) { + } + + /** + * Sets a {@link KeyScheme} to be used for the master key. + * This uses a default {@link KeyGenParameterSpec} associated with the provided + * {@code KeyScheme}. + * NOTE: Either this method OR {@link #setKeyGenParameterSpec} should be used to set + * the parameters to use for building the master key. Calling either function after + * the other will throw an {@link IllegalArgumentException}. + * + * @param keyScheme The KeyScheme to use. + * @return This builder. + */ + public Builder setKeyScheme(KeyScheme keyScheme) { + return null; + } + + /** + * When used with {@link #setKeyScheme(KeyScheme)}, sets that the built master key should + * require the user to authenticate before it's unlocked, probably using the + * androidx.biometric library. + * + * This method sets the validity duration of the key to + * {@link #getDefaultAuthenticationValidityDurationSeconds()}. + * + * @param authenticationRequired Whether user authentication should be required to use + * the key. + * @return This builder. + */ + public Builder setUserAuthenticationRequired(boolean authenticationRequired) { + return null; + } + + /** + * When used with {@link #setKeyScheme(KeyScheme)}, sets that the built master key should + * require the user to authenticate before it's unlocked, probably using the + * androidx.biometric library, and that the key should remain unlocked for the provided + * duration. + * + * @param authenticationRequired Whether user authentication should be + * required to use the key. + * @param userAuthenticationValidityDurationSeconds Duration in seconds that the key + * should remain unlocked following user + * authentication. + * @return This builder. + */ + public Builder setUserAuthenticationRequired(boolean authenticationRequired, + int userAuthenticationValidityDurationSeconds) { + return null; + } + + /** + * Sets whether or not to request this key is strong box backed. This setting is only + * applicable on {@link Build.VERSION_CODES#P} and above, and only on devices that + * support Strongbox. + * + * @param requestStrongBoxBacked Whether to request to use strongbox + * @return This builder. + */ + public Builder setRequestStrongBoxBacked(boolean requestStrongBoxBacked) { + return null; + } + + /** + * Builds a {@link MasterKey} from this builder. + * + * @return The master key. + */ + public MasterKey build() throws GeneralSecurityException, IOException { + return null; + } + } +} \ No newline at end of file diff --git a/java/ql/test/stubs/guava-30.0/com/google/common/base/Splitter.java b/java/ql/test/stubs/guava-30.0/com/google/common/base/Splitter.java index 379ff766dbc..521b6a605a5 100644 --- a/java/ql/test/stubs/guava-30.0/com/google/common/base/Splitter.java +++ b/java/ql/test/stubs/guava-30.0/com/google/common/base/Splitter.java @@ -25,7 +25,7 @@ public final class Splitter { } public Splitter omitEmptyStrings() { - return null;; + return null; } public Iterable split(final CharSequence sequence) { diff --git a/java/ql/test/stubs/guava-30.0/com/google/common/collect/AbstractMultimap.java b/java/ql/test/stubs/guava-30.0/com/google/common/collect/AbstractMultimap.java new file mode 100644 index 00000000000..0b9120bfd8b --- /dev/null +++ b/java/ql/test/stubs/guava-30.0/com/google/common/collect/AbstractMultimap.java @@ -0,0 +1,90 @@ +/* + * Copyright (C) 2012 The Guava Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.common.collect; + +import java.util.Collection; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; + +abstract class AbstractMultimap implements Multimap { + @Override + public boolean isEmpty() { + return false; + } + + @Override + public boolean containsValue(Object value) { + return false; + } + + @Override + public boolean containsEntry(Object key, Object value) { + return false; + } + + @Override + public boolean remove(Object key, Object value) { + return false; + } + + @Override + public boolean put(K key, V value) { + return false; + } + + @Override + public boolean putAll(K key, Iterable values) { + return false; + } + + @Override + public boolean putAll(Multimap multimap) { + return false; + } + + @Override + public Collection replaceValues(K key, Iterable values) { + return null; + } + + @Override + public Collection> entries() { + return null; + } + + @Override + public Set keySet() { + return null; + } + + @Override + public Multiset keys() { + return null; + } + + @Override + public Collection values() { + return null; + } + + @Override + public Map> asMap() { + return null; + } + +} diff --git a/java/ql/test/stubs/guava-30.0/com/google/common/collect/AbstractTable.java b/java/ql/test/stubs/guava-30.0/com/google/common/collect/AbstractTable.java new file mode 100644 index 00000000000..9003783bab9 --- /dev/null +++ b/java/ql/test/stubs/guava-30.0/com/google/common/collect/AbstractTable.java @@ -0,0 +1,90 @@ +/* + * Copyright (C) 2013 The Guava Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ + +package com.google.common.collect; + +import java.util.Collection; +import java.util.Map; +import java.util.Set; + +abstract class AbstractTable implements Table { + @Override + public boolean containsRow(Object rowKey) { + return false; + } + + @Override + public boolean containsColumn(Object columnKey) { + return false; + } + + @Override + public Set rowKeySet() { + return null; + } + + @Override + public Set columnKeySet() { + return null; + } + + @Override + public boolean containsValue(Object value) { + return false; + } + + @Override + public boolean contains(Object rowKey, Object columnKey) { + return false; + } + + @Override + public V get(Object rowKey, Object columnKey) { + return null; + } + + @Override + public boolean isEmpty() { + return false; + } + + @Override + public void clear() { + } + + @Override + public V remove(Object rowKey, Object columnKey) { + return null; + } + + @Override + public V put(R rowKey, C columnKey, V value) { + return null; + } + + @Override + public void putAll(Table table) { + } + + @Override + public Set> cellSet() { + return null; + } + + @Override + public Collection values() { + return null; + } + +} diff --git a/java/ql/test/stubs/guava-30.0/com/google/common/collect/ImmutableCollection.java b/java/ql/test/stubs/guava-30.0/com/google/common/collect/ImmutableCollection.java new file mode 100644 index 00000000000..670016cdab6 --- /dev/null +++ b/java/ql/test/stubs/guava-30.0/com/google/common/collect/ImmutableCollection.java @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2008 The Guava Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.common.collect; + +import java.io.Serializable; +import java.util.AbstractCollection; +import java.util.Collection; +import java.util.Iterator; + +public abstract class ImmutableCollection extends AbstractCollection implements Serializable { + ImmutableCollection() {} + + public ImmutableList asList() { + return null; + } + + public abstract static class Builder { + Builder() {} + + public abstract Builder add(E element); + + public Builder add(E... elements) { + return null; + } + + public Builder addAll(Iterable elements) { + return null; + } + + public Builder addAll(Iterator elements) { + return null; + } + + public abstract ImmutableCollection build(); + } +} diff --git a/java/ql/test/stubs/guava-30.0/com/google/common/collect/ImmutableList.java b/java/ql/test/stubs/guava-30.0/com/google/common/collect/ImmutableList.java new file mode 100644 index 00000000000..3e4fcf39d0a --- /dev/null +++ b/java/ql/test/stubs/guava-30.0/com/google/common/collect/ImmutableList.java @@ -0,0 +1,101 @@ +/* + * Copyright (C) 2007 The Guava Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.common.collect; + +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.Comparator; +import java.util.Iterator; +import java.util.List; + +public abstract class ImmutableList extends ImmutableCollection + implements List{ + + public static ImmutableList of() { + return null; + } + + public static ImmutableList of(E element) { + return null; + } + + public static ImmutableList of(E e1, E e2) { + return null; + } + + public static ImmutableList of(E e1, E e2, E e3) { + return null; + } + + public static ImmutableList of(E e1, E e2, E e3, E e4) { + return null; + } + + public static ImmutableList of( + E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8, E e9, E e10, E e11, E e12, E... others) { + return null; + } + + public static ImmutableList copyOf(Iterable elements) { + return null; + } + + public static ImmutableList copyOf(Collection elements) { + return null; + } + + public static ImmutableList copyOf(Iterator elements) { + return null; + } + + public static ImmutableList copyOf(E[] elements) { + return null; + } + + public static > ImmutableList sortedCopyOf( + Iterable elements) { + return null; + } + + public static ImmutableList sortedCopyOf( + Comparator comparator, Iterable elements) { + return null; + } + + ImmutableList() {} + + public ImmutableList reverse() { + return null; + } + + public static Builder builder() { + return null; + } + + public static final class Builder extends ImmutableCollection.Builder { + @Override + public Builder add(E element) { + return null; + } + + @Override + public ImmutableList build() { + return null; + } + } +} diff --git a/java/ql/test/stubs/guava-30.0/com/google/common/collect/ImmutableMap.java b/java/ql/test/stubs/guava-30.0/com/google/common/collect/ImmutableMap.java new file mode 100644 index 00000000000..631d25768fb --- /dev/null +++ b/java/ql/test/stubs/guava-30.0/com/google/common/collect/ImmutableMap.java @@ -0,0 +1,149 @@ +/* + * Copyright (C) 2008 The Guava Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.common.collect; + +import java.util.Collection; +import java.util.Comparator; +import java.util.Map; + +public abstract class ImmutableMap implements Map { + public static ImmutableMap of() { + return null; + } + + public static ImmutableMap of(K k1, V v1) { + return null; + } + + public static ImmutableMap of(K k1, V v1, K k2, V v2) { + return null; + } + + public static ImmutableMap of(K k1, V v1, K k2, V v2, K k3, V v3) { + return null; + } + + public static ImmutableMap of(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4) { + return null; + } + + public static ImmutableMap of( + K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5) { + return null; + } + + public static Builder builder() { + return null; + } + + public static Builder builderWithExpectedSize(int expectedSize) { + return null; + } + + public static class Builder { + public Builder() { + } + + public Builder put(K key, V value) { + return null; + } + + public Builder put(Entry entry) { + return null; + } + + public Builder putAll(Map map) { + return null; + } + + public Builder putAll(Iterable> entries) { + return null; + } + + public Builder orderEntriesByValue(Comparator valueComparator) { + return null; + } + + public ImmutableMap build() { + return null; + } + + } + public static ImmutableMap copyOf(Map map) { + return null; + } + + public static ImmutableMap copyOf( + Iterable> entries) { + return null; + } + + @Override + public final V put(K k, V v) { + return null; + } + + @Override + public final void putAll(Map map) { + } + + @Override + public final V remove(Object o) { + return null; + } + + @Override + public final void clear() { + } + + @Override + public boolean isEmpty() { + return false; + } + + @Override + public boolean containsKey(Object key) { + return false; + } + + @Override + public boolean containsValue(Object value) { + return false; + } + + @Override + public abstract V get(Object key); + + @Override + public ImmutableSet> entrySet() { + return null; + } + + @Override + public ImmutableSet keySet() { + return null; + } + + @Override + public ImmutableCollection values() { + return null; + } + + // public ImmutableSetMultimap asMultimap() { + // return null; + // } +} diff --git a/java/ql/test/stubs/guava-30.0/com/google/common/collect/ImmutableMultimap.java b/java/ql/test/stubs/guava-30.0/com/google/common/collect/ImmutableMultimap.java new file mode 100644 index 00000000000..c1345f72f3f --- /dev/null +++ b/java/ql/test/stubs/guava-30.0/com/google/common/collect/ImmutableMultimap.java @@ -0,0 +1,128 @@ +/* + * Copyright (C) 2008 The Guava Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.common.collect; + +import java.util.Collection; +import java.util.Comparator; +import java.util.Map; +import java.util.Map.Entry; + +public abstract class ImmutableMultimap extends AbstractMultimap { + public static ImmutableMultimap of() { + return null; + } + + public static ImmutableMultimap of(K k1, V v1) { + return null; + } + + public static ImmutableMultimap of(K k1, V v1, K k2, V v2) { + return null; + } + + public static ImmutableMultimap of(K k1, V v1, K k2, V v2, K k3, V v3) { + return null; + } + + public static ImmutableMultimap of(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4) { + return null; + } + + public static ImmutableMultimap of( + K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5) { + return null; + } + + public static Builder builder() { + return null; + } + + public static class Builder { + public Builder() { + } + + public Builder put(K key, V value) { + return null; + } + + public Builder put(Entry entry) { + return null; + } + + public Builder putAll(Iterable> entries) { + return null; + } + + public Builder putAll(K key, Iterable values) { + return null; + } + + public Builder putAll(K key, V... values) { + return null; + } + + public Builder putAll(Multimap multimap) { + return null; + } + + public Builder orderKeysBy(Comparator keyComparator) { + return null; + } + + public Builder orderValuesBy(Comparator valueComparator) { + return null; + } + + public ImmutableMultimap build() { + return null; + } + + } + public static ImmutableMultimap copyOf(Multimap multimap) { + return null; + } + + public static ImmutableMultimap copyOf( + Iterable> entries) { + return null; + } + + @Override + public ImmutableCollection removeAll(Object key) { + return null; + } + + @Override + public void clear() { + } + + @Override + public abstract ImmutableCollection get(K key); + + public abstract ImmutableMultimap inverse(); + + @Override + public boolean containsKey(Object key) { + return false; + } + + @Override + public int size() { + return 0; + } + +} diff --git a/java/ql/test/stubs/guava-30.0/com/google/common/collect/ImmutableMultiset.java b/java/ql/test/stubs/guava-30.0/com/google/common/collect/ImmutableMultiset.java new file mode 100644 index 00000000000..0fb82a18c80 --- /dev/null +++ b/java/ql/test/stubs/guava-30.0/com/google/common/collect/ImmutableMultiset.java @@ -0,0 +1,125 @@ +/* + * Copyright (C) 2008 The Guava Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.common.collect; + +import java.util.Collection; +import java.util.Iterator; + +public abstract class ImmutableMultiset extends ImmutableCollection + implements Multiset { + + public static ImmutableMultiset of() { + return null; + } + + public static ImmutableMultiset of(E element) { + return null; + } + + public static ImmutableMultiset of(E e1, E e2) { + return null; + } + + public static ImmutableMultiset of(E e1, E e2, E e3) { + return null; + } + + public static ImmutableMultiset of(E e1, E e2, E e3, E e4) { + return null; + } + + public static ImmutableMultiset of(E e1, E e2, E e3, E e4, E e5) { + return null; + } + + public static ImmutableMultiset of(E e1, E e2, E e3, E e4, E e5, E e6, E... others) { + return null; + } + + public static ImmutableMultiset copyOf(E[] elements) { + return null; + } + + public static ImmutableMultiset copyOf(Iterable elements) { + return null; + } + + public static ImmutableMultiset copyOf(Iterator elements) { + return null; + } + + @Override + public boolean contains(Object object) { + return false; + } + + @Override + public final int add(E element, int occurrences) { + return 0; + } + + @Override + public final int remove(Object element, int occurrences) { + return 0; + } + + @Override + public final int setCount(E element, int count) { + return 0; + } + + @Override + public final boolean setCount(E element, int oldCount, int newCount) { + return false; + } + + @Override + public abstract ImmutableSet elementSet(); + + @Override + public ImmutableSet> entrySet() { + return null; + } + + public static Builder builder() { + return null; + } + + public static class Builder extends ImmutableCollection.Builder { + public Builder() { + } + + @Override + public Builder add(E element) { + return null; + } + + public Builder addCopies(E element, int occurrences) { + return null; + } + + public Builder setCount(E element, int count) { + return null; + } + + @Override + public ImmutableMultiset build() { + return null; + } + + } +} diff --git a/java/ql/test/stubs/guava-30.0/com/google/common/collect/ImmutableSet.java b/java/ql/test/stubs/guava-30.0/com/google/common/collect/ImmutableSet.java new file mode 100644 index 00000000000..938b5aedf59 --- /dev/null +++ b/java/ql/test/stubs/guava-30.0/com/google/common/collect/ImmutableSet.java @@ -0,0 +1,86 @@ +/* + * Copyright (C) 2007 The Guava Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.common.collect; + +import java.util.Collection; +import java.util.Iterator; +import java.util.Set; + +public abstract class ImmutableSet extends ImmutableCollection implements Set { + public static ImmutableSet of() { + return null; + } + + public static ImmutableSet of(E element) { + return null; + } + + public static ImmutableSet of(E e1, E e2) { + return null; + } + + public static ImmutableSet of(E e1, E e2, E e3) { + return null; + } + + public static ImmutableSet of(E e1, E e2, E e3, E e4) { + return null; + } + + public static ImmutableSet of(E e1, E e2, E e3, E e4, E e5) { + return null; + } + + public static ImmutableSet of(E e1, E e2, E e3, E e4, E e5, E e6, E... others) { + return null; + } + + public static ImmutableSet copyOf(Collection elements) { + return null; + } + + public static ImmutableSet copyOf(Iterable elements) { + return null; + } + + public static ImmutableSet copyOf(Iterator elements) { + return null; + } + + public static ImmutableSet copyOf(E[] elements) { + return null; + } + + ImmutableSet() {} + + public static Builder builder() { + return null; + } + + public static class Builder extends ImmutableCollection.Builder { + public Builder() { + } + + public Builder add(E element) { + return null; + } + + public ImmutableSet build() { + return null; + } + } +} diff --git a/java/ql/test/stubs/guava-30.0/com/google/common/collect/ImmutableSortedMap.java b/java/ql/test/stubs/guava-30.0/com/google/common/collect/ImmutableSortedMap.java new file mode 100644 index 00000000000..dc3bfd49083 --- /dev/null +++ b/java/ql/test/stubs/guava-30.0/com/google/common/collect/ImmutableSortedMap.java @@ -0,0 +1,105 @@ +/* + * Copyright (C) 2009 The Guava Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.common.collect; + +import java.util.Comparator; +import java.util.Map; +import java.util.SortedMap; + +public final class ImmutableSortedMap extends ImmutableMap{ + + public static ImmutableSortedMap of() { + return null; + } + + public static , V> ImmutableSortedMap of(K k1, V v1) { + return null; + } + + public static , V> ImmutableSortedMap of( + K k1, V v1, K k2, V v2) { + return null; + } + + public static , V> ImmutableSortedMap of( + K k1, V v1, K k2, V v2, K k3, V v3) { + return null; + } + + public static , V> ImmutableSortedMap of( + K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4) { + return null; + } + + public static , V> ImmutableSortedMap of( + K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5) { + return null; + } + + public static ImmutableSortedMap copyOf(Map map) { + return null; + } + + public static ImmutableSortedMap copyOf( + Map map, Comparator comparator) { + return null; + } + + public static ImmutableSortedMap copyOf( + Iterable> entries) { + return null; + } + + public static ImmutableSortedMap copyOf( + Iterable> entries, + Comparator comparator) { + return null; + } + + public static ImmutableSortedMap copyOfSorted(SortedMap map) { + return null; + } + + @Override + public V get(Object key) { + return null; + } + + @Override + public int size() { + return 0; + } + + public static , V> Builder naturalOrder() { + return null; + } + + public static Builder orderedBy(Comparator comparator) { + return null; + } + + public static , V> Builder reverseOrder() { + return null; + } + + public static class Builder extends ImmutableMap.Builder { + public Builder(Comparator comparator) { + } + + } + +} diff --git a/java/ql/test/stubs/guava-30.0/com/google/common/collect/ImmutableSortedSet.java b/java/ql/test/stubs/guava-30.0/com/google/common/collect/ImmutableSortedSet.java new file mode 100644 index 00000000000..fb22c85b5ef --- /dev/null +++ b/java/ql/test/stubs/guava-30.0/com/google/common/collect/ImmutableSortedSet.java @@ -0,0 +1,111 @@ +/* + * Copyright (C) 2008 The Guava Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.common.collect; + +import java.util.Collection; +import java.util.Comparator; +import java.util.Iterator; +import java.util.NavigableSet; +import java.util.SortedSet; + +public abstract class ImmutableSortedSet extends ImmutableSet + implements NavigableSet { + + public static ImmutableSortedSet of() { + return null; + } + + public static > ImmutableSortedSet of(E element) { + return null; + } + + public static > ImmutableSortedSet of(E e1, E e2) { + return null; + } + + public static > ImmutableSortedSet of(E e1, E e2, E e3) { + return null; + } + + public static > ImmutableSortedSet of(E e1, E e2, E e3, E e4) { + return null; + } + + public static > ImmutableSortedSet of( + E e1, E e2, E e3, E e4, E e5) { + return null; + } + + public static > ImmutableSortedSet of( + E e1, E e2, E e3, E e4, E e5, E e6, E... remaining) { + return null; + } + + public static > ImmutableSortedSet copyOf(E[] elements) { + return null; + } + + public static ImmutableSortedSet copyOf(Iterable elements) { + return null; + } + + public static ImmutableSortedSet copyOf(Collection elements) { + return null; + } + + public static ImmutableSortedSet copyOf(Iterator elements) { + return null; + } + + public static ImmutableSortedSet copyOf( + Comparator comparator, Iterator elements) { + return null; + } + + public static ImmutableSortedSet copyOf( + Comparator comparator, Iterable elements) { + return null; + } + + public static ImmutableSortedSet copyOf( + Comparator comparator, Collection elements) { + return null; + } + + public static ImmutableSortedSet copyOfSorted(SortedSet sortedSet) { + return null; + } + + public static Builder orderedBy(Comparator comparator) { + return null; + } + + public static > Builder reverseOrder() { + return null; + } + + public static > Builder naturalOrder() { + return null; + } + + public static final class Builder extends ImmutableSet.Builder { + public Builder(Comparator comparator) { + } + + } + +} diff --git a/java/ql/test/stubs/guava-30.0/com/google/common/collect/ImmutableTable.java b/java/ql/test/stubs/guava-30.0/com/google/common/collect/ImmutableTable.java new file mode 100644 index 00000000000..73b3907b352 --- /dev/null +++ b/java/ql/test/stubs/guava-30.0/com/google/common/collect/ImmutableTable.java @@ -0,0 +1,124 @@ +/* + * Copyright (C) 2009 The Guava Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.common.collect; + +import java.util.Map; + +public abstract class ImmutableTable extends AbstractTable { + + public static ImmutableTable of() { + return null; + } + + public static ImmutableTable of(R rowKey, C columnKey, V value) { + return null; + } + + public static ImmutableTable copyOf( + Table table) { + return null; + } + + public static Builder builder() { + return null; + } + + public static final class Builder { + public Builder() {} + + public Builder put(R rowKey, C columnKey, V value) { + return null; + } + + public Builder put(Cell cell) { + return null; + } + + public Builder putAll(Table table) { + return null; + } + + public ImmutableTable build() { + return null; + } + + } + @Override + public ImmutableSet> cellSet() { + return null; + } + + @Override + public ImmutableCollection values() { + return null; + } + + @Override + public ImmutableMap column(C columnKey) { + return null; + } + + @Override + public ImmutableSet columnKeySet() { + return null; + } + + @Override + public abstract ImmutableMap> columnMap(); + + @Override + public ImmutableMap row(R rowKey) { + return null; + } + + @Override + public ImmutableSet rowKeySet() { + return null; + } + + @Override + public abstract ImmutableMap> rowMap(); + + @Override + public boolean contains(Object rowKey, Object columnKey) { + return false; + } + + @Override + public boolean containsValue(Object value) { + return false; + } + + @Override + public final void clear() { + } + + @Override + public final V put(R rowKey, C columnKey, V value) { + return null; + } + + @Override + public final void putAll(Table table) { + } + + @Override + public final V remove(Object rowKey, Object columnKey) { + return null; + } + +} diff --git a/java/ql/test/stubs/guava-30.0/com/google/common/collect/Multimap.java b/java/ql/test/stubs/guava-30.0/com/google/common/collect/Multimap.java new file mode 100644 index 00000000000..80223a450c9 --- /dev/null +++ b/java/ql/test/stubs/guava-30.0/com/google/common/collect/Multimap.java @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2007 The Guava Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.common.collect; + + +import java.util.Collection; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; +import java.util.function.BiConsumer; + +public interface Multimap { + int size(); + + boolean isEmpty(); + + boolean containsKey(Object key); + + boolean containsValue(Object value); + + boolean containsEntry(Object key, Object value); + + boolean put(K key, V value); + + boolean remove(Object key, Object value); + + boolean putAll(K key, Iterable values); + + boolean putAll(Multimap multimap); + + Collection replaceValues(K key, Iterable values); + + Collection removeAll(Object key); + + void clear(); + + Collection get(K key); + + Set keySet(); + + Multiset keys(); + + Collection values(); + + Collection> entries(); + + default void forEach(BiConsumer action) { + } + + Map> asMap(); +} diff --git a/java/ql/test/stubs/guava-30.0/com/google/common/collect/Multiset.java b/java/ql/test/stubs/guava-30.0/com/google/common/collect/Multiset.java new file mode 100644 index 00000000000..c67f63e79a0 --- /dev/null +++ b/java/ql/test/stubs/guava-30.0/com/google/common/collect/Multiset.java @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2007 The Guava Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.common.collect; + + +import java.util.Collection; +import java.util.Set; +import java.util.function.ObjIntConsumer; + +public interface Multiset extends Collection { + int count(Object element); + + int add(E element, int occurrences); + + int remove(Object element, int occurrences); + + int setCount(E element, int count); + + boolean setCount(E element, int oldCount, int newCount); + + Set elementSet(); + + Set> entrySet(); + + default void forEachEntry(ObjIntConsumer action) { + } + + boolean equals(Object object); + + interface Entry { + E getElement(); + + int getCount(); + } +} diff --git a/java/ql/test/stubs/guava-30.0/com/google/common/collect/Sets.java b/java/ql/test/stubs/guava-30.0/com/google/common/collect/Sets.java new file mode 100644 index 00000000000..77d3812f082 --- /dev/null +++ b/java/ql/test/stubs/guava-30.0/com/google/common/collect/Sets.java @@ -0,0 +1,93 @@ +/* + * Copyright (C) 2007 The Guava Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.common.collect; + +import java.util.AbstractSet; +import java.util.Collection; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.NavigableSet; +import java.util.NoSuchElementException; +import java.util.Set; +import java.util.function.Predicate; + +public final class Sets { + private Sets() {} + + public static HashSet newHashSet() { + return null; + } + + public static HashSet newHashSet(E... elements) { + return null; + } + + public static HashSet newHashSet(Iterable elements) { + return null; + } + public abstract static class SetView extends AbstractSet { + private SetView() {} + } + + public static SetView union(final Set set1, final Set set2) { + return null; + } + + public static SetView intersection(final Set set1, final Set set2) { + return null; + } + + public static SetView difference(final Set set1, final Set set2) { + return null; + } + + public static SetView symmetricDifference( + final Set set1, final Set set2) { + return null; + } + + public static Set filter(Set unfiltered, Predicate predicate) { + return null; + } + + + public static Set> cartesianProduct(List> sets) { + return null; + } + + public static Set> cartesianProduct(Set... sets) { + return null; + } + + public static Set> powerSet(Set set) { + return null; + } + + public static Set> combinations(Set set, final int size) { + return null; + } + + public static NavigableSet synchronizedNavigableSet(NavigableSet navigableSet) { + return null; + } + + public static > NavigableSet subSet( + NavigableSet set, Object range) { + return null; + } +} diff --git a/java/ql/test/stubs/guava-30.0/com/google/common/collect/Table.java b/java/ql/test/stubs/guava-30.0/com/google/common/collect/Table.java new file mode 100644 index 00000000000..d310bd99182 --- /dev/null +++ b/java/ql/test/stubs/guava-30.0/com/google/common/collect/Table.java @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2008 The Guava Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.common.collect; + +import java.util.Collection; +import java.util.Map; +import java.util.Set; + +public interface Table { + boolean contains(Object rowKey, Object columnKey); + + boolean containsRow(Object rowKey); + + boolean containsColumn(Object columnKey); + + boolean containsValue(Object value); + + V get(Object rowKey, Object columnKey); + + boolean isEmpty(); + + int size(); + + void clear(); + + V put(R rowKey, C columnKey, V value); + + void putAll(Table table); + + V remove(Object rowKey, Object columnKey); + + Map row(R rowKey); + + Map column(C columnKey); + + Set> cellSet(); + + Set rowKeySet(); + + Set columnKeySet(); + + Collection values(); + + Map> rowMap(); + + Map> columnMap(); + + interface Cell { + R getRowKey(); + + C getColumnKey(); + + V getValue(); + } +} diff --git a/javascript/change-notes/2020-11-25-prototype-pollution.md b/javascript/change-notes/2020-11-25-prototype-pollution.md new file mode 100644 index 00000000000..af0dad5ae0d --- /dev/null +++ b/javascript/change-notes/2020-11-25-prototype-pollution.md @@ -0,0 +1,11 @@ +lgtm,codescanning +* We've improved the detection of prototype pollution, and the queries involved have been reorganized: + * A new query "Prototype-polluting assignment" (`js/prototype-polluting-assignment`) has been added. This query + highlights direct modifications of an object obtained via a user-controlled property name, which may accidentally alter `Object.prototype`. + * The query previously named "Prototype pollution" (`js/prototype-pollution`) has been renamed to "Prototype-polluting merge call". + This highlights indirect modification of `Object.prototype` via an unsafe `merge` call taking a user-controlled object as argument. + * The query previously named "Prototype pollution in utility function" (`js/prototype-pollution-utility`) has been renamed to "Prototype-polluting function". + This query highlights the implementation of an unsafe `merge` function, to ensure a robust API is exposed downstream. + * The above queries have been moved to the Security/CWE-915 folder, and assigned the following tags: CWE-078, CWE-079, CWE-094, CWE-400, and CWE-915. + * The query "Type confusion through parameter tampering" (`js/type-confusion-through-parameter-tampering`) now highlights + ineffective prototype pollution checks that can be bypassed by type confusion. diff --git a/javascript/change-notes/2020-11-30-loginjection.md b/javascript/change-notes/2020-11-30-loginjection.md new file mode 100644 index 00000000000..dd2ecaa557a --- /dev/null +++ b/javascript/change-notes/2020-11-30-loginjection.md @@ -0,0 +1,2 @@ +lgtm,codescanning +* The `js/log-injection` query has been moved into non-experimental, and the precision of the query has been changed to medium. diff --git a/javascript/change-notes/2020-12-09-external-flow-sources.md b/javascript/change-notes/2020-12-09-external-flow-sources.md new file mode 100644 index 00000000000..57df56294af --- /dev/null +++ b/javascript/change-notes/2020-12-09-external-flow-sources.md @@ -0,0 +1,2 @@ +lgtm,codescanning +* Custom remote flow sources can now be specified by including a file named `codeql-javascript-remote-flow-sources.json` in your code base. See documentation for more details. diff --git a/javascript/change-notes/2020-12-16-build-artifact-leak.md b/javascript/change-notes/2020-12-16-build-artifact-leak.md new file mode 100644 index 00000000000..0ef26c549d6 --- /dev/null +++ b/javascript/change-notes/2020-12-16-build-artifact-leak.md @@ -0,0 +1,2 @@ +lgtm,codescanning +* The `js/build-artifact-leak` query no longer reports when only a safe subset of the properties on `process.env` are included in a build-artifact. diff --git a/javascript/change-notes/2020-12-16-indirect-cmd-libraries.md b/javascript/change-notes/2020-12-16-indirect-cmd-libraries.md new file mode 100644 index 00000000000..4d4e98ea8c1 --- /dev/null +++ b/javascript/change-notes/2020-12-16-indirect-cmd-libraries.md @@ -0,0 +1,9 @@ +lgtm,codescanning +* The `js/indirect-command-line-injection` query now supports more command-line parsing libraries. + Affected packages are + [arg](https://www.npmjs.com/package/arg), + [argparse](https://www.npmjs.com/package/argparse), + [command-line-args](https://www.npmjs.com/package/command-line-args), + [meow](https://www.npmjs.com/package/meow), + [dashdash](https://www.npmjs.com/package/dashdash), + [commander](https://www.npmjs.com/package/commander). diff --git a/javascript/change-notes/2020-12-22-execa.md b/javascript/change-notes/2020-12-22-execa.md new file mode 100644 index 00000000000..1310315eaa5 --- /dev/null +++ b/javascript/change-notes/2020-12-22-execa.md @@ -0,0 +1,4 @@ +lgtm,codescanning +* The command injection security queries now recognize additional sinks. + Affected packages are + [execa](https://npmjs.com/package/execa) diff --git a/javascript/change-notes/2021-01-04-superliniar-redos.md b/javascript/change-notes/2021-01-04-superliniar-redos.md new file mode 100644 index 00000000000..82c9ba6e298 --- /dev/null +++ b/javascript/change-notes/2021-01-04-superliniar-redos.md @@ -0,0 +1,3 @@ +lgtm,codescanning +* The `js/polynomial-redos` query has been improved by replacing the algorithm that detects expensive regular expressions. + This change reduces the number of false positives and detects new true positives. \ No newline at end of file diff --git a/javascript/change-notes/2021-01-08-js-incomplete-multi-character-sanitization.md b/javascript/change-notes/2021-01-08-js-incomplete-multi-character-sanitization.md new file mode 100644 index 00000000000..653ba2a8994 --- /dev/null +++ b/javascript/change-notes/2021-01-08-js-incomplete-multi-character-sanitization.md @@ -0,0 +1,2 @@ +lgtm,codescanning +* The query "Incomplete multi-character sanitization" (`js/incomplete-multi-character-sanitization`) has been improved to produce additional true positives and fewer false positives. diff --git a/javascript/change-notes/2021-01-14-polynomial-redos.md b/javascript/change-notes/2021-01-14-polynomial-redos.md new file mode 100644 index 00000000000..8bbc16386ac --- /dev/null +++ b/javascript/change-notes/2021-01-14-polynomial-redos.md @@ -0,0 +1,2 @@ +lgtm,codescanning +* The `js/polynomial-redos` query now flags uses of expensive regular expressions where the source is library input. diff --git a/javascript/change-notes/2021-01-18-angular-templates.md b/javascript/change-notes/2021-01-18-angular-templates.md new file mode 100644 index 00000000000..3ec349f8d18 --- /dev/null +++ b/javascript/change-notes/2021-01-18-angular-templates.md @@ -0,0 +1,4 @@ +lgtm,codescanning +* Support for Angular has improved. Angular templates are now parsed and used to + establish data flow between components. +* Support for RxJS has improved. Taint is now tracked through RxJS Observable objects. diff --git a/javascript/change-notes/2021-01-18-server-crash.md b/javascript/change-notes/2021-01-18-server-crash.md new file mode 100644 index 00000000000..bf5383c3bd8 --- /dev/null +++ b/javascript/change-notes/2021-01-18-server-crash.md @@ -0,0 +1,2 @@ +lgtm,codescanning +* The `js/server-crash` query has been added. It highlights servers may be terminated by a malicious user. diff --git a/javascript/change-notes/2021-01-21-type-inference-compound.md b/javascript/change-notes/2021-01-21-type-inference-compound.md new file mode 100644 index 00000000000..6969555f2d7 --- /dev/null +++ b/javascript/change-notes/2021-01-21-type-inference-compound.md @@ -0,0 +1,2 @@ +lgtm,codescanning +* Added support for modern compound assignments (`||=`, `&&=`, and `??=`) in the type inference. diff --git a/javascript/change-notes/2021-01-21-unneeded-defensive-code.md b/javascript/change-notes/2021-01-21-unneeded-defensive-code.md new file mode 100644 index 00000000000..c4c8573db46 --- /dev/null +++ b/javascript/change-notes/2021-01-21-unneeded-defensive-code.md @@ -0,0 +1,2 @@ +lgtm,codescanning +* The query "Unneeded defensive code" (`js/unneeded-defensive-code`) no longer flags uses of function parameters. diff --git a/javascript/change-notes/2021-02-08-immutable.md b/javascript/change-notes/2021-02-08-immutable.md new file mode 100644 index 00000000000..8f4a11113e2 --- /dev/null +++ b/javascript/change-notes/2021-02-08-immutable.md @@ -0,0 +1,4 @@ +lgtm,codescanning +* The dataflow libraries now model dataflow in the Immutable.js library. + Affected packages are + [Immutable.js](https://npmjs.com/package/immutable) diff --git a/javascript/change-notes/2021-02-08-xml-parser-taint.md b/javascript/change-notes/2021-02-08-xml-parser-taint.md new file mode 100644 index 00000000000..2028be3e06f --- /dev/null +++ b/javascript/change-notes/2021-02-08-xml-parser-taint.md @@ -0,0 +1,8 @@ +lgtm,codescanning +* The security queries now track taint through XML parsers. + Affected packages are + [xml2js](https://www.npmjs.com/package/xml2js), + [sax](https://www.npmjs.com/package/sax), + [xml-js](https://www.npmjs.com/package/xml-js), + [htmlparser2](https://www.npmjs.com/package/htmlparser2), and + [node-expat](https://www.npmjs.com/package/node-expat) diff --git a/javascript/change-notes/2021-02-08-xss-through-dom-forms.md b/javascript/change-notes/2021-02-08-xss-through-dom-forms.md new file mode 100644 index 00000000000..33c864bbaef --- /dev/null +++ b/javascript/change-notes/2021-02-08-xss-through-dom-forms.md @@ -0,0 +1,6 @@ +lgtm,codescanning +* The `js/xss-through-dom` query now recognizes form inputs as sources. + Affected packages are + [formik](https://www.npmjs.com/package/formik) and + [react-final-form](https://www.npmjs.com/package/react-final-form) and + [react-hook-form](https://www.npmjs.com/package/react-hook-form) diff --git a/javascript/change-notes/2021-02-09-form-parsers.md b/javascript/change-notes/2021-02-09-form-parsers.md new file mode 100644 index 00000000000..ec45a6c144d --- /dev/null +++ b/javascript/change-notes/2021-02-09-form-parsers.md @@ -0,0 +1,7 @@ +lgtm,codescanning +* Server side form parsing libraries are now recognized as source of remote user input. + Affected packages are + [multer](https://www.npmjs.com/package/multer), + [busboy](https://www.npmjs.com/package/busboy), + [formidable](https://www.npmjs.com/package/formidable), and + [multiparty](https://www.npmjs.com/package/formidable). diff --git a/javascript/change-notes/2021-02-11-apollo-client.md b/javascript/change-notes/2021-02-11-apollo-client.md new file mode 100644 index 00000000000..93ec78f1f41 --- /dev/null +++ b/javascript/change-notes/2021-02-11-apollo-client.md @@ -0,0 +1,8 @@ +lgtm,codescanning +* URIs used in the Apollo-link libraries are now recognized as sinks for `js/request-forgery`. + Affected packages are + [apollo-link-http](https://www.npmjs.com/package/apollo-link-http), + [apollo-client](https://www.npmjs.com/package/apollo-client), + [apollo-boost](https://www.npmjs.com/package/apollo-boost), + [apollo-client-preset](https://www.npmjs.com/package/apollo-client-preset), and + [apollo-link-ws](https://www.npmjs.com/package/apollo-link-ws) diff --git a/javascript/config/suites/javascript/security b/javascript/config/suites/javascript/security index e8575ed8db5..9f826d04314 100644 --- a/javascript/config/suites/javascript/security +++ b/javascript/config/suites/javascript/security @@ -37,8 +37,9 @@ + semmlecode-javascript-queries/Security/CWE-338/InsecureRandomness.ql: /Security/CWE/CWE-338 + semmlecode-javascript-queries/Security/CWE-346/CorsMisconfigurationForCredentials.ql: /Security/CWE/CWE-346 + semmlecode-javascript-queries/Security/CWE-352/MissingCsrfMiddleware.ql: /Security/CWE/CWE-352 -+ semmlecode-javascript-queries/Security/CWE-400/PrototypePollution.ql: /Security/CWE/CWE-400 -+ semmlecode-javascript-queries/Security/CWE-400/PrototypePollutionUtility.ql: /Security/CWE/CWE-400 ++ semmlecode-javascript-queries/Security/CWE-915/PrototypePollutingAssignment.ql: /Security/CWE/CWE-915 ++ semmlecode-javascript-queries/Security/CWE-915/PrototypePollutingFunction.ql: /Security/CWE/CWE-915 ++ semmlecode-javascript-queries/Security/CWE-915/PrototypePollutingMergeCall.ql: /Security/CWE/CWE-915 + semmlecode-javascript-queries/Security/CWE-400/RemotePropertyInjection.ql: /Security/CWE/CWE-400 + semmlecode-javascript-queries/Security/CWE-502/UnsafeDeserialization.ql: /Security/CWE/CWE-502 + semmlecode-javascript-queries/Security/CWE-506/HardcodedDataInterpretedAsCode.ql: /Security/CWE/CWE-506 @@ -48,6 +49,7 @@ + semmlecode-javascript-queries/Security/CWE-640/HostHeaderPoisoningInEmailGeneration.ql: /Security/CWE/CWE-640 + semmlecode-javascript-queries/Security/CWE-643/XpathInjection.ql: /Security/CWE/CWE-643 + semmlecode-javascript-queries/Security/CWE-730/RegExpInjection.ql: /Security/CWE/CWE-730 ++ semmlecode-javascript-queries/Security/CWE-730/ServerCrash.ql: /Security/CWE/CWE-730 + semmlecode-javascript-queries/Security/CWE-754/UnvalidatedDynamicMethodCall.ql: /Security/CWE/CWE-754 + semmlecode-javascript-queries/Security/CWE-770/MissingRateLimiting.ql: /Security/CWE/CWE-770 + semmlecode-javascript-queries/Security/CWE-776/XmlBomb.ql: /Security/CWE/CWE-776 diff --git a/javascript/extractor/src/com/semmle/jcorn/AngularExpressionParser.java b/javascript/extractor/src/com/semmle/jcorn/AngularExpressionParser.java new file mode 100644 index 00000000000..79c1a1e30db --- /dev/null +++ b/javascript/extractor/src/com/semmle/jcorn/AngularExpressionParser.java @@ -0,0 +1,63 @@ +package com.semmle.jcorn; + +import java.util.ArrayList; +import java.util.List; + +import com.semmle.js.ast.AngularPipeRef; +import com.semmle.js.ast.CallExpression; +import com.semmle.js.ast.Expression; +import com.semmle.js.ast.Identifier; +import com.semmle.js.ast.Position; +import com.semmle.js.ast.SourceLocation; +import com.semmle.ts.ast.NonNullAssertion; + +/** + * Parser for Angular template expressions, based on the JS parser with + * modified handling of the pipe operator. + */ +public class AngularExpressionParser extends CustomParser { + public AngularExpressionParser(Options options, String input, int startPos) { + super(options, input, startPos); + } + + @Override + protected Expression buildBinary( + int startPos, + Position startLoc, + Expression left, + Expression right, + String op, + boolean logical) { + // Angular pipe expression: `x|f:a` is desugared to `f(x, a)` + if (op.equals("|")) { + DestructuringErrors refDestructuringErrors = new DestructuringErrors(); + List arguments = new ArrayList<>(); + arguments.add(left); + while (this.type == TokenType.colon) { + this.next(); + int argStartPos = this.pos; + Position argStartLocation = this.curPosition(); + Expression arg = parseMaybeUnary(refDestructuringErrors, false); + arguments.add(parseExprOp(arg, argStartPos, argStartLocation, TokenType.plusMin.binop, true)); + } + SourceLocation loc = new SourceLocation(startLoc); + if (right instanceof Identifier) { + right = new AngularPipeRef(new SourceLocation(right.getLoc()), (Identifier)right); + } + return this.finishNode(new CallExpression(loc, right, new ArrayList<>(), arguments, false, false)); + } + return super.buildBinary(startPos, startLoc, left, right, op, logical); + } + + @Override + protected Expression parseExprAtom(DestructuringErrors refDestructuringErrors) { + // Parse postfix "!" operator + Position startLoc = this.startLoc; + Expression expr = super.parseExprAtom(refDestructuringErrors); + if (this.type == TokenType.prefix && "!".equals(this.value)) { + this.next(); // consume "!" token + return finishNode(new NonNullAssertion(new SourceLocation(startLoc), expr)); + } + return expr; + } +} diff --git a/javascript/extractor/src/com/semmle/jcorn/Parser.java b/javascript/extractor/src/com/semmle/jcorn/Parser.java index 7c018b6a456..827b6d4ec03 100644 --- a/javascript/extractor/src/com/semmle/jcorn/Parser.java +++ b/javascript/extractor/src/com/semmle/jcorn/Parser.java @@ -3,9 +3,21 @@ package com.semmle.jcorn; import static com.semmle.jcorn.Whitespace.isNewLine; import static com.semmle.jcorn.Whitespace.lineBreak; +import java.io.File; +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Set; +import java.util.Stack; +import java.util.function.Function; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + import com.semmle.jcorn.Identifiers.Dialect; import com.semmle.jcorn.Options.AllowReserved; -import com.semmle.jcorn.TokenType.Properties; import com.semmle.js.ast.ArrayExpression; import com.semmle.js.ast.ArrayPattern; import com.semmle.js.ast.ArrowFunctionExpression; @@ -45,7 +57,6 @@ import com.semmle.js.ast.INode; import com.semmle.js.ast.IPattern; import com.semmle.js.ast.Identifier; import com.semmle.js.ast.IfStatement; -import com.semmle.js.ast.FieldDefinition; import com.semmle.js.ast.ImportDeclaration; import com.semmle.js.ast.ImportDefaultSpecifier; import com.semmle.js.ast.ImportNamespaceSpecifier; @@ -95,18 +106,6 @@ import com.semmle.util.data.StringUtil; import com.semmle.util.exception.CatastrophicError; import com.semmle.util.exception.Exceptions; import com.semmle.util.io.WholeIO; -import java.io.File; -import java.util.ArrayList; -import java.util.LinkedHashMap; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.Set; -import java.util.Stack; -import java.util.function.Function; -import java.util.regex.Matcher; -import java.util.regex.Pattern; /** * Java port of Acorn. @@ -1462,7 +1461,7 @@ public class Parser { return left; } - private Expression buildBinary( + protected Expression buildBinary( int startPos, Position startLoc, Expression left, diff --git a/javascript/extractor/src/com/semmle/js/ast/AngularPipeRef.java b/javascript/extractor/src/com/semmle/js/ast/AngularPipeRef.java new file mode 100644 index 00000000000..fbe8525b234 --- /dev/null +++ b/javascript/extractor/src/com/semmle/js/ast/AngularPipeRef.java @@ -0,0 +1,27 @@ +package com.semmle.js.ast; + +/** + * An identifier occurring as the right operand of an Angular pipe expression, + * which has been desugared to a function call with this expression as the callee. + *

    + * For example, x | f:y is desugared to f(x, y) where the + * f is an instance of {@link AngularPipeRef}, and evaluates to the function + * being invoked. + */ +public class AngularPipeRef extends Expression { + private final Identifier identifier; + + public AngularPipeRef(SourceLocation loc, Identifier identifier) { + super("AngularPipeRef", loc); + this.identifier = identifier; + } + + @Override + public A accept(Visitor v, Q q) { + return v.visit(this, q); + } + + public Identifier getIdentifier() { + return identifier; + } +} diff --git a/javascript/extractor/src/com/semmle/js/ast/DeclarationFlags.java b/javascript/extractor/src/com/semmle/js/ast/DeclarationFlags.java index 28546fdeca8..cbd8b1eedf7 100644 --- a/javascript/extractor/src/com/semmle/js/ast/DeclarationFlags.java +++ b/javascript/extractor/src/com/semmle/js/ast/DeclarationFlags.java @@ -88,59 +88,59 @@ public class DeclarationFlags { return (flags & declareKeyword) != 0; } - /** Returns a mask with the computed bit set to the value of enable. */ + /** Returns a mask with the computed bit set to the value of enable. */ public static int getComputed(boolean enable) { return enable ? computed : 0; } - /** Returns a mask with the abstract bit set to the value of enable. */ + /** Returns a mask with the abstract bit set to the value of enable. */ public static int getAbstract(boolean enable) { return enable ? abstract_ : 0; } - /** Returns a mask with the static bit set to the value of enable. */ + /** Returns a mask with the static bit set to the value of enable. */ public static int getStatic(boolean enable) { return enable ? static_ : 0; } - /** Returns a mask with the public bit set to the value of enable. */ + /** Returns a mask with the public bit set to the value of enable. */ public static int getPublic(boolean enable) { return enable ? public_ : 0; } - /** Returns a mask with the readonly bit set to the value of enable. */ + /** Returns a mask with the readonly bit set to the value of enable. */ public static int getReadonly(boolean enable) { return enable ? readonly : 0; } - /** Returns a mask with the private bit set to the value of enable. */ + /** Returns a mask with the private bit set to the value of enable. */ public static int getPrivate(boolean enable) { return enable ? private_ : 0; } - /** Returns a mask with the protected bit set to the value of enable. */ + /** Returns a mask with the protected bit set to the value of enable. */ public static int getProtected(boolean enable) { return enable ? protected_ : 0; } - /** Returns a mask with the optional bit set to the value of enable. */ + /** Returns a mask with the optional bit set to the value of enable. */ public static int getOptional(boolean enable) { return enable ? optional : 0; } /** - * Returns a mask with the definite assignment assertion bit set to the value of enable. + * Returns a mask with the definite assignment assertion bit set to the value of enable. */ public static int getDefiniteAssignmentAssertion(boolean enable) { return enable ? definiteAssignmentAssertion : 0; } - /** Returns a mask with the declare keyword bit set to the value of enable. */ + /** Returns a mask with the declare keyword bit set to the value of enable. */ public static int getDeclareKeyword(boolean enable) { return enable ? declareKeyword : 0; } - /** Returns true if the nth bit is set in flags. */ + /** Returns true if the nth bit is set in flags. */ public static boolean hasNthFlag(int flags, int n) { return (flags & (1 << n)) != 0; } diff --git a/javascript/extractor/src/com/semmle/js/ast/DefaultVisitor.java b/javascript/extractor/src/com/semmle/js/ast/DefaultVisitor.java index 151936f46dc..4db7dbc400f 100644 --- a/javascript/extractor/src/com/semmle/js/ast/DefaultVisitor.java +++ b/javascript/extractor/src/com/semmle/js/ast/DefaultVisitor.java @@ -93,6 +93,11 @@ public class DefaultVisitor implements Visitor { else return visit((Expression) nd, c); } + @Override + public R visit(AngularPipeRef nd, C c) { + return visit((Expression) nd, c); + } + @Override public R visit(AssignmentExpression nd, C c) { return visit((Expression) nd, c); diff --git a/javascript/extractor/src/com/semmle/js/ast/Literal.java b/javascript/extractor/src/com/semmle/js/ast/Literal.java index 15408b05916..3c53798b851 100644 --- a/javascript/extractor/src/com/semmle/js/ast/Literal.java +++ b/javascript/extractor/src/com/semmle/js/ast/Literal.java @@ -6,7 +6,7 @@ import com.semmle.ts.ast.ITypeExpression; /** * A literal constant. * - *

    A null literal may occur as a TypeScript type annotation - other literals are always + *

    A null literal may occur as a TypeScript type annotation - other literals are always * expressions. */ public class Literal extends Expression implements ITypeExpression { diff --git a/javascript/extractor/src/com/semmle/js/ast/MemberDefinition.java b/javascript/extractor/src/com/semmle/js/ast/MemberDefinition.java index c04b79fa366..7cacafa96ed 100644 --- a/javascript/extractor/src/com/semmle/js/ast/MemberDefinition.java +++ b/javascript/extractor/src/com/semmle/js/ast/MemberDefinition.java @@ -40,7 +40,7 @@ public abstract class MemberDefinition extends Node { return flags; } - /** Returns true if this has the static modifier. */ + /** Returns true if this has the static modifier. */ public boolean isStatic() { return DeclarationFlags.isStatic(flags); } @@ -55,7 +55,7 @@ public abstract class MemberDefinition extends Node { return DeclarationFlags.isAbstract(flags); } - /** Returns true if has the public modifier (not true for implicitly public members). */ + /** Returns true if has the public modifier (not true for implicitly public members). */ public boolean hasPublicKeyword() { return DeclarationFlags.isPublic(flags); } @@ -75,7 +75,7 @@ public abstract class MemberDefinition extends Node { return DeclarationFlags.isReadonly(flags); } - /** Returns true if this has the declare modifier. */ + /** Returns true if this has the declare modifier. */ public boolean hasDeclareKeyword() { return DeclarationFlags.hasDeclareKeyword(flags); } diff --git a/javascript/extractor/src/com/semmle/js/ast/NodeCopier.java b/javascript/extractor/src/com/semmle/js/ast/NodeCopier.java index c381a2d6b10..0a0895d6598 100644 --- a/javascript/extractor/src/com/semmle/js/ast/NodeCopier.java +++ b/javascript/extractor/src/com/semmle/js/ast/NodeCopier.java @@ -1,5 +1,8 @@ package com.semmle.js.ast; +import java.util.ArrayList; +import java.util.List; + import com.semmle.js.ast.jsx.JSXAttribute; import com.semmle.js.ast.jsx.JSXClosingElement; import com.semmle.js.ast.jsx.JSXElement; @@ -48,8 +51,6 @@ import com.semmle.ts.ast.TypeofTypeExpr; import com.semmle.ts.ast.UnaryTypeExpr; import com.semmle.ts.ast.UnionTypeExpr; import com.semmle.util.data.IntList; -import java.util.ArrayList; -import java.util.List; /** Deep cloning of AST nodes. */ public class NodeCopier implements Visitor { @@ -77,6 +78,11 @@ public class NodeCopier implements Visitor { return new IntList(list); } + @Override + public INode visit(AngularPipeRef nd, Void q) { + return new AngularPipeRef(nd.getLoc(), copy(nd.getIdentifier())); + } + @Override public AssignmentExpression visit(AssignmentExpression nd, Void q) { return new AssignmentExpression( diff --git a/javascript/extractor/src/com/semmle/js/ast/Position.java b/javascript/extractor/src/com/semmle/js/ast/Position.java index 7d7ed274c3e..3bf14982e24 100644 --- a/javascript/extractor/src/com/semmle/js/ast/Position.java +++ b/javascript/extractor/src/com/semmle/js/ast/Position.java @@ -1,6 +1,13 @@ package com.semmle.js.ast; -/** A source position identifying a single character. */ +/** + * A source position identifying a single character. + *

    + * Note that this class remains distinct from {@link com.semmle.util.locations.Position}, + * due to the 1-based line number convention and the tendency for users of this class to provide + * dummy offset values. Although the classes are structurally identical, it is not always safe to + * convert one into the other. + */ public class Position implements Comparable { private final int line, column, offset; @@ -23,6 +30,8 @@ public class Position implements Comparable { /** * The offset (0-based) of this position from the start of the file, that is, the number of * characters that precede it. + *

    + * Note that in some cases, a dummy value is filled in for the offset. */ public int getOffset() { return offset; diff --git a/javascript/extractor/src/com/semmle/js/ast/Visitor.java b/javascript/extractor/src/com/semmle/js/ast/Visitor.java index 98551d2e324..f2a65c83620 100644 --- a/javascript/extractor/src/com/semmle/js/ast/Visitor.java +++ b/javascript/extractor/src/com/semmle/js/ast/Visitor.java @@ -54,6 +54,8 @@ import com.semmle.ts.ast.UnionTypeExpr; *

    Visit methods take a context argument of type {@link C} and return a result of type {@link R}. */ public interface Visitor { + public R visit(AngularPipeRef nd, C q); + public R visit(AssignmentExpression nd, C q); public R visit(AssignmentPattern nd, C q); diff --git a/javascript/extractor/src/com/semmle/js/extractor/ASTExtractor.java b/javascript/extractor/src/com/semmle/js/extractor/ASTExtractor.java index 62a1465aea5..bb270353869 100644 --- a/javascript/extractor/src/com/semmle/js/extractor/ASTExtractor.java +++ b/javascript/extractor/src/com/semmle/js/extractor/ASTExtractor.java @@ -1,5 +1,6 @@ package com.semmle.js.extractor; +import java.nio.file.Path; import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -9,6 +10,7 @@ import java.util.Stack; import com.semmle.js.ast.AClass; import com.semmle.js.ast.AFunction; import com.semmle.js.ast.AFunctionExpression; +import com.semmle.js.ast.AngularPipeRef; import com.semmle.js.ast.ArrayExpression; import com.semmle.js.ast.ArrayPattern; import com.semmle.js.ast.ArrowFunctionExpression; @@ -153,6 +155,9 @@ import com.semmle.ts.ast.TypeofTypeExpr; import com.semmle.ts.ast.UnaryTypeExpr; import com.semmle.ts.ast.UnionTypeExpr; import com.semmle.util.collections.CollectionUtil; +import com.semmle.util.data.Pair; +import com.semmle.util.locations.OffsetTranslation; +import com.semmle.util.locations.SourceMap; import com.semmle.util.trap.TrapWriter; import com.semmle.util.trap.TrapWriter.Label; @@ -165,22 +170,32 @@ public class ASTExtractor { private final Label toplevelLabel; private final LexicalExtractor lexicalExtractor; private final RegExpExtractor regexpExtractor; + private final ExtractorConfig config; - public ASTExtractor(LexicalExtractor lexicalExtractor, ScopeManager scopeManager) { + public ASTExtractor(ExtractorConfig config, LexicalExtractor lexicalExtractor, ScopeManager scopeManager) { + this.config = config; this.trapwriter = lexicalExtractor.getTrapwriter(); this.locationManager = lexicalExtractor.getLocationManager(); this.contextManager = new SyntacticContextManager(); this.scopeManager = scopeManager; this.lexicalExtractor = lexicalExtractor; this.regexpExtractor = new RegExpExtractor(trapwriter, locationManager); - this.toplevelLabel = - trapwriter.globalID( - "script;{" - + locationManager.getFileLabel() - + "}," - + locationManager.getStartLine() - + ',' - + locationManager.getStartColumn()); + this.toplevelLabel = makeTopLevelLabel(trapwriter, locationManager.getFileLabel(), locationManager.getStartLine(), locationManager.getStartColumn()); + } + + /** + * Returns the label for the top-level starting at the given location. + *

    + * May be used to refer to the top-level before it has been extracted. + */ + public static Label makeTopLevelLabel(TrapWriter trapWriter, Label fileLabel, int startLine, int startColumn) { + return trapWriter.globalID( + "script;{" + + fileLabel + + "}," + + startLine + + ',' + + startColumn); } public TrapWriter getTrapwriter() { @@ -210,48 +225,48 @@ public class ASTExtractor { */ public enum IdContext { /** An identifier that binds to a variable. */ - varBind, + VAR_BIND, /** An identifier that declares a variable. */ - varDecl, + VAR_DECL, /** An identifier that declares both a variable and a type. */ - varAndTypeDecl, + VAR_AND_TYPE_DECL, /** * An identifier that is not associated with variables or types, such as a property name and * statement label. */ - label, + LABEL, /** An identifier that binds to a type (and not a variable). */ - typeBind, + TYPE_BIND, /** An identifier that declares a type (and not a variable). */ - typeDecl, + TYPE_DECL, /** * An identifier that is part of a type, but should not bind to a type name. Unlike {@link - * #label}, this will not result in an expression. + * #LABEL}, this will not result in an expression. */ - typeLabel, + TYPE_LABEL, /** * An identifier that refers to a variable from inside a type, i.e. the operand to a - * typeof type or left operand to an is type. + * typeof type or left operand to an is type. * *

    This is generally treated as a type, except a variable binding will be emitted for it. */ - varInTypeBind, + VAR_IN_TYPE_BIND, /** An identifier that refers to a namespace from inside a type. */ - namespaceBind, + NAMESPACE_BIND, /** An identifier that declares a namespace. */ - namespaceDecl, + NAMESPACE_DECL, /** An identifier that declares a variable and a namespace. */ - varAndNamespaceDecl, + VAR_AND_NAMESPACE_DECL, /** * An identifier that occurs in a type-only import. @@ -259,7 +274,7 @@ public class ASTExtractor { * These may declare a type and/or a namespace, but for compatibility with our AST, * must be emitted as a VarDecl (with no variable binding). */ - typeOnlyImport, + TYPE_ONLY_IMPORT, /** * An identifier that occurs in a type-only export. @@ -267,13 +282,13 @@ public class ASTExtractor { * These may refer to a type and/or a namespace, but for compatibility with our AST, * must be emitted as an ExportVarAccess (with no variable binding). */ - typeOnlyExport, + TYPE_ONLY_EXPORT, /** An identifier that declares a variable, type, and namepsace. */ - varAndTypeAndNamespaceDecl, + VAR_AND_TYPE_AND_NAMESPACE_DECL, /** - * An identifier that occurs as part of a named export, such as export { A }. + * An identifier that occurs as part of a named export, such as export { A }. * *

    This may refer to a variable, type, and/or a namespace, and will export exactly those that * can be resolved. @@ -282,30 +297,30 @@ public class ASTExtractor { * explicitly declared, since TypeScript only emits the export code when it refers to a declared * variable. */ - export, + EXPORT, /** * An identifier that occurs as a qualified name in a default export expression, such as - * A in export default A.B. + * A in export default A.B. * - *

    This acts like {@link #export}, except it cannot refer to a type (i.e. it must be a + *

    This acts like {@link #EXPORT}, except it cannot refer to a type (i.e. it must be a * variable and/or a namespace). */ - exportBase; + EXPORT_BASE; /** - * True if this occurs as part of a type annotation, i.e. it is {@link #typeBind} or {@link - * #typeDecl}, {@link #typeLabel}, {@link #varInTypeBind}, or {@link #namespaceBind}. + * True if this occurs as part of a type annotation, i.e. it is {@link #TYPE_BIND} or {@link + * #TYPE_DECL}, {@link #TYPE_LABEL}, {@link #VAR_IN_TYPE_BIND}, or {@link #NAMESPACE_BIND}. * - *

    Does not hold for {@link #varAndTypeDecl}, {@link #typeOnlyImport}, or @{link {@link #typeOnlyExport} + *

    Does not hold for {@link #VAR_AND_TYPE_DECL}, {@link #TYPE_ONLY_IMPORT}, or @{link {@link #TYPE_ONLY_EXPORT} * as these do not occur in type annotations. */ public boolean isInsideType() { - return this == typeBind - || this == typeDecl - || this == typeLabel - || this == varInTypeBind - || this == namespaceBind; + return this == TYPE_BIND + || this == TYPE_DECL + || this == TYPE_LABEL + || this == VAR_IN_TYPE_BIND + || this == NAMESPACE_BIND; } }; @@ -339,11 +354,11 @@ public class ASTExtractor { } private Label visit(INode child, Label parent, int childIndex) { - return visit(child, parent, childIndex, IdContext.varBind); + return visit(child, parent, childIndex, IdContext.VAR_BIND); } private Label visitAll(List children, Label parent) { - return visitAll(children, parent, IdContext.varBind, 0); + return visitAll(children, parent, IdContext.VAR_BIND, 0); } private Label visit(INode child, Label parent, int childIndex, IdContext idContext) { @@ -426,7 +441,7 @@ public class ASTExtractor { public Label visit(InvokeExpression nd, Context c) { Label key = super.visit(nd, c); visit(nd.getCallee(), key, -1); - visitAll(nd.getTypeArguments(), key, IdContext.typeBind, -2, -1); + visitAll(nd.getTypeArguments(), key, IdContext.TYPE_BIND, -2, -1); visitAll(nd.getArguments(), key); if (nd.getResolvedSignatureId() != -1) { Label signature = trapwriter.globalID("signature;" + nd.getResolvedSignatureId()); @@ -481,51 +496,51 @@ public class ASTExtractor { emitNodeSymbol(nd, key); trapwriter.addTuple("literals", name, name, key); switch (c.idcontext) { - case varBind: - case varInTypeBind: + case VAR_BIND: + case VAR_IN_TYPE_BIND: addVariableBinding("bind", key, name); break; - case varDecl: + case VAR_DECL: addVariableBinding("decl", key, name); break; - case varAndTypeDecl: + case VAR_AND_TYPE_DECL: addVariableBinding("decl", key, name); addTypeBinding("typedecl", key, name); break; - case typeBind: + case TYPE_BIND: addTypeBinding("typebind", key, name); break; - case typeDecl: + case TYPE_DECL: addTypeBinding("typedecl", key, name); break; - case namespaceBind: + case NAMESPACE_BIND: addNamespaceBinding("namespacebind", key, name); break; - case namespaceDecl: + case NAMESPACE_DECL: addNamespaceBinding("namespacedecl", key, name); break; - case varAndNamespaceDecl: + case VAR_AND_NAMESPACE_DECL: addVariableBinding("decl", key, name); addNamespaceBinding("namespacedecl", key, name); break; - case typeOnlyImport: + case TYPE_ONLY_IMPORT: addTypeBinding("typedecl", key, name); addNamespaceBinding("namespacedecl", key, name); break; - case typeOnlyExport: + case TYPE_ONLY_EXPORT: addTypeBinding("typebind", key, name); addNamespaceBinding("namespacebind", key, name); break; - case varAndTypeAndNamespaceDecl: + case VAR_AND_TYPE_AND_NAMESPACE_DECL: addVariableBinding("decl", key, name); addTypeBinding("typedecl", key, name); addNamespaceBinding("namespacedecl", key, name); break; - case export: - case exportBase: + case EXPORT: + case EXPORT_BASE: // At the time of writing, this kind of export is only allowed at the top-level. boolean resolved = false; - if (c.idcontext != IdContext.exportBase) { + if (c.idcontext != IdContext.EXPORT_BASE) { resolved |= addTypeBinding("typebind", key, name); } resolved |= addNamespaceBinding("namespacebind", key, name); @@ -534,8 +549,8 @@ public class ASTExtractor { addVariableBinding("bind", key, name); } break; - case label: - case typeLabel: + case LABEL: + case TYPE_LABEL: break; } return key; @@ -647,20 +662,20 @@ public class ASTExtractor { // The context can either be typeBind, namespaceBind, or varInTypeBind. IdContext baseIdContext = - c.idcontext == IdContext.varInTypeBind - ? IdContext.varInTypeBind - : IdContext.namespaceBind; + c.idcontext == IdContext.VAR_IN_TYPE_BIND + ? IdContext.VAR_IN_TYPE_BIND + : IdContext.NAMESPACE_BIND; visit(nd.getObject(), key, 0, baseIdContext); // Ensure the property name is not a TypeAccess, since this would create two // TypeAccesses from the same type usage, easily leading to duplicate query // results. The qualified access is the one we prefer to select. - visit(nd.getProperty(), key, 1, IdContext.typeLabel); + visit(nd.getProperty(), key, 1, IdContext.TYPE_LABEL); } else { IdContext baseIdContext = - c.idcontext == IdContext.export ? IdContext.exportBase : IdContext.varBind; + c.idcontext == IdContext.EXPORT ? IdContext.EXPORT_BASE : IdContext.VAR_BIND; visit(nd.getObject(), key, 0, baseIdContext); - visit(nd.getProperty(), key, 1, nd.isComputed() ? IdContext.varBind : IdContext.label); + visit(nd.getProperty(), key, 1, nd.isComputed() ? IdContext.VAR_BIND : IdContext.LABEL); } if (nd.isOptional()) { trapwriter.addTuple("isOptionalChaining", key); @@ -689,7 +704,10 @@ public class ASTExtractor { + locationManager.getStartLine() + "," + locationManager.getStartColumn()); - scopeManager.enterScope(3, moduleScopeKey, toplevelLabel); + Scope moduleScope = scopeManager.enterScope(ScopeKind.MODULE, moduleScopeKey, toplevelLabel); + if (sourceType.hasNoGlobalScope()) { + scopeManager.setImplicitVariableScope(moduleScope); + } scopeManager.addVariables( sourceType.getPredefinedLocals(platform, locationManager.getSourceFileExtension())); trapwriter.addTuple("is_module", toplevelLabel); @@ -763,7 +781,7 @@ public class ASTExtractor { scopeManager.collectDeclaredNames(nd.getLeft(), isStrict, true, DeclKind.var); scopeManager.enterScope(nd); scopeManager.addNames(lexicals); - visit(nd.getLeft(), key, 0, IdContext.varDecl); + visit(nd.getLeft(), key, 0, IdContext.VAR_DECL); visit(nd.getRight(), key, 1); return key; } @@ -771,7 +789,7 @@ public class ASTExtractor { @Override public Label visit(ComprehensionExpression nd, Context c) { Label key = super.visit(nd, c); - visitAll(nd.getBlocks(), key, IdContext.varBind, 1); + visitAll(nd.getBlocks(), key, IdContext.VAR_BIND, 1); visit(nd.getFilter(), key, -1); visit(nd.getBody(), key, 0); for (int i = nd.getBlocks().size(); i > 0; --i) scopeManager.leaveScope(); @@ -845,7 +863,7 @@ public class ASTExtractor { scopeManager.enterScope(nd); scopeManager.addNames(lexicals); visitAll(head, key); - visit(body, key, -1, IdContext.varBind); + visit(body, key, -1, IdContext.VAR_BIND); scopeManager.leaveScope(); return key; } @@ -853,9 +871,9 @@ public class ASTExtractor { @Override public Label visit(VariableDeclarator nd, Context c) { Label key = super.visit(nd, c); - visit(nd.getId(), key, 0, IdContext.varDecl); + visit(nd.getId(), key, 0, IdContext.VAR_DECL); visit(nd.getInit(), key, 1); - visit(nd.getTypeAnnotation(), key, 2, IdContext.typeBind); + visit(nd.getTypeAnnotation(), key, 2, IdContext.TYPE_BIND); for (int i = 0; i < DeclarationFlags.numberOfFlags; ++i) { if (DeclarationFlags.hasNthFlag(nd.getFlags(), i)) { trapwriter.addTuple(DeclarationFlags.relationNames.get(i), key); @@ -913,7 +931,7 @@ public class ASTExtractor { // The name of a function declaration binds to the outer scope. if (nd instanceof FunctionDeclaration) { - visit(nd.getId(), key, -1, IdContext.varDecl); + visit(nd.getId(), key, -1, IdContext.VAR_DECL); } DeclaredNames locals = @@ -925,7 +943,7 @@ public class ASTExtractor { // The name of a function expression binds to its own scope. if (nd.getId() != null && nd instanceof AFunctionExpression) { scopeManager.addVariables(nd.getId().getName()); - visit(nd.getId(), key, -1, IdContext.varDecl); + visit(nd.getId(), key, -1, IdContext.VAR_DECL); } for (TypeParameter tp : nd.getTypeParameters()) { @@ -936,7 +954,7 @@ public class ASTExtractor { for (IPattern param : nd.getAllParams()) { scopeManager.addNames( scopeManager.collectDeclaredNames(param, isStrict, false, DeclKind.var)); - Label paramKey = visit(param, key, i, IdContext.varDecl); + Label paramKey = visit(param, key, i, IdContext.VAR_DECL); // Extract optional parameters if (nd.getOptionalParameterIndices().contains(i)) { @@ -953,10 +971,10 @@ public class ASTExtractor { } // add return type at index -3 - visit(nd.getReturnType(), key, -3, IdContext.typeBind); + visit(nd.getReturnType(), key, -3, IdContext.TYPE_BIND); // add 'this' type at index -4 - visit(nd.getThisParameterType(), key, -4, IdContext.typeBind); + visit(nd.getThisParameterType(), key, -4, IdContext.TYPE_BIND); // add parameter stuff at index -5 and down extractParameterDefaultsAndTypes(nd, key, i); @@ -985,12 +1003,12 @@ public class ASTExtractor { if (nd.hasDefault(j)) this.visit(nd.getDefault(j), key, -(4 * j + 5)); // parameter type annotations are populated at indices -6, -10, ... if (nd.hasParameterType(j)) - this.visit(nd.getParameterType(j), key, -(4 * j + 6), IdContext.typeBind); + this.visit(nd.getParameterType(j), key, -(4 * j + 6), IdContext.TYPE_BIND); } // type parameters are at indices -7, -11, -15, ... - visitAll(nd.getTypeParameters(), key, IdContext.typeDecl, -7, -4); + visitAll(nd.getTypeParameters(), key, IdContext.TYPE_DECL, -7, -4); // parameter decorators are at indices -8, -12, -16, ... - visitAll(nd.getParameterDecorators(), key, IdContext.varBind, -8, -4); + visitAll(nd.getParameterDecorators(), key, IdContext.VAR_BIND, -8, -4); } @Override @@ -1043,14 +1061,14 @@ public class ASTExtractor { */ if (!lexicals.isEmpty()) { VariableDeclaration decl = (VariableDeclaration) nd.getInit(); - Label declkey = visit((Statement) decl, new Context(key, 0, IdContext.varBind)); + Label declkey = visit((Statement) decl, new Context(key, 0, IdContext.VAR_BIND)); int idx = 0; for (VariableDeclarator declarator : decl.getDeclarations()) { Label declaratorKey = - visit((Expression) declarator, new Context(declkey, idx++, IdContext.varBind)); + visit((Expression) declarator, new Context(declkey, idx++, IdContext.VAR_BIND)); // the 'let' bound variable lives in the new scope - visit(declarator.getId(), declaratorKey, 0, IdContext.varDecl); + visit(declarator.getId(), declaratorKey, 0, IdContext.VAR_DECL); // but its initialiser does not scopeManager.leaveScope(); @@ -1092,7 +1110,7 @@ public class ASTExtractor { @Override public Label visit(ArrayExpression nd, Context c) { Label key = super.visit(nd, c); - visitAll(nd.getElements(), key, IdContext.varBind, 0); + visitAll(nd.getElements(), key, IdContext.VAR_BIND, 0); trapwriter.addTuple("array_size", key, nd.getElements().size()); return key; } @@ -1102,7 +1120,7 @@ public class ASTExtractor { Label key = super.visit(nd, c); visitAll(nd.getElements(), key, c.idcontext, 0); visit(nd.getRest(), key, -1, c.idcontext); - visitAll(nd.getDefaults(), key, IdContext.varBind, -2, -1); + visitAll(nd.getDefaults(), key, IdContext.VAR_BIND, -2, -1); trapwriter.addTuple("array_size", key, nd.getElements().size()); return key; } @@ -1118,7 +1136,7 @@ public class ASTExtractor { @Override public Label visit(ObjectExpression nd, Context c) { Label key = super.visit(nd, c); - visitAll(nd.getProperties(), key, IdContext.varBind, 0); + visitAll(nd.getProperties(), key, IdContext.VAR_BIND, 0); return key; } @@ -1129,15 +1147,81 @@ public class ASTExtractor { String tostring = lexicalExtractor.mkToString(nd); trapwriter.addTuple("properties", propkey, c.parent, c.childIndex, kind, tostring); locationManager.emitNodeLocation(nd, propkey); - visitAll(nd.getDecorators(), propkey, IdContext.varBind, -1, -1); - visit(nd.getKey(), propkey, 0, nd.isComputed() ? IdContext.varBind : IdContext.label); - visit(nd.getValue(), propkey, 1, c.idcontext); - visit(nd.getDefaultValue(), propkey, 2, IdContext.varBind); + visitAll(nd.getDecorators(), propkey, IdContext.VAR_BIND, -1, -1); + visit(nd.getKey(), propkey, 0, nd.isComputed() ? IdContext.VAR_BIND : IdContext.LABEL); + Label valueLabel = visit(nd.getValue(), propkey, 1, c.idcontext); + visit(nd.getDefaultValue(), propkey, 2, IdContext.VAR_BIND); if (nd.isComputed()) trapwriter.addTuple("is_computed", propkey); if (nd.isMethod()) trapwriter.addTuple("is_method", propkey); + + // Extract the value of a property named `template` as HTML, in order to support + // Angular2 components with an inline template. + if (!nd.isComputed() && "template".equals(tryGetIdentifierName(nd.getKey()))) { + extractStringValueAsHtml(nd.getValue(), valueLabel); + } + return propkey; } + /** + * Extracts the string value of expr as an HTML snippet. + */ + private void extractStringValueAsHtml(Expression expr, Label exprLabel) { + TextualExtractor textualExtractor = lexicalExtractor.getTextualExtractor(); + if (textualExtractor.isSnippet()) { + return; // do not create nested snippets + } + Pair sourceAndOffset = tryGetStringValueFromExpression(expr); + if (sourceAndOffset == null) { + return; + } + String source = sourceAndOffset.fst(); + SourceLocation loc = expr.getLoc(); + Path originalFile = textualExtractor.getExtractedFile().toPath(); + Path vfile = originalFile.resolveSibling(originalFile.getFileName().toString() + "." + loc.getStart().getLine() + "." + loc.getStart().getColumn() + ".html"); + SourceMap sourceMap = textualExtractor.getSourceMap().offsetBy(loc.getStart().getOffset(), sourceAndOffset.snd()); + TextualExtractor innerTextualExtractor = new TextualExtractor( + trapwriter, + locationManager, + source, + false, + getMetrics(), + vfile.toFile(), + sourceMap); + HTMLExtractor html = HTMLExtractor.forEmbeddedHtml(config); + List

  • All YAML files, that is, files with one of the extensions supported by {@link * FileType#YAML} (currently ".raml", ".yaml", ".yml"). - *
  • Files with base name "package.json". + *
  • Files with base name "package.json" or "tsconfig.json", and files whose base name + * is of the form "codeql-javascript-*.json". *
  • JavaScript, JSON or YAML files whose base name starts with ".eslintrc". *
  • All extension-less files. * @@ -402,10 +403,12 @@ public class AutoBuild { for (FileType filetype : defaultExtract) for (String extension : filetype.getExtensions()) patterns.add("**/*" + extension); - // include .eslintrc files, package.json files, and tsconfig.json files + // include .eslintrc files, package.json files, tsconfig.json files, and + // codeql-javascript-*.json files patterns.add("**/.eslintrc*"); patterns.add("**/package.json"); patterns.add("**/tsconfig.json"); + patterns.add("**/codeql-javascript-*.json"); // include any explicitly specified extensions for (String extension : fileTypes.keySet()) patterns.add("**/*" + extension); @@ -719,13 +722,13 @@ public class AutoBuild { } /** - * Prepares package.json files in a virtual source root, and, if enabled, + * Prepares package.json files in a virtual source root, and, if enabled, * installs dependencies for use by the TypeScript type checker. *

    * Some packages must be downloaded while others exist within the same repo ("monorepos") * but are not in a location where TypeScript would look for it. *

    - * Downloaded packages are intalled under SCRATCH_DIR, in a mirrored directory hierarchy + * Downloaded packages are intalled under SCRATCH_DIR, in a mirrored directory hierarchy * we call the "virtual source root". *

    * Packages that exists within the repo are not downloaded. Since they are part of the main source tree, diff --git a/javascript/extractor/src/com/semmle/js/extractor/ExprKinds.java b/javascript/extractor/src/com/semmle/js/extractor/ExprKinds.java index 44216d6b8d0..cfaa252a9f5 100644 --- a/javascript/extractor/src/com/semmle/js/extractor/ExprKinds.java +++ b/javascript/extractor/src/com/semmle/js/extractor/ExprKinds.java @@ -148,23 +148,24 @@ public class ExprKinds { exprKinds.put("BindExpression", 97); exprKinds.put("ExternalModuleReference", 98); exprKinds.put("NonNullAssertion", 105); + exprKinds.put("AngularPipeRef", 119); } private static final Map idKinds = new EnumMap(IdContext.class); static { - idKinds.put(IdContext.label, 0); - idKinds.put(IdContext.varDecl, 78); - idKinds.put(IdContext.varAndTypeDecl, 78); - idKinds.put(IdContext.namespaceDecl, 78); - idKinds.put(IdContext.varAndNamespaceDecl, 78); - idKinds.put(IdContext.varAndTypeAndNamespaceDecl, 78); - idKinds.put(IdContext.typeOnlyImport, 78); - idKinds.put(IdContext.typeOnlyExport, 103); - idKinds.put(IdContext.varBind, 79); - idKinds.put(IdContext.export, 103); - idKinds.put(IdContext.exportBase, 103); + idKinds.put(IdContext.LABEL, 0); + idKinds.put(IdContext.VAR_DECL, 78); + idKinds.put(IdContext.VAR_AND_TYPE_DECL, 78); + idKinds.put(IdContext.NAMESPACE_DECL, 78); + idKinds.put(IdContext.VAR_AND_NAMESPACE_DECL, 78); + idKinds.put(IdContext.VAR_AND_TYPE_AND_NAMESPACE_DECL, 78); + idKinds.put(IdContext.TYPE_ONLY_IMPORT, 78); + idKinds.put(IdContext.TYPE_ONLY_EXPORT, 103); + idKinds.put(IdContext.VAR_BIND, 79); + idKinds.put(IdContext.EXPORT, 103); + idKinds.put(IdContext.EXPORT_BASE, 103); } public static int getExprKind(final Expression expr, final IdContext idContext) { diff --git a/javascript/extractor/src/com/semmle/js/extractor/ExtractorConfig.java b/javascript/extractor/src/com/semmle/js/extractor/ExtractorConfig.java index 825a031b62e..8543ddf16da 100644 --- a/javascript/extractor/src/com/semmle/js/extractor/ExtractorConfig.java +++ b/javascript/extractor/src/com/semmle/js/extractor/ExtractorConfig.java @@ -10,6 +10,10 @@ import java.util.LinkedHashSet; import java.util.Set; import com.semmle.extractor.html.HtmlPopulator; +import com.semmle.jcorn.AngularExpressionParser; +import com.semmle.jcorn.CustomParser; +import com.semmle.jcorn.Options; +import com.semmle.jcorn.Parser; import com.semmle.js.parser.JcornWrapper; import com.semmle.util.data.StringUtil; import com.semmle.util.exception.UserError; @@ -78,6 +82,9 @@ public class ExtractorConfig { /** A CommonJS module that is not also an ES2015 module. */ COMMONJS_MODULE, + /** An Angular template expression. */ + ANGULAR_TEMPLATE, + /** Automatically determined source type. */ AUTO; @@ -86,6 +93,18 @@ public class ExtractorConfig { return StringUtil.lc(name()); } + /** + * Gets the parser to use for parsing this source type. + */ + public Parser createParser(Options options, String input, int startPos) { + switch (this) { + case ANGULAR_TEMPLATE: + return new AngularExpressionParser(options, input, startPos); + default: + return new CustomParser(options, input, startPos); + } + } + /** * Returns true if this source is executed directly in the global scope, or false if it has its * own local scope. @@ -94,6 +113,14 @@ public class ExtractorConfig { return this != SCRIPT; } + /** + * Returns true if this source type cannot access the global scope directly, and undeclared + * variables are implicitly declared in its local scope. Implies {@link #hasLocalScope()}. + */ + public boolean hasNoGlobalScope() { + return this == ANGULAR_TEMPLATE; + } + /** Returns true if this source is implicitly in strict mode. */ public boolean isStrictMode() { return this == MODULE; diff --git a/javascript/extractor/src/com/semmle/js/extractor/FileSnippet.java b/javascript/extractor/src/com/semmle/js/extractor/FileSnippet.java index 12d74fcef3f..4e0a41a5218 100644 --- a/javascript/extractor/src/com/semmle/js/extractor/FileSnippet.java +++ b/javascript/extractor/src/com/semmle/js/extractor/FileSnippet.java @@ -11,10 +11,10 @@ public class FileSnippet { private Path originalFile; private int line; private int column; - private int topLevelKind; + private TopLevelKind topLevelKind; private SourceType sourceType; - public FileSnippet(Path originalFile, int line, int column, int topLevelKind, SourceType sourceType) { + public FileSnippet(Path originalFile, int line, int column, TopLevelKind topLevelKind, SourceType sourceType) { this.originalFile = originalFile; this.line = line; this.column = column; @@ -34,7 +34,7 @@ public class FileSnippet { return column; } - public int getTopLevelKind() { + public TopLevelKind getTopLevelKind() { return topLevelKind; } diff --git a/javascript/extractor/src/com/semmle/js/extractor/HTMLExtractor.java b/javascript/extractor/src/com/semmle/js/extractor/HTMLExtractor.java index 06bfda3728d..561bbdb9171 100644 --- a/javascript/extractor/src/com/semmle/js/extractor/HTMLExtractor.java +++ b/javascript/extractor/src/com/semmle/js/extractor/HTMLExtractor.java @@ -1,7 +1,10 @@ package com.semmle.js.extractor; import java.io.File; +import java.io.IOException; import java.nio.file.Path; +import java.util.List; +import java.util.regex.Matcher; import java.util.regex.Pattern; import com.semmle.extractor.html.HtmlPopulator; @@ -9,234 +12,338 @@ import com.semmle.js.extractor.ExtractorConfig.Platform; import com.semmle.js.extractor.ExtractorConfig.SourceType; import com.semmle.js.parser.ParseError; import com.semmle.util.data.Option; +import com.semmle.util.data.Pair; import com.semmle.util.data.StringUtil; import com.semmle.util.io.WholeIO; +import com.semmle.util.locations.Position; import com.semmle.util.trap.TrapWriter; +import com.semmle.util.trap.TrapWriter.Label; import net.htmlparser.jericho.Attribute; import net.htmlparser.jericho.Attributes; import net.htmlparser.jericho.Element; import net.htmlparser.jericho.HTMLElementName; -import net.htmlparser.jericho.RowColumnVector; import net.htmlparser.jericho.Segment; /** Extractor for handling HTML and XHTML files. */ public class HTMLExtractor implements IExtractor { - private class JavaScriptHTMLElementHandler implements HtmlPopulator.ElementHandler { - private final ScopeManager scopeManager; - private final TextualExtractor textualExtractor; - private LoCInfo locInfo; + private LoCInfo locInfo = new LoCInfo(0, 0); - public JavaScriptHTMLElementHandler(TextualExtractor textualExtractor) { - this.textualExtractor = textualExtractor; + private class JavaScriptHTMLElementHandler implements HtmlPopulator.ElementHandler { + private final ScopeManager scopeManager; + private final TextualExtractor textualExtractor; + + public JavaScriptHTMLElementHandler(TextualExtractor textualExtractor) { + this.textualExtractor = textualExtractor; - this.locInfo = new LoCInfo(0, 0); + this.scopeManager = + new ScopeManager(textualExtractor.getTrapwriter(), config.getEcmaVersion()); + } - this.scopeManager = new ScopeManager(textualExtractor.getTrapwriter(), config.getEcmaVersion()); - } + /* + * Extract all JavaScript snippets appearing in (in-line) script elements and as + * attribute values. + */ + @Override + public void handleElement(Element elt, HtmlPopulator.Context context) { + if (elt.getName().equals(HTMLElementName.SCRIPT)) { + SourceType sourceType = getScriptSourceType(elt, textualExtractor.getExtractedFile()); + if (sourceType != null) { + // Jericho sometimes misparses empty elements, which will show up as start tags + // ending in "/"; we manually exclude these cases to avoid spurious syntax + // errors + if (elt.getStartTag().getTagContent().toString().trim().endsWith("/")) return; - /* - * Extract all JavaScript snippets appearing in (in-line) script elements and as - * attribute values. - */ - @Override - public void handleElement(Element elt) { - LoCInfo snippetLoC = null; - if (elt.getName().equals(HTMLElementName.SCRIPT)) { - SourceType sourceType = getScriptSourceType(elt, textualExtractor.getExtractedFile()); - if (sourceType != null) { - // Jericho sometimes misparses empty elements, which will show up as start tags - // ending in "/"; we manually exclude these cases to avoid spurious syntax - // errors - if (elt.getStartTag().getTagContent().toString().trim().endsWith("/")) - return; + Segment content = elt.getContent(); + String source = content.toString(); + boolean isTypeScript = isTypeScriptTag(elt); - Segment content = elt.getContent(); - String source = content.toString(); - boolean isTypeScript = isTypeScriptTag(elt); + /* + * Script blocks in XHTML files may wrap (parts of) their code inside CDATA + * sections. We need to unwrap them in order not to confuse the JavaScript + * parser. + * + * Note that CDATA sections do not nest, so they can be detected by a regular + * expression. + * + * In order to preserve position information, we replace the CDATA section + * markers with an equivalent number of whitespace characters. This will yield + * surprising results for CDATA sections inside string literals, but those are + * likely to be rare. + */ + source = source.replace("", " "); + if (!source.trim().isEmpty()) { + extractSnippet( + TopLevelKind.INLINE_SCRIPT, + config.withSourceType(sourceType), + scopeManager, + textualExtractor, + source, + content.getBegin(), + isTypeScript, + elt, + context); + } + } + } else { + Attributes attributes = elt.getAttributes(); + // attributes can be null for directives + if (attributes != null) + for (Attribute attr : attributes) { + // ignore empty attributes + if (attr.getValue() == null || attr.getValue().isEmpty()) continue; - /* - * Script blocks in XHTML files may wrap (parts of) their code inside CDATA - * sections. We need to unwrap them in order not to confuse the JavaScript - * parser. - * - * Note that CDATA sections do not nest, so they can be detected by a regular - * expression. - * - * In order to preserve position information, we replace the CDATA section - * markers with an equivalent number of whitespace characters. This will yield - * surprising results for CDATA sections inside string literals, but those are - * likely to be rare. - */ - source = source.replace("", " "); - if (!source.trim().isEmpty()) { - RowColumnVector contentStart = content.getRowColumnVector(); - snippetLoC = extractSnippet(1, config.withSourceType(sourceType), scopeManager, - textualExtractor, source, contentStart.getRow(), contentStart.getColumn(), - isTypeScript); - } - } - } else { - Attributes attributes = elt.getAttributes(); - // attributes can be null for directives - if (attributes != null) - for (Attribute attr : attributes) { - // ignore empty attributes - if (attr.getValue() == null || attr.getValue().isEmpty()) - continue; + String source = attr.getValue(); + int valueStart = attr.getValueSegment().getBegin(); + if (JS_ATTRIBUTE.matcher(attr.getName()).matches()) { + extractSnippet( + TopLevelKind.EVENT_HANDLER, + config, + scopeManager, + textualExtractor, + source, + valueStart, + false /* isTypeScript */, + attr, + context); + } else if (isAngularTemplateAttributeName(attr.getName())) { + // For an attribute *ngFor="let var of EXPR", start parsing at EXPR + int offset = 0; + if (attr.getName().equals("*ngFor")) { + Matcher m = ANGULAR_FOR_LOOP_DECL.matcher(source); + if (m.matches()) { + String expr = m.group(2); + offset = m.end(2) - expr.length(); + source = expr; + } + } + extractSnippet( + TopLevelKind.ANGULAR_TEMPLATE, + config.withSourceType(SourceType.ANGULAR_TEMPLATE), + scopeManager, + textualExtractor, + source, + valueStart + offset, + false /* isTypeScript */, + attr, + context); + } else if (source.startsWith("javascript:")) { + source = source.substring(11); + extractSnippet( + TopLevelKind.JAVASCRIPT_URL, + config, + scopeManager, + textualExtractor, + source, + valueStart + 11, + false /* isTypeScript */, + attr, + context); + } + } + } + } + } - String source = attr.getValue(); - RowColumnVector valueStart = attr.getValueSegment().getRowColumnVector(); - if (JS_ATTRIBUTE.matcher(attr.getName()).matches()) { - snippetLoC = extractSnippet(2, config, scopeManager, textualExtractor, source, - valueStart.getRow(), valueStart.getColumn(), false /* isTypeScript */); - } else if (source.startsWith("javascript:")) { - source = source.substring(11); - snippetLoC = extractSnippet(3, config, scopeManager, textualExtractor, source, - valueStart.getRow(), valueStart.getColumn() + 11, false /* isTypeScript */); - } - } - } + private boolean isAngularTemplateAttributeName(String name) { + return name.startsWith("[") && name.endsWith("]") || + name.startsWith("(") && name.endsWith(")") || + name.startsWith("*ng"); + } - if (snippetLoC != null) - locInfo.add(snippetLoC); - } + private static final Pattern ANGULAR_FOR_LOOP_DECL = Pattern.compile("^ *let +(\\w+) +of(?: +|(?!\\w))(.*)"); - public LoCInfo getLoCInfo() { - return this.locInfo; - } - } + /** List of HTML attributes whose value is interpreted as JavaScript. */ + private static final Pattern JS_ATTRIBUTE = + Pattern.compile( + "^on(abort|blur|change|(dbl)?click|error|focus|key(down|press|up)|load|mouse(down|move|out|over|up)|re(set|size)|select|submit|unload)$", + Pattern.CASE_INSENSITIVE); - /** List of HTML attributes whose value is interpreted as JavaScript. */ - private static final Pattern JS_ATTRIBUTE = Pattern.compile( - "^on(abort|blur|change|(dbl)?click|error|focus|key(down|press|up)|load|mouse(down|move|out|over|up)|re(set|size)|select|submit|unload)$", - Pattern.CASE_INSENSITIVE); + private final ExtractorConfig config; + private final ExtractorState state; + private final boolean isEmbedded; - private final ExtractorConfig config; - private final ExtractorState state; + public HTMLExtractor(ExtractorConfig config, ExtractorState state, boolean isEmbedded) { + this.config = config.withPlatform(Platform.WEB); + this.state = state; + this.isEmbedded = isEmbedded; + } - public HTMLExtractor(ExtractorConfig config, ExtractorState state) { - this.config = config.withPlatform(Platform.WEB); - this.state = state; - } + public HTMLExtractor(ExtractorConfig config, ExtractorState state) { + this(config, state, false); + } - @Override - public LoCInfo extract(TextualExtractor textualExtractor) { - JavaScriptHTMLElementHandler eltHandler = new JavaScriptHTMLElementHandler(textualExtractor); + /** Creates an HTML extractor for embedded HTML snippets. */ + public static HTMLExtractor forEmbeddedHtml(ExtractorConfig config) { + return new HTMLExtractor(config, null, true); + } + + @Override + public LoCInfo extract(TextualExtractor textualExtractor) throws IOException { + return extractEx(textualExtractor).snd(); + } - HtmlPopulator extractor = new HtmlPopulator(this.config.getHtmlHandling(), textualExtractor.getSource(), - textualExtractor.getTrapwriter(), textualExtractor.getLocationManager().getFileLabel()); + public Pair, LoCInfo> extractEx(TextualExtractor textualExtractor) { + // Angular templates contain attribute names that are not valid HTML/XML, such as [foo], (foo), [(foo)], and *foo. + // Allow a large number of errors in attribute names, so the Jericho parser does not give up. + Attributes.setDefaultMaxErrorCount(100); + JavaScriptHTMLElementHandler eltHandler = new JavaScriptHTMLElementHandler(textualExtractor); - extractor.doit(Option.some(eltHandler)); + LocationManager locationManager = textualExtractor.getLocationManager(); + HtmlPopulator extractor = + new HtmlPopulator( + this.config.getHtmlHandling(), + textualExtractor.getSource(), + textualExtractor.getTrapwriter(), + locationManager.getFileLabel()); - return eltHandler.getLoCInfo(); - } + // For efficiency, avoid building the source map if not needed (i.e. for plain HTML files). + if (textualExtractor.hasNonTrivialSourceMap()) { + extractor.setSourceMap(textualExtractor.getSourceMap()); + } - /** - * Deduce the {@link SourceType} with which the given script - * element should be extracted, returning null if it cannot be - * determined. - */ - private SourceType getScriptSourceType(Element script, File file) { - String scriptType = getAttributeValueLC(script, "type"); - String scriptLanguage = getScriptLanguage(script); + List